diff options
Diffstat (limited to 'tex')
847 files changed, 149115 insertions, 32959 deletions
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf Binary files differindex ff75a0a20..a13a07a4e 100644 --- a/tex/context/base/context-version.pdf +++ b/tex/context/base/context-version.pdf diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index f0385c065..ec59205b7 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2013.06.07 17:34} +\newcontextversion{2017.05.14 19:09} %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/mkii/context.mkii b/tex/context/base/mkii/context.mkii index 84679a9a2..b31ece259 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2013.06.07 17:34} +\edef\contextversion{2017.05.14 19:09} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-cs.mkii b/tex/context/base/mkii/mult-cs.mkii new file mode 100644 index 000000000..837a397fb --- /dev/null +++ b/tex/context/base/mkii/mult-cs.mkii @@ -0,0 +1,1970 @@ +% this file is auto-generated, don't edit this file +% +% definitions for interface variables for language cs +% +\setinterfacevariable{Addition}{Pridavek} +\setinterfacevariable{Alphabetic}{Alphabetic} +\setinterfacevariable{Balloon}{Bublinka} +\setinterfacevariable{Cap}{Kap} +\setinterfacevariable{Capital}{Kapitalky} +\setinterfacevariable{Character}{Pismeno} +\setinterfacevariable{Characters}{Pismena} +\setinterfacevariable{CloseDocument}{ZavritDokument} +\setinterfacevariable{ExitViewer}{UkoncitProhlizec} +\setinterfacevariable{FirstPage}{PrvniStrana} +\setinterfacevariable{FitHeight}{FitHeight} +\setinterfacevariable{FitWidth}{FitWidth} +\setinterfacevariable{GotoPage}{JdiNaStranku} +\setinterfacevariable{Greek}{Recky} +\setinterfacevariable{Help}{Napoveda} +\setinterfacevariable{HideField}{SkryjPole} +\setinterfacevariable{HideLayer}{HideLayer} +\setinterfacevariable{Key}{Klavesa} +\setinterfacevariable{LastPage}{PosledniStrana} +\setinterfacevariable{LoadForm}{NacistFormular} +\setinterfacevariable{MONTH}{MESIC} +\setinterfacevariable{New}{Novy} +\setinterfacevariable{NextJump}{NasledujiciSkok} +\setinterfacevariable{NextPage}{DalsiStrana} +\setinterfacevariable{Numbers}{Cisla} +\setinterfacevariable{OpenNamedDocument}{OpenNamedDocument} +\setinterfacevariable{Ordinal}{Ordinal} +\setinterfacevariable{Paragraph}{Odstavec} +\setinterfacevariable{PauseMovie}{PozastavitFilm} +\setinterfacevariable{PauseRendering}{PauseRendering} +\setinterfacevariable{PauseSound}{PozastavitZvuk} +\setinterfacevariable{PreviousJump}{PredchoziSkok} +\setinterfacevariable{PreviousPage}{PredchoziStrana} +\setinterfacevariable{PrintDocument}{VytisknoutDokument} +\setinterfacevariable{Query}{Query} +\setinterfacevariable{QueryAgain}{QueryAgain} +\setinterfacevariable{ResetForm}{ResetFormulare} +\setinterfacevariable{ResumeMovie}{PokracovatFilm} +\setinterfacevariable{ResumeRendering}{ResumeRendering} +\setinterfacevariable{ResumeSound}{PokracovatZvuk} +\setinterfacevariable{Romannumerals}{Rimskecislice} +\setinterfacevariable{SaveDocument}{UlozitDokument} +\setinterfacevariable{SaveForm}{UlozitFormular} +\setinterfacevariable{SaveNamedDocument}{SaveNamedDocument} +\setinterfacevariable{SearchAgain}{HledatZnovu} +\setinterfacevariable{SearchDocument}{ProhledatDokument} +\setinterfacevariable{ShowBookmarks}{UkazZalozky} +\setinterfacevariable{ShowField}{UkazPole} +\setinterfacevariable{ShowThumbs}{UkazNahledy} +\setinterfacevariable{StartMovie}{SpustitFilm} +\setinterfacevariable{StartRendering}{StartRendering} +\setinterfacevariable{StartSound}{StartZvuk} +\setinterfacevariable{StopMovie}{ZastavitFilm} +\setinterfacevariable{StopRendering}{StopRendering} +\setinterfacevariable{StopSound}{StopZvuk} +\setinterfacevariable{SubmitForm}{PoslatFormular} +\setinterfacevariable{ToggleLayer}{ToggleLayer} +\setinterfacevariable{ToggleViewer}{ZmenitProhlizec} +\setinterfacevariable{URL}{URL} +\setinterfacevariable{VideLayer}{VideLayer} +\setinterfacevariable{ViewerHelp}{NapovedaProhlizece} +\setinterfacevariable{WEEKDAY}{VSEDNIDEN} +\setinterfacevariable{WORD}{SLOVO} +\setinterfacevariable{WORDS}{SLOVA} +\setinterfacevariable{Word}{Slovo} +\setinterfacevariable{Words}{Slova} +\setinterfacevariable{abbreviation}{zkratka} +\setinterfacevariable{abbreviations}{zkratky} +\setinterfacevariable{absolute}{absolutni} +\setinterfacevariable{action}{akce} +\setinterfacevariable{after}{po} +\setinterfacevariable{all}{vse} +\setinterfacevariable{alphabetic}{alphabetic} +\setinterfacevariable{always}{vzdy} +\setinterfacevariable{anchor}{anchor} +\setinterfacevariable{and}{and} +\setinterfacevariable{answerarea}{answerarea} +\setinterfacevariable{appendices}{dodatky} +\setinterfacevariable{appendix}{dodatek} +\setinterfacevariable{april}{duben} +\setinterfacevariable{aside}{aside} +\setinterfacevariable{atleftmargin}{atleftmargin} +\setinterfacevariable{atmargin}{naokraji} +\setinterfacevariable{atpage}{nastrance} +\setinterfacevariable{atrightmargin}{atrightmargin} +\setinterfacevariable{attachment}{attachment} +\setinterfacevariable{august}{srpen} +\setinterfacevariable{author}{autor} +\setinterfacevariable{auto}{auto} +\setinterfacevariable{autointro}{autouvod} +\setinterfacevariable{autopunctuation}{autopunctuation} +\setinterfacevariable{back}{zpet} +\setinterfacevariable{background}{pozadi} +\setinterfacevariable{backmatter}{epilogy} +\setinterfacevariable{backpart}{epilog} +\setinterfacevariable{backspace}{zpetnamezera} +\setinterfacevariable{backward}{zpet} +\setinterfacevariable{bbl}{bbl} +\setinterfacevariable{before}{pred} +\setinterfacevariable{begin}{begin} +\setinterfacevariable{bib}{bib} +\setinterfacevariable{big}{velke} +\setinterfacevariable{bigbodyfont}{bigbodyfont} +\setinterfacevariable{bigger}{bigger} +\setinterfacevariable{bigpreference}{vysokapriorita} +\setinterfacevariable{blank}{prazdny} +\setinterfacevariable{block}{block} +\setinterfacevariable{blockquote}{blockquote} +\setinterfacevariable{bodymatter}{hlavnicasti} +\setinterfacevariable{bodypart}{hlavnicast} +\setinterfacevariable{bold}{tucne} +\setinterfacevariable{bolditalic}{tucnekurzivni} +\setinterfacevariable{boldslanted}{tucnesklonene} +\setinterfacevariable{bookmark}{zalozka} +\setinterfacevariable{both}{obe} +\setinterfacevariable{bothtext}{bothtext} +\setinterfacevariable{bottom}{spodek} +\setinterfacevariable{box}{box} +\setinterfacevariable{brief}{brief} +\setinterfacevariable{broad}{siroky} +\setinterfacevariable{buffer}{buffer} +\setinterfacevariable{by}{skrz} +\setinterfacevariable{calligraphic}{kaligraficke} +\setinterfacevariable{camel}{camel} +\setinterfacevariable{cap}{kap} +\setinterfacevariable{capital}{kapitalky} +\setinterfacevariable{center}{center} +\setinterfacevariable{centerlast}{centerlast} +\setinterfacevariable{chapter}{kapitola} +\setinterfacevariable{character}{pismeno} +\setinterfacevariable{characters}{pismena} +\setinterfacevariable{chemical}{chemical} +\setinterfacevariable{chemicals}{chemicals} +\setinterfacevariable{chemistry}{chemistry} +\setinterfacevariable{cite}{cite} +\setinterfacevariable{color}{barevne} +\setinterfacevariable{column}{column} +\setinterfacevariable{columns}{sloupce} +\setinterfacevariable{combination}{combination} +\setinterfacevariable{command}{prikaz} +\setinterfacevariable{commands}{prikazy} +\setinterfacevariable{comment}{komentar} +\setinterfacevariable{component}{komponenta} +\setinterfacevariable{compressseparator}{compressseparator} +\setinterfacevariable{concept}{koncept} +\setinterfacevariable{construction}{construction} +\setinterfacevariable{content}{obsah} +\setinterfacevariable{contents}{obsah} +\setinterfacevariable{continue}{pokracovat} +\setinterfacevariable{continued}{continued} +\setinterfacevariable{controls}{controls} +\setinterfacevariable{conversion}{konverze} +\setinterfacevariable{current}{aktualni} +\setinterfacevariable{cutspace}{cutspace} +\setinterfacevariable{dataset}{dataset} +\setinterfacevariable{date}{datum} +\setinterfacevariable{day}{den} +\setinterfacevariable{december}{prosinec} +\setinterfacevariable{default}{implicitni} +\setinterfacevariable{depth}{podlehloubky} +\setinterfacevariable{description}{popis} +\setinterfacevariable{disable}{zablokovat} +\setinterfacevariable{display}{obrazovka} +\setinterfacevariable{dot}{tecka} +\setinterfacevariable{doublesided}{dvoustranny} +\setinterfacevariable{down}{down} +\setinterfacevariable{each}{kazdy} +\setinterfacevariable{edge}{hrana} +\setinterfacevariable{effective}{effective} +\setinterfacevariable{eight}{eight} +\setinterfacevariable{embed}{embed} +\setinterfacevariable{empty}{prazdne} +\setinterfacevariable{enable}{enable} +\setinterfacevariable{end}{end} +\setinterfacevariable{endnote}{endnote} +\setinterfacevariable{enumeration}{vycet} +\setinterfacevariable{environment}{prostredi} +\setinterfacevariable{even}{sude} +\setinterfacevariable{export}{export} +\setinterfacevariable{external}{externi} +\setinterfacevariable{extremestretch}{extremestretch} +\setinterfacevariable{fact}{fakt} +\setinterfacevariable{february}{unor} +\setinterfacevariable{figure}{obrazek} +\setinterfacevariable{figures}{obrazky} +\setinterfacevariable{file}{soubor} +\setinterfacevariable{final}{finalni} +\setinterfacevariable{first}{prvni} +\setinterfacevariable{firstcolumn}{firstcolumn} +\setinterfacevariable{firstpage}{prvnistranka} +\setinterfacevariable{firstsubpage}{prvnipodstranka} +\setinterfacevariable{fit}{prizpusobive} +\setinterfacevariable{five}{pet} +\setinterfacevariable{fix}{fixuj} +\setinterfacevariable{fixed}{fixne} +\setinterfacevariable{flexible}{prizpusobive} +\setinterfacevariable{float}{plvouciobjekt} +\setinterfacevariable{flushinner}{flushinner} +\setinterfacevariable{flushleft}{flushleft} +\setinterfacevariable{flushouter}{flushouter} +\setinterfacevariable{flushright}{flushright} +\setinterfacevariable{followingpage}{followingpage} +\setinterfacevariable{footer}{upati} +\setinterfacevariable{footnote}{poznamkapodcarou} +\setinterfacevariable{force}{sila} +\setinterfacevariable{foreground}{popredi} +\setinterfacevariable{formula}{rovnice} +\setinterfacevariable{formulas}{rovnice} +\setinterfacevariable{forward}{vpred} +\setinterfacevariable{four}{ctyri} +\setinterfacevariable{fractions}{fractions} +\setinterfacevariable{frame}{ramecek} +\setinterfacevariable{framedtext}{oramovanytext} +\setinterfacevariable{friday}{patek} +\setinterfacevariable{frontmatter}{prednicasti} +\setinterfacevariable{frontpart}{prednicast} +\setinterfacevariable{fullhz}{fullhz} +\setinterfacevariable{global}{globalne} +\setinterfacevariable{graphic}{graf} +\setinterfacevariable{graphics}{grafy} +\setinterfacevariable{gray}{seda} +\setinterfacevariable{greek}{recky} +\setinterfacevariable{grid}{mrizka} +\setinterfacevariable{halfline}{pulradku} +\setinterfacevariable{handwritten}{rukopisne} +\setinterfacevariable{hang}{zaveseni} +\setinterfacevariable{hanging}{visici} +\setinterfacevariable{head}{hlavicka} +\setinterfacevariable{header}{zahlavi} +\setinterfacevariable{height}{vyska} +\setinterfacevariable{helptext}{textnapovedy} +\setinterfacevariable{hencefore}{vyse} +\setinterfacevariable{here}{zde} +\setinterfacevariable{hereafter}{nize} +\setinterfacevariable{hidden}{skryte} +\setinterfacevariable{hiddenbar}{hiddenbar} +\setinterfacevariable{hiding}{skryt} +\setinterfacevariable{high}{vysoko} +\setinterfacevariable{horizontal}{horizontalne} +\setinterfacevariable{hyphenated}{hyphenated} +\setinterfacevariable{hz}{hz} +\setinterfacevariable{inbetween}{mezi} +\setinterfacevariable{index}{rejstrik} +\setinterfacevariable{indices}{rejstriky} +\setinterfacevariable{inherit}{inherit} +\setinterfacevariable{ininner}{ininner} +\setinterfacevariable{ininneredge}{ininneredge} +\setinterfacevariable{ininnermargin}{ininnermargin} +\setinterfacevariable{inleft}{ivlevo} +\setinterfacevariable{inleftedge}{nalevo} +\setinterfacevariable{inleftmargin}{nalevyokraj} +\setinterfacevariable{inline}{inline} +\setinterfacevariable{inmargin}{naokraji} +\setinterfacevariable{inner}{uvnitr} +\setinterfacevariable{inneredge}{inneredge} +\setinterfacevariable{innermargin}{innermargin} +\setinterfacevariable{inother}{inother} +\setinterfacevariable{inouter}{inouter} +\setinterfacevariable{inouteredge}{inouteredge} +\setinterfacevariable{inoutermargin}{inoutermargin} +\setinterfacevariable{inright}{ivpravo} +\setinterfacevariable{inrightedge}{napravo} +\setinterfacevariable{inrightmargin}{napravyokraj} +\setinterfacevariable{integral}{integral} +\setinterfacevariable{interaction}{interakce} +\setinterfacevariable{interactionmenu}{interaktivnimenu} +\setinterfacevariable{interactive}{interactive} +\setinterfacevariable{intermezzi}{intermezzi} +\setinterfacevariable{intermezzo}{intermezzo} +\setinterfacevariable{intext}{dotextu} +\setinterfacevariable{intro}{uvod} +\setinterfacevariable{italic}{kurziva} +\setinterfacevariable{italicbold}{kurzivnitucne} +\setinterfacevariable{item}{polozka} +\setinterfacevariable{itemize}{vycet} +\setinterfacevariable{its}{pol} +\setinterfacevariable{january}{leden} +\setinterfacevariable{joinedup}{spojeno} +\setinterfacevariable{july}{cervenec} +\setinterfacevariable{june}{cerven} +\setinterfacevariable{keep}{drzet} +\setinterfacevariable{kerncharacters}{kerncharacters} +\setinterfacevariable{knockout}{knockout} +\setinterfacevariable{label}{popisek} +\setinterfacevariable{landscape}{nasirku} +\setinterfacevariable{last}{posledni} +\setinterfacevariable{lastcolumn}{lastcolumn} +\setinterfacevariable{lastpage}{poslednistrana} +\setinterfacevariable{lastpagenumber}{lastpagenumber} +\setinterfacevariable{lastsubpage}{poslaednipodstranka} +\setinterfacevariable{layer}{layer} +\setinterfacevariable{left}{vlevo} +\setinterfacevariable{leftedge}{levahrana} +\setinterfacevariable{lefthanging}{lefthanging} +\setinterfacevariable{leftmargin}{levyokraj} +\setinterfacevariable{leftpage}{levastranka} +\setinterfacevariable{lefttoright}{lefttoright} +\setinterfacevariable{legend}{legenda} +\setinterfacevariable{less}{less} +\setinterfacevariable{lesshyphenation}{lesshyphenation} +\setinterfacevariable{letterspacing}{letterspacing} +\setinterfacevariable{line}{radek} +\setinterfacevariable{linenote}{linenote} +\setinterfacevariable{lines}{radky} +\setinterfacevariable{linked}{linked} +\setinterfacevariable{list}{seznam} +\setinterfacevariable{local}{lokalne} +\setinterfacevariable{localenvironment}{lokalnihoprostredi} +\setinterfacevariable{logo}{logo} +\setinterfacevariable{logos}{loga} +\setinterfacevariable{lohi}{nivy} +\setinterfacevariable{long}{long} +\setinterfacevariable{loose}{uvolnene} +\setinterfacevariable{low}{nizko} +\setinterfacevariable{ls}{ls} +\setinterfacevariable{makeup}{zlom} +\setinterfacevariable{mar}{mar} +\setinterfacevariable{march}{brezen} +\setinterfacevariable{margin}{marginalie} +\setinterfacevariable{marginedge}{textovahrana} +\setinterfacevariable{margintext}{marginalnitext} +\setinterfacevariable{margintitle}{titulmarginalie} +\setinterfacevariable{marking}{znaceni} +\setinterfacevariable{math}{math} +\setinterfacevariable{mathalignment}{mathalignment} +\setinterfacevariable{mathcases}{mathcases} +\setinterfacevariable{mathematics}{mathematika} +\setinterfacevariable{mathmatrix}{mathmatrix} +\setinterfacevariable{max}{max} +\setinterfacevariable{maxdepth}{maxdepth} +\setinterfacevariable{maxheight}{maxheight} +\setinterfacevariable{maxwidth}{maxwidth} +\setinterfacevariable{may}{kveten} +\setinterfacevariable{mediaeval}{stredoveky} +\setinterfacevariable{medium}{stredni} +\setinterfacevariable{middle}{nastred} +\setinterfacevariable{min}{min} +\setinterfacevariable{mindepth}{mindepth} +\setinterfacevariable{minheight}{minvyska} +\setinterfacevariable{minwidth}{minsirka} +\setinterfacevariable{mirrored}{zrcadleno} +\setinterfacevariable{mixed}{mixed} +\setinterfacevariable{monday}{pondeli} +\setinterfacevariable{mono}{mono} +\setinterfacevariable{monobold}{monotucne} +\setinterfacevariable{mononormal}{mononormal} +\setinterfacevariable{month}{mesic} +\setinterfacevariable{more}{more} +\setinterfacevariable{morehyphenation}{morehyphenation} +\setinterfacevariable{name}{jmeno} +\setinterfacevariable{narrow}{uzky} +\setinterfacevariable{negative}{negativ} +\setinterfacevariable{never}{nikdy} +\setinterfacevariable{new}{novy} +\setinterfacevariable{next}{dalsi} +\setinterfacevariable{nextevenpage}{dalsisudastranka} +\setinterfacevariable{nextoddpage}{dalsilichastranka} +\setinterfacevariable{nextpage}{dalsistranka} +\setinterfacevariable{nextsubpage}{dalsipodstranka} +\setinterfacevariable{nine}{nine} +\setinterfacevariable{no}{ne} +\setinterfacevariable{nocheck}{nocheck} +\setinterfacevariable{nodepth}{nodepth} +\setinterfacevariable{nofit}{nofit} +\setinterfacevariable{nogrid}{nogrid} +\setinterfacevariable{noheight}{noheight} +\setinterfacevariable{nohz}{nohz} +\setinterfacevariable{noline}{noline} +\setinterfacevariable{nomarking}{zadneznaceni} +\setinterfacevariable{none}{zadny} +\setinterfacevariable{nonumber}{nonumber} +\setinterfacevariable{norepeat}{norepeat} +\setinterfacevariable{normal}{normalni} +\setinterfacevariable{nospacing}{nospacing} +\setinterfacevariable{not}{ne} +\setinterfacevariable{notation}{notation} +\setinterfacevariable{note}{note} +\setinterfacevariable{nothanging}{nothanging} +\setinterfacevariable{nothyphenated}{nothyphenated} +\setinterfacevariable{notjoinedup}{notjoinedup} +\setinterfacevariable{november}{listopad} +\setinterfacevariable{nowhere}{nikde} +\setinterfacevariable{nowhite}{zadnabila} +\setinterfacevariable{number}{cislo} +\setinterfacevariable{numbers}{cisla} +\setinterfacevariable{october}{rijen} +\setinterfacevariable{odd}{liche} +\setinterfacevariable{off}{vyp} +\setinterfacevariable{offset}{offset} +\setinterfacevariable{old}{old} +\setinterfacevariable{oldstyle}{oldstyle} +\setinterfacevariable{on}{zap} +\setinterfacevariable{one}{jedna} +\setinterfacevariable{opposite}{naproti} +\setinterfacevariable{ordinal}{ordinal} +\setinterfacevariable{outer}{vnejsi} +\setinterfacevariable{outeredge}{outeredge} +\setinterfacevariable{outermargin}{outermargin} +\setinterfacevariable{overbar}{nadtrzeno} +\setinterfacevariable{overbars}{nadtrzeni} +\setinterfacevariable{overlay}{prekryv} +\setinterfacevariable{overprint}{overprint} +\setinterfacevariable{overstrike}{preskrtnuto} +\setinterfacevariable{overstrikes}{preskrtnuti} +\setinterfacevariable{packed}{zhustene} +\setinterfacevariable{page}{stranka} +\setinterfacevariable{pagecomment}{komentarstranky} +\setinterfacevariable{pagenumber}{cislostranky} +\setinterfacevariable{paper}{papir} +\setinterfacevariable{paragraph}{odstavec} +\setinterfacevariable{part}{cast} +\setinterfacevariable{positive}{positiv} +\setinterfacevariable{postponing}{odlozit} +\setinterfacevariable{postscript}{postscript} +\setinterfacevariable{precedingpage}{followingpage} +\setinterfacevariable{preference}{nastaveni} +\setinterfacevariable{preview}{nahled} +\setinterfacevariable{previous}{predchozi} +\setinterfacevariable{previousevenpage}{predchozisudastranka} +\setinterfacevariable{previousoddpage}{predchozilichastranka} +\setinterfacevariable{previouspage}{predchozistranka} +\setinterfacevariable{previoussubpage}{predchozipodstranka} +\setinterfacevariable{print}{print} +\setinterfacevariable{printable}{tisknutelne} +\setinterfacevariable{process}{process} +\setinterfacevariable{product}{produkt} +\setinterfacevariable{program}{program} +\setinterfacevariable{project}{projekt} +\setinterfacevariable{protected}{chranene} +\setinterfacevariable{quadruple}{ctyrnasobny} +\setinterfacevariable{quarterline}{quarterline} +\setinterfacevariable{quotation}{citace} +\setinterfacevariable{quote}{citovat} +\setinterfacevariable{ran}{rozsah} +\setinterfacevariable{random}{nahodny} +\setinterfacevariable{readonly}{pouzeprocteni} +\setinterfacevariable{rectangular}{pravouhly} +\setinterfacevariable{reference}{odkaz} +\setinterfacevariable{referral}{znacka} +\setinterfacevariable{register}{rejstrik} +\setinterfacevariable{regular}{pravidelne} +\setinterfacevariable{relative}{relativni} +\setinterfacevariable{repeat}{opakovat} +\setinterfacevariable{required}{pozadovane} +\setinterfacevariable{reset}{reset} +\setinterfacevariable{reverse}{reverse} +\setinterfacevariable{right}{vpravo} +\setinterfacevariable{rightedge}{pravahrana} +\setinterfacevariable{righthanging}{righthanging} +\setinterfacevariable{rightmargin}{pravyokraj} +\setinterfacevariable{rightpage}{pravastranka} +\setinterfacevariable{righttoleft}{righttoleft} +\setinterfacevariable{roman}{antikva} +\setinterfacevariable{romannumerals}{rimskecislice} +\setinterfacevariable{rotate}{otoc} +\setinterfacevariable{rotated}{otoceno} +\setinterfacevariable{round}{zaobleny} +\setinterfacevariable{row}{row} +\setinterfacevariable{rule}{linka} +\setinterfacevariable{samepage}{stejnastranka} +\setinterfacevariable{sans}{sans} +\setinterfacevariable{sansbold}{sanstucne} +\setinterfacevariable{sansnormal}{sansnormal} +\setinterfacevariable{sansserif}{bezserifu} +\setinterfacevariable{saturday}{sobota} +\setinterfacevariable{screen}{rastr} +\setinterfacevariable{section}{sekce} +\setinterfacevariable{sectionblockenvironment}{sectionblockenvironment} +\setinterfacevariable{sectionnumber}{cislooddilu} +\setinterfacevariable{see}{viz} +\setinterfacevariable{selectfont}{selectfont} +\setinterfacevariable{september}{zari} +\setinterfacevariable{serif}{serif} +\setinterfacevariable{serifbold}{serifbold} +\setinterfacevariable{serifnormal}{serifnormal} +\setinterfacevariable{serried}{semknuto} +\setinterfacevariable{setups}{setups} +\setinterfacevariable{seven}{seven} +\setinterfacevariable{sheet}{sheet} +\setinterfacevariable{shiftdown}{shiftdown} +\setinterfacevariable{shiftup}{shiftup} +\setinterfacevariable{short}{short} +\setinterfacevariable{simplefonts}{simplefonts} +\setinterfacevariable{simplelist}{simplelist} +\setinterfacevariable{singlesided}{jednostranne} +\setinterfacevariable{six}{six} +\setinterfacevariable{slanted}{sklonene} +\setinterfacevariable{slantedbold}{sklonenetucne} +\setinterfacevariable{small}{male} +\setinterfacevariable{smallbodyfont}{smallbodyfont} +\setinterfacevariable{smallbold}{maletucne} +\setinterfacevariable{smallbolditalic}{maletucnekurzivni} +\setinterfacevariable{smallboldslanted}{maletucnesklonene} +\setinterfacevariable{smallcaps}{kapitalky} +\setinterfacevariable{smaller}{smaller} +\setinterfacevariable{smallitalic}{malekurzivni} +\setinterfacevariable{smallitalicbold}{malekurzivnitucne} +\setinterfacevariable{smallnormal}{malenormalni} +\setinterfacevariable{smallslanted}{malesklonene} +\setinterfacevariable{smallslantedbold}{malesklonenetucne} +\setinterfacevariable{smalltype}{maletype} +\setinterfacevariable{somewhere}{nekde} +\setinterfacevariable{sorted}{tridene} +\setinterfacevariable{sorting}{sorting} +\setinterfacevariable{space}{mezera} +\setinterfacevariable{spacing}{mezerovani} +\setinterfacevariable{speech}{speech} +\setinterfacevariable{split}{split} +\setinterfacevariable{spot}{spot} +\setinterfacevariable{standard}{standardni} +\setinterfacevariable{start}{start} +\setinterfacevariable{starter}{starter} +\setinterfacevariable{sticker}{sticker} +\setinterfacevariable{stop}{stop} +\setinterfacevariable{stopper}{predel} +\setinterfacevariable{stretch}{natahnout} +\setinterfacevariable{stretched}{stretched} +\setinterfacevariable{strict}{striktni} +\setinterfacevariable{strong}{strong} +\setinterfacevariable{strut}{strut} +\setinterfacevariable{sub}{pod} +\setinterfacevariable{subbackward}{podzpet} +\setinterfacevariable{subformula}{subrovnice} +\setinterfacevariable{subforward}{podvpred} +\setinterfacevariable{subject}{tema} +\setinterfacevariable{subpage}{podstranka} +\setinterfacevariable{subs}{subs} +\setinterfacevariable{subsection}{podsekce} +\setinterfacevariable{subsubject}{podtema} +\setinterfacevariable{subsubsection}{podpodsekce} +\setinterfacevariable{subsubsubject}{podpodtema} +\setinterfacevariable{subsubsubsection}{podpodpodsekce} +\setinterfacevariable{subsubsubsubject}{podpodpodtema} +\setinterfacevariable{subsubsubsubsection}{podpodpodpodsekce} +\setinterfacevariable{subsubsubsubsubject}{podpodpodpodtema} +\setinterfacevariable{subsubsubsubsubsection}{podpodpodpodpodsekce} +\setinterfacevariable{subsubsubsubsubsubject}{podpodpodpodpodtema} +\setinterfacevariable{subsubsubsubsubsubsection}{podpodpodpodpodpodsekce} +\setinterfacevariable{subsubsubsubsubsubsubject}{podpodpodpodpodpodtema} +\setinterfacevariable{subsubsubsubsubsubsubsection}{podpodpodpodpodpodpodsekce} +\setinterfacevariable{subsubsubsubsubsubsubsubject}{podpodpodpodpodpodpodtema} +\setinterfacevariable{subsubsubsubsubsubsubsubsection}{podpodpodpodpodpodpodpodsekce} +\setinterfacevariable{subsubsubsubsubsubsubsubsubject}{podpodpodpodpodpodpodpodtema} +\setinterfacevariable{subsubsubsubsubsubsubsubsubsection}{podpodpodpodpodpodpodpodpodsekce} +\setinterfacevariable{subsubsubsubsubsubsubsubsubsubject}{podpodpodpodpodpodpodpodpodtema} +\setinterfacevariable{sunday}{nedele} +\setinterfacevariable{support}{podpora} +\setinterfacevariable{sym}{sym} +\setinterfacevariable{symbol}{symbol} +\setinterfacevariable{synchronize}{synchronize} +\setinterfacevariable{synonym}{synonym} +\setinterfacevariable{system}{system} +\setinterfacevariable{table}{tabulka} +\setinterfacevariable{tablehead}{zahlavitabulky} +\setinterfacevariable{tables}{tabulky} +\setinterfacevariable{tabletail}{konectabulky} +\setinterfacevariable{tabulate}{tabelator} +\setinterfacevariable{tabulatehead}{tabulatehead} +\setinterfacevariable{tabulatetail}{tabulatetail} +\setinterfacevariable{tall}{vysoko} +\setinterfacevariable{teletype}{strojopis} +\setinterfacevariable{temporary}{docasne} +\setinterfacevariable{test}{test} +\setinterfacevariable{text}{text} +\setinterfacevariable{three}{tri} +\setinterfacevariable{thursday}{ctvrtek} +\setinterfacevariable{tight}{tight} +\setinterfacevariable{title}{titul} +\setinterfacevariable{toggle}{toggle} +\setinterfacevariable{tolerant}{tolerantni} +\setinterfacevariable{top}{vrsek} +\setinterfacevariable{tuesday}{utery} +\setinterfacevariable{two}{dve} +\setinterfacevariable{txt}{txt} +\setinterfacevariable{type}{opis} +\setinterfacevariable{typing}{typing} +\setinterfacevariable{unavailable}{nedostupne} +\setinterfacevariable{underbar}{podtrzeno} +\setinterfacevariable{underbars}{podtrzeni} +\setinterfacevariable{understrike}{understrike} +\setinterfacevariable{understrikes}{understrikes} +\setinterfacevariable{unframed}{unframed} +\setinterfacevariable{unit}{jednotka} +\setinterfacevariable{units}{jednotky} +\setinterfacevariable{unknown}{neznamy} +\setinterfacevariable{unpacked}{rozbalene} +\setinterfacevariable{up}{up} +\setinterfacevariable{url}{url} +\setinterfacevariable{used}{uzito} +\setinterfacevariable{value}{hodnota} +\setinterfacevariable{vertical}{vertikalne} +\setinterfacevariable{very}{velmi} +\setinterfacevariable{verystrict}{velmistriktni} +\setinterfacevariable{verytolerant}{velmitolerantni} +\setinterfacevariable{vfenced}{vfenced} +\setinterfacevariable{vulgarfraction}{vulgarfraction} +\setinterfacevariable{weak}{weak} +\setinterfacevariable{wednesday}{streda} +\setinterfacevariable{week}{tyden} +\setinterfacevariable{weekday}{vsedniden} +\setinterfacevariable{white}{bily} +\setinterfacevariable{wide}{siroce} +\setinterfacevariable{width}{sirka} +\setinterfacevariable{word}{slovo} +\setinterfacevariable{words}{words} +\setinterfacevariable{xml}{xml} +\setinterfacevariable{year}{rok} +\setinterfacevariable{yes}{ano} +% definitions for interface constants for language cs +% +\setinterfaceconstant{action}{akce} +\setinterfaceconstant{address}{adresa} +\setinterfaceconstant{after}{po} +\setinterfaceconstant{afterhead}{pohlavicce} +\setinterfaceconstant{afterkey}{klavesapo} +\setinterfaceconstant{aftersection}{aftersection} +\setinterfaceconstant{align}{zarovnani} +\setinterfaceconstant{aligncharacter}{aligncharacter} +\setinterfaceconstant{alignmentcharacter}{alignmentcharacter} +\setinterfaceconstant{alignsymbol}{alignsymbol} +\setinterfaceconstant{aligntitle}{zarovnejtitul} +\setinterfaceconstant{alternative}{alternativa} +\setinterfaceconstant{anchor}{anchor} +\setinterfaceconstant{andtext}{andtext} +\setinterfaceconstant{apa}{apa} +\setinterfaceconstant{arguments}{arguments} +\setinterfaceconstant{arrow}{sipka} +\setinterfaceconstant{artauthor}{artauthor} +\setinterfaceconstant{artauthoretaldisplay}{artauthoretaldisplay} +\setinterfaceconstant{artauthoretallimit}{artauthoretallimit} +\setinterfaceconstant{artauthoretaltext}{artauthoretaltext} +\setinterfaceconstant{artoffset}{artoffset} +\setinterfaceconstant{at}{u} +\setinterfaceconstant{author}{autor} +\setinterfaceconstant{authorconversion}{authorconversion} +\setinterfaceconstant{authoretaldisplay}{authoretaldisplay} +\setinterfaceconstant{authoretallimit}{authoretallimit} +\setinterfaceconstant{authoretaltext}{authoretaltext} +\setinterfaceconstant{auto}{auto} +\setinterfaceconstant{autocase}{autocase} +\setinterfaceconstant{autofile}{autofile} +\setinterfaceconstant{autofocus}{autoostreni} +\setinterfaceconstant{autohang}{autohang} +\setinterfaceconstant{autostrut}{autostrut} +\setinterfaceconstant{autowidth}{autosirka} +\setinterfaceconstant{availableheight}{availableheight} +\setinterfaceconstant{availablewidth}{availablewidth} +\setinterfaceconstant{axis}{osa} +\setinterfaceconstant{background}{pozadi} +\setinterfaceconstant{backgroundcolor}{barvapozadi} +\setinterfaceconstant{backgroundcorner}{rohpozadi} +\setinterfaceconstant{backgrounddepth}{hloubkapozadi} +\setinterfaceconstant{backgroundoffset}{offsetpozadi} +\setinterfaceconstant{backgroundradius}{polomerpozadi} +\setinterfaceconstant{backgroundscreen}{rastrpozadi} +\setinterfaceconstant{backreference}{backreference} +\setinterfaceconstant{backspace}{zpetnamezera} +\setinterfaceconstant{balance}{rovnovaha} +\setinterfaceconstant{before}{pred} +\setinterfaceconstant{beforehead}{predhlavickou} +\setinterfaceconstant{beforesection}{beforesection} +\setinterfaceconstant{bet}{bet} +\setinterfaceconstant{bidi}{bidi} +\setinterfaceconstant{big}{velky} +\setinterfaceconstant{blank}{prazdny} +\setinterfaceconstant{bleedoffset}{bleedoffset} +\setinterfaceconstant{blockway}{dobloku} +\setinterfaceconstant{bodyfont}{zakladnifont} +\setinterfaceconstant{boffset}{boffset} +\setinterfaceconstant{boldfeatures}{boldfeatures} +\setinterfaceconstant{boldfont}{boldfont} +\setinterfaceconstant{bolditalicfeatures}{bolditalicfeatures} +\setinterfaceconstant{bolditalicfont}{bolditalicfont} +\setinterfaceconstant{boldslantedfeatures}{boldslantedfeatures} +\setinterfaceconstant{boldslantedfont}{boldslantedfont} +\setinterfaceconstant{bookmark}{zalozka} +\setinterfaceconstant{bottom}{spodek} +\setinterfaceconstant{bottomafter}{bottomafter} +\setinterfaceconstant{bottombefore}{bottombefore} +\setinterfaceconstant{bottomcommand}{bottomcommand} +\setinterfaceconstant{bottomdistance}{vzdalenostspodku} +\setinterfaceconstant{bottomframe}{ramecekdole} +\setinterfaceconstant{bottomoffset}{offsetspodku} +\setinterfaceconstant{bottomspace}{bottomspace} +\setinterfaceconstant{bottomstate}{statusspodku} +\setinterfaceconstant{buffer}{buffer} +\setinterfaceconstant{cache}{cache} +\setinterfaceconstant{calculate}{pocitat} +\setinterfaceconstant{category}{category} +\setinterfaceconstant{ccommand}{cprikaz} +\setinterfaceconstant{character}{character} +\setinterfaceconstant{characters}{characters} +\setinterfaceconstant{check}{check} +\setinterfaceconstant{click}{klik} +\setinterfaceconstant{clickin}{klikuvnitr} +\setinterfaceconstant{clickout}{klikvne} +\setinterfaceconstant{clipoffset}{clipoffset} +\setinterfaceconstant{closeaction}{zavriakci} +\setinterfaceconstant{closecommand}{closecommand} +\setinterfaceconstant{closepage}{closepage} +\setinterfaceconstant{closepageaction}{akcezavrenistranky} +\setinterfaceconstant{closesymbol}{closesymbol} +\setinterfaceconstant{color}{barva} +\setinterfaceconstant{column}{sloupec} +\setinterfaceconstant{columndistance}{vzdalenostsloupcu} +\setinterfaceconstant{columns}{sloupce} +\setinterfaceconstant{comma}{comma} +\setinterfaceconstant{command}{prikaz} +\setinterfaceconstant{commandafter}{prikazpo} +\setinterfaceconstant{commandbefore}{predchoziprikaz} +\setinterfaceconstant{commands}{prikazy} +\setinterfaceconstant{comment}{comment} +\setinterfaceconstant{commentchar}{commentchar} +\setinterfaceconstant{commentoffset}{commentoffset} +\setinterfaceconstant{compact}{compact} +\setinterfaceconstant{component}{component} +\setinterfaceconstant{compoundhyphen}{compoundhyphen} +\setinterfaceconstant{compress}{compress} +\setinterfaceconstant{compressseparator}{compressseparator} +\setinterfaceconstant{concerns}{concerns} +\setinterfaceconstant{connector}{connector} +\setinterfaceconstant{continue}{pokracovat} +\setinterfaceconstant{contrastcolor}{kontrastnibarva} +\setinterfaceconstant{controls}{controls} +\setinterfaceconstant{conversion}{konverze} +\setinterfaceconstant{convertfile}{konverzesouboru} +\setinterfaceconstant{copies}{copies} +\setinterfaceconstant{corner}{roh} +\setinterfaceconstant{coupling}{propojeni} +\setinterfaceconstant{couplingway}{zpusobpropojeni} +\setinterfaceconstant{criterium}{kriterium} +\setinterfaceconstant{cropoffset}{cropoffset} +\setinterfaceconstant{crossreference}{crossreference} +\setinterfaceconstant{cssfile}{cssfile} +\setinterfaceconstant{current}{aktualni} +\setinterfaceconstant{cutspace}{cutspace} +\setinterfaceconstant{dash}{pomlcka} +\setinterfaceconstant{dat}{dat} +\setinterfaceconstant{database}{database} +\setinterfaceconstant{dataset}{dataset} +\setinterfaceconstant{date}{datum} +\setinterfaceconstant{deepnumbercommand}{deepnumbercommand} +\setinterfaceconstant{deeptextcommand}{deeptextcommand} +\setinterfaceconstant{default}{implicitni} +\setinterfaceconstant{delay}{prodleva} +\setinterfaceconstant{depth}{hloubka} +\setinterfaceconstant{depthcorrection}{korekcehloubky} +\setinterfaceconstant{direction}{smer} +\setinterfaceconstant{directory}{adresar} +\setinterfaceconstant{display}{obrazovka} +\setinterfaceconstant{distance}{vzdalenost} +\setinterfaceconstant{domain}{domain} +\setinterfaceconstant{dot}{tecka} +\setinterfaceconstant{doublesided}{oboustranne} +\setinterfaceconstant{down}{down} +\setinterfaceconstant{dummy}{dummy} +\setinterfaceconstant{dx}{dx} +\setinterfaceconstant{dy}{dy} +\setinterfaceconstant{edge}{hrana} +\setinterfaceconstant{edgedistance}{vzdalenosthrany} +\setinterfaceconstant{editor}{editor} +\setinterfaceconstant{editoretaldisplay}{editoretaldisplay} +\setinterfaceconstant{editoretallimit}{editoretallimit} +\setinterfaceconstant{editoretaltext}{editoretaltext} +\setinterfaceconstant{empty}{prazdne} +\setinterfaceconstant{entities}{entities} +\setinterfaceconstant{entries}{entries} +\setinterfaceconstant{equalheight}{equalheight} +\setinterfaceconstant{equalwidth}{equalwidth} +\setinterfaceconstant{escape}{escape} +\setinterfaceconstant{etaldisplay}{etaldisplay} +\setinterfaceconstant{etallimit}{etallimit} +\setinterfaceconstant{etaloption}{etaloption} +\setinterfaceconstant{etaltext}{etaltext} +\setinterfaceconstant{evenmargin}{sudamarginalie} +\setinterfaceconstant{exact}{exact} +\setinterfaceconstant{exitoffset}{exitoffset} +\setinterfaceconstant{expansion}{expanzen} +\setinterfaceconstant{export}{export} +\setinterfaceconstant{extras}{extras} +\setinterfaceconstant{factor}{faktor} +\setinterfaceconstant{fallback}{fallback} +\setinterfaceconstant{family}{rodina} +\setinterfaceconstant{features}{features} +\setinterfaceconstant{fences}{fences} +\setinterfaceconstant{field}{field} +\setinterfaceconstant{fieldbackgroundcolor}{barvapozadipole} +\setinterfaceconstant{fieldframecolor}{barvarameckupole} +\setinterfaceconstant{fieldlayer}{fieldlayer} +\setinterfaceconstant{fieldoffset}{offsetpole} +\setinterfaceconstant{file}{soubor} +\setinterfaceconstant{filler}{filler} +\setinterfaceconstant{filtercommand}{filtercommand} +\setinterfaceconstant{finalnamesep}{finalnamesep} +\setinterfaceconstant{finalpagesep}{finalpagesep} +\setinterfaceconstant{finalpubsep}{finalpubsep} +\setinterfaceconstant{first}{prvni} +\setinterfaceconstant{firstnamesep}{firstnamesep} +\setinterfaceconstant{firstpage}{prvnistranka} +\setinterfaceconstant{focus}{zaostreni} +\setinterfaceconstant{focusin}{focusin} +\setinterfaceconstant{focusoffset}{focusoffset} +\setinterfaceconstant{focusout}{focusout} +\setinterfaceconstant{footer}{upati} +\setinterfaceconstant{footerdistance}{vzdalenostupati} +\setinterfaceconstant{footerstate}{statusupati} +\setinterfaceconstant{force}{sila} +\setinterfaceconstant{foregroundcolor}{foregroundcolor} +\setinterfaceconstant{foregroundstyle}{foregroundstyle} +\setinterfaceconstant{format}{formatovat} +\setinterfaceconstant{fractions}{fractions} +\setinterfaceconstant{frame}{ramecek} +\setinterfaceconstant{framecolor}{barvaramecku} +\setinterfaceconstant{framecorner}{rohramecku} +\setinterfaceconstant{framedepth}{hloubkaramecku} +\setinterfaceconstant{frameoffset}{offsetramecku} +\setinterfaceconstant{frameradius}{polomerramecku} +\setinterfaceconstant{frames}{ramecky} +\setinterfaceconstant{freeregion}{freeregion} +\setinterfaceconstant{from}{z} +\setinterfaceconstant{functioncolor}{functioncolor} +\setinterfaceconstant{functionstyle}{functionstyle} +\setinterfaceconstant{get}{ziskat} +\setinterfaceconstant{global}{globalne} +\setinterfaceconstant{goodies}{goodies} +\setinterfaceconstant{grid}{mrizka} +\setinterfaceconstant{group}{group} +\setinterfaceconstant{groupsuffix}{groupsuffix} +\setinterfaceconstant{hang}{zaveseni} +\setinterfaceconstant{hcompact}{hcompact} +\setinterfaceconstant{headalign}{headalign} +\setinterfaceconstant{headcolor}{barvahlavicky} +\setinterfaceconstant{headcommand}{headcommand} +\setinterfaceconstant{headconversion}{konverzehlavicky} +\setinterfaceconstant{header}{zahlavi} +\setinterfaceconstant{headerdistance}{vzdalenostzahlavi} +\setinterfaceconstant{headerstate}{statuszahlavi} +\setinterfaceconstant{headlabel}{popisekhlavicky} +\setinterfaceconstant{headnumber}{cislonadpisu} +\setinterfaceconstant{headstyle}{stylhlavicky} +\setinterfaceconstant{height}{vyska} +\setinterfaceconstant{hfactor}{vfaktor} +\setinterfaceconstant{hfil}{hfil} +\setinterfaceconstant{hidenumber}{hidenumber} +\setinterfaceconstant{hoffset}{hoffset} +\setinterfaceconstant{horoffset}{horoffset} +\setinterfaceconstant{hyphen}{hyphen} +\setinterfaceconstant{hyphens}{hyphens} +\setinterfaceconstant{icommand}{iprikaz} +\setinterfaceconstant{ignore}{ignore} +\setinterfaceconstant{in}{v} +\setinterfaceconstant{inbetween}{mezi} +\setinterfaceconstant{increment}{zvysit} +\setinterfaceconstant{incrementnumber}{zvysujicicislo} +\setinterfaceconstant{indenting}{odsazovani} +\setinterfaceconstant{indentnext}{odsadpristi} +\setinterfaceconstant{index}{index} +\setinterfaceconstant{indicator}{indikator} +\setinterfaceconstant{initialsep}{initialsep} +\setinterfaceconstant{inner}{vnitrni} +\setinterfaceconstant{innermargin}{innermargin} +\setinterfaceconstant{inputfile}{inputfile} +\setinterfaceconstant{insidesection}{insidesection} +\setinterfaceconstant{instance}{instance} +\setinterfaceconstant{intent}{intent} +\setinterfaceconstant{interaction}{interakce} +\setinterfaceconstant{interlinespace}{meziradkovamezera} +\setinterfaceconstant{internalgrid}{internalgrid} +\setinterfaceconstant{italicfeatures}{italicfeatures} +\setinterfaceconstant{italicfont}{italicfont} +\setinterfaceconstant{itemalign}{itemalign} +\setinterfaceconstant{items}{polozky} +\setinterfaceconstant{joiners}{joiners} +\setinterfaceconstant{journalconversion}{journalconversion} +\setinterfaceconstant{juniorsep}{juniorsep} +\setinterfaceconstant{keeptogether}{keeptogether} +\setinterfaceconstant{ken}{ken} +\setinterfaceconstant{keyexpansion}{keyexpansion} +\setinterfaceconstant{keys}{keys} +\setinterfaceconstant{keyword}{keyword} +\setinterfaceconstant{label}{popisek} +\setinterfaceconstant{labeloffset}{labeloffset} +\setinterfaceconstant{language}{language} +\setinterfaceconstant{last}{last} +\setinterfaceconstant{lastnamesep}{lastnamesep} +\setinterfaceconstant{lastpage}{poslednistrana} +\setinterfaceconstant{lastpagesep}{lastpagesep} +\setinterfaceconstant{lastpubsep}{lastpubsep} +\setinterfaceconstant{layout}{layout} +\setinterfaceconstant{left}{vlevo} +\setinterfaceconstant{leftcolor}{barvavlevo} +\setinterfaceconstant{leftcompoundhyphen}{leftcompoundhyphen} +\setinterfaceconstant{leftedge}{levahrana} +\setinterfaceconstant{leftedgedistance}{vzdalenostlevehrany} +\setinterfaceconstant{leftframe}{ramecekvlevo} +\setinterfaceconstant{lefthyphen}{lefthyphen} +\setinterfaceconstant{leftmargin}{levyokraj} +\setinterfaceconstant{leftmargindistance}{vzdalenostlevehookraje} +\setinterfaceconstant{leftoffset}{levyoffset} +\setinterfaceconstant{leftquotation}{citacevlevo} +\setinterfaceconstant{leftquote}{citovatvlevo} +\setinterfaceconstant{leftsentence}{vetavlevo} +\setinterfaceconstant{leftspeech}{leftspeech} +\setinterfaceconstant{leftstyle}{stylvlevo} +\setinterfaceconstant{leftsubsentence}{podvetavlevo} +\setinterfaceconstant{lefttext}{textvlevo} +\setinterfaceconstant{leftwidth}{sirkavlevo} +\setinterfaceconstant{leftwords}{leftwords} +\setinterfaceconstant{less}{less} +\setinterfaceconstant{level}{uroven} +\setinterfaceconstant{levels}{urovne} +\setinterfaceconstant{limittext}{limittext} +\setinterfaceconstant{line}{radek} +\setinterfaceconstant{linecorrection}{korekceradku} +\setinterfaceconstant{lines}{radky} +\setinterfaceconstant{list}{seznam} +\setinterfaceconstant{listtext}{listtext} +\setinterfaceconstant{local}{lokalne} +\setinterfaceconstant{location}{misto} +\setinterfaceconstant{loffset}{loffset} +\setinterfaceconstant{logo}{logo} +\setinterfaceconstant{logos}{loga} +\setinterfaceconstant{marcolor}{barvaznacky} +\setinterfaceconstant{margin}{marginalie} +\setinterfaceconstant{margindistance}{vzdalenostokraje} +\setinterfaceconstant{marginedge}{textovahrana} +\setinterfaceconstant{marginedgetext}{textmarginalnihookraje} +\setinterfaceconstant{margintext}{textmarginalie} +\setinterfaceconstant{mark}{mark} +\setinterfaceconstant{marking}{znaceni} +\setinterfaceconstant{marstyle}{stylsnacky} +\setinterfaceconstant{mask}{mask} +\setinterfaceconstant{mathclass}{mathclass} +\setinterfaceconstant{mathlimits}{mathlimits} +\setinterfaceconstant{mathstyle}{mathstyle} +\setinterfaceconstant{max}{max} +\setinterfaceconstant{maxdepth}{maxdepth} +\setinterfaceconstant{maxheight}{maxvyska} +\setinterfaceconstant{maxwidth}{maxsirka} +\setinterfaceconstant{maybeyear}{maybeyear} +\setinterfaceconstant{menu}{menu} +\setinterfaceconstant{method}{metoda} +\setinterfaceconstant{middle}{stredni} +\setinterfaceconstant{middlecommand}{middlecommand} +\setinterfaceconstant{middlespeech}{middlespeech} +\setinterfaceconstant{middletext}{strednitext} +\setinterfaceconstant{midsentence}{midsentence} +\setinterfaceconstant{min}{min} +\setinterfaceconstant{mindepth}{mindepth} +\setinterfaceconstant{minheight}{minvyska} +\setinterfaceconstant{minwidth}{minsirka} +\setinterfaceconstant{moffset}{moffset} +\setinterfaceconstant{monthconversion}{monthconversion} +\setinterfaceconstant{more}{more} +\setinterfaceconstant{mpdepth}{mpdepth} +\setinterfaceconstant{mpheight}{mpheight} +\setinterfaceconstant{mpoffset}{mpoffset} +\setinterfaceconstant{mpwidth}{mpwidth} +\setinterfaceconstant{n}{n} +\setinterfaceconstant{name}{jmeno} +\setinterfaceconstant{namesep}{namesep} +\setinterfaceconstant{nbottom}{nspodek} +\setinterfaceconstant{nc}{nc} +\setinterfaceconstant{next}{dalsi} +\setinterfaceconstant{nextleft}{nextleft} +\setinterfaceconstant{nextleftquotation}{nextleftquotation} +\setinterfaceconstant{nextright}{nextright} +\setinterfaceconstant{nextrightquotation}{nextrightquotation} +\setinterfaceconstant{nl}{nl} +\setinterfaceconstant{nleft}{nvlevo} +\setinterfaceconstant{nlines}{nradky} +\setinterfaceconstant{norm}{norm} +\setinterfaceconstant{note}{note} +\setinterfaceconstant{nr}{nr} +\setinterfaceconstant{nright}{nvpravo} +\setinterfaceconstant{ntop}{nvrsek} +\setinterfaceconstant{number}{cislo} +\setinterfaceconstant{numberalign}{numberalign} +\setinterfaceconstant{numbercolor}{barvacisla} +\setinterfaceconstant{numbercommand}{ciselnyprikaz} +\setinterfaceconstant{numberconversion}{numberconversion} +\setinterfaceconstant{numberconversionset}{numberconversionset} +\setinterfaceconstant{numberdistance}{numberdistance} +\setinterfaceconstant{numbering}{cislovani} +\setinterfaceconstant{numberorder}{numberorder} +\setinterfaceconstant{numberprefix}{numberprefix} +\setinterfaceconstant{numbersegments}{numbersegments} +\setinterfaceconstant{numberseparator}{oddelovaccisla} +\setinterfaceconstant{numberseparatorset}{numberseparatorset} +\setinterfaceconstant{numberset}{numberset} +\setinterfaceconstant{numberstarter}{numberstarter} +\setinterfaceconstant{numberstopper}{numberstopper} +\setinterfaceconstant{numberstyle}{stylcisla} +\setinterfaceconstant{numberwidth}{numberwidth} +\setinterfaceconstant{nx}{nx} +\setinterfaceconstant{ny}{ny} +\setinterfaceconstant{object}{objekt} +\setinterfaceconstant{obstruction}{prekazka} +\setinterfaceconstant{oddmargin}{lichyokraj} +\setinterfaceconstant{offset}{offset} +\setinterfaceconstant{openaction}{otevriakci} +\setinterfaceconstant{openpage}{openpage} +\setinterfaceconstant{openpageaction}{akceotevrenistranky} +\setinterfaceconstant{openup}{openup} +\setinterfaceconstant{opticalsize}{opticalsize} +\setinterfaceconstant{option}{volba} +\setinterfaceconstant{order}{order} +\setinterfaceconstant{orientation}{orientation} +\setinterfaceconstant{otherstext}{otherstext} +\setinterfaceconstant{outermargin}{outermargin} +\setinterfaceconstant{overprint}{overprint} +\setinterfaceconstant{ownnumber}{vlastnicislo} +\setinterfaceconstant{page}{stranka} +\setinterfaceconstant{pageboundaries}{hranicestranky} +\setinterfaceconstant{pagecolor}{barvastranky} +\setinterfaceconstant{pagecolormodel}{pagecolormodel} +\setinterfaceconstant{pagecommand}{strankovyprikaz} +\setinterfaceconstant{pageconnector}{pageconnector} +\setinterfaceconstant{pageconversion}{pageconversion} +\setinterfaceconstant{pageconversionset}{pageconversionset} +\setinterfaceconstant{pageleft}{pageleft} +\setinterfaceconstant{pagenumber}{cislostranky} +\setinterfaceconstant{pageprefix}{pageprefix} +\setinterfaceconstant{pageprefixconnector}{pageprefixconnector} +\setinterfaceconstant{pageprefixconversion}{pageprefixconversion} +\setinterfaceconstant{pageprefixconversionset}{pageprefixconversionset} +\setinterfaceconstant{pageprefixsegments}{pageprefixsegments} +\setinterfaceconstant{pageprefixseparatorset}{pageprefixseparatorset} +\setinterfaceconstant{pageprefixset}{pageprefixset} +\setinterfaceconstant{pageprefixstarter}{pageprefixstarter} +\setinterfaceconstant{pageprefixstopper}{pageprefixstopper} +\setinterfaceconstant{pageright}{pageright} +\setinterfaceconstant{pagesegments}{pagesegments} +\setinterfaceconstant{pagesep}{pagesep} +\setinterfaceconstant{pageseparatorset}{pageseparatorset} +\setinterfaceconstant{pageset}{pageset} +\setinterfaceconstant{pagestarter}{pagestarter} +\setinterfaceconstant{pagestate}{pagestate} +\setinterfaceconstant{pagestopper}{pagestopper} +\setinterfaceconstant{pagestyle}{stylstranky} +\setinterfaceconstant{palet}{paleta} +\setinterfaceconstant{paper}{papir} +\setinterfaceconstant{paragraph}{odstavec} +\setinterfaceconstant{period}{period} +\setinterfaceconstant{place}{umistit} +\setinterfaceconstant{placehead}{umistihlavicku} +\setinterfaceconstant{placestopper}{predelmista} +\setinterfaceconstant{position}{position} +\setinterfaceconstant{prefix}{prefix} +\setinterfaceconstant{prefixconnector}{prefixconnector} +\setinterfaceconstant{prefixconversion}{prefixconversion} +\setinterfaceconstant{prefixconversionset}{prefixconversionset} +\setinterfaceconstant{prefixsegments}{prefixsegments} +\setinterfaceconstant{prefixseparatorset}{prefixseparatorset} +\setinterfaceconstant{prefixset}{prefixset} +\setinterfaceconstant{prefixstarter}{prefixstarter} +\setinterfaceconstant{prefixstopper}{prefixstopper} +\setinterfaceconstant{preset}{prednastaveni} +\setinterfaceconstant{preview}{nahled} +\setinterfaceconstant{previous}{predchozi} +\setinterfaceconstant{previousnumber}{predchozicislo} +\setinterfaceconstant{printable}{tisknutelne} +\setinterfaceconstant{process}{process} +\setinterfaceconstant{profile}{profile} +\setinterfaceconstant{properties}{properties} +\setinterfaceconstant{pubsep}{pubsep} +\setinterfaceconstant{quotechar}{quotechar} +\setinterfaceconstant{radius}{polomer} +\setinterfaceconstant{random}{nahodne} +\setinterfaceconstant{range}{range} +\setinterfaceconstant{reduction}{redukce} +\setinterfaceconstant{ref}{ref} +\setinterfaceconstant{refcommand}{refcommand} +\setinterfaceconstant{reference}{odkaz} +\setinterfaceconstant{referencemethod}{referencemethod} +\setinterfaceconstant{referenceprefix}{referenceprefix} +\setinterfaceconstant{referencing}{odkazujici} +\setinterfaceconstant{region}{region} +\setinterfaceconstant{regionin}{oblastuvnitr} +\setinterfaceconstant{regionout}{oblastvne} +\setinterfaceconstant{register}{register} +\setinterfaceconstant{regularfeatures}{regularfeatures} +\setinterfaceconstant{regularfont}{regularfont} +\setinterfaceconstant{renderingsetup}{renderingsetup} +\setinterfaceconstant{repeat}{opakovat} +\setinterfaceconstant{reset}{reset} +\setinterfaceconstant{resetnumber}{resetnumber} +\setinterfaceconstant{resolution}{rozliseni} +\setinterfaceconstant{resources}{resources} +\setinterfaceconstant{reverse}{reverse} +\setinterfaceconstant{right}{vpravo} +\setinterfaceconstant{rightchars}{rightchars} +\setinterfaceconstant{rightcolor}{barvavpravo} +\setinterfaceconstant{rightcompoundhyphen}{rightcompoundhyphen} +\setinterfaceconstant{rightedge}{pravahrana} +\setinterfaceconstant{rightedgedistance}{vzdalenostpravehrany} +\setinterfaceconstant{rightframe}{ramecekvpravo} +\setinterfaceconstant{righthyphen}{righthyphen} +\setinterfaceconstant{rightmargin}{pravyokraj} +\setinterfaceconstant{rightmargindistance}{vzdalenostpravehookraje} +\setinterfaceconstant{rightoffset}{pravyoffset} +\setinterfaceconstant{rightquotation}{citacevpravo} +\setinterfaceconstant{rightquote}{citovatvpravo} +\setinterfaceconstant{rightsentence}{vetavpravo} +\setinterfaceconstant{rightspeech}{rightspeech} +\setinterfaceconstant{rightstyle}{stylvpravo} +\setinterfaceconstant{rightsubsentence}{podvetavpravo} +\setinterfaceconstant{righttext}{textvpravo} +\setinterfaceconstant{rightwidth}{sirkavpravo} +\setinterfaceconstant{rightwords}{rightwords} +\setinterfaceconstant{roffset}{roffset} +\setinterfaceconstant{rotation}{rotace} +\setinterfaceconstant{rule}{linka} +\setinterfaceconstant{rulecolor}{barvalinky} +\setinterfaceconstant{rulecommand}{rulecommand} +\setinterfaceconstant{rulethickness}{tloustkalinky} +\setinterfaceconstant{samepage}{stejnastranka} +\setinterfaceconstant{sample}{vzor} +\setinterfaceconstant{samplesize}{samplesize} +\setinterfaceconstant{saveinlist}{saveinlist} +\setinterfaceconstant{scale}{meritko} +\setinterfaceconstant{scope}{rozsah} +\setinterfaceconstant{screen}{rastr} +\setinterfaceconstant{section}{oddil} +\setinterfaceconstant{sectionblock}{sectionblock} +\setinterfaceconstant{sectionconversion}{sectionconversion} +\setinterfaceconstant{sectionconversionset}{sectionconversionset} +\setinterfaceconstant{sectionnumber}{cislooddilu} +\setinterfaceconstant{sectionresetset}{sectionresetset} +\setinterfaceconstant{sectionsegments}{sectionsegments} +\setinterfaceconstant{sectionseparatorset}{sectionseparatorset} +\setinterfaceconstant{sectionset}{sectionset} +\setinterfaceconstant{sectionstarter}{sectionstarter} +\setinterfaceconstant{sectionstopper}{sectionstopper} +\setinterfaceconstant{separator}{oddelovac} +\setinterfaceconstant{separatorcolor}{separatorcolor} +\setinterfaceconstant{separatorstyle}{separatorstyle} +\setinterfaceconstant{set}{set} +\setinterfaceconstant{setups}{setups} +\setinterfaceconstant{shrink}{shrink} +\setinterfaceconstant{side}{pocitat} +\setinterfaceconstant{sidealign}{sidealign} +\setinterfaceconstant{sidemethod}{sidemethod} +\setinterfaceconstant{sidespaceafter}{bocnimezeraza} +\setinterfaceconstant{sidespacebefore}{bocnimezerapred} +\setinterfaceconstant{sign}{znak} +\setinterfaceconstant{size}{velikost} +\setinterfaceconstant{slantedfeatures}{slantedfeatures} +\setinterfaceconstant{slantedfont}{slantedfont} +\setinterfaceconstant{small}{male} +\setinterfaceconstant{smallcapsfeatures}{smallcapsfeatures} +\setinterfaceconstant{smallcapsfont}{smallcapsfont} +\setinterfaceconstant{solution}{solution} +\setinterfaceconstant{sort}{sort} +\setinterfaceconstant{sorttype}{sorttype} +\setinterfaceconstant{source}{zdroj} +\setinterfaceconstant{space}{mezera} +\setinterfaceconstant{spaceafter}{mezeraza} +\setinterfaceconstant{spacebefore}{mezerapred} +\setinterfaceconstant{spaceinbetween}{spaceinbetween} +\setinterfaceconstant{spacing}{mezerovani} +\setinterfaceconstant{specification}{specification} +\setinterfaceconstant{split}{split} +\setinterfaceconstant{splitcolor}{splitcolor} +\setinterfaceconstant{splitmethod}{splitmethod} +\setinterfaceconstant{splitoffset}{splitoffset} +\setinterfaceconstant{spot}{spot} +\setinterfaceconstant{stack}{stack} +\setinterfaceconstant{stackname}{stackname} +\setinterfaceconstant{start}{start} +\setinterfaceconstant{starter}{starter} +\setinterfaceconstant{state}{status} +\setinterfaceconstant{step}{krok} +\setinterfaceconstant{stop}{stop} +\setinterfaceconstant{stopper}{predel} +\setinterfaceconstant{stretch}{natahnout} +\setinterfaceconstant{strip}{strip} +\setinterfaceconstant{strut}{strut} +\setinterfaceconstant{style}{pismeno} +\setinterfaceconstant{stylealternative}{stylealternative} +\setinterfaceconstant{sub}{pod} +\setinterfaceconstant{subtitle}{podtitulek} +\setinterfaceconstant{suffix}{suffix} +\setinterfaceconstant{suffixseparator}{suffixseparator} +\setinterfaceconstant{suffixstopper}{suffixstopper} +\setinterfaceconstant{surnamefirstnamesep}{surnamefirstnamesep} +\setinterfaceconstant{surnameinitialsep}{surnameinitialsep} +\setinterfaceconstant{surnamesep}{surnamesep} +\setinterfaceconstant{svgstyle}{svgstyle} +\setinterfaceconstant{sx}{sx} +\setinterfaceconstant{sy}{sy} +\setinterfaceconstant{symalign}{symzarovnani} +\setinterfaceconstant{symbol}{symbol} +\setinterfaceconstant{symbolcommand}{symbolcommand} +\setinterfaceconstant{symbolset}{sadasymbolu} +\setinterfaceconstant{symcolor}{barvasymbolu} +\setinterfaceconstant{symstyle}{stylsymboly} +\setinterfaceconstant{synonym}{synonymum} +\setinterfaceconstant{synonymcolor}{barvasynonyma} +\setinterfaceconstant{synonymcommand}{synonymcommand} +\setinterfaceconstant{synonymstyle}{stylsynonyma} +\setinterfaceconstant{tab}{tab} +\setinterfaceconstant{text}{text} +\setinterfaceconstant{textalign}{textalign} +\setinterfaceconstant{textcolor}{barvatextu} +\setinterfaceconstant{textcommand}{textovyprikaz} +\setinterfaceconstant{textdistance}{textdistance} +\setinterfaceconstant{textheight}{vyskatextu} +\setinterfaceconstant{textlayer}{textlayer} +\setinterfaceconstant{textmargin}{textmargin} +\setinterfaceconstant{textmethod}{textmethod} +\setinterfaceconstant{textseparator}{oddelovactextu} +\setinterfaceconstant{textsize}{velikosttextu} +\setinterfaceconstant{textstate}{statustextu} +\setinterfaceconstant{textstyle}{styltextu} +\setinterfaceconstant{textwidth}{sirkatextu} +\setinterfaceconstant{threshold}{threshold} +\setinterfaceconstant{title}{titul} +\setinterfaceconstant{titlecolor}{barvatitulek} +\setinterfaceconstant{titlecommand}{titlecommand} +\setinterfaceconstant{titledistance}{vzdalenosttitulek} +\setinterfaceconstant{titleleft}{titleleft} +\setinterfaceconstant{titleright}{titleright} +\setinterfaceconstant{titlestyle}{styltitulek} +\setinterfaceconstant{to}{na} +\setinterfaceconstant{toffset}{toffset} +\setinterfaceconstant{tolerance}{tolerance} +\setinterfaceconstant{top}{vrsek} +\setinterfaceconstant{topcommand}{topcommand} +\setinterfaceconstant{topdistance}{vzdalenostvrsku} +\setinterfaceconstant{topframe}{rameceknahore} +\setinterfaceconstant{topoffset}{offsetvrsku} +\setinterfaceconstant{topspace}{svrchnimezera} +\setinterfaceconstant{topstate}{statusvrsku} +\setinterfaceconstant{totalnumber}{totalnumber} +\setinterfaceconstant{transform}{transform} +\setinterfaceconstant{translate}{translate} +\setinterfaceconstant{trimoffset}{trimoffset} +\setinterfaceconstant{type}{typ} +\setinterfaceconstant{unit}{jednotka} +\setinterfaceconstant{unknownreference}{neznamyodkaz} +\setinterfaceconstant{up}{up} +\setinterfaceconstant{urlalternative}{urlalternativa} +\setinterfaceconstant{urlspace}{prostorurl} +\setinterfaceconstant{validate}{validovat} +\setinterfaceconstant{values}{values} +\setinterfaceconstant{vcommand}{vprikaz} +\setinterfaceconstant{vcompact}{vcompact} +\setinterfaceconstant{vector}{vector} +\setinterfaceconstant{veroffset}{offsethlavicky} +\setinterfaceconstant{vfil}{vfil} +\setinterfaceconstant{viewerprefix}{viewerprefix} +\setinterfaceconstant{voffset}{voffset} +\setinterfaceconstant{vonsep}{vonsep} +\setinterfaceconstant{way}{zpusob} +\setinterfaceconstant{wfactor}{sfaktor} +\setinterfaceconstant{white}{bily} +\setinterfaceconstant{width}{sirka} +\setinterfaceconstant{words}{words} +\setinterfaceconstant{xfactor}{xfaktor} +\setinterfaceconstant{xhtml}{xhtml} +\setinterfaceconstant{xmax}{xmax} +\setinterfaceconstant{xmlsetup}{xmlsetup} +\setinterfaceconstant{xoffset}{xoffset} +\setinterfaceconstant{xscale}{xmeritko} +\setinterfaceconstant{xstep}{xkrok} +\setinterfaceconstant{yfactor}{yfaktor} +\setinterfaceconstant{ymax}{ymax} +\setinterfaceconstant{yoffset}{yoffset} +\setinterfaceconstant{yscale}{ymeritko} +\setinterfaceconstant{ystep}{ykrok} +% definitions for interface elements for language cs +% +\setinterfaceelement{answerlines}{answerlines} +\setinterfaceelement{answerspace}{answerspace} +\setinterfaceelement{begin}{zacatek} +\setinterfaceelement{complete}{uplny} +\setinterfaceelement{coupled}{propojene} +\setinterfaceelement{currentlocal}{aktualnelokalni} +\setinterfaceelement{end}{konec} +\setinterfaceelement{endsetup}{} +\setinterfaceelement{get}{ziskat} +\setinterfaceelement{increment}{zvysit} +\setinterfaceelement{list}{seznam} +\setinterfaceelement{listof}{seznam} +\setinterfaceelement{load}{nacist} +\setinterfaceelement{local}{lokalne} +\setinterfaceelement{makeup}{zlom} +\setinterfaceelement{next}{dalsi} +\setinterfaceelement{place}{umisti} +\setinterfaceelement{previous}{predchozi} +\setinterfaceelement{previouslocal}{predchozilokalni} +\setinterfaceelement{reserve}{rezervovat} +\setinterfaceelement{see}{viz} +\setinterfaceelement{setup}{nastaveni} +\setinterfaceelement{start}{start} +\setinterfaceelement{stop}{stop} +\setinterfaceelement{text}{text} +\setinterfaceelement{type}{opis} +% definitions for interface commands for language cs +% +\setinterfacecommand{CAPPED}{KAP} +\setinterfacecommand{Character}{Znak} +\setinterfacecommand{Characters}{Znaky} +\setinterfacecommand{MONTH}{MESIC} +\setinterfacecommand{Numbers}{Cisla} +\setinterfacecommand{Romannumerals}{Rimskecislice} +\setinterfacecommand{SmallCapped}{Kap} +\setinterfacecommand{SmallCaps}{Kaps} +\setinterfacecommand{WEEKDAY}{VSEDNIDEN} +\setinterfacecommand{WORD}{SLOVO} +\setinterfacecommand{WORDS}{SLOVA} +\setinterfacecommand{Word}{Slovo} +\setinterfacecommand{Words}{Slova} +\setinterfacecommand{about}{oref} +\setinterfacecommand{adaptlayout}{prizpusobvzhled} +\setinterfacecommand{alignment}{alignment} +\setinterfacecommand{arg}{arg} +\setinterfacecommand{at}{pref} +\setinterfacecommand{atleftmargin}{atleftmargin} +\setinterfacecommand{atpage}{nastrane} +\setinterfacecommand{atrightmargin}{atrightmargin} +\setinterfacecommand{background}{pozadi} +\setinterfacecommand{backspace}{odsazenizleva} +\setinterfacecommand{blackrule}{cernalinka} +\setinterfacecommand{blackrules}{cernelinky} +\setinterfacecommand{blank}{preskoc} +\setinterfacecommand{bookmark}{zalozka} +\setinterfacecommand{bottomdistance}{vzdalenostspodku} +\setinterfacecommand{bottomheight}{vyskaspodku} +\setinterfacecommand{bottomspace}{bottomspace} +\setinterfacecommand{but}{spodek} +\setinterfacecommand{button}{tlacitko} +\setinterfacecommand{bypassblocks}{bypassblocks} +\setinterfacecommand{character}{znak} +\setinterfacecommand{characters}{znaky} +\setinterfacecommand{chem}{chem} +\setinterfacecommand{clip}{orez} +\setinterfacecommand{clonefield}{klonujpole} +\setinterfacecommand{color}{barva} +\setinterfacecommand{colorbar}{barevnalista} +\setinterfacecommand{colorvalue}{hodnotabarvy} +\setinterfacecommand{column}{sloupec} +\setinterfacecommand{comparecolorgroup}{porovnejskupinubarev} +\setinterfacecommand{comparepalet}{porovnejpaletu} +\setinterfacecommand{completepagenumber}{completepagenumber} +\setinterfacecommand{completeregister}{completeregister} +\setinterfacecommand{component}{komponenta} +\setinterfacecommand{convertnumber}{konvertujcislo} +\setinterfacecommand{copyfield}{kopirujpole} +\setinterfacecommand{correctwhitespace}{korekcebilehomista} +\setinterfacecommand{coupledocument}{propojenydokument} +\setinterfacecommand{couplemarking}{propojeneznaceni} +\setinterfacecommand{couplepage}{parovastrana} +\setinterfacecommand{couplepaper}{dvoustrannypapir} +\setinterfacecommand{coupleregister}{propojenyrejstrik} +\setinterfacecommand{crlf}{crlf} +\setinterfacecommand{currentdate}{aktualnidatum} +\setinterfacecommand{currentheadnumber}{aktualnicislonadpisu} +\setinterfacecommand{cutspace}{cutspace} +\setinterfacecommand{date}{datum} +\setinterfacecommand{decouplemarking}{rozpojeneznaceni} +\setinterfacecommand{decrementnumber}{decrementnumber} +\setinterfacecommand{define}{definuj} +\setinterfacecommand{defineaccent}{definujakcent} +\setinterfacecommand{defineblank}{definujpreskok} +\setinterfacecommand{defineblock}{definujblok} +\setinterfacecommand{definebodyfont}{definujzakladnifont} +\setinterfacecommand{definebodyfontenvironment}{definujprostredizakladnihofontu} +\setinterfacecommand{definebuffer}{definujbuffer} +\setinterfacecommand{definecharacter}{definujznak} +\setinterfacecommand{definecolor}{definujbarvu} +\setinterfacecommand{definecolorgroup}{definujskupinubarev} +\setinterfacecommand{definecolumnbreak}{definecolumnbreak} +\setinterfacecommand{definecolumnset}{definecolumnset} +\setinterfacecommand{definecombination}{definecombination} +\setinterfacecommand{definecombinedlist}{definujkombinovanyseznam} +\setinterfacecommand{definecommand}{definujprikaz} +\setinterfacecommand{defineconversion}{definujkonverzi} +\setinterfacecommand{definedescription}{definujpopis} +\setinterfacecommand{defineenumeration}{definujvycet} +\setinterfacecommand{definefield}{definujpole} +\setinterfacecommand{definefieldstack}{definujzasobnikpoli} +\setinterfacecommand{definefiguresymbol}{definujobrazeksymbol} +\setinterfacecommand{definefloat}{definujplvouciobjekt} +\setinterfacecommand{definefont}{definujfont} +\setinterfacecommand{definefontstyle}{definujstylfontu} +\setinterfacecommand{definefontsynonym}{definujsynonumumfontu} +\setinterfacecommand{defineframed}{definujoramovani} +\setinterfacecommand{defineframedtext}{definujoramovanytext} +\setinterfacecommand{definehbox}{definujhbox} +\setinterfacecommand{definehead}{definujnadpis} +\setinterfacecommand{defineindentedtext}{defineindentedtext} +\setinterfacecommand{defineinmargin}{defineinmargin} +\setinterfacecommand{defineinteractionmenu}{definujinterakcnimenu} +\setinterfacecommand{defineitemgroup}{defineitemgroup} +\setinterfacecommand{definelabel}{definujpopisek} +\setinterfacecommand{definelayer}{definelayer} +\setinterfacecommand{definelayout}{definelayout} +\setinterfacecommand{definelist}{definujseznam} +\setinterfacecommand{definelogo}{definujlogo} +\setinterfacecommand{definemainfield}{definujhlavnipole} +\setinterfacecommand{definemakeup}{definujupravu} +\setinterfacecommand{definemarking}{definujznaceni} +\setinterfacecommand{definemathalignment}{definemathalignment} +\setinterfacecommand{defineoutput}{definujvystup} +\setinterfacecommand{defineoverlay}{definujprekryv} +\setinterfacecommand{definepagebreak}{definepagebreak} +\setinterfacecommand{definepalet}{definujpaletu} +\setinterfacecommand{definepapersize}{definujvelikostpapiru} +\setinterfacecommand{defineparagraphs}{definujodstavce} +\setinterfacecommand{defineplacement}{defineplacement} +\setinterfacecommand{defineprofile}{definujprofil} +\setinterfacecommand{defineprogram}{definujprogram} +\setinterfacecommand{definerawfont}{definerawfont} +\setinterfacecommand{definereference}{definujodkaz} +\setinterfacecommand{definereferenceformat}{definujformatodkazu} +\setinterfacecommand{definereferencelist}{definujseznamodkazu} +\setinterfacecommand{defineregister}{definujrejstrik} +\setinterfacecommand{definerule}{definerule} +\setinterfacecommand{definesection}{definujsekci} +\setinterfacecommand{definesectionblock}{definujbloksekce} +\setinterfacecommand{definesorting}{definujtrideni} +\setinterfacecommand{definestartstop}{definujstartstop} +\setinterfacecommand{definestyle}{definujstyl} +\setinterfacecommand{definesubfield}{definujpodpole} +\setinterfacecommand{definesymbol}{definujsymbol} +\setinterfacecommand{definesynonyms}{definujsynonyma} +\setinterfacecommand{definetabletemplate}{definujsablonutabulky} +\setinterfacecommand{definetabulate}{definujtabelaci} +\setinterfacecommand{definetext}{definujtext} +\setinterfacecommand{definetextbackground}{definetextbackground} +\setinterfacecommand{definetextposition}{definetextposition} +\setinterfacecommand{definetextvariable}{definetextvariable} +\setinterfacecommand{definetype}{definetype} +\setinterfacecommand{definetyping}{definujopis} +\setinterfacecommand{defineversion}{definujverzi} +\setinterfacecommand{determineheadnumber}{stanovcislonadpisu} +\setinterfacecommand{determinelistcharacteristics}{stanovcharakteristickuseznamu} +\setinterfacecommand{determineregistercharacteristics}{urcicharakteristikurejstriku} +\setinterfacecommand{dimension}{rozmer} +\setinterfacecommand{disableinteractionmenu}{zablokujinterakcnimenu} +\setinterfacecommand{domicile}{bydliste} +\setinterfacecommand{donttest}{zadnytest} +\setinterfacecommand{edgedistance}{vzdalenostokraje} +\setinterfacecommand{edgewidth}{sirkaokraje} +\setinterfacecommand{emptylines}{emptylines} +\setinterfacecommand{environment}{prostredi} +\setinterfacecommand{externalfigure}{externiobraz} +\setinterfacecommand{fact}{fakt} +\setinterfacecommand{field}{pole} +\setinterfacecommand{fieldstack}{zasobnikpoli} +\setinterfacecommand{fillinfield}{vyplnovepole} +\setinterfacecommand{fillinline}{vyplnovyradek} +\setinterfacecommand{fillinrules}{vyplnovelinky} +\setinterfacecommand{fillintext}{vyplnenytext} +\setinterfacecommand{fitfield}{prizpusobivepole} +\setinterfacecommand{fixedspace}{tvrdamezera} +\setinterfacecommand{fixedspaces}{tvrdemezery} +\setinterfacecommand{followprofile}{dodrzujprofil} +\setinterfacecommand{followprofileversion}{dodrzujverziprofilu} +\setinterfacecommand{followversion}{dodrzujverzi} +\setinterfacecommand{footerdistance}{vzdalenostupati} +\setinterfacecommand{footerheight}{vyskaupati} +\setinterfacecommand{footnote}{poznamkapodcarou} +\setinterfacecommand{footnotetext}{footnotetext} +\setinterfacecommand{forceblocks}{forceblocks} +\setinterfacecommand{formulanumber}{cislorovnice} +\setinterfacecommand{fraction}{zlomek} +\setinterfacecommand{framed}{oramovani} +\setinterfacecommand{from}{zref} +\setinterfacecommand{getbuffer}{ziskejbuffer} +\setinterfacecommand{getmarking}{ziskejznaceni} +\setinterfacecommand{getnumber}{getnumber} +\setinterfacecommand{godown}{jdidolu} +\setinterfacecommand{goto}{jdina} +\setinterfacecommand{gotobox}{jdinabox} +\setinterfacecommand{gotopage}{jdinastranu} +\setinterfacecommand{graycolor}{sedabarva} +\setinterfacecommand{greyvalue}{hodnotasedi} +\setinterfacecommand{grid}{mrizka} +\setinterfacecommand{hairline}{vlasovalinka} +\setinterfacecommand{head}{nadpis} +\setinterfacecommand{headerdistance}{vzdalenostzahlavi} +\setinterfacecommand{headerheight}{vyskazahlavi} +\setinterfacecommand{headlevel}{hlavniuroven} +\setinterfacecommand{headnumber}{cislonadpisu} +\setinterfacecommand{headsym}{headsym} +\setinterfacecommand{headtext}{texthlavicky} +\setinterfacecommand{hideblocks}{schovejbloky} +\setinterfacecommand{high}{vysoky} +\setinterfacecommand{hl}{hl} +\setinterfacecommand{immediatebetweenlist}{immediatebetweenlist} +\setinterfacecommand{immediatetolist}{immediatetolist} +\setinterfacecommand{in}{tref} +\setinterfacecommand{incrementnumber}{zvysujicicislo} +\setinterfacecommand{indenting}{odsazovani} +\setinterfacecommand{inframed}{zaramovani} +\setinterfacecommand{infull}{plnezneni} +\setinterfacecommand{ininner}{ininner} +\setinterfacecommand{inleft}{vlevo} +\setinterfacecommand{inleftedge}{nalevo} +\setinterfacecommand{inleftmargin}{nalevyokraj} +\setinterfacecommand{inline}{vradku} +\setinterfacecommand{inmargin}{naokraj} +\setinterfacecommand{inmframed}{mazaramovani} +\setinterfacecommand{inneredgedistance}{inneredgedistance} +\setinterfacecommand{inneredgewidth}{inneredgewidth} +\setinterfacecommand{innermargindistance}{innermargindistance} +\setinterfacecommand{innermarginwidth}{innermarginwidth} +\setinterfacecommand{inothermargin}{nadruhyokraj} +\setinterfacecommand{inouter}{inouter} +\setinterfacecommand{inright}{vpravo} +\setinterfacecommand{inrightedge}{napravo} +\setinterfacecommand{inrightmargin}{napravyokraj} +\setinterfacecommand{installlanguage}{instalacejazyka} +\setinterfacecommand{interactionbar}{interakcnilista} +\setinterfacecommand{interactionbuttons}{interakcnitlacitka} +\setinterfacecommand{interactionmenu}{interaktivnimenu} +\setinterfacecommand{item}{polozka} +\setinterfacecommand{items}{polozky} +\setinterfacecommand{its}{pol} +\setinterfacecommand{keepblocks}{zachovejbloky} +\setinterfacecommand{label}{poppisek} +\setinterfacecommand{labels}{popisky} +\setinterfacecommand{labeltext}{textpopisku} +\setinterfacecommand{language}{jazyk} +\setinterfacecommand{leftaligned}{zarovnanovlevo} +\setinterfacecommand{leftedgedistance}{vzdalenostlevehookraje} +\setinterfacecommand{leftedgewidth}{sirkalevehookraje} +\setinterfacecommand{leftmargindistance}{vzdalenostlevemarginalie} +\setinterfacecommand{leftmarginwidth}{sirkalevemarginalie} +\setinterfacecommand{leg}{leg} +\setinterfacecommand{linecorrection}{linecorrection} +\setinterfacecommand{linewidth}{tloustkacary} +\setinterfacecommand{listheight}{vyskaseznamu} +\setinterfacecommand{listlength}{delkaseznamu} +\setinterfacecommand{listsymbol}{listsymbol} +\setinterfacecommand{listwidth}{sirkaseznamu} +\setinterfacecommand{localfootnotes}{localfootnotes} +\setinterfacecommand{logfields}{zaznamovepole} +\setinterfacecommand{lohi}{nivy} +\setinterfacecommand{low}{nizky} +\setinterfacecommand{macroname}{jmeno} +\setinterfacecommand{mainlanguage}{hlavnijazyk} +\setinterfacecommand{makeupheight}{vyskasazby} +\setinterfacecommand{makeupwidth}{sirkasazby} +\setinterfacecommand{mar}{okr} +\setinterfacecommand{marginblock}{marginblock} +\setinterfacecommand{margindistance}{vzdalenostmarginalie} +\setinterfacecommand{marginrule}{marginalnilinka} +\setinterfacecommand{margintext}{marginalnitext} +\setinterfacecommand{margintitle}{marginalninadpis} +\setinterfacecommand{marginwidth}{sirkamarginalie} +\setinterfacecommand{marginword}{marginalnislovo} +\setinterfacecommand{marking}{znaceni} +\setinterfacecommand{markversion}{oznacverzi} +\setinterfacecommand{mathematics}{matematika} +\setinterfacecommand{menubutton}{tlacitkomenu} +\setinterfacecommand{mframed}{maoramovani} +\setinterfacecommand{midaligned}{zarovnanonastred} +\setinterfacecommand{mirror}{zrcadlit} +\setinterfacecommand{month}{mesic} +\setinterfacecommand{moveformula}{moveformula} +\setinterfacecommand{moveongrid}{premistinamrizku} +\setinterfacecommand{movesidefloat}{movesidefloat} +\setinterfacecommand{navigating}{navigating} +\setinterfacecommand{nodimension}{zadnyrozmer} +\setinterfacecommand{noheaderandfooterlines}{zadnezahlaviaupati} +\setinterfacecommand{noindenting}{zadneodsazovani} +\setinterfacecommand{nolist}{zadnyseznam} +\setinterfacecommand{nomarking}{zadneznaceni} +\setinterfacecommand{nomoreblocks}{zadnedalsibloky} +\setinterfacecommand{nomorefiles}{zadnedalsisoubory} +\setinterfacecommand{nop}{nop} +\setinterfacecommand{nospace}{zadnamezera} +\setinterfacecommand{note}{poznamka} +\setinterfacecommand{notopandbottomlines}{zadnehorniadolniradky} +\setinterfacecommand{notsmallcapped}{nokap} +\setinterfacecommand{nowhitespace}{zadnebilemisto} +\setinterfacecommand{numberofsubpages}{numberofsubpages} +\setinterfacecommand{numbers}{cisla} +\setinterfacecommand{outeredgedistance}{outeredgedistance} +\setinterfacecommand{outeredgewidth}{outeredgewidth} +\setinterfacecommand{outermargindistance}{outermargindistance} +\setinterfacecommand{outermarginwidth}{outermarginwidth} +\setinterfacecommand{packed}{zhustene} +\setinterfacecommand{page}{strana} +\setinterfacecommand{pagedepth}{pagedepth} +\setinterfacecommand{pagenumber}{cislostrany} +\setinterfacecommand{pageoffset}{pageoffset} +\setinterfacecommand{pagereference}{odkaznastranu} +\setinterfacecommand{paperheight}{vyskapapiru} +\setinterfacecommand{paperwidth}{sirkapapiru} +\setinterfacecommand{periods}{tecky} +\setinterfacecommand{placebookmarks}{umistizalozky} +\setinterfacecommand{placecombinedlist}{umistikombinovanyseznam} +\setinterfacecommand{placefloat}{placefloat} +\setinterfacecommand{placefootnotes}{umistipoznamkypodcarou} +\setinterfacecommand{placeformula}{umistirovnici} +\setinterfacecommand{placeheadnumber}{placeheadnumber} +\setinterfacecommand{placeheadtext}{placeheadtext} +\setinterfacecommand{placelegend}{umistilegendu} +\setinterfacecommand{placelist}{umistiseznam} +\setinterfacecommand{placelistofsynonyms}{placelistofsynonyms} +\setinterfacecommand{placelocalfootnotes}{umistilokalnipoznamkypodcarou} +\setinterfacecommand{placelogos}{umistiloga} +\setinterfacecommand{placeongrid}{umistinamrizku} +\setinterfacecommand{placeontopofeachother}{umistinadsebe} +\setinterfacecommand{placepagenumber}{placepagenumber} +\setinterfacecommand{placerawlist}{placerawlist} +\setinterfacecommand{placereferencelist}{placereferencelist} +\setinterfacecommand{placeregister}{umistirejstrik} +\setinterfacecommand{placerule}{placerule} +\setinterfacecommand{placesidebyside}{umistivedlesebe} +\setinterfacecommand{placesubformula}{umistipodrovnici} +\setinterfacecommand{placetextvariable}{placetextvariable} +\setinterfacecommand{position}{pozice} +\setinterfacecommand{positiontext}{positiontext} +\setinterfacecommand{printpaperheight}{vyskatiskpapiru} +\setinterfacecommand{printpaperwidth}{sirkatiskpapiru} +\setinterfacecommand{processblocks}{zpracujbloky} +\setinterfacecommand{processpage}{zpracujstranu} +\setinterfacecommand{product}{produkt} +\setinterfacecommand{program}{program} +\setinterfacecommand{project}{projekt} +\setinterfacecommand{publication}{publikace} +\setinterfacecommand{quotation}{citace} +\setinterfacecommand{quote}{citovat} +\setinterfacecommand{ran}{ran} +\setinterfacecommand{redo}{opakovat} +\setinterfacecommand{ref}{ref} +\setinterfacecommand{reference}{odkaz} +\setinterfacecommand{referral}{odkaz} +\setinterfacecommand{referraldate}{odkaznadatum} +\setinterfacecommand{referring}{odkazujici} +\setinterfacecommand{remark}{oznaceni} +\setinterfacecommand{reset}{reset} +\setinterfacecommand{resetmarking}{resetznaceni} +\setinterfacecommand{resetnumber}{resetnumber} +\setinterfacecommand{resettext}{resettextcontent} +\setinterfacecommand{rightaligned}{zarovnanovpravo} +\setinterfacecommand{rightedgedistance}{vzdalenostpravehookraje} +\setinterfacecommand{rightedgewidth}{sirkapravehookraje} +\setinterfacecommand{rightmargindistance}{vzdalenostpravemarginalie} +\setinterfacecommand{rightmarginwidth}{sirkapravemarginalie} +\setinterfacecommand{romannumerals}{rimskecislice} +\setinterfacecommand{rotate}{otocit} +\setinterfacecommand{savebuffer}{savebuffer} +\setinterfacecommand{scale}{meritko} +\setinterfacecommand{screen}{obrazovka} +\setinterfacecommand{selectblocks}{vyberbloky} +\setinterfacecommand{selectpaper}{vyberpapir} +\setinterfacecommand{selectversion}{vyberverzi} +\setinterfacecommand{setnumber}{setnumber} +\setinterfacecommand{settextcontent}{settextcontent} +\setinterfacecommand{settextvariable}{settextvariable} +\setinterfacecommand{setupalign}{nastavzarovnani} +\setinterfacecommand{setupanswerarea}{setupanswerarea} +\setinterfacecommand{setuparranging}{nastavusporadani} +\setinterfacecommand{setupbackground}{nastavpozadi} +\setinterfacecommand{setupbackgrounds}{nastavpozadi} +\setinterfacecommand{setupblackrules}{nastavcernelinky} +\setinterfacecommand{setupblank}{nastavpreskok} +\setinterfacecommand{setupblock}{nastavblok} +\setinterfacecommand{setupbodyfont}{nastavzakladnifont} +\setinterfacecommand{setupbodyfontenvironment}{nastavprostredizakladnihofontu} +\setinterfacecommand{setupbottom}{nastavspodek} +\setinterfacecommand{setupbottomtexts}{nastavdolnitexty} +\setinterfacecommand{setupbuffer}{nastavbuffer} +\setinterfacecommand{setupbuttons}{nastavtlacitka} +\setinterfacecommand{setupcapitals}{nastavkapitalky} +\setinterfacecommand{setupcaption}{nastavpopisek} +\setinterfacecommand{setupcaptions}{nastavpopisky} +\setinterfacecommand{setupclipping}{nastavorez} +\setinterfacecommand{setupcolor}{nastavbarvu} +\setinterfacecommand{setupcolors}{nastavbarvy} +\setinterfacecommand{setupcolumns}{nastavsloupce} +\setinterfacecommand{setupcolumnset}{setupcolumnset} +\setinterfacecommand{setupcolumnsetlines}{setupcolumnsetlines} +\setinterfacecommand{setupcolumnsetstart}{setupcolumnsetstart} +\setinterfacecommand{setupcombinations}{nastavspojeni} +\setinterfacecommand{setupcombinedlist}{nastavkombinovanyseznam} +\setinterfacecommand{setupcomment}{nastavkomentar} +\setinterfacecommand{setupdescription}{setupdescription} +\setinterfacecommand{setupdescriptions}{nastavpopisy} +\setinterfacecommand{setupenumeration}{setupenumeration} +\setinterfacecommand{setupenumerations}{nastavvycty} +\setinterfacecommand{setupexternalfigures}{nastavexterniobrazy} +\setinterfacecommand{setupfield}{nastavpole} +\setinterfacecommand{setupfields}{nastavvsechnapole} +\setinterfacecommand{setupfillinlines}{nastavvyplnoveradky} +\setinterfacecommand{setupfillinrules}{nastavvyplnovelinky} +\setinterfacecommand{setupfloat}{nastavplvouciobjekt} +\setinterfacecommand{setupfloats}{nastavplvouciobjekty} +\setinterfacecommand{setupfloatsplitting}{nastavdeleniplvoucichobjektu} +\setinterfacecommand{setupfooter}{nastavupati} +\setinterfacecommand{setupfootertexts}{nastavtextyupati} +\setinterfacecommand{setupfootnotedefinition}{nastavdefinicipoznamekpodcarou} +\setinterfacecommand{setupfootnotes}{nastavpoznamkypodcarou} +\setinterfacecommand{setupforms}{setupforms} +\setinterfacecommand{setupformula}{setupformula} +\setinterfacecommand{setupformulas}{nastavrovnice} +\setinterfacecommand{setupframed}{nastavoramovani} +\setinterfacecommand{setupframedtext}{setupframedtext} +\setinterfacecommand{setupframedtexts}{nastavoramovanetexty} +\setinterfacecommand{setuphead}{nastavnadpis} +\setinterfacecommand{setupheader}{nastavzahlavi} +\setinterfacecommand{setupheadertexts}{nastavtextyzahlavi} +\setinterfacecommand{setupheadnumber}{nastavcislonadpisu} +\setinterfacecommand{setupheads}{nastavnadpisy} +\setinterfacecommand{setupheadtext}{nastavtexthlavicky} +\setinterfacecommand{setuphyphenmark}{nastavdelitko} +\setinterfacecommand{setupindentedtext}{setupindentedtext} +\setinterfacecommand{setupindenting}{nastavodsazovani} +\setinterfacecommand{setupinmargin}{nastavmarginalie} +\setinterfacecommand{setupinteraction}{nastavinterakci} +\setinterfacecommand{setupinteractionbar}{nastavinterakcnilistu} +\setinterfacecommand{setupinteractionmenu}{nastavinterakcnimenu} +\setinterfacecommand{setupinteractionscreen}{nastavinterakcniobrazovku} +\setinterfacecommand{setupinterlinespace}{nastavmeziradkovoumezeru} +\setinterfacecommand{setupitemgroup}{setupitemgroup} +\setinterfacecommand{setupitemgroups}{nastavvycty} +\setinterfacecommand{setupitems}{nastavpolozky} +\setinterfacecommand{setuplabeltext}{nastavtextpopisku} +\setinterfacecommand{setuplanguage}{nastavjazyk} +\setinterfacecommand{setuplayout}{nastavvzhled} +\setinterfacecommand{setuplegend}{nastavlegendu} +\setinterfacecommand{setuplinenumbering}{nastavcislovaniradku} +\setinterfacecommand{setuplines}{nastavradky} +\setinterfacecommand{setuplinewidth}{nastavsirkucary} +\setinterfacecommand{setuplist}{nastavseznam} +\setinterfacecommand{setupmakeup}{nastavupravu} +\setinterfacecommand{setupmarginblock}{setupmarginblock} +\setinterfacecommand{setupmarginblocks}{nastavmarginalniblok} +\setinterfacecommand{setupmargindata}{setupmargindata} +\setinterfacecommand{setupmarginrules}{nastavmarginalnilinky} +\setinterfacecommand{setupmarking}{nastavznaceni} +\setinterfacecommand{setupmathalignment}{setupmathalignment} +\setinterfacecommand{setupnarrower}{nastavzuzeni} +\setinterfacecommand{setupnumber}{setupnumber} +\setinterfacecommand{setupnumbering}{nastavcislovani} +\setinterfacecommand{setupoppositeplacing}{nastavumisteniprotejsku} +\setinterfacecommand{setupoutput}{nastavvystup} +\setinterfacecommand{setuppagecomment}{nastavkomentarstrany} +\setinterfacecommand{setuppagenumber}{nastavcislostrany} +\setinterfacecommand{setuppagenumbering}{nastavcislovanistran} +\setinterfacecommand{setuppagetransitions}{nastavprechodstrany} +\setinterfacecommand{setuppalet}{nastavpaletu} +\setinterfacecommand{setuppaper}{setuppaper} +\setinterfacecommand{setuppapersize}{nastavvelikostpapiru} +\setinterfacecommand{setupparagraphnumbering}{nastavcislovaniodstavcu} +\setinterfacecommand{setupparagraphs}{nastavodstavce} +\setinterfacecommand{setupplacement}{setupplacement} +\setinterfacecommand{setuppositioning}{nastavumistovani} +\setinterfacecommand{setupprofiles}{nastavprofily} +\setinterfacecommand{setupprograms}{nastavprogramy} +\setinterfacecommand{setuppublications}{nastavpublikace} +\setinterfacecommand{setupquote}{nastavcitaci} +\setinterfacecommand{setupreferencelist}{nastavseznamodkazu} +\setinterfacecommand{setupreferencing}{nastavodkazovani} +\setinterfacecommand{setupregister}{nastavrejstrik} +\setinterfacecommand{setuprotate}{nastavotoceni} +\setinterfacecommand{setuprule}{setuprule} +\setinterfacecommand{setupscreens}{nastavrastr} +\setinterfacecommand{setupsection}{nastavsekci} +\setinterfacecommand{setupsectionblock}{nastavbloksekce} +\setinterfacecommand{setupsorting}{nastavtrideni} +\setinterfacecommand{setupspacing}{nastavradkovani} +\setinterfacecommand{setupstartstop}{setupstartstop} +\setinterfacecommand{setupstrut}{setupstrut} +\setinterfacecommand{setupsubpagenumber}{nastavpodcislostrany} +\setinterfacecommand{setupsymbolset}{nastavsadusymbolu} +\setinterfacecommand{setupsynchronization}{nastavsynchronizaci} +\setinterfacecommand{setupsynchronizationbar}{nastavsynchronizacnilistu} +\setinterfacecommand{setupsynonyms}{nastavsynonyma} +\setinterfacecommand{setupsystem}{nastavsystem} +\setinterfacecommand{setuptab}{nastavtab} +\setinterfacecommand{setuptables}{nastavtabulky} +\setinterfacecommand{setuptabulate}{nastavtabelaci} +\setinterfacecommand{setuptext}{nastavtext} +\setinterfacecommand{setuptextbackground}{setuptextbackground} +\setinterfacecommand{setuptextposition}{setuptextposition} +\setinterfacecommand{setuptextrules}{nastavtextovelinky} +\setinterfacecommand{setuptexttexts}{nastavtexttexty} +\setinterfacecommand{setuptextvariable}{setuptextvariable} +\setinterfacecommand{setupthinrules}{nastavtenkelinky} +\setinterfacecommand{setuptolerance}{nastavtoleranci} +\setinterfacecommand{setuptop}{nastavhorejsek} +\setinterfacecommand{setuptoptexts}{nastavhornitexty} +\setinterfacecommand{setuptype}{nastavtype} +\setinterfacecommand{setuptyping}{nastavopis} +\setinterfacecommand{setupunderbar}{nastavpodtrzeni} +\setinterfacecommand{setupurl}{nastavurl} +\setinterfacecommand{setupversions}{nastavverze} +\setinterfacecommand{setupwhitespace}{nastavbilamista} +\setinterfacecommand{showbodyfont}{ukazzakladnifont} +\setinterfacecommand{showbodyfontenvironment}{ukazpostredizakladnihofontu} +\setinterfacecommand{showcolor}{ukazbarvu} +\setinterfacecommand{showcolorgroup}{ukazskupinubarev} +\setinterfacecommand{showexternalfigures}{ukazexterniobrazy} +\setinterfacecommand{showfields}{ukazpole} +\setinterfacecommand{showframe}{ukazramecek} +\setinterfacecommand{showgrid}{ukazmrizku} +\setinterfacecommand{showlayout}{ukazvzhled} +\setinterfacecommand{showmakeup}{ukazupravu} +\setinterfacecommand{showpalet}{ukazpaletu} +\setinterfacecommand{showprint}{ukazvytisk} +\setinterfacecommand{showsetups}{ukaznastaveni} +\setinterfacecommand{showstruts}{ukazpodpery} +\setinterfacecommand{showsymbolset}{ukazsadusymbolu} +\setinterfacecommand{smallcapped}{kap} +\setinterfacecommand{someline}{nejakyradek} +\setinterfacecommand{somewhere}{nekde} +\setinterfacecommand{space}{mezera} +\setinterfacecommand{splitfloat}{rozdelplvouciobjekt} +\setinterfacecommand{startalignment}{startzarovnavani} +\setinterfacecommand{startbackground}{startpozadi} +\setinterfacecommand{startcoding}{startkodovani} +\setinterfacecommand{startcolor}{startbarva} +\setinterfacecommand{startcolumnmakeup}{startcolumnmakeup} +\setinterfacecommand{startcolumns}{startsloupce} +\setinterfacecommand{startcolumnset}{startcolumnset} +\setinterfacecommand{startcombination}{startspojeni} +\setinterfacecommand{startcomponent}{startkomponenta} +\setinterfacecommand{startdocument}{startdokument} +\setinterfacecommand{startenvironment}{startprostredi} +\setinterfacecommand{startfigure}{startobraz} +\setinterfacecommand{startframed}{startframed} +\setinterfacecommand{startglobal}{startglobalni} +\setinterfacecommand{startline}{startradek} +\setinterfacecommand{startlinecorrection}{startkorekceradku} +\setinterfacecommand{startlinenumbering}{startcislovaniradku} +\setinterfacecommand{startlines}{startradky} +\setinterfacecommand{startlocal}{startlokalni} +\setinterfacecommand{startlocalfootnotes}{startlokalnipoznamkypodcarou} +\setinterfacecommand{startmakeup}{startuprava} +\setinterfacecommand{startmarginblock}{startmarginalniblok} +\setinterfacecommand{startmarginrule}{startmarginalnilinka} +\setinterfacecommand{startnarrower}{startzuzeni} +\setinterfacecommand{startopposite}{startprotejsek} +\setinterfacecommand{startoverlay}{startprekryv} +\setinterfacecommand{startoverzicht}{startprehled} +\setinterfacecommand{startpacked}{startzhustene} +\setinterfacecommand{startpositioning}{startumistovani} +\setinterfacecommand{startproduct}{startprodukt} +\setinterfacecommand{startprofile}{startprofil} +\setinterfacecommand{startproject}{startprojekt} +\setinterfacecommand{startquotation}{startcitace} +\setinterfacecommand{startraster}{startrastr} +\setinterfacecommand{startsymbolset}{startsadasymbolu} +\setinterfacecommand{startsynchronization}{startsynchronizace} +\setinterfacecommand{starttable}{starttabulka} +\setinterfacecommand{starttables}{starttabulky} +\setinterfacecommand{starttext}{starttext} +\setinterfacecommand{starttextbackground}{starttextbackground} +\setinterfacecommand{starttextrule}{starttextovalinka} +\setinterfacecommand{startunpacked}{startnezhustene} +\setinterfacecommand{startversion}{startverze} +\setinterfacecommand{stopalignment}{stopzarovnavani} +\setinterfacecommand{stopbackground}{stoppozadi} +\setinterfacecommand{stopcoding}{stopkodovani} +\setinterfacecommand{stopcolor}{stopbarva} +\setinterfacecommand{stopcolumnmakeup}{stopcolumnmakeup} +\setinterfacecommand{stopcolumns}{stopsloupce} +\setinterfacecommand{stopcolumnset}{stopcolumnset} +\setinterfacecommand{stopcombination}{stopspojeni} +\setinterfacecommand{stopcomponent}{stopkomponenta} +\setinterfacecommand{stopdocument}{stopdokument} +\setinterfacecommand{stopenvironment}{stopprostredi} +\setinterfacecommand{stopframed}{stopframed} +\setinterfacecommand{stopglobal}{stopglobalni} +\setinterfacecommand{stopline}{stopradek} +\setinterfacecommand{stoplinecorrection}{stopkorekceradku} +\setinterfacecommand{stoplinenumbering}{stopcislovaniradku} +\setinterfacecommand{stoplines}{stopradky} +\setinterfacecommand{stoplocal}{stoplokalni} +\setinterfacecommand{stoplocalfootnotes}{stoplokalnipoznamkypodcarou} +\setinterfacecommand{stopmakeup}{stopuprava} +\setinterfacecommand{stopmarginblock}{stopmarginalniblok} +\setinterfacecommand{stopmarginrule}{stopmarginalnilinka} +\setinterfacecommand{stopnarrower}{stopzuzeni} +\setinterfacecommand{stopopposite}{stopprotejsek} +\setinterfacecommand{stopoverlay}{stopprekryv} +\setinterfacecommand{stopoverzicht}{stopprehled} +\setinterfacecommand{stoppacked}{stopzhustene} +\setinterfacecommand{stoppositioning}{stopumistovani} +\setinterfacecommand{stopproduct}{stopprodukt} +\setinterfacecommand{stopprofile}{stopprofil} +\setinterfacecommand{stopproject}{stopprojekt} +\setinterfacecommand{stopquotation}{stopcitace} +\setinterfacecommand{stopraster}{stoprastr} +\setinterfacecommand{stopsynchronization}{stopsynchronizace} +\setinterfacecommand{stoptable}{stoptabulka} +\setinterfacecommand{stoptables}{stoptabulky} +\setinterfacecommand{stoptext}{stoptext} +\setinterfacecommand{stoptextbackground}{stoptextbackground} +\setinterfacecommand{stoptextrule}{stoptextovalinka} +\setinterfacecommand{stopunpacked}{stopnezhustene} +\setinterfacecommand{stopversion}{stopverze} +\setinterfacecommand{stretched}{roztazene} +\setinterfacecommand{subformulanumber}{cislopodrovnice} +\setinterfacecommand{subpagenumber}{subpagenumber} +\setinterfacecommand{switchtobodyfont}{prepninazakladnifont} +\setinterfacecommand{switchtorawfont}{switchtorawfont} +\setinterfacecommand{sym}{sym} +\setinterfacecommand{symbol}{symbol} +\setinterfacecommand{symoffset}{symoffset} +\setinterfacecommand{synchronizationbar}{synchronizacnilista} +\setinterfacecommand{synchronize}{synchronizovat} +\setinterfacecommand{tab}{tab} +\setinterfacecommand{testcolumn}{testcolumn} +\setinterfacecommand{testpage}{testpage} +\setinterfacecommand{tex}{tex} +\setinterfacecommand{textbackground}{textbackground} +\setinterfacecommand{textheight}{vyskatextu} +\setinterfacecommand{textreference}{odkaznatext} +\setinterfacecommand{textrule}{textovalinka} +\setinterfacecommand{textvariable}{textvariable} +\setinterfacecommand{textwidth}{sirkatextu} +\setinterfacecommand{thinrule}{tenkalinka} +\setinterfacecommand{thinrules}{tenkelinky} +\setinterfacecommand{tooltip}{bublinkovanapoveda} +\setinterfacecommand{topdistance}{vzdalenosthorejsku} +\setinterfacecommand{topheight}{vyskahorejsku} +\setinterfacecommand{topspace}{odsazenishora} +\setinterfacecommand{totalnumberofpages}{celkovypocetstran} +\setinterfacecommand{translate}{prelozit} +\setinterfacecommand{txt}{txt} +\setinterfacecommand{typ}{pis} +\setinterfacecommand{type}{opis} +\setinterfacecommand{typebuffer}{typebuffer} +\setinterfacecommand{typefile}{opissoubor} +\setinterfacecommand{unitmeaning}{vyznam} +\setinterfacecommand{unknown}{neznamo} +\setinterfacecommand{useJSscripts}{uzijJSscripts} +\setinterfacecommand{useURL}{uzijURL} +\setinterfacecommand{useXMLfilter}{useXMLfilter} +\setinterfacecommand{useblocks}{uzijbloky} +\setinterfacecommand{usecommands}{uzijprikazy} +\setinterfacecommand{useencoding}{uzijkodovani} +\setinterfacecommand{useexternaldocument}{uzijexternidokument} +\setinterfacecommand{useexternalfigure}{uzijexterniobraz} +\setinterfacecommand{useexternalfile}{uzijexternisoubor} +\setinterfacecommand{useexternalfiles}{uzijexternisoubory} +\setinterfacecommand{useexternalsoundtrack}{uzijexternizvuk} +\setinterfacecommand{usemodule}{uzijmodul} +\setinterfacecommand{usemodules}{uzijmoduly} +\setinterfacecommand{usepath}{uzijadresar} +\setinterfacecommand{usereferences}{uzijodkazy} +\setinterfacecommand{usespecials}{uzijspeciality} +\setinterfacecommand{usesymbols}{uzijsymbol} +\setinterfacecommand{usetypescript}{usetypescript} +\setinterfacecommand{usetypescriptfile}{usetypescriptfile} +\setinterfacecommand{useurl}{uzijurl} +\setinterfacecommand{version}{verze} +\setinterfacecommand{vl}{vl} +\setinterfacecommand{weekday}{vsedniden} +\setinterfacecommand{whitespace}{bilemisto} +\setinterfacecommand{wordright}{slovovpravo} +\setinterfacecommand{writebetweenlist}{zapismeziseznam} +\setinterfacecommand{writetolist}{zapisdoseznamu} +\setinterfacecommand{writetoreferencelist}{zapisdoseznamuodkazu} +\setinterfacecommand{writetoregister}{zapisdorejstriku} +% +\endinput
\ No newline at end of file diff --git a/tex/context/base/mkii/mult-de.mkii b/tex/context/base/mkii/mult-de.mkii index 0762fadfc..ec1fb10f4 100644 --- a/tex/context/base/mkii/mult-de.mkii +++ b/tex/context/base/mkii/mult-de.mkii @@ -76,6 +76,7 @@ \setinterfacevariable{all}{alles} \setinterfacevariable{alphabetic}{alphabetic} \setinterfacevariable{always}{immer} +\setinterfacevariable{anchor}{anchor} \setinterfacevariable{and}{und} \setinterfacevariable{answerarea}{answerarea} \setinterfacevariable{appendices}{anhaenge} @@ -169,9 +170,11 @@ \setinterfacevariable{down}{down} \setinterfacevariable{each}{jede} \setinterfacevariable{edge}{kante} +\setinterfacevariable{effective}{effective} \setinterfacevariable{eight}{acht} \setinterfacevariable{embed}{embed} \setinterfacevariable{empty}{leer} +\setinterfacevariable{enable}{enable} \setinterfacevariable{end}{end} \setinterfacevariable{endnote}{endnote} \setinterfacevariable{enumeration}{nummerierung} @@ -206,9 +209,10 @@ \setinterfacevariable{force}{zwinge} \setinterfacevariable{foreground}{vordergrund} \setinterfacevariable{formula}{formel} -\setinterfacevariable{formulae}{formeln} +\setinterfacevariable{formulas}{formeln} \setinterfacevariable{forward}{vorwaerts} \setinterfacevariable{four}{vier} +\setinterfacevariable{fractions}{fractions} \setinterfacevariable{frame}{rahmen} \setinterfacevariable{framedtext}{umrahmtertext} \setinterfacevariable{friday}{freitag} @@ -233,6 +237,7 @@ \setinterfacevariable{here}{hier} \setinterfacevariable{hereafter}{nachher} \setinterfacevariable{hidden}{versteckt} +\setinterfacevariable{hiddenbar}{hiddenbar} \setinterfacevariable{hiding}{verbergen} \setinterfacevariable{high}{hoch} \setinterfacevariable{horizontal}{horizontal} @@ -376,6 +381,7 @@ \setinterfacevariable{note}{note} \setinterfacevariable{nothanging}{nothanging} \setinterfacevariable{nothyphenated}{nothyphenated} +\setinterfacevariable{notjoinedup}{notjoinedup} \setinterfacevariable{november}{november} \setinterfacevariable{nowhere}{nirgens} \setinterfacevariable{nowhite}{keinweiss} @@ -621,6 +627,7 @@ \setinterfaceconstant{anchor}{anchor} \setinterfaceconstant{andtext}{andtext} \setinterfaceconstant{apa}{apa} +\setinterfaceconstant{arguments}{arguments} \setinterfaceconstant{arrow}{pfeil} \setinterfaceconstant{artauthor}{artauthor} \setinterfaceconstant{artauthoretaldisplay}{artauthoretaldisplay} @@ -721,6 +728,7 @@ \setinterfaceconstant{controls}{controls} \setinterfaceconstant{conversion}{konversion} \setinterfaceconstant{convertfile}{konvertieredatei} +\setinterfaceconstant{copies}{copies} \setinterfaceconstant{corner}{winkel} \setinterfaceconstant{coupling}{verknuepfung} \setinterfaceconstant{couplingway}{verkopplungsart} @@ -769,6 +777,7 @@ \setinterfaceconstant{etaloption}{etaloption} \setinterfaceconstant{etaltext}{etaltext} \setinterfaceconstant{evenmargin}{geraderand} +\setinterfaceconstant{exact}{exact} \setinterfaceconstant{exitoffset}{exitoffset} \setinterfaceconstant{expansion}{expansion} \setinterfaceconstant{export}{export} @@ -811,6 +820,7 @@ \setinterfaceconstant{frameoffset}{rahmenoffset} \setinterfaceconstant{frameradius}{rahmenradius} \setinterfaceconstant{frames}{umrahmen} +\setinterfaceconstant{freeregion}{freeregion} \setinterfaceconstant{from}{von} \setinterfaceconstant{functioncolor}{functioncolor} \setinterfaceconstant{functionstyle}{functionstyle} @@ -1160,6 +1170,7 @@ \setinterfaceconstant{splitoffset}{splitoffset} \setinterfaceconstant{spot}{spot} \setinterfaceconstant{stack}{stack} +\setinterfaceconstant{stackname}{stackname} \setinterfaceconstant{start}{start} \setinterfaceconstant{starter}{starter} \setinterfaceconstant{state}{status} @@ -1170,6 +1181,7 @@ \setinterfaceconstant{strip}{strip} \setinterfaceconstant{strut}{strut} \setinterfaceconstant{style}{stil} +\setinterfaceconstant{stylealternative}{stylealternative} \setinterfaceconstant{sub}{unter} \setinterfaceconstant{subtitle}{untertitel} \setinterfaceconstant{suffix}{suffix} @@ -1225,6 +1237,7 @@ \setinterfaceconstant{topspace}{kopfspatium} \setinterfaceconstant{topstate}{statusoben} \setinterfaceconstant{totalnumber}{totalnumber} +\setinterfaceconstant{transform}{transform} \setinterfaceconstant{translate}{translate} \setinterfaceconstant{trimoffset}{trimoffset} \setinterfaceconstant{type}{typ} @@ -1305,6 +1318,7 @@ \setinterfacecommand{Words}{Woerter} \setinterfacecommand{about}{ueber} \setinterfacecommand{adaptlayout}{passelayoutan} +\setinterfacecommand{alignment}{alignment} \setinterfacecommand{arg}{arg} \setinterfacecommand{at}{bei} \setinterfacecommand{atleftmargin}{atleftmargin} @@ -1521,11 +1535,13 @@ \setinterfacecommand{leftmargindistance}{linkemarginalafstand} \setinterfacecommand{leftmarginwidth}{linkemarginalbreite} \setinterfacecommand{leg}{leg} +\setinterfacecommand{linecorrection}{linecorrection} \setinterfacecommand{linewidth}{liniendicke} \setinterfacecommand{listheight}{listenhoehe} \setinterfacecommand{listlength}{listenlaenge} \setinterfacecommand{listsymbol}{listsymbol} \setinterfacecommand{listwidth}{listenbreite} +\setinterfacecommand{localfootnotes}{localfootnotes} \setinterfacecommand{logfields}{registrierefelder} \setinterfacecommand{lohi}{tiho} \setinterfacecommand{low}{tief} @@ -1534,6 +1550,7 @@ \setinterfacecommand{makeupheight}{satzhoehe} \setinterfacecommand{makeupwidth}{satzbreite} \setinterfacecommand{mar}{mar} +\setinterfacecommand{marginblock}{marginblock} \setinterfacecommand{margindistance}{marginalafstand} \setinterfacecommand{marginrule}{marginallinie} \setinterfacecommand{margintext}{marginaltext} @@ -1633,6 +1650,7 @@ \setinterfacecommand{rightmarginwidth}{rechtemarginalbreite} \setinterfacecommand{romannumerals}{roemischezahlen} \setinterfacecommand{rotate}{drehen} +\setinterfacecommand{savebuffer}{savebuffer} \setinterfacecommand{scale}{format} \setinterfacecommand{screen}{bildschirm} \setinterfacecommand{selectblocks}{waehlebloeckeaus} @@ -1668,7 +1686,9 @@ \setinterfacecommand{setupcombinations}{stellekombinationein} \setinterfacecommand{setupcombinedlist}{stellezusammengestelltelisteein} \setinterfacecommand{setupcomment}{stellekommentarein} +\setinterfacecommand{setupdescription}{setupdescription} \setinterfacecommand{setupdescriptions}{definierebeschreibungen} +\setinterfacecommand{setupenumeration}{setupenumeration} \setinterfacecommand{setupenumerations}{stellebeschreibungein} \setinterfacecommand{setupexternalfigures}{stelleexterneabbildungenein} \setinterfacecommand{setupfield}{stellefeldein} @@ -1683,8 +1703,10 @@ \setinterfacecommand{setupfootnotedefinition}{stellefussnotendefinitionein} \setinterfacecommand{setupfootnotes}{stellefussnotenein} \setinterfacecommand{setupforms}{setupforms} +\setinterfacecommand{setupformula}{setupformula} \setinterfacecommand{setupformulas}{stelleformelnein} \setinterfacecommand{setupframed}{stelleumrahmtein} +\setinterfacecommand{setupframedtext}{setupframedtext} \setinterfacecommand{setupframedtexts}{stelleumrahmtetexteein} \setinterfacecommand{setuphead}{stelleueberschriftein} \setinterfacecommand{setupheader}{stellekopfzeileein} @@ -1713,7 +1735,9 @@ \setinterfacecommand{setuplinewidth}{stellelinienbreiteein} \setinterfacecommand{setuplist}{stellelisteein} \setinterfacecommand{setupmakeup}{stelleumbruchein} +\setinterfacecommand{setupmarginblock}{setupmarginblock} \setinterfacecommand{setupmarginblocks}{stellemarginalblockein} +\setinterfacecommand{setupmargindata}{setupmargindata} \setinterfacecommand{setupmarginrules}{stellemarginallinieein} \setinterfacecommand{setupmarking}{stellebeschriftungein} \setinterfacecommand{setupmathalignment}{setupmathalignment} @@ -1892,6 +1916,7 @@ \setinterfacecommand{testcolumn}{testcolumn} \setinterfacecommand{testpage}{testpage} \setinterfacecommand{tex}{tex} +\setinterfacecommand{textbackground}{textbackground} \setinterfacecommand{textheight}{texthoehe} \setinterfacecommand{textreference}{textreferenz} \setinterfacecommand{textrule}{textlinie} diff --git a/tex/context/base/mkii/mult-en.mkii b/tex/context/base/mkii/mult-en.mkii index a16b87a48..a4838128b 100644 --- a/tex/context/base/mkii/mult-en.mkii +++ b/tex/context/base/mkii/mult-en.mkii @@ -76,6 +76,7 @@ \setinterfacevariable{all}{all} \setinterfacevariable{alphabetic}{alphabetic} \setinterfacevariable{always}{always} +\setinterfacevariable{anchor}{anchor} \setinterfacevariable{and}{and} \setinterfacevariable{answerarea}{answerarea} \setinterfacevariable{appendices}{appendices} @@ -169,9 +170,11 @@ \setinterfacevariable{down}{down} \setinterfacevariable{each}{each} \setinterfacevariable{edge}{edge} +\setinterfacevariable{effective}{effective} \setinterfacevariable{eight}{eight} \setinterfacevariable{embed}{embed} \setinterfacevariable{empty}{empty} +\setinterfacevariable{enable}{enable} \setinterfacevariable{end}{end} \setinterfacevariable{endnote}{endnote} \setinterfacevariable{enumeration}{enumeration} @@ -206,9 +209,10 @@ \setinterfacevariable{force}{force} \setinterfacevariable{foreground}{foreground} \setinterfacevariable{formula}{formula} -\setinterfacevariable{formulae}{formulae} +\setinterfacevariable{formulas}{formulas} \setinterfacevariable{forward}{forward} \setinterfacevariable{four}{four} +\setinterfacevariable{fractions}{fractions} \setinterfacevariable{frame}{frame} \setinterfacevariable{framedtext}{framedtext} \setinterfacevariable{friday}{friday} @@ -233,6 +237,7 @@ \setinterfacevariable{here}{here} \setinterfacevariable{hereafter}{hereafter} \setinterfacevariable{hidden}{hidden} +\setinterfacevariable{hiddenbar}{hiddenbar} \setinterfacevariable{hiding}{hiding} \setinterfacevariable{high}{high} \setinterfacevariable{horizontal}{horizontal} @@ -376,6 +381,7 @@ \setinterfacevariable{note}{note} \setinterfacevariable{nothanging}{nothanging} \setinterfacevariable{nothyphenated}{nothyphenated} +\setinterfacevariable{notjoinedup}{notjoinedup} \setinterfacevariable{november}{november} \setinterfacevariable{nowhere}{nowhere} \setinterfacevariable{nowhite}{nowhite} @@ -621,6 +627,7 @@ \setinterfaceconstant{anchor}{anchor} \setinterfaceconstant{andtext}{andtext} \setinterfaceconstant{apa}{apa} +\setinterfaceconstant{arguments}{arguments} \setinterfaceconstant{arrow}{arrow} \setinterfaceconstant{artauthor}{artauthor} \setinterfaceconstant{artauthoretaldisplay}{artauthoretaldisplay} @@ -721,6 +728,7 @@ \setinterfaceconstant{controls}{controls} \setinterfaceconstant{conversion}{conversion} \setinterfaceconstant{convertfile}{convertfile} +\setinterfaceconstant{copies}{copies} \setinterfaceconstant{corner}{corner} \setinterfaceconstant{coupling}{coupling} \setinterfaceconstant{couplingway}{couplingway} @@ -769,6 +777,7 @@ \setinterfaceconstant{etaloption}{etaloption} \setinterfaceconstant{etaltext}{etaltext} \setinterfaceconstant{evenmargin}{evenmargin} +\setinterfaceconstant{exact}{exact} \setinterfaceconstant{exitoffset}{exitoffset} \setinterfaceconstant{expansion}{expansion} \setinterfaceconstant{export}{export} @@ -811,6 +820,7 @@ \setinterfaceconstant{frameoffset}{frameoffset} \setinterfaceconstant{frameradius}{frameradius} \setinterfaceconstant{frames}{frames} +\setinterfaceconstant{freeregion}{freeregion} \setinterfaceconstant{from}{from} \setinterfaceconstant{functioncolor}{functioncolor} \setinterfaceconstant{functionstyle}{functionstyle} @@ -1160,6 +1170,7 @@ \setinterfaceconstant{splitoffset}{splitoffset} \setinterfaceconstant{spot}{spot} \setinterfaceconstant{stack}{stack} +\setinterfaceconstant{stackname}{stackname} \setinterfaceconstant{start}{start} \setinterfaceconstant{starter}{starter} \setinterfaceconstant{state}{state} @@ -1170,6 +1181,7 @@ \setinterfaceconstant{strip}{strip} \setinterfaceconstant{strut}{strut} \setinterfaceconstant{style}{style} +\setinterfaceconstant{stylealternative}{stylealternative} \setinterfaceconstant{sub}{sub} \setinterfaceconstant{subtitle}{subtitle} \setinterfaceconstant{suffix}{suffix} @@ -1225,6 +1237,7 @@ \setinterfaceconstant{topspace}{topspace} \setinterfaceconstant{topstate}{topstate} \setinterfaceconstant{totalnumber}{totalnumber} +\setinterfaceconstant{transform}{transform} \setinterfaceconstant{translate}{translate} \setinterfaceconstant{trimoffset}{trimoffset} \setinterfaceconstant{type}{type} @@ -1305,6 +1318,7 @@ \setinterfacecommand{Words}{Words} \setinterfacecommand{about}{about} \setinterfacecommand{adaptlayout}{adaptlayout} +\setinterfacecommand{alignment}{alignment} \setinterfacecommand{arg}{arg} \setinterfacecommand{at}{at} \setinterfacecommand{atleftmargin}{atleftmargin} @@ -1521,11 +1535,13 @@ \setinterfacecommand{leftmargindistance}{leftmargindistance} \setinterfacecommand{leftmarginwidth}{leftmarginwidth} \setinterfacecommand{leg}{leg} +\setinterfacecommand{linecorrection}{linecorrection} \setinterfacecommand{linewidth}{linethickness} \setinterfacecommand{listheight}{listheight} \setinterfacecommand{listlength}{listlength} \setinterfacecommand{listsymbol}{listsymbol} \setinterfacecommand{listwidth}{listwidth} +\setinterfacecommand{localfootnotes}{localfootnotes} \setinterfacecommand{logfields}{logfields} \setinterfacecommand{lohi}{lohi} \setinterfacecommand{low}{low} @@ -1534,6 +1550,7 @@ \setinterfacecommand{makeupheight}{makeupheight} \setinterfacecommand{makeupwidth}{makeupwidth} \setinterfacecommand{mar}{mar} +\setinterfacecommand{marginblock}{marginblock} \setinterfacecommand{margindistance}{margindistance} \setinterfacecommand{marginrule}{marginrule} \setinterfacecommand{margintext}{margintext} @@ -1633,6 +1650,7 @@ \setinterfacecommand{rightmarginwidth}{rightmarginwidth} \setinterfacecommand{romannumerals}{romannumerals} \setinterfacecommand{rotate}{rotate} +\setinterfacecommand{savebuffer}{savebuffer} \setinterfacecommand{scale}{scale} \setinterfacecommand{screen}{screen} \setinterfacecommand{selectblocks}{selectblocks} @@ -1668,7 +1686,9 @@ \setinterfacecommand{setupcombinations}{setupcombinations} \setinterfacecommand{setupcombinedlist}{setupcombinedlist} \setinterfacecommand{setupcomment}{setupcomment} +\setinterfacecommand{setupdescription}{setupdescription} \setinterfacecommand{setupdescriptions}{setupdescriptions} +\setinterfacecommand{setupenumeration}{setupenumeration} \setinterfacecommand{setupenumerations}{setupenumerations} \setinterfacecommand{setupexternalfigures}{setupexternalfigures} \setinterfacecommand{setupfield}{setupfield} @@ -1683,8 +1703,10 @@ \setinterfacecommand{setupfootnotedefinition}{setupfootnotedefinition} \setinterfacecommand{setupfootnotes}{setupfootnotes} \setinterfacecommand{setupforms}{setupforms} +\setinterfacecommand{setupformula}{setupformula} \setinterfacecommand{setupformulas}{setupformulae} \setinterfacecommand{setupframed}{setupframed} +\setinterfacecommand{setupframedtext}{setupframedtext} \setinterfacecommand{setupframedtexts}{setupframedtexts} \setinterfacecommand{setuphead}{setuphead} \setinterfacecommand{setupheader}{setupheader} @@ -1713,7 +1735,9 @@ \setinterfacecommand{setuplinewidth}{setuplinewidth} \setinterfacecommand{setuplist}{setuplist} \setinterfacecommand{setupmakeup}{setupmakeup} +\setinterfacecommand{setupmarginblock}{setupmarginblock} \setinterfacecommand{setupmarginblocks}{setupmarginblocks} +\setinterfacecommand{setupmargindata}{setupmargindata} \setinterfacecommand{setupmarginrules}{setupmarginrules} \setinterfacecommand{setupmarking}{setupmarking} \setinterfacecommand{setupmathalignment}{setupmathalignment} @@ -1892,6 +1916,7 @@ \setinterfacecommand{testcolumn}{testcolumn} \setinterfacecommand{testpage}{testpage} \setinterfacecommand{tex}{tex} +\setinterfacecommand{textbackground}{textbackground} \setinterfacecommand{textheight}{textheight} \setinterfacecommand{textreference}{textreference} \setinterfacecommand{textrule}{textrule} diff --git a/tex/context/base/mkii/mult-fr.mkii b/tex/context/base/mkii/mult-fr.mkii index 6c71d4aad..318bfc31c 100644 --- a/tex/context/base/mkii/mult-fr.mkii +++ b/tex/context/base/mkii/mult-fr.mkii @@ -76,6 +76,7 @@ \setinterfacevariable{all}{tout} \setinterfacevariable{alphabetic}{alphabetic} \setinterfacevariable{always}{toujours} +\setinterfacevariable{anchor}{anchor} \setinterfacevariable{and}{and} \setinterfacevariable{answerarea}{answerarea} \setinterfacevariable{appendices}{annexes} @@ -169,9 +170,11 @@ \setinterfacevariable{down}{down} \setinterfacevariable{each}{chaque} \setinterfacevariable{edge}{bord} +\setinterfacevariable{effective}{effective} \setinterfacevariable{eight}{eight} \setinterfacevariable{embed}{embed} \setinterfacevariable{empty}{vide} +\setinterfacevariable{enable}{enable} \setinterfacevariable{end}{end} \setinterfacevariable{endnote}{notefin} \setinterfacevariable{enumeration}{enumeration} @@ -206,9 +209,10 @@ \setinterfacevariable{force}{force} \setinterfacevariable{foreground}{premierplan} \setinterfacevariable{formula}{formule} -\setinterfacevariable{formulae}{formules} +\setinterfacevariable{formulas}{formules} \setinterfacevariable{forward}{avance} \setinterfacevariable{four}{quatre} +\setinterfacevariable{fractions}{fractions} \setinterfacevariable{frame}{cadre} \setinterfacevariable{framedtext}{texteencadre} \setinterfacevariable{friday}{vendredi} @@ -233,6 +237,7 @@ \setinterfacevariable{here}{ici} \setinterfacevariable{hereafter}{suivant} \setinterfacevariable{hidden}{cache} +\setinterfacevariable{hiddenbar}{hiddenbar} \setinterfacevariable{hiding}{cache} \setinterfacevariable{high}{haut} \setinterfacevariable{horizontal}{horizontale} @@ -376,6 +381,7 @@ \setinterfacevariable{note}{note} \setinterfacevariable{nothanging}{nonsuspendu} \setinterfacevariable{nothyphenated}{nothyphenated} +\setinterfacevariable{notjoinedup}{notjoinedup} \setinterfacevariable{november}{novembre} \setinterfacevariable{nowhere}{nulpart} \setinterfacevariable{nowhite}{sansblanc} @@ -621,6 +627,7 @@ \setinterfaceconstant{anchor}{anchor} \setinterfaceconstant{andtext}{andtext} \setinterfaceconstant{apa}{apa} +\setinterfaceconstant{arguments}{arguments} \setinterfaceconstant{arrow}{fleche} \setinterfaceconstant{artauthor}{artauthor} \setinterfaceconstant{artauthoretaldisplay}{artauthoretaldisplay} @@ -721,6 +728,7 @@ \setinterfaceconstant{controls}{controles} \setinterfaceconstant{conversion}{conversion} \setinterfaceconstant{convertfile}{conversionfichier} +\setinterfaceconstant{copies}{copies} \setinterfaceconstant{corner}{coin} \setinterfaceconstant{coupling}{couplage} \setinterfaceconstant{couplingway}{modecouplage} @@ -769,6 +777,7 @@ \setinterfaceconstant{etaloption}{etaloption} \setinterfaceconstant{etaltext}{etaltext} \setinterfaceconstant{evenmargin}{margepaire} +\setinterfaceconstant{exact}{exact} \setinterfaceconstant{exitoffset}{exitoffset} \setinterfaceconstant{expansion}{expansion} \setinterfaceconstant{export}{export} @@ -811,6 +820,7 @@ \setinterfaceconstant{frameoffset}{decalagecadre} \setinterfaceconstant{frameradius}{rayoncadre} \setinterfaceconstant{frames}{cadres} +\setinterfaceconstant{freeregion}{freeregion} \setinterfaceconstant{from}{de} \setinterfaceconstant{functioncolor}{functioncolor} \setinterfaceconstant{functionstyle}{functionstyle} @@ -1160,6 +1170,7 @@ \setinterfaceconstant{splitoffset}{splitoffset} \setinterfaceconstant{spot}{spot} \setinterfaceconstant{stack}{stack} +\setinterfaceconstant{stackname}{stackname} \setinterfaceconstant{start}{demarre} \setinterfaceconstant{starter}{starter} \setinterfaceconstant{state}{etat} @@ -1170,6 +1181,7 @@ \setinterfaceconstant{strip}{strip} \setinterfaceconstant{strut}{strut} \setinterfaceconstant{style}{style} +\setinterfaceconstant{stylealternative}{stylealternative} \setinterfaceconstant{sub}{sous} \setinterfaceconstant{subtitle}{soustitre} \setinterfaceconstant{suffix}{suffix} @@ -1225,6 +1237,7 @@ \setinterfaceconstant{topspace}{espacesup} \setinterfaceconstant{topstate}{etatsup} \setinterfaceconstant{totalnumber}{totalnumber} +\setinterfaceconstant{transform}{transform} \setinterfaceconstant{translate}{translate} \setinterfaceconstant{trimoffset}{trimoffset} \setinterfaceconstant{type}{type} @@ -1305,6 +1318,7 @@ \setinterfacecommand{Words}{Mots} \setinterfacecommand{about}{concernant} \setinterfacecommand{adaptlayout}{adaptedisposition} +\setinterfacecommand{alignment}{alignment} \setinterfacecommand{arg}{arg} \setinterfacecommand{at}{a} \setinterfacecommand{atleftmargin}{atleftmargin} @@ -1521,11 +1535,13 @@ \setinterfacecommand{leftmargindistance}{distancemargegauche} \setinterfacecommand{leftmarginwidth}{largeurmargegauche} \setinterfacecommand{leg}{leg} +\setinterfacecommand{linecorrection}{linecorrection} \setinterfacecommand{linewidth}{largeurligne} \setinterfacecommand{listheight}{hauteurliste} \setinterfacecommand{listlength}{llongueurliste} \setinterfacecommand{listsymbol}{listesymbole} \setinterfacecommand{listwidth}{largeurliste} +\setinterfacecommand{localfootnotes}{localfootnotes} \setinterfacecommand{logfields}{logchamp} \setinterfacecommand{lohi}{baha} \setinterfacecommand{low}{bas} @@ -1534,6 +1550,7 @@ \setinterfacecommand{makeupheight}{hauteurmakeup} \setinterfacecommand{makeupwidth}{largeurmakeup} \setinterfacecommand{mar}{mar} +\setinterfacecommand{marginblock}{marginblock} \setinterfacecommand{margindistance}{distancemarge} \setinterfacecommand{marginrule}{margereglee} \setinterfacecommand{margintext}{textemarge} @@ -1633,6 +1650,7 @@ \setinterfacecommand{rightmarginwidth}{largeurmargedroite} \setinterfacecommand{romannumerals}{chiffresromains} \setinterfacecommand{rotate}{oriente} +\setinterfacecommand{savebuffer}{savebuffer} \setinterfacecommand{scale}{echelle} \setinterfacecommand{screen}{ecran} \setinterfacecommand{selectblocks}{selectionneblocs} @@ -1668,7 +1686,9 @@ \setinterfacecommand{setupcombinations}{reglecombinaisons} \setinterfacecommand{setupcombinedlist}{reglelisteimbriquee} \setinterfacecommand{setupcomment}{reglecommentaire} +\setinterfacecommand{setupdescription}{setupdescription} \setinterfacecommand{setupdescriptions}{regledescriptions} +\setinterfacecommand{setupenumeration}{setupenumeration} \setinterfacecommand{setupenumerations}{regleenumerations} \setinterfacecommand{setupexternalfigures}{reglefiguresexternes} \setinterfacecommand{setupfield}{reglechamp} @@ -1683,8 +1703,10 @@ \setinterfacecommand{setupfootnotedefinition}{definitnotepdp} \setinterfacecommand{setupfootnotes}{reglenotepdp} \setinterfacecommand{setupforms}{regleformulaires} +\setinterfacecommand{setupformula}{setupformula} \setinterfacecommand{setupformulas}{regleformules} \setinterfacecommand{setupframed}{regleencadre} +\setinterfacecommand{setupframedtext}{setupframedtext} \setinterfacecommand{setupframedtexts}{setupframedtexts} \setinterfacecommand{setuphead}{regletete} \setinterfacecommand{setupheader}{regleentete} @@ -1713,7 +1735,9 @@ \setinterfacecommand{setuplinewidth}{regleepaisseurligne} \setinterfacecommand{setuplist}{regleliste} \setinterfacecommand{setupmakeup}{reglemakeup} +\setinterfacecommand{setupmarginblock}{setupmarginblock} \setinterfacecommand{setupmarginblocks}{regleblocmarge} +\setinterfacecommand{setupmargindata}{setupmargindata} \setinterfacecommand{setupmarginrules}{reglemargereglee} \setinterfacecommand{setupmarking}{reglemarquage} \setinterfacecommand{setupmathalignment}{setupmathalignment} @@ -1892,6 +1916,7 @@ \setinterfacecommand{testcolumn}{testcolumn} \setinterfacecommand{testpage}{testpage} \setinterfacecommand{tex}{tex} +\setinterfacecommand{textbackground}{textbackground} \setinterfacecommand{textheight}{hauteurtexte} \setinterfacecommand{textreference}{referencetexte} \setinterfacecommand{textrule}{ligneregleetexte} diff --git a/tex/context/base/mkii/mult-it.mkii b/tex/context/base/mkii/mult-it.mkii index a875555bd..269d1e545 100644 --- a/tex/context/base/mkii/mult-it.mkii +++ b/tex/context/base/mkii/mult-it.mkii @@ -76,6 +76,7 @@ \setinterfacevariable{all}{tutti} \setinterfacevariable{alphabetic}{alphabetic} \setinterfacevariable{always}{sempre} +\setinterfacevariable{anchor}{anchor} \setinterfacevariable{and}{and} \setinterfacevariable{answerarea}{answerarea} \setinterfacevariable{appendices}{appendici} @@ -169,9 +170,11 @@ \setinterfacevariable{down}{down} \setinterfacevariable{each}{ogni} \setinterfacevariable{edge}{bordo} +\setinterfacevariable{effective}{effective} \setinterfacevariable{eight}{eight} \setinterfacevariable{embed}{embed} \setinterfacevariable{empty}{vuoto} +\setinterfacevariable{enable}{enable} \setinterfacevariable{end}{end} \setinterfacevariable{endnote}{endnote} \setinterfacevariable{enumeration}{enumerazione} @@ -206,9 +209,10 @@ \setinterfacevariable{force}{forza} \setinterfacevariable{foreground}{foreground} \setinterfacevariable{formula}{formula} -\setinterfacevariable{formulae}{formule} +\setinterfacevariable{formulas}{formule} \setinterfacevariable{forward}{avanti} \setinterfacevariable{four}{quattro} +\setinterfacevariable{fractions}{fractions} \setinterfacevariable{frame}{cornice} \setinterfacevariable{framedtext}{testoincorniciato} \setinterfacevariable{friday}{venerdi} @@ -233,6 +237,7 @@ \setinterfacevariable{here}{qui} \setinterfacevariable{hereafter}{seguente} \setinterfacevariable{hidden}{nascosto} +\setinterfacevariable{hiddenbar}{hiddenbar} \setinterfacevariable{hiding}{nascondere} \setinterfacevariable{high}{alto} \setinterfacevariable{horizontal}{orizzontale} @@ -376,6 +381,7 @@ \setinterfacevariable{note}{note} \setinterfacevariable{nothanging}{nonsospeso} \setinterfacevariable{nothyphenated}{nonsillabato} +\setinterfacevariable{notjoinedup}{notjoinedup} \setinterfacevariable{november}{novembre} \setinterfacevariable{nowhere}{danessunaparte} \setinterfacevariable{nowhite}{nobianco} @@ -621,6 +627,7 @@ \setinterfaceconstant{anchor}{anchor} \setinterfaceconstant{andtext}{andtext} \setinterfaceconstant{apa}{apa} +\setinterfaceconstant{arguments}{arguments} \setinterfaceconstant{arrow}{freccia} \setinterfaceconstant{artauthor}{artauthor} \setinterfaceconstant{artauthoretaldisplay}{artauthoretaldisplay} @@ -721,6 +728,7 @@ \setinterfaceconstant{controls}{controlli} \setinterfaceconstant{conversion}{conversione} \setinterfaceconstant{convertfile}{convertifile} +\setinterfaceconstant{copies}{copies} \setinterfaceconstant{corner}{angolo} \setinterfaceconstant{coupling}{accoppiamento} \setinterfaceconstant{couplingway}{modoaccoppiamento} @@ -769,6 +777,7 @@ \setinterfaceconstant{etaloption}{etaloption} \setinterfaceconstant{etaltext}{etaltext} \setinterfaceconstant{evenmargin}{marginepari} +\setinterfaceconstant{exact}{exact} \setinterfaceconstant{exitoffset}{exitoffset} \setinterfaceconstant{expansion}{espansione} \setinterfaceconstant{export}{export} @@ -811,6 +820,7 @@ \setinterfaceconstant{frameoffset}{offsetcornice} \setinterfaceconstant{frameradius}{raggiocornice} \setinterfaceconstant{frames}{cornici} +\setinterfaceconstant{freeregion}{freeregion} \setinterfaceconstant{from}{da} \setinterfaceconstant{functioncolor}{functioncolor} \setinterfaceconstant{functionstyle}{functionstyle} @@ -1160,6 +1170,7 @@ \setinterfaceconstant{splitoffset}{splitoffset} \setinterfaceconstant{spot}{spot} \setinterfaceconstant{stack}{stack} +\setinterfaceconstant{stackname}{stackname} \setinterfaceconstant{start}{inizia} \setinterfaceconstant{starter}{starter} \setinterfaceconstant{state}{stato} @@ -1170,6 +1181,7 @@ \setinterfaceconstant{strip}{strip} \setinterfaceconstant{strut}{strut} \setinterfaceconstant{style}{stile} +\setinterfaceconstant{stylealternative}{stylealternative} \setinterfaceconstant{sub}{sotto} \setinterfaceconstant{subtitle}{sottotitolo} \setinterfaceconstant{suffix}{suffix} @@ -1225,6 +1237,7 @@ \setinterfaceconstant{topspace}{spaziocima} \setinterfaceconstant{topstate}{statocima} \setinterfaceconstant{totalnumber}{totalnumber} +\setinterfaceconstant{transform}{transform} \setinterfaceconstant{translate}{translate} \setinterfaceconstant{trimoffset}{trimoffset} \setinterfaceconstant{type}{type} @@ -1305,6 +1318,7 @@ \setinterfacecommand{Words}{Parole} \setinterfacecommand{about}{intorno} \setinterfacecommand{adaptlayout}{adattalayout} +\setinterfacecommand{alignment}{alignment} \setinterfacecommand{arg}{arg} \setinterfacecommand{at}{al} \setinterfacecommand{atleftmargin}{atleftmargin} @@ -1521,11 +1535,13 @@ \setinterfacecommand{leftmargindistance}{distanzamarginesinistro} \setinterfacecommand{leftmarginwidth}{ampiezzamarginesinistro} \setinterfacecommand{leg}{leg} +\setinterfacecommand{linecorrection}{linecorrection} \setinterfacecommand{linewidth}{spessoreriga} \setinterfacecommand{listheight}{altezzaelenco} \setinterfacecommand{listlength}{lunghezzaelenco} \setinterfacecommand{listsymbol}{listsymbol} \setinterfacecommand{listwidth}{ampiezzaelenco} +\setinterfacecommand{localfootnotes}{localfootnotes} \setinterfacecommand{logfields}{logcampi} \setinterfacecommand{lohi}{pedap} \setinterfacecommand{low}{ped} @@ -1534,6 +1550,7 @@ \setinterfacecommand{makeupheight}{altezzamakeup} \setinterfacecommand{makeupwidth}{ampiezzamakeup} \setinterfacecommand{mar}{mar} +\setinterfacecommand{marginblock}{marginblock} \setinterfacecommand{margindistance}{distanzamargine} \setinterfacecommand{marginrule}{lineamargine} \setinterfacecommand{margintext}{testoinmargine} @@ -1633,6 +1650,7 @@ \setinterfacecommand{rightmarginwidth}{ampiezzamarginedestro} \setinterfacecommand{romannumerals}{numeriromani} \setinterfacecommand{rotate}{ruota} +\setinterfacecommand{savebuffer}{savebuffer} \setinterfacecommand{scale}{scala} \setinterfacecommand{screen}{schermo} \setinterfacecommand{selectblocks}{selezionablocchi} @@ -1668,7 +1686,9 @@ \setinterfacecommand{setupcombinations}{impostacombinazioni} \setinterfacecommand{setupcombinedlist}{impostaelencocombinato} \setinterfacecommand{setupcomment}{impostacommento} +\setinterfacecommand{setupdescription}{setupdescription} \setinterfacecommand{setupdescriptions}{impostadescrizioni} +\setinterfacecommand{setupenumeration}{setupenumeration} \setinterfacecommand{setupenumerations}{impostaenumerazioni} \setinterfacecommand{setupexternalfigures}{impostafigureesterne} \setinterfacecommand{setupfield}{impostacampo} @@ -1683,8 +1703,10 @@ \setinterfacecommand{setupfootnotedefinition}{impostadefinizionenotepdp} \setinterfacecommand{setupfootnotes}{impostanotepdp} \setinterfacecommand{setupforms}{impostaforms} +\setinterfacecommand{setupformula}{setupformula} \setinterfacecommand{setupformulas}{impostaformule} \setinterfacecommand{setupframed}{impostaincorniciato} +\setinterfacecommand{setupframedtext}{setupframedtext} \setinterfacecommand{setupframedtexts}{impostatestiincorniciati} \setinterfacecommand{setuphead}{impostatesta} \setinterfacecommand{setupheader}{impostainstestazione} @@ -1713,7 +1735,9 @@ \setinterfacecommand{setuplinewidth}{impostaampiezzariga} \setinterfacecommand{setuplist}{impostaelenco} \setinterfacecommand{setupmakeup}{impostamakeup} +\setinterfacecommand{setupmarginblock}{setupmarginblock} \setinterfacecommand{setupmarginblocks}{impostablocchimargine} +\setinterfacecommand{setupmargindata}{setupmargindata} \setinterfacecommand{setupmarginrules}{impostalineemargine} \setinterfacecommand{setupmarking}{impostamarcatura} \setinterfacecommand{setupmathalignment}{setupmathalignment} @@ -1892,6 +1916,7 @@ \setinterfacecommand{testcolumn}{testcolumn} \setinterfacecommand{testpage}{testpage} \setinterfacecommand{tex}{tex} +\setinterfacecommand{textbackground}{textbackground} \setinterfacecommand{textheight}{altezzatesto} \setinterfacecommand{textreference}{riferimentotesto} \setinterfacecommand{textrule}{lineatesto} diff --git a/tex/context/base/mkii/mult-nl.mkii b/tex/context/base/mkii/mult-nl.mkii index efc0d2be3..30703e4a6 100644 --- a/tex/context/base/mkii/mult-nl.mkii +++ b/tex/context/base/mkii/mult-nl.mkii @@ -76,6 +76,7 @@ \setinterfacevariable{all}{alles} \setinterfacevariable{alphabetic}{alphabetic} \setinterfacevariable{always}{altijd} +\setinterfacevariable{anchor}{anker} \setinterfacevariable{and}{en} \setinterfacevariable{answerarea}{antwoordgebied} \setinterfacevariable{appendices}{bijlagen} @@ -139,7 +140,7 @@ \setinterfacevariable{color}{kleur} \setinterfacevariable{column}{kolom} \setinterfacevariable{columns}{kolommen} -\setinterfacevariable{combination}{combination} +\setinterfacevariable{combination}{combinatie} \setinterfacevariable{command}{commando} \setinterfacevariable{commands}{commandos} \setinterfacevariable{comment}{commentaar} @@ -169,9 +170,11 @@ \setinterfacevariable{down}{omlaag} \setinterfacevariable{each}{elk} \setinterfacevariable{edge}{rand} +\setinterfacevariable{effective}{effectief} \setinterfacevariable{eight}{acht} \setinterfacevariable{embed}{sluitin} \setinterfacevariable{empty}{leeg} +\setinterfacevariable{enable}{enable} \setinterfacevariable{end}{eind} \setinterfacevariable{endnote}{eindnoot} \setinterfacevariable{enumeration}{doornummering} @@ -206,9 +209,10 @@ \setinterfacevariable{force}{forceer} \setinterfacevariable{foreground}{voorgrond} \setinterfacevariable{formula}{formule} -\setinterfacevariable{formulae}{formules} +\setinterfacevariable{formulas}{formules} \setinterfacevariable{forward}{vooruit} \setinterfacevariable{four}{vier} +\setinterfacevariable{fractions}{fractions} \setinterfacevariable{frame}{kader} \setinterfacevariable{framedtext}{kadertekst} \setinterfacevariable{friday}{vrijdag} @@ -233,6 +237,7 @@ \setinterfacevariable{here}{hier} \setinterfacevariable{hereafter}{hieronder} \setinterfacevariable{hidden}{verborgen} +\setinterfacevariable{hiddenbar}{hiddenbar} \setinterfacevariable{hiding}{verbergen} \setinterfacevariable{high}{hoog} \setinterfacevariable{horizontal}{horizontaal} @@ -376,6 +381,7 @@ \setinterfacevariable{note}{note} \setinterfacevariable{nothanging}{niethangend} \setinterfacevariable{nothyphenated}{nietafgebroken} +\setinterfacevariable{notjoinedup}{nietaansluitend} \setinterfacevariable{november}{november} \setinterfacevariable{nowhere}{nergens} \setinterfacevariable{nowhite}{geenwit} @@ -621,6 +627,7 @@ \setinterfaceconstant{anchor}{anker} \setinterfaceconstant{andtext}{andtext} \setinterfaceconstant{apa}{apa} +\setinterfaceconstant{arguments}{argumenten} \setinterfaceconstant{arrow}{pijl} \setinterfaceconstant{artauthor}{artauthor} \setinterfaceconstant{artauthoretaldisplay}{artauthoretaldisplay} @@ -721,6 +728,7 @@ \setinterfaceconstant{controls}{sturing} \setinterfaceconstant{conversion}{conversie} \setinterfaceconstant{convertfile}{converteerfile} +\setinterfaceconstant{copies}{kopieen} \setinterfaceconstant{corner}{hoek} \setinterfaceconstant{coupling}{koppeling} \setinterfaceconstant{couplingway}{koppelwijze} @@ -769,6 +777,7 @@ \setinterfaceconstant{etaloption}{etaloption} \setinterfaceconstant{etaltext}{etaltext} \setinterfaceconstant{evenmargin}{evenmarge} +\setinterfaceconstant{exact}{exact} \setinterfaceconstant{exitoffset}{exitoffset} \setinterfaceconstant{expansion}{expansie} \setinterfaceconstant{export}{exporteer} @@ -811,6 +820,7 @@ \setinterfaceconstant{frameoffset}{kaderoffset} \setinterfaceconstant{frameradius}{kaderstraal} \setinterfaceconstant{frames}{hokjes} +\setinterfaceconstant{freeregion}{vrijgebied} \setinterfaceconstant{from}{van} \setinterfaceconstant{functioncolor}{functioncolor} \setinterfaceconstant{functionstyle}{functionstyle} @@ -1160,6 +1170,7 @@ \setinterfaceconstant{splitoffset}{splitsoffset} \setinterfaceconstant{spot}{spot} \setinterfaceconstant{stack}{stapel} +\setinterfaceconstant{stackname}{stapelnaam} \setinterfaceconstant{start}{start} \setinterfaceconstant{starter}{opener} \setinterfaceconstant{state}{status} @@ -1170,6 +1181,7 @@ \setinterfaceconstant{strip}{strip} \setinterfaceconstant{strut}{strut} \setinterfaceconstant{style}{letter} +\setinterfaceconstant{stylealternative}{stylevariant} \setinterfaceconstant{sub}{sub} \setinterfaceconstant{subtitle}{subtitel} \setinterfaceconstant{suffix}{suffix} @@ -1225,6 +1237,7 @@ \setinterfaceconstant{topspace}{kopwit} \setinterfaceconstant{topstate}{bovenstatus} \setinterfaceconstant{totalnumber}{totalnumber} +\setinterfaceconstant{transform}{transformatie} \setinterfaceconstant{translate}{translate} \setinterfaceconstant{trimoffset}{trimoffset} \setinterfaceconstant{type}{type} @@ -1305,6 +1318,7 @@ \setinterfacecommand{Words}{Woorden} \setinterfacecommand{about}{about} \setinterfacecommand{adaptlayout}{paslayoutaan} +\setinterfacecommand{alignment}{uitlijnen} \setinterfacecommand{arg}{arg} \setinterfacecommand{at}{op} \setinterfacecommand{atleftmargin}{oplinkermarge} @@ -1521,11 +1535,13 @@ \setinterfacecommand{leftmargindistance}{linkermargeafstand} \setinterfacecommand{leftmarginwidth}{linkermargebreedte} \setinterfacecommand{leg}{leg} +\setinterfacecommand{linecorrection}{regelcorrectie} \setinterfacecommand{linewidth}{lijndikte} \setinterfacecommand{listheight}{lijsthoogte} \setinterfacecommand{listlength}{lijstlengte} \setinterfacecommand{listsymbol}{lijstsymbool} \setinterfacecommand{listwidth}{lijstbreedte} +\setinterfacecommand{localfootnotes}{lokalevoetnoten} \setinterfacecommand{logfields}{registreervelden} \setinterfacecommand{lohi}{laho} \setinterfacecommand{low}{laag} @@ -1534,6 +1550,7 @@ \setinterfacecommand{makeupheight}{zethoogte} \setinterfacecommand{makeupwidth}{zetbreedte} \setinterfacecommand{mar}{mar} +\setinterfacecommand{marginblock}{margeblok} \setinterfacecommand{margindistance}{margeafstand} \setinterfacecommand{marginrule}{kantlijn} \setinterfacecommand{margintext}{margetekst} @@ -1633,6 +1650,7 @@ \setinterfacecommand{rightmarginwidth}{rechtermargebreedte} \setinterfacecommand{romannumerals}{romeins} \setinterfacecommand{rotate}{roteer} +\setinterfacecommand{savebuffer}{bewaarbuffer} \setinterfacecommand{scale}{schaal} \setinterfacecommand{screen}{scherm} \setinterfacecommand{selectblocks}{selecteerblokken} @@ -1668,7 +1686,9 @@ \setinterfacecommand{setupcombinations}{stelcombinatiesin} \setinterfacecommand{setupcombinedlist}{stelsamengesteldelijstin} \setinterfacecommand{setupcomment}{stelcommentaarin} +\setinterfacecommand{setupdescription}{steldoordefinierenin} \setinterfacecommand{setupdescriptions}{steldoordefinierenin} +\setinterfacecommand{setupenumeration}{steldoornummerenin} \setinterfacecommand{setupenumerations}{steldoornummerenin} \setinterfacecommand{setupexternalfigures}{stelexternefigurenin} \setinterfacecommand{setupfield}{stelveldin} @@ -1683,8 +1703,10 @@ \setinterfacecommand{setupfootnotedefinition}{stelvoetnootdefinitiein} \setinterfacecommand{setupfootnotes}{stelvoetnotenin} \setinterfacecommand{setupforms}{stelformulierenin} +\setinterfacecommand{setupformula}{stelformulein} \setinterfacecommand{setupformulas}{stelformulesin} \setinterfacecommand{setupframed}{stelomlijndin} +\setinterfacecommand{setupframedtext}{stelkadertekstin} \setinterfacecommand{setupframedtexts}{stelkadertekstenin} \setinterfacecommand{setuphead}{stelkopin} \setinterfacecommand{setupheader}{stelhoofdin} @@ -1713,7 +1735,9 @@ \setinterfacecommand{setuplinewidth}{stellijndiktein} \setinterfacecommand{setuplist}{stellijstin} \setinterfacecommand{setupmakeup}{stelopmaakin} +\setinterfacecommand{setupmarginblock}{stelmargeblokkenin} \setinterfacecommand{setupmarginblocks}{stelmargeblokkenin} +\setinterfacecommand{setupmargindata}{stelinmargein} \setinterfacecommand{setupmarginrules}{stelkantlijnin} \setinterfacecommand{setupmarking}{stelmarkeringin} \setinterfacecommand{setupmathalignment}{stelwiskundeuitlijnenin} @@ -1892,6 +1916,7 @@ \setinterfacecommand{testcolumn}{testkolom} \setinterfacecommand{testpage}{testpagina} \setinterfacecommand{tex}{tex} +\setinterfacecommand{textbackground}{tekstachtergrond} \setinterfacecommand{textheight}{teksthoogte} \setinterfacecommand{textreference}{tekstreferentie} \setinterfacecommand{textrule}{tekstlijn} @@ -1925,7 +1950,7 @@ \setinterfacecommand{useexternalsoundtrack}{gebruikexterngeluidsfragment} \setinterfacecommand{usemodule}{gebruikmodule} \setinterfacecommand{usemodules}{gebruikmodules} -\setinterfacecommand{usepath}{gebruikgebied} +\setinterfacecommand{usepath}{gebruikpad} \setinterfacecommand{usereferences}{gebruikreferenties} \setinterfacecommand{usespecials}{gebruikspecials} \setinterfacecommand{usesymbols}{gebruiksymbolen} diff --git a/tex/context/base/mkii/mult-pe.mkii b/tex/context/base/mkii/mult-pe.mkii index 7e5c53791..8b300ae73 100644 --- a/tex/context/base/mkii/mult-pe.mkii +++ b/tex/context/base/mkii/mult-pe.mkii @@ -76,6 +76,7 @@ \setinterfacevariable{all}{همه} \setinterfacevariable{alphabetic}{alphabetic} \setinterfacevariable{always}{همواره} +\setinterfacevariable{anchor}{anchor} \setinterfacevariable{and}{and} \setinterfacevariable{answerarea}{answerarea} \setinterfacevariable{appendices}{پیوستها} @@ -169,9 +170,11 @@ \setinterfacevariable{down}{down} \setinterfacevariable{each}{هر} \setinterfacevariable{edge}{لبه} +\setinterfacevariable{effective}{effective} \setinterfacevariable{eight}{eight} \setinterfacevariable{embed}{embed} \setinterfacevariable{empty}{تهی} +\setinterfacevariable{enable}{enable} \setinterfacevariable{end}{end} \setinterfacevariable{endnote}{تهنوشت} \setinterfacevariable{enumeration}{شمارهبندی} @@ -206,9 +209,10 @@ \setinterfacevariable{force}{اجبار} \setinterfacevariable{foreground}{پیشزمینه} \setinterfacevariable{formula}{فرمول} -\setinterfacevariable{formulae}{فرمولها} +\setinterfacevariable{formulas}{فرمولها} \setinterfacevariable{forward}{بهجلو} \setinterfacevariable{four}{چهار} +\setinterfacevariable{fractions}{fractions} \setinterfacevariable{frame}{قالب} \setinterfacevariable{framedtext}{متنقالبی} \setinterfacevariable{friday}{جمعه} @@ -233,6 +237,7 @@ \setinterfacevariable{here}{اینجا} \setinterfacevariable{hereafter}{ازاینبهبعد} \setinterfacevariable{hidden}{پنهانی} +\setinterfacevariable{hiddenbar}{hiddenbar} \setinterfacevariable{hiding}{پنهانکردن} \setinterfacevariable{high}{بلند} \setinterfacevariable{horizontal}{افقی} @@ -376,6 +381,7 @@ \setinterfacevariable{note}{note} \setinterfacevariable{nothanging}{بدونآویزانکردن} \setinterfacevariable{nothyphenated}{بدونشکست} +\setinterfacevariable{notjoinedup}{notjoinedup} \setinterfacevariable{november}{نوامبر} \setinterfacevariable{nowhere}{هیچحا} \setinterfacevariable{nowhite}{سفیدنه} @@ -621,6 +627,7 @@ \setinterfaceconstant{anchor}{anchor} \setinterfaceconstant{andtext}{andtext} \setinterfaceconstant{apa}{apa} +\setinterfaceconstant{arguments}{arguments} \setinterfaceconstant{arrow}{پیکان} \setinterfaceconstant{artauthor}{artauthor} \setinterfaceconstant{artauthoretaldisplay}{artauthoretaldisplay} @@ -721,6 +728,7 @@ \setinterfaceconstant{controls}{کنترلها} \setinterfaceconstant{conversion}{تبدیل} \setinterfaceconstant{convertfile}{پروندهتبدیل} +\setinterfaceconstant{copies}{copies} \setinterfaceconstant{corner}{گوشه} \setinterfaceconstant{coupling}{تزویج} \setinterfaceconstant{couplingway}{روشتزویج} @@ -769,6 +777,7 @@ \setinterfaceconstant{etaloption}{etaloption} \setinterfaceconstant{etaltext}{etaltext} \setinterfaceconstant{evenmargin}{حاشیهزوج} +\setinterfaceconstant{exact}{exact} \setinterfaceconstant{exitoffset}{exitoffset} \setinterfaceconstant{expansion}{گسترش} \setinterfaceconstant{export}{export} @@ -811,6 +820,7 @@ \setinterfaceconstant{frameoffset}{آفستقالب} \setinterfaceconstant{frameradius}{شعاعقالب} \setinterfaceconstant{frames}{قالبها} +\setinterfaceconstant{freeregion}{freeregion} \setinterfaceconstant{from}{از} \setinterfaceconstant{functioncolor}{functioncolor} \setinterfaceconstant{functionstyle}{functionstyle} @@ -1160,6 +1170,7 @@ \setinterfaceconstant{splitoffset}{شکافتنآفست} \setinterfaceconstant{spot}{لکه} \setinterfaceconstant{stack}{توده} +\setinterfaceconstant{stackname}{stackname} \setinterfaceconstant{start}{شروع} \setinterfaceconstant{starter}{starter} \setinterfaceconstant{state}{وضعیت} @@ -1170,6 +1181,7 @@ \setinterfaceconstant{strip}{strip} \setinterfaceconstant{strut}{بست} \setinterfaceconstant{style}{سبک} +\setinterfaceconstant{stylealternative}{stylealternative} \setinterfaceconstant{sub}{زیر} \setinterfaceconstant{subtitle}{زیرعنوان} \setinterfaceconstant{suffix}{پسوند} @@ -1225,6 +1237,7 @@ \setinterfaceconstant{topspace}{فضایبالا} \setinterfaceconstant{topstate}{وضعیتبالا} \setinterfaceconstant{totalnumber}{totalnumber} +\setinterfaceconstant{transform}{transform} \setinterfaceconstant{translate}{translate} \setinterfaceconstant{trimoffset}{trimoffset} \setinterfaceconstant{type}{تایپ} @@ -1305,6 +1318,7 @@ \setinterfacecommand{Words}{Words} \setinterfacecommand{about}{درمورد} \setinterfacecommand{adaptlayout}{تنظیمطرحبندی} +\setinterfacecommand{alignment}{alignment} \setinterfacecommand{arg}{افزودن} \setinterfacecommand{at}{در} \setinterfacecommand{atleftmargin}{درحاشیهچپ} @@ -1521,11 +1535,13 @@ \setinterfacecommand{leftmargindistance}{فاصلهحاشیهچپ} \setinterfacecommand{leftmarginwidth}{عرضحاشیهچپ} \setinterfacecommand{leg}{پا} +\setinterfacecommand{linecorrection}{linecorrection} \setinterfacecommand{linewidth}{عرضخط} \setinterfacecommand{listheight}{ارتفاعخط} \setinterfacecommand{listlength}{طوللیست} \setinterfacecommand{listsymbol}{نمادلیست} \setinterfacecommand{listwidth}{عرضلیست} +\setinterfacecommand{localfootnotes}{localfootnotes} \setinterfacecommand{logfields}{میدانهایگزارش} \setinterfacecommand{lohi}{پابا} \setinterfacecommand{low}{پایین} @@ -1534,6 +1550,7 @@ \setinterfacecommand{makeupheight}{ارتفاعآرایش} \setinterfacecommand{makeupwidth}{عرضآرایش} \setinterfacecommand{mar}{حاش} +\setinterfacecommand{marginblock}{marginblock} \setinterfacecommand{margindistance}{فاصلهحاشیه} \setinterfacecommand{marginrule}{خطحاشیه} \setinterfacecommand{margintext}{متنحاشیه} @@ -1633,6 +1650,7 @@ \setinterfacecommand{rightmarginwidth}{عرضحاشیهراست} \setinterfacecommand{romannumerals}{اعدادلاتین} \setinterfacecommand{rotate}{دوران} +\setinterfacecommand{savebuffer}{savebuffer} \setinterfacecommand{scale}{مقیاس} \setinterfacecommand{screen}{پرده} \setinterfacecommand{selectblocks}{انتخاببلوکها} @@ -1668,7 +1686,9 @@ \setinterfacecommand{setupcombinations}{بارگذاریترکیبها} \setinterfacecommand{setupcombinedlist}{بارگذاریلیستترکیبی} \setinterfacecommand{setupcomment}{بارگذاریتوضیح} +\setinterfacecommand{setupdescription}{setupdescription} \setinterfacecommand{setupdescriptions}{بارگذاریشرح} +\setinterfacecommand{setupenumeration}{setupenumeration} \setinterfacecommand{setupenumerations}{بارگذاریشمارهگذاریها} \setinterfacecommand{setupexternalfigures}{بارگذاریشکلهایخارجی} \setinterfacecommand{setupfield}{بارگذاریمیدان} @@ -1683,8 +1703,10 @@ \setinterfacecommand{setupfootnotedefinition}{بارگذاریتعریفپانوشت} \setinterfacecommand{setupfootnotes}{بارگذاریپانوشتها} \setinterfacecommand{setupforms}{بارگذاریطرح} +\setinterfacecommand{setupformula}{setupformula} \setinterfacecommand{setupformulas}{بارگذاریفرمولها} \setinterfacecommand{setupframed}{بارگذاریقالبی} +\setinterfacecommand{setupframedtext}{setupframedtext} \setinterfacecommand{setupframedtexts}{بارگذاریمتنقالبی} \setinterfacecommand{setuphead}{بارگذاریسر} \setinterfacecommand{setupheader}{بارگذاریسربرگ} @@ -1713,7 +1735,9 @@ \setinterfacecommand{setuplinewidth}{بارگذاریعرضخط} \setinterfacecommand{setuplist}{بارگذاریلیست} \setinterfacecommand{setupmakeup}{بارگذاریآرایش} +\setinterfacecommand{setupmarginblock}{setupmarginblock} \setinterfacecommand{setupmarginblocks}{بارگذاریبلوکهایحاشیه} +\setinterfacecommand{setupmargindata}{setupmargindata} \setinterfacecommand{setupmarginrules}{بارگذاریخطهایحاشیه} \setinterfacecommand{setupmarking}{بارگذارینشانهگذاری} \setinterfacecommand{setupmathalignment}{بارگذاریتنظیمریاضی} @@ -1892,6 +1916,7 @@ \setinterfacecommand{testcolumn}{ستونامتحان} \setinterfacecommand{testpage}{صفحهتست} \setinterfacecommand{tex}{تک} +\setinterfacecommand{textbackground}{textbackground} \setinterfacecommand{textheight}{ارتفاعمتن} \setinterfacecommand{textreference}{مرجعمتن} \setinterfacecommand{textrule}{خطمتن} diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii index f7121f703..26d0cd9c6 100644 --- a/tex/context/base/mkii/mult-ro.mkii +++ b/tex/context/base/mkii/mult-ro.mkii @@ -76,6 +76,7 @@ \setinterfacevariable{all}{tot} \setinterfacevariable{alphabetic}{alphabetic} \setinterfacevariable{always}{totdeauna} +\setinterfacevariable{anchor}{anchor} \setinterfacevariable{and}{and} \setinterfacevariable{answerarea}{answerarea} \setinterfacevariable{appendices}{apendixuri} @@ -169,9 +170,11 @@ \setinterfacevariable{down}{down} \setinterfacevariable{each}{fiecare} \setinterfacevariable{edge}{bordura} +\setinterfacevariable{effective}{effective} \setinterfacevariable{eight}{eight} \setinterfacevariable{embed}{embed} \setinterfacevariable{empty}{gol} +\setinterfacevariable{enable}{enable} \setinterfacevariable{end}{end} \setinterfacevariable{endnote}{endnote} \setinterfacevariable{enumeration}{enumerare} @@ -206,9 +209,10 @@ \setinterfacevariable{force}{fortat} \setinterfacevariable{foreground}{primplan} \setinterfacevariable{formula}{formula} -\setinterfacevariable{formulae}{formule} +\setinterfacevariable{formulas}{formule} \setinterfacevariable{forward}{avans} \setinterfacevariable{four}{patru} +\setinterfacevariable{fractions}{fractions} \setinterfacevariable{frame}{incadrat} \setinterfacevariable{framedtext}{textinconjurat} \setinterfacevariable{friday}{vineri} @@ -233,6 +237,7 @@ \setinterfacevariable{here}{aici} \setinterfacevariable{hereafter}{urmator} \setinterfacevariable{hidden}{ascuns} +\setinterfacevariable{hiddenbar}{hiddenbar} \setinterfacevariable{hiding}{ascundere} \setinterfacevariable{high}{inalt} \setinterfacevariable{horizontal}{orizontal} @@ -376,6 +381,7 @@ \setinterfacevariable{note}{note} \setinterfacevariable{nothanging}{nothanging} \setinterfacevariable{nothyphenated}{nedespsilabe} +\setinterfacevariable{notjoinedup}{notjoinedup} \setinterfacevariable{november}{noiembrie} \setinterfacevariable{nowhere}{niciunde} \setinterfacevariable{nowhite}{faraalb} @@ -621,6 +627,7 @@ \setinterfaceconstant{anchor}{anchor} \setinterfaceconstant{andtext}{andtext} \setinterfaceconstant{apa}{apa} +\setinterfaceconstant{arguments}{arguments} \setinterfaceconstant{arrow}{sageata} \setinterfaceconstant{artauthor}{artauthor} \setinterfaceconstant{artauthoretaldisplay}{artauthoretaldisplay} @@ -721,6 +728,7 @@ \setinterfaceconstant{controls}{controale} \setinterfaceconstant{conversion}{conversie} \setinterfaceconstant{convertfile}{convertestefisier} +\setinterfaceconstant{copies}{copies} \setinterfaceconstant{corner}{colt} \setinterfaceconstant{coupling}{cuplare} \setinterfaceconstant{couplingway}{modcuplare} @@ -769,6 +777,7 @@ \setinterfaceconstant{etaloption}{etaloption} \setinterfaceconstant{etaltext}{etaltext} \setinterfaceconstant{evenmargin}{marginepara} +\setinterfaceconstant{exact}{exact} \setinterfaceconstant{exitoffset}{exitoffset} \setinterfaceconstant{expansion}{expansiune} \setinterfaceconstant{export}{export} @@ -811,6 +820,7 @@ \setinterfaceconstant{frameoffset}{offsetframe} \setinterfaceconstant{frameradius}{razaframe} \setinterfaceconstant{frames}{frames} +\setinterfaceconstant{freeregion}{freeregion} \setinterfaceconstant{from}{dela} \setinterfaceconstant{functioncolor}{functioncolor} \setinterfaceconstant{functionstyle}{functionstyle} @@ -1160,6 +1170,7 @@ \setinterfaceconstant{splitoffset}{splitoffset} \setinterfaceconstant{spot}{spot} \setinterfaceconstant{stack}{stack} +\setinterfaceconstant{stackname}{stackname} \setinterfaceconstant{start}{start} \setinterfaceconstant{starter}{starter} \setinterfaceconstant{state}{stare} @@ -1170,6 +1181,7 @@ \setinterfaceconstant{strip}{strip} \setinterfaceconstant{strut}{strut} \setinterfaceconstant{style}{stil} +\setinterfaceconstant{stylealternative}{stylealternative} \setinterfaceconstant{sub}{sub} \setinterfaceconstant{subtitle}{subtitlu} \setinterfaceconstant{suffix}{suffix} @@ -1225,6 +1237,7 @@ \setinterfaceconstant{topspace}{spatiusus} \setinterfaceconstant{topstate}{staresus} \setinterfaceconstant{totalnumber}{totalnumber} +\setinterfaceconstant{transform}{transform} \setinterfaceconstant{translate}{translate} \setinterfaceconstant{trimoffset}{trimoffset} \setinterfaceconstant{type}{type} @@ -1305,6 +1318,7 @@ \setinterfacecommand{Words}{Cuvinte} \setinterfacecommand{about}{despre} \setinterfacecommand{adaptlayout}{adapteazaaspect} +\setinterfacecommand{alignment}{alignment} \setinterfacecommand{arg}{arg} \setinterfacecommand{at}{la} \setinterfacecommand{atleftmargin}{atleftmargin} @@ -1521,11 +1535,13 @@ \setinterfacecommand{leftmargindistance}{distantamarginestanga} \setinterfacecommand{leftmarginwidth}{latimemarginestanga} \setinterfacecommand{leg}{leg} +\setinterfacecommand{linecorrection}{linecorrection} \setinterfacecommand{linewidth}{grosimelinie} \setinterfacecommand{listheight}{inaltimelista} \setinterfacecommand{listlength}{lungimelista} \setinterfacecommand{listsymbol}{listsymbol} \setinterfacecommand{listwidth}{latimelista} +\setinterfacecommand{localfootnotes}{localfootnotes} \setinterfacecommand{logfields}{logcampuri} \setinterfacecommand{lohi}{jossus} \setinterfacecommand{low}{jos} @@ -1534,6 +1550,7 @@ \setinterfacecommand{makeupheight}{inaltimemakeup} \setinterfacecommand{makeupwidth}{latimemakeup} \setinterfacecommand{mar}{mar} +\setinterfacecommand{marginblock}{marginblock} \setinterfacecommand{margindistance}{distantamargine} \setinterfacecommand{marginrule}{liniemargine} \setinterfacecommand{margintext}{textmarginal} @@ -1633,6 +1650,7 @@ \setinterfacecommand{rightmarginwidth}{latimemarginedreapta} \setinterfacecommand{romannumerals}{numereromane} \setinterfacecommand{rotate}{roteste} +\setinterfacecommand{savebuffer}{savebuffer} \setinterfacecommand{scale}{scala} \setinterfacecommand{screen}{ecran} \setinterfacecommand{selectblocks}{selecteazablocuri} @@ -1668,7 +1686,9 @@ \setinterfacecommand{setupcombinations}{seteazacombinari} \setinterfacecommand{setupcombinedlist}{seteazalistacombinata} \setinterfacecommand{setupcomment}{seteazacomentariu} +\setinterfacecommand{setupdescription}{setupdescription} \setinterfacecommand{setupdescriptions}{seteazadescriere} +\setinterfacecommand{setupenumeration}{setupenumeration} \setinterfacecommand{setupenumerations}{seteazaenumerare} \setinterfacecommand{setupexternalfigures}{seteazafiguriexterne} \setinterfacecommand{setupfield}{seteazacamp} @@ -1683,8 +1703,10 @@ \setinterfacecommand{setupfootnotedefinition}{seteazadefinireanotasubsol} \setinterfacecommand{setupfootnotes}{seteazanotasubsol} \setinterfacecommand{setupforms}{seteazaformulare} +\setinterfacecommand{setupformula}{setupformula} \setinterfacecommand{setupformulas}{seteazaformule} \setinterfacecommand{setupframed}{seteazainconjurat} +\setinterfacecommand{setupframedtext}{setupframedtext} \setinterfacecommand{setupframedtexts}{definestetexteinconjurate} \setinterfacecommand{setuphead}{seteazatitlu} \setinterfacecommand{setupheader}{seteazaantet} @@ -1713,7 +1735,9 @@ \setinterfacecommand{setuplinewidth}{seteazagrosimelinie} \setinterfacecommand{setuplist}{seteazalista} \setinterfacecommand{setupmakeup}{seteazamakeup} +\setinterfacecommand{setupmarginblock}{setupmarginblock} \setinterfacecommand{setupmarginblocks}{seteazablocurimarginale} +\setinterfacecommand{setupmargindata}{setupmargindata} \setinterfacecommand{setupmarginrules}{seteazaliniimargine} \setinterfacecommand{setupmarking}{seteazamarcaje} \setinterfacecommand{setupmathalignment}{setupmathalignment} @@ -1892,6 +1916,7 @@ \setinterfacecommand{testcolumn}{testcolumn} \setinterfacecommand{testpage}{testpage} \setinterfacecommand{tex}{tex} +\setinterfacecommand{textbackground}{textbackground} \setinterfacecommand{textheight}{inaltimetext} \setinterfacecommand{textreference}{referintatext} \setinterfacecommand{textrule}{riglatext} diff --git a/tex/context/base/mkii/pack-box.mkii b/tex/context/base/mkii/pack-box.mkii index 1752e2b91..928450385 100644 --- a/tex/context/base/mkii/pack-box.mkii +++ b/tex/context/base/mkii/pack-box.mkii @@ -27,7 +27,7 @@ % \definelayer[\v!tekst+2][\c!positie=\v!ja] % we need to set the size, else we get dimensions depending -% on the content, which in itsel fis ok, but can lead to loops +% on the content, which in itself is ok, but can lead to loops % due to rounding errors (happened in demo-obv) \definelayer[\v!text-2][\c!position=\v!yes,\c!width=\overlaywidth,\c!height=\overlayheight] diff --git a/tex/context/base/mkii/page-mul.mkii b/tex/context/base/mkii/page-mul.mkii index decf784f0..bf258abed 100644 --- a/tex/context/base/mkii/page-mul.mkii +++ b/tex/context/base/mkii/page-mul.mkii @@ -1656,9 +1656,9 @@ {\goodbreak} \installcolumnbreakhandler {MUL} \v!yes - {\par % todo: since - {\testrulewidth\zeropoint\ruledvskip\textheight} % we misuse a - \penalty-200 % side effect + {\par % todo: since + {\testrulewidth\zeropoint\ruledvskip\textheight}% we misuse a + \penalty-200 % side effect \vskip-\textheight }% bugged : \prevdepth-\thousandpoint} % signals top of column to \blank diff --git a/tex/context/base/mkiv/anch-bar.mkiv b/tex/context/base/mkiv/anch-bar.mkiv index b5df21a07..f8581da32 100644 --- a/tex/context/base/mkiv/anch-bar.mkiv +++ b/tex/context/base/mkiv/anch-bar.mkiv @@ -15,8 +15,10 @@ \unprotect -%D We will implement a sidebar mechanism using the -%D functionality from \type {core-pos}. +%D This can be done better now ... + +%D We will implement a sidebar mechanism using the functionality from +%D \type {core-pos}. %D %D \starttyping %D \definesidebar[whow][rulecolor=green,distance=0pt] @@ -96,10 +98,10 @@ {\def\currentsidebar{#1}% \setupcurrentsidebar[#2]}% \scratchdistance\sidebarparameter\c!distance\relax + \scratchdimen\sidebarparameter\c!leftmargindistance\relax \edef\m_level{\sidebarparameter\c!level}% \ifx\m_level\empty \ifnum\c_anch_sidebars_level=\plusone - \scratchdimen\sidebarparameter\c!leftmargindistance\relax \ifdim\scratchdimen=\zeropoint \advance\d_anch_sidebars_distance\scratchdistance\relax \else @@ -110,7 +112,6 @@ \fi \else \ifnum\m_level=\plusone - \scratchdimen\sidebarparameter\c!leftmargindistance\relax \ifdim\scratchdimen=\zeropoint \advance\d_anch_sidebars_distance\scratchdistance\relax \else @@ -147,7 +148,6 @@ \startMPpositionmethod{mpos:sidebar} \startMPpositiongraphic{mpos:sidebar}{linecolor,linewidth,distance,alternative}% - if unknown context_apos : input mp-apos.mpiv ; fi ; anch_sidebars_draw ( \MPp\MPbself,\MPp\MPeself,\MPy\MPbself,\MPy\MPeself,\MPh\MPbself,\MPd\MPeself, \MPx{\textanchor},\MPy{\textanchor},\MPw{\textanchor},\MPh{\textanchor}, diff --git a/tex/context/base/mkiv/anch-bck.mkvi b/tex/context/base/mkiv/anch-bck.mkvi index ee392f114..207f64537 100644 --- a/tex/context/base/mkiv/anch-bck.mkvi +++ b/tex/context/base/mkiv/anch-bck.mkvi @@ -98,12 +98,24 @@ \setuevalue{\currenttextbackground}{\groupedcommand{\starttextbackground[\currenttextbackground]}{\stoptextbackground}}% \setuevalue{\e!start\currenttextbackground}{\starttextbackground[\currenttextbackground]}% \setuevalue{\e!stop \currenttextbackground}{\stoptextbackground}% -% \doif{\textbackgroundparameter\c!state}\v!start\checkpositionoverlays \to \everydefinetextbackground -% \appendtoks -% \doif{\textbackgroundparameter\c!state}\v!start\checkpositionoverlays -% \to \everysetuptextbackground +\newconstant \c_anch_backgrounds_pos_state +\newconditional\c_anch_backgrounds_pos_no_shape + +\def\anch_backgrounds_bpos + {\ifconditional\c_anch_backgrounds_pos_no_shape + \bposkind\v_anch_backgrounds_text_current\plusthree + \else + \bposkind\v_anch_backgrounds_text_current\c_anch_backgrounds_pos_state + \fi} + +\def\anch_backgrounds_epos + {\ifconditional\c_anch_backgrounds_pos_no_shape + \eposkind\v_anch_backgrounds_text_current\plusthree + \else + \eposkind\v_anch_backgrounds_text_current\c_anch_backgrounds_pos_state + \fi} \unexpanded\def\starttextbackground {\begingroup @@ -122,6 +134,29 @@ \anch_backgrounds_text_preset_nop \anch_backgrounds_text_start_indeed} +% ugly hack to register usage + +\newcount \c_anch_backgrounds_text_count +\newcount \c_anch_backgrounds_text_check +\newconstant\c_anch_backgrounds_text_state + +\unexpanded\def\starttextbackground + {\begingroup + \global\advance\c_anch_backgrounds_text_count\plusone + \advance\c_anch_backgrounds_text_level\plusone + \dodoubleempty\anch_backgrounds_text_start} + +\def\anch_backgrounds_text_level_start + {\c_anch_backgrounds_text_check\c_anch_backgrounds_text_count} + +\def\anch_backgrounds_text_level_stop + {\c_anch_backgrounds_text_state + \ifnum\c_anch_backgrounds_text_count>\c_anch_backgrounds_text_check + \plusone + \else + \zerocount + \fi} + % todo \backgroundvariable\c!variant \let\anch_backgrounds_text_start_indeed\relax @@ -199,41 +234,52 @@ \unexpanded\def\starttextbackgroundmanual {\begingroup + \c_anch_backgrounds_pos_state\plusone \usetextbackgroundstyleandcolor\c!style\c!color - \bpos\v_anch_backgrounds_text_current} + \anch_backgrounds_bpos} \unexpanded\def\stoptextbackgroundmanual - {\epos\v_anch_backgrounds_text_current + {\anch_backgrounds_epos \carryoverpar\endgroup} \def\anch_backgrounds_text_start_txt {\ifvmode \dontleavehmode \fi \begingroup + \c_anch_backgrounds_pos_state\plusone \usetextbackgroundstyleandcolor\c!style\c!color - \bpos\v_anch_backgrounds_text_current} + \anch_backgrounds_bpos} \def\anch_backgrounds_text_stop_txt - {\epos\v_anch_backgrounds_text_current + {\anch_backgrounds_epos \carryoverpar\endgroup} \newskip\textbackgroundskip -\def\anch_backgrounds_text_start_par +% maybe we should have a resetter for such compensation struts + +\def\anch_backgrounds_reset_attributes + {\scratchcounter\attribute\snapmethodattribute + \resetallattributes % \attribute\linenumberattribute \attributeunsetvalue + \attribute\snapmethodattribute\scratchcounter} + +\def\anch_backgrounds_text_start_par % beware .. background shapes {\endgraf % new \textbackgroundparameter\c!before \begingroup + \c_anch_backgrounds_pos_state\plustwo \begingroup - \resetallattributes % \attribute\linenumberattribute \attributeunsetvalue + \anch_backgrounds_reset_attributes \noindent \ifgridsnapping \spac_helpers_assign_skip\textbackgroundskip{\textbackgroundparameter\c!topoffset}% \ifdim\textbackgroundskip>\zeropoint - \struttedbox{\hbox{\raise\textbackgroundskip\hbox{\bpos\v_anch_backgrounds_text_current}}}% + \struttedbox % not always ok (e.g. setups) + {\hpack{\raise\textbackgroundskip\hpack{\anch_backgrounds_bpos}}}% \else - \bpos\v_anch_backgrounds_text_current + \anch_backgrounds_bpos \fi \else - \bpos\v_anch_backgrounds_text_current + \anch_backgrounds_bpos \fi \endgraf % we need a vertical nobreak - 29/06/2004 \endgroup @@ -276,17 +322,19 @@ \endgroup \begingroup \forgeteverypar % NOT REALLY NEEDED, SAVES HASH/MEM - \resetallattributes % \attribute\linenumberattribute \attributeunsetvalue + \anch_backgrounds_reset_attributes \nobreak \noindent \strut \hfill \kern\zeropoint + % so far \spac_helpers_assign_skip\textbackgroundskip{\textbackgroundparameter\c!bottomoffset}% \ifgridsnapping % experimental, pascal (todo: topoffset in same way) \ifdim\textbackgroundskip>\zeropoint - \struttedbox\plusone{\hbox{\lower\textbackgroundskip\hbox{\epos\v_anch_backgrounds_text_current}}}% + \struttedbox % not always ok (e.g. setups) + {\hpack{\lower\textbackgroundskip\hpack{\anch_backgrounds_epos}}}% \else - \epos\v_anch_backgrounds_text_current + \anch_backgrounds_epos \fi \else - \epos\v_anch_backgrounds_text_current + \anch_backgrounds_epos \fi \endgraf \carryoverpar\endgroup @@ -300,9 +348,165 @@ \global\let\checkpositionoverlays\relax \fi} +% shape handling + +\definesystemattribute[textbackground][public] + +% \def\page_prepare_backgrounds#1% +% {\clf_collectbackgrounds\realpageno#1\relax} + +\def\anch_backgrounds_bpos + {\ifconditional\c_anch_backgrounds_pos_no_shape + \attribute\textbackgroundattribute\attributeunsetvalue + \bposkind\v_anch_backgrounds_text_current\plusthree + \else\ifnum\c_anch_backgrounds_pos_state=\plusone + \bposkind\v_anch_backgrounds_text_current\c_anch_backgrounds_pos_state + \clf_registerbackground{\v_anch_backgrounds_text_current}% + \else + \bposkind\v_anch_backgrounds_text_current\c_anch_backgrounds_pos_state + \attribute\textbackgroundattribute\attributeunsetvalue + \fi\fi} + +% plugs into other code + +\def\strc_floats_wrap_free_region + {\global\setbox\floatbox\hpack % we always need to wrap + {\ifconditional\c_strc_floats_trace_free + \strc_floats_show_free_region + \fi + \box\floatbox}} + +\startuseMPgraphic{floatfree} + draw_free_region( + \the\wd\floatbox, + \the\ht\floatbox, + \the\dp\floatbox, + \the\d_free_offset_left, + \the\d_free_offset_right, + \the\d_free_offset_top, + \the\d_free_offset_bottom + ) ; +\stopuseMPgraphic + +\def\strc_floats_show_free_region + {\lower\dp\floatbox\hpack to \zeropoint {\useMPgraphic{floatfree}}} + +\newconditional\c_strc_floats_mark_as_free +\newconditional\c_strc_floats_trace_free +\newconstant \c_free_offset_kind +\newdimen \d_free_offset_left +\newdimen \d_free_offset_right +\newdimen \d_free_offset_top +\newdimen \d_free_offset_bottom + +\installtextracker{floats.freeregion} + {\settrue \c_strc_floats_trace_free} + {\setfalse\c_strc_floats_trace_free} + +\def\strc_floats_mark_as_free#1#2#3#4#5% + {\c_free_offset_kind #1% + \d_free_offset_left #2% + \d_free_offset_right #3% + \d_free_offset_top #4% + \d_free_offset_bottom#5% + \strc_floats_wrap_free_region + \anch_mark_tagged_box_free + \floatbox + \c_free_offset_kind + \d_free_offset_left + \d_free_offset_right + \d_free_offset_top + \d_free_offset_bottom} + +\ifx\strc_floats_mark_pag_as_free\relax \else + \writestatus{error}{wrong place for pag_as_free}\wait +\fi + +\ifx\strc_floats_mark_par_as_free\relax \else + \writestatus{error}{wrong place for par_as_free}\wait +\fi + +\def\strc_floats_mark_pag_as_free + {\ifpositioning + \ifconditional\c_strc_floats_mark_as_free + \strc_floats_mark_as_free + \plusone + \zeropoint + \zeropoint + \d_strc_floats_top + \d_strc_floats_bottom + \fi + \fi} + +\def\strc_floats_mark_par_as_free + {\ifpositioning + \ifconditional\c_strc_floats_mark_as_free + \ifcase\c_page_sides_float_type + \or % backspace + \strc_floats_mark_as_free + \plustwo + \zeropoint + \d_page_sides_leftskip + \d_page_sides_topskip + \d_page_sides_bottomskip + \or % leftedge + \strc_floats_mark_as_free + \plustwo + \zeropoint + \d_page_sides_leftskip + \d_page_sides_topskip + \d_page_sides_bottomskip + \or % leftmargin + \strc_floats_mark_as_free + \plustwo + \zeropoint + \d_page_sides_leftskip + \d_page_sides_topskip + \d_page_sides_bottomskip + \or % leftside + \strc_floats_mark_as_free + \plustwo + \d_page_sides_leftskip + \d_strc_floats_margin + \d_page_sides_topskip + \d_page_sides_bottomskip + \or % rightside + \strc_floats_mark_as_free + \plusthree + \d_strc_floats_margin + \d_page_sides_rightskip + \d_page_sides_topskip + \d_page_sides_bottomskip + \or % rightmargin + \strc_floats_mark_as_free + \plusthree + \d_page_sides_rightskip + \zeropoint + \d_page_sides_topskip + \d_page_sides_bottomskip + \or % rightedge + \strc_floats_mark_as_free + \plusthree + \d_page_sides_rightskip + \zeropoint + \d_page_sides_topskip + \d_page_sides_bottomskip + \or % cutspace + \strc_floats_mark_as_free + \plusthree + \d_page_sides_rightskip + \zeropoint + \d_page_sides_topskip + \d_page_sides_bottomskip + \fi + \fi + \fi} + +% so far + \setuptextbackground [\c!mp=mpos:region:draw, - \c!method=mpos:region, % mpos:regionshape + \c!method=mpos:region, \c!state=\v!start, \c!location=\v!text, \c!leftoffset=\!!zeropoint, % 1em, @@ -348,7 +552,6 @@ dashtype=1] \startuseMPgraphic{mpos:region:setup} - if unknown context_abck : input mp-abck.mpiv ; fi ; boxgridtype := \MPvar{gridtype} ; boxlinetype := \MPvar{linetype} ; boxfilltype := \MPvar{filltype} ; @@ -360,9 +563,13 @@ boxlineradius := \MPvar{lineradius} ; boxlineoffset := \MPvar{lineoffset} ; % - def boxgridoptions = withcolor \MPvar{gridcolor} enddef ; - def boxlineoptions = withcolor \MPvar{linecolor} enddef ; - def boxfilloptions = withcolor \MPvar{fillcolor} enddef ; + def boxgridcolor = \MPvar{gridcolor} enddef ; + def boxlinecolor = \MPvar{linecolor} enddef ; + def boxfillcolor = \MPvar{fillcolor} enddef ; + % + def boxgridoptions = withcolor boxgridcolor enddef ; + def boxlineoptions = withcolor boxlinecolor enddef ; + def boxfilloptions = withcolor boxfillcolor enddef ; \stopuseMPgraphic \startuseMPgraphic{mpos:region:extra} @@ -373,17 +580,6 @@ setbounds currentpicture to multibox ; \stopuseMPgraphic -% \startMPpositionmethod{mpos:region} -% \startMPpositiongraphic{mpos:region}{fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,gridshift,lineradius,lineoffset} -% \includeMPgraphic{mpos:region:setup} ; -% \includeMPgraphic{mpos:region:extra} ; -% \MPgetmultipars{\MPvar{self}}{\MPanchorid} ; -% \includeMPgraphic{\MPvar{mp}} ; -% \includeMPgraphic{mpos:region:anchor} ; -% \stopMPpositiongraphic -% \MPpositiongraphic{mpos:region}{}% -% \stopMPpositionmethod - \startMPpositiongraphic{mpos:region}{fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,gridshift,lineradius,lineoffset} \includeMPgraphic{mpos:region:setup} ; \includeMPgraphic{mpos:region:extra} ; @@ -392,12 +588,17 @@ \includeMPgraphic{mpos:region:anchor} ; \stopMPpositiongraphic -\startMPpositiongraphic{mpos:regionshape}{fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,gridshift,lineradius,lineoffset} - \includeMPgraphic{mpos:region:setup} ; - \includeMPgraphic{mpos:region:extra} ; - \MPgetmultishapes{\MPvar{self}}{\MPanchorid} ; - \includeMPgraphic{\MPvar{mp}} ; - \includeMPgraphic{mpos:region:anchor} ; +%D For old times sake: + +\startMPpositiongraphic{mpos:box}{fillcolor,linecolor,linewidth} + string tag; tag := "\MPvar{self}" ; + path box ; box := positionbox(tag) ; + + box := box enlarged \MPvar{filloffset} ; + fill box withcolor \MPvar{fillcolor} ; + draw box withcolor \MPvar{linecolor} withpen pencircle scaled \MPvar{linewidth} ; + + positioninregion; \stopMPpositiongraphic \startMPpositionmethod{mpos:region} @@ -448,7 +649,6 @@ linewidth=1pt] \startMPpositiongraphic{mpos:encircle}{linecolor,fillcolor,linewidth,lineoffset} - if unknown context_apos : input mp-apos.mpiv ; fi ; \MPgetposboxes{\MPvar{self}}{\MPanchorid} if nofposboxes = 1 : posboxes[1] := posboxes[1] enlarged \MPvar{lineoffset} cornered \MPvar{lineoffset} ; @@ -464,7 +664,6 @@ linewidth=1pt] \startMPpositiongraphic{mpos:connect}{linecolor,lineoffset,linewidth} - if unknown context_apos : input mp-apos.mpiv ; fi ; boxlinewidth := \MPvar{linewidth} ; boxlineoffset := \MPvar{lineoffset} ; def boxlineoptions = withcolor \MPvar{linecolor} enddef ; diff --git a/tex/context/base/mkiv/anch-pgr.lua b/tex/context/base/mkiv/anch-pgr.lua index b5c2ae628..8a63c5b54 100644 --- a/tex/context/base/mkiv/anch-pgr.lua +++ b/tex/context/base/mkiv/anch-pgr.lua @@ -6,236 +6,546 @@ if not modules then modules = { } end modules ['anch-pgr'] = { license = "see context related readme files" } --- todo: we need to clean up lists (of previous pages) +-- This is a bit messy module but backgrounds are messy anyway. Especially when we want to +-- follow shapes. This will always be work in progress as it also depends on new features +-- in context. +-- +-- Alas, shapes and inline didn't work as expected end of 2016 so I had to pick up this +-- thread again. But with regular excursions to listening to Brad Mehldau's Mehliana I +-- could keep myself motivated. Some old stuff has been removed, some suboptimal code has +-- been replaced. Background code is still not perfect, but some day ... the details manual +-- will discuss this issue. -local format = string.format -local abs = math.abs -local concat, sort = table.concat, table.sort +local abs, div, floor, round, min, max = math.abs, math.div, math.floor, math.round, math.min, math.max +local sort, concat = table.sort, table.concat local splitter = lpeg.splitat(":") local lpegmatch = lpeg.match -local jobpositions = job.positions -local formatters = string.formatters +local jobpositions = job.positions +local formatters = string.formatters +local setmetatableindex = table.setmetatableindex -local commands = commands -local context = context +local commands = commands +local context = context -local implement = interfaces.implement +local implement = interfaces.implement -local report_graphics = logs.reporter("graphics") +local report_graphics = logs.reporter("backgrounds") +local report_shapes = logs.reporter("backgrounds","shapes") +local report_free = logs.reporter("backgrounds","free") -local f_b_tag = formatters["b:%s"] -local f_e_tag = formatters["e:%s"] -local f_p_tag = formatters["p:%s"] +local trace_shapes = false trackers.register("backgrounds.shapes", function(v) trace_shapes = v end) +local trace_ranges = false trackers.register("backgrounds.shapes.ranges",function(v) trace_ranges = v end) +local trace_free = false trackers.register("backgrounds.shapes.free", function(v) trace_free = v end) -local f_tag_two = formatters["%s:%s"] +local f_b_tag = formatters["b:%s"] +local f_e_tag = formatters["e:%s"] +local f_p_tag = formatters["p:%s"] -local f_point = formatters["%p"] -local f_pair = formatters["(%p,%p)"] -local f_path = formatters["%--t--cycle"] +local f_tag_two = formatters["%s:%s"] -local function regionarea(r) - local rx, ry = r.x, r.y - local rw = rx + r.w - local rh = ry + r.h - local rd = ry - r.d - return { - f_pair(rx, rh - ry), - f_pair(rw, rh - ry), - f_pair(rw, rd - ry), - f_pair(rx, rd - ry), - } -end +local f_point = formatters["%p"] +local f_pair = formatters["(%p,%p)"] +local f_path = formatters["%--t--cycle"] +local f_pair_i = formatters["(%r,%r)"] -- rounded + +graphics = graphics or { } +local backgrounds = { } +graphics.backgrounds = backgrounds + +-- -- -- + +local texsetattribute = tex.setattribute +local pdfgetpos = pdf.getpos -- why not a generic name ! + +local a_textbackground = attributes.private("textbackground") + +local nuts = nodes.nuts +local tonut = nodes.tonut +local tonode = nodes.tonode + +local new_latelua = nuts.pool.latelua +local new_rule = nuts.pool.rule +local new_kern = nuts.pool.kern +local new_hlist = nuts.pool.hlist + +local getbox = nuts.getbox +local getid = nuts.getid +----- getlist = nuts.getlist +local setlink = nuts.setlink +local getheight = nuts.getheight +local getdepth = nuts.getdepth + +local nodecodes = nodes.nodecodes +local localpar_code = nodecodes.localpar --- we can use a 'local t, n' and reuse the table +local insert_before = nuts.insert_before +local insert_after = nuts.insert_after -local eps = 2 +local processranges = nodes.processranges -local function add(t,x,y,last,direction) - local n = #t - if n == 0 then - t[n+1] = { x, y } +local unsetvalue = attributes.unsetvalue + +local jobpositions = job.positions + +local data = { } +local realpage = 1 +local recycle = 1000 -- only tables can overflow this +local enabled = false + +-- Freeing the data is somewhat tricky as we can have backgrounds spanning +-- many pages but for an arbitrary background shape that is not so common. + +local function check(a,index,depth,d,where,ht,dp) + -- this is not yet r2l ready + local w = d.shapes[realpage] + local x, y = pdfgetpos() + if trace_ranges then + report_shapes("attribute %i, index %i, depth %i, location %s, position (%p,%p)", + a,index,depth,where,x,y) + end + local n = #w + if d.index ~= index then + n = n + 1 + d.index = index + d.depth = depth +-- w[n] = { x, x, y, ht, dp } + w[n] = { y, ht, dp, x, x } else - local tn = t[n] - local lx = tn[1] - local ly = tn[2] - if x == lx and y == ly then - -- quick skip - elseif n == 1 then - -- if abs(lx-x) <= eps or abs(ly-y) <= eps then - if abs(lx-x) > eps or abs(ly-y) > eps then - t[n+1] = { x, y } + local wn = w[n] + local wh = wn[2] + local wd = wn[3] + if depth < d.depth then + local wy = wn[1] + wn[1] = y + d.depth = depth + local dy = wy - y + wh = wh - dy + wd = wd - dy + end + if where == "r" then + if x > wn[5] then + wn[5] = x end else - local tm = t[n-1] - local px = tm[1] - local py = tm[2] - if (direction == "down" and y > ly) or (direction == "up" and y < ly) then - -- move back from too much hang - elseif abs(lx-px) <= eps and abs(lx-x) <= eps then - if abs(ly-y) > eps then - tn[2] = y - end - elseif abs(ly-py) <= eps and abs(ly-y) <= eps then - if abs(lx-x) > eps then - tn[1] = x - end - elseif not last then - t[n+1] = { x, y } + if x < wn[4] then + wn[4] = x end end + if ht > wh then + wn[2] = ht + end + if dp > wd then + wn[3] = dp + end end + -- inspect(w) end --- local function add(t,x,y,last) --- t[#t+1] = { x, y } +local index = 0 + +local function flush(head,f,l,a,parent,depth) + local d = data[a] + if d then + local ix = index + local ht = getheight(parent) + local dp = getdepth(parent) + local ln = new_latelua(function() check(a,ix,depth,d,"l",ht,dp) end) + local rn = new_latelua(function() check(a,ix,depth,d,"r",ht,dp) end) + if trace_ranges then + ln = new_hlist(setlink(new_rule(65536,65536*4,0),new_kern(-65536),ln)) + rn = new_hlist(setlink(new_rule(65536,0,65536*4),new_kern(-65536),rn)) + end + if getid(f) == localpar_code then -- we need to clean this mess + insert_after(head,f,ln) + else + head, f = insert_before(head,f,ln) + end + insert_after(head,l,rn) + end + return head, true +end + +local function registerbackground(name) + local n = #data + 1 + if n > recycle then + -- we could also free all e: that are beyond a page but we don't always + -- know the page so a recycle is nicer and the s lists are kept anyway + -- so the amount of kept data is not that large + n = 1 + end + local b = jobpositions.tobesaved["b:"..name] + if b then + local s = setmetatableindex("table") + b.s = s + data[n] = { + bpos = b, + name = name, + n = n, + shapes = s, + count = 0, + sindex = 0, + } + texsetattribute(a_textbackground,n) + if not enabled then + nodes.tasks.enableaction("contributers", "nodes.handlers.textbackgrounds") + enabled = true + end + else + texsetattribute(a_textbackground,unsetvalue) + end +end + +-- local function collectbackgrounds(r,n) +-- if enabled then +-- local parent = getbox(n) +-- local head = getlist(parent) +-- realpage = r +-- processranges(a_textbackground,flush,head) -- ,parent) +-- end -- end +-- +-- interfaces.implement { +-- name = "collectbackgrounds", +-- actions = collectbackgrounds, +-- arguments = { "integer", "integer" } +-- } + +nodes.handlers.textbackgrounds = function(head,where,parent) -- we have hlistdir and local dir + -- todo enable action in register + head = tonut(head) + index = index + 1 + local head, done = processranges(a_textbackground,flush,head,parent) + return tonode(head), done +end + +interfaces.implement { + name = "registerbackground", + actions = registerbackground, + arguments = { "string" } +} + +-- optimized already but we can assume a cycle i.e. prune the last point and then +-- even less code .. we could merge some loops but his is more robust + +local function topairs(t,n) + local r = { } + for i=1,n do + local ti = t[i] + r[i] = f_pair_i(ti[1]/65556,ti[2]/65536) + end + return concat(r," ") +end + +local eps = 65536 / 4 -- 2 +local pps = eps +local nps = - pps + +local function unitvector(x,y) + if x < pps and x > nps then + x = 0 + elseif x < 0 then + x = -1 + else + x = 1 + end + if y < pps and y > nps then + y = 0 + elseif y < 0 then + y = -1 + else + y = 1 + end + return x, y +end local function finish(t) - local n = #t - if n > 1 then - local first = t[1] - local last = t[n] - if abs(first[1]-last[1]) <= eps and abs(first[2]-last[2]) <= eps then - t[n] = nil + local tm = #t + if tm < 2 then + return + end + if trace_ranges then + report_shapes("initial list: %s",topairs(t,tm)) + end + -- remove similar points + local n = 1 + local tn = tm + local tf = t[1] + local tx = tf[1] + local ty = tf[2] + for i=2,#t do + local ti = t[i] + local ix = ti[1] + local iy = ti[2] + local dx = ix - tx + local dy = iy - ty + if dx > eps or dx < - eps or dy > eps or dy < - eps then + n = n + 1 + t[n] = ti + tx = ix + ty = iy end end -end + if trace_shapes then + report_shapes("removing similar points: %s",topairs(t,n)) + end + if n > 2 then + -- remove redundant points + repeat + tn = n + n = 0 + local tm = t[tn] + local tmx = tm[1] + local tmy = tm[2] + local tp = t[1] + local tpx = tp[1] + local tpy = tp[2] + for i=1,tn do -- while and only step when done + local ti = tp + local tix = tpx + local tiy = tpy + if i == tn then + tp = t[1] + else + tp = t[i+1] + end + tpx = tp[1] + tpy = tp[2] -local function clip(t,ytop,ybot) - local first, last = 1, #t - for i=first,last do - local y = t[i][2] - if ytop < y then - first = i + local vx1, vx2 = unitvector(tix - tmx,tpx - tix) + if vx1 ~= vx2 then + n = n + 1 + t[n] = ti + else + local vy1, vy2 = unitvector(tiy - tmy,tpy - tiy) + if vy1 ~= vy2 then + n = n + 1 + t[n] = ti + end + end + + tmx = tix + tmy = tiy + end + until n == tn or n <= 2 + if trace_shapes then + report_shapes("removing redundant points: %s",topairs(t,n)) end - if ybot > y then - last = i - break + -- remove spikes + if n > 2 then + repeat + tn = n + n = 0 + local tm = t[tn] + local tmx = tm[1] + local tmy = tm[2] + local tp = t[1] + local tpx = tp[1] + local tpy = tp[2] + for i=1,tn do -- while and only step when done + local ti = tp + local tix = tpx + local tiy = tpy + if i == tn then + tp = t[1] + else + tp = t[i+1] + end + tpx = tp[1] + tpy = tp[2] + + local vx1, vx2 = unitvector(tix - tmx,tpx - tix) + if vx1 ~= - vx2 then + n = n + 1 + t[n] = ti + else + local vy1, vy2 = unitvector(tiy - tmy,tpy - tiy) + if vy1 ~= - vy2 then + n = n + 1 + t[n] = ti + end + end + + tmx = tix + tmy = tiy + end + until n == tn or n <= 2 + if trace_shapes then + report_shapes("removing spikes: %s",topairs(t,n)) + end + end + end + -- prune trailing points + if tm > n then + for i=tm,n+1,-1 do + t[i] = nil end end - local lp = { } - lp[#lp+1] = { t[first][1], ytop } - for i=first+1,last-1 do - lp[#lp+1] = { t[i][1], t[i][2] } + if n > 1 then + local tf = t[1] + local tl = t[n] + local dx = tf[1] - tl[1] + local dy = tf[2] - tl[2] + if dx > eps or dx < - eps or dy > eps or dy < - eps then + -- different points + else + -- saves a point (as we -- cycle anyway) + t[n] = nil + n = n -1 + end + if trace_shapes then + report_shapes("removing cyclic endpoints: %s",topairs(t,n)) + end end - lp[#lp+1] = { t[last][1], ybot } - return lp + return t end --- todo: mark regions and free paragraphs in collected +local eps = 65536 -local function shapes(r,rx,ry,rw,rh,rd,lytop,lybot,rytop,rybot,obeyhang) - -- we assume that we only hang per page and not cross pages - -- which makes sense as hanging is only uses in special cases +-- The next function can introduce redundant points but these are removed later on +-- in the unspiker. It makes checking easier. + +local function shape(kind,b,p,realpage,xmin,xmax,ymin,ymax,fh,ld) + local s = b.s + if not s then + if trace_shapes then + report_shapes("calculating %s area, no shape",kind) + end + return + end + s = s[realpage] + if not s then + if trace_shapes then + report_shapes("calculating %s area, no shape for page %s",kind,realpage) + end + return + end + local ns = #s + if ns == 0 then + if trace_shapes then + report_shapes("calculating %s area, empty shape for page %s",kind,realpage) + end + return + end -- - -- we can remove data as soon as a page is done so we could - -- remember per page and discard areas after each shipout - local leftshape, rightshape - leftshape = { { rx, rh } } -- spikes get removed so we can start at the edge - rightshape = { { rw, rh } } -- even if we hang next - local paragraphs = r.paragraphs - local extending = false - if paragraphs then - for i=1,#paragraphs do - local p = paragraphs[i] - local ha = p.ha - if obeyhang and ha and ha ~= 0 then - local py = p.y - local ph = p.h - local pd = p.d - local hi = p.hi - local hang = ha * (ph + pd) - local py_ph = py + ph - -- ha < 0 hi < 0 : right top - -- ha < 0 hi > 0 : left top - if ha < 0 then - if hi < 0 then -- right - add(rightshape,rw, py_ph,"up") - add(rightshape,rw + hi,py_ph,"up") - add(rightshape,rw + hi,py_ph + hang,"up") - add(rightshape,rw, py_ph + hang,"up") - else - -- left - add(leftshape,rx,py_ph,"down") - add(leftshape,rx + hi,py_ph,"down") - add(leftshape,rx + hi,py_ph + hang,"down") - add(leftshape,rx,py_ph + hang,"down") + if trace_shapes then + report_shapes("calculating %s area, using shape for page %s",kind,realpage) + end + -- it's a bit inefficient to use the par values and later compensate for b and + -- e but this keeps the code (loop) cleaner + local ph = p and p.h or 0 + local pd = p and p.d or 0 + -- + xmax = xmax + eps + xmin = xmin - eps + ymax = ymax + eps + ymin = ymin - eps + local ls = { } -- left shape + local rs = { } -- right shape + local pl = nil -- previous left x + local pr = nil -- previous right x + local n = 0 + local xl = nil + local xr = nil + local mh = ph -- min + local md = pd -- min + for i=1,ns do + local si = s[i] + local y = si[1] + local ll = si[4] -- can be sparse + if ll then + xl = ll + local rr = si[5] -- can be sparse + if rr then + xr = rr + end + end + if trace_ranges then + report_shapes("original : [%02i] xl=%p xr=%p y=%p",i,xl,xr,y) + end + if xl ~= xr then -- could be catched in the finalizer + local xm = xl + (xr - xl)/2 -- midpoint should be in region + if xm >= xmin and xm <= xmax and y >= ymin and y <= ymax then + local ht = si[2] -- can be sparse + if ht then + ph = ht + local dp = si[3] -- can be sparse + if dp then + pd = dp end - else - -- maybe some day end - extending = true -- false - else -- we need to clip to the next par - local ps = p.ps - if ps then - local py = p.y - local ph = p.h - local pd = p.d - local step = ph + pd - local size = #ps * step - local py_ph = py + ph - add(leftshape,rx,py_ph,"up") - add(rightshape,rw,py_ph,"down") - for i=1,#ps do - local p = ps[i] - local l = p[1] - local w = p[2] - add(leftshape,rx + l, py_ph,"up") - add(rightshape,rx + l + w, py_ph,"down") - py_ph = py_ph - step - add(leftshape,rx + l, py_ph,"up") - add(rightshape,rx + l + w, py_ph,"down") + local h = y + (ph < mh and mh or ph) + local d = y - (pd < md and md or pd) + if pl then + n = n + 1 + ls[n] = { pl, h } + rs[n] = { pr, h } + if trace_ranges then + report_shapes("paragraph : [%02i] xl=%p xr=%p y=%p",i,pl,pr,h) end - extending = true - elseif extending then - local py = p.y - local ph = p.h - local pd = p.d - local py_ph = py + ph - local py_pd = py - pd - add(leftshape,leftshape[#leftshape][1],py_ph,"up") - add(rightshape,rightshape[#rightshape][1],py_ph,"down") - add(leftshape,rx,py_ph,"up") -- shouldn't this be py_pd - add(rightshape,rw,py_ph,"down") -- shouldn't this be py_pd - extending = false + end + n = n + 1 + ls[n] = { xl, h } + rs[n] = { xr, h } + if trace_ranges then + report_shapes("height : [%02i] xl=%p xr=%p y=%p",i,xl,xr,h) + end + n = n + 1 + ls[n] = { xl, d } + rs[n] = { xr, d } + if trace_ranges then + report_shapes("depth : [%02i] xl=%p xr=%p y=%p",i,xl,xr,d) end end + pl, pr = xl, xr + else + if trace_ranges then + report_shapes("ignored : [%02i] xl=%p xr=%p y=%p",i,xl,xr,y) + end end end - -- we can have a simple variant when no paragraphs - if extending then - -- not ok - leftshape[#leftshape][2] = rd - rightshape[#rightshape][2] = rw - else - add(leftshape,rx,rd,"up") - add(rightshape,rw,rd,"down") + -- + if true and n > 0 then + -- use height of b and depth of e, maybe check for weird border + -- cases here + if fh then + local lsf, rsf = ls[1], rs[1] + if lsf[2] < fh then + lsf[2] = fh + end + if rsf[2] < fh then + rsf[2] = fh + end + end + if fd then + local lsl, rsl = ls[n], rs[n] + if lsl[2] > fd then + lsl[2] = fd + end + if rsl[2] > fd then + rsl[2] = fd + end + end + end + -- + for i=n,1,-1 do + n = n + 1 rs[n] = ls[i] end - return clip(leftshape,lytop,lybot), clip(rightshape,rytop,rybot) + return rs end --- local function shapes(r,rx,ry,rw,rh,rd,lytop,lybot,rytop,rybot,obeyhang) --- local leftshape = { { rx, rh }, { rx, rd } } --- local rightshape = { { rw, rh }, { rw, rd } } --- return clip(leftshape,lytop,lybot), clip(rightshape,rytop,rybot) --- end - -local function singlepart(b,e,r,left,right,obeyhang) +local function singlepart(b,e,p,realpage,r,left,right) local bx, by = b.x, b.y local ex, ey = e.x, e.y local rx, ry = r.x, r.y + local bh, bd = by + b.h, by - b.d + local eh, ed = ey + e.h, ey - e.d + local rh, rd = ry + r.h, ry - r.d local rw = rx + r.w - local rh = ry + r.h - local rd = ry - r.d if left then rx = rx + left rw = rw - right end - local bh = by + b.h - local bd = by - b.d - local eh = ey + e.h - local ed = ey - e.d if ex == rx then -- We probably have a strut at the next line so we force a width -- although of course it is better to move up. But as we have whitespace @@ -244,169 +554,160 @@ local function singlepart(b,e,r,left,right,obeyhang) end local area if by == ey then + if trace_shapes then + report_shapes("calculating single area, partial line") + end + area = { + { bx, bh }, + { ex, eh }, + { ex, ed }, + { bx, bd }, + } + elseif b.k == 2 then area = { - f_pair(bx,bh-ry), - f_pair(ex,eh-ry), - f_pair(ex,ed-ry), - f_pair(bx,bd-ry), + { rx, bh }, + { rw, bh }, + { rw, ed }, + { rx, ed }, } else - area = { } - local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,bd,ed,bh,eh,obeyhang) - add(area,bx,bh-ry) - for i=1,#rightshapes do - local ri = rightshapes[i] - add(area,ri[1],ri[2]-ry) - end - add(area,ex,eh-ry) - add(area,ex,ed-ry) - for i=#leftshapes,1,-1 do - local li = leftshapes[i] - add(area,li[1],li[2]-ry) - end - add(area,bx,bd-ry) - add(area,bx,bh-ry,true) -- finish last straight line (but no add as we cycle) - finish(area) - for i=1,#area do - local a = area[i] - area[i] = f_pair(a[1],a[2]) - end + area = shape("single",b,p,realpage,rx,rw,rd,rh,bh,ed) + end + if not area then + area = { + { bx, bh }, + { rw, bh }, + { rw, eh }, + { ex, eh }, + { ex, ed }, + { rx, ed }, + { rx, bd }, + { bx, bd }, + } end return { location = "single", region = r, - area = area, + area = finish(area), } end -local function firstpart(b,r,left,right,obeyhang) +local function firstpart(b,e,p,realpage,r,left,right) local bx, by = b.x, b.y local rx, ry = r.x, r.y + local bh, bd = by + b.h, by - b.d + local rh, rd = ry + r.h, ry - r.d local rw = rx + r.w - local rh = ry + r.h - local rd = ry - r.d if left then rx = rx + left rw = rw - right end - local bh = by + b.h - local bd = by - b.d - local area = { } - local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,bd,rd,bh,rd,obeyhang) - add(area,bx,bh-ry) - for i=1,#rightshapes do - local ri = rightshapes[i] - add(area,ri[1],ri[2]-ry) - end - for i=#leftshapes,1,-1 do - local li = leftshapes[i] - add(area,li[1],li[2]-ry) - end - add(area,bx,bd-ry) - add(area,bx,bh-ry,true) -- finish last straight line (but no add as we cycle) - finish(area) - for i=1,#area do - local a = area[i] - area[i] = f_pair(a[1],a[2]) + local area = shape("first",b,p,realpage,rx,rw,rd,rh,bh,false) + if not area then + if b.k == 2 then + area = { + { rx, bh }, + { rw, bh }, + { rw, rd }, + { rx, rd }, + } + else + area = { + { bx, bh }, + { rw, bh }, + { rw, rd }, -- { rw, eh }, + { rx, rd }, -- { rx, ed }, + { rx, bd }, + { bx, bd }, + } + end end return { location = "first", region = r, - area = area, + area = finish(area), } end -local function middlepart(r,left,right,obeyhang) +local function middlepart(b,e,p,realpage,r,left,right) local rx, ry = r.x, r.y + local rh, rd = ry + r.h, ry - r.d local rw = rx + r.w - local rh = ry + r.h - local rd = ry - r.d if left then rx = rx + left rw = rw - right end - local area = { } - local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,rh,rd,rh,rd,obeyhang) - for i=#leftshapes,1,-1 do - local li = leftshapes[i] - add(area,li[1],li[2]-ry) - end - for i=1,#rightshapes do - local ri = rightshapes[i] - add(area,ri[1],ri[2]-ry) - end - finish(area) - for i=1,#area do - local a = area[i] - area[i] = f_pair(a[1],a[2]) + local area = shape("middle",b,p,realpage,rx,rw,rd,rh,false,false) + if not area then + area = { + { rw, rh }, + { rw, rd }, + { rx, rd }, + { rx, rh }, + } end return { location = "middle", region = r, - area = area, + area = finish(area), } end -local function lastpart(e,r,left,right,obeyhang) +local function lastpart(b,e,p,realpage,r,left,right) local ex, ey = e.x, e.y local rx, ry = r.x, r.y + local eh, ed = ey + e.h, ey - e.d + local rh, rd = ry + r.h, ry - r.d local rw = rx + r.w - local rh = ry + r.h - local rd = ry - r.d if left then rx = rx + left rw = rw - right end - local eh = ey + e.h - local ed = ey - e.d - local area = { } - -- two cases: till end and halfway e line - local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,rh,ed,rh,eh,obeyhang) - for i=1,#rightshapes do - local ri = rightshapes[i] - add(area,ri[1],ri[2]-ry) - end - add(area,ex,eh-ry) - add(area,ex,ed-ry) - for i=#leftshapes,1,-1 do - local li = leftshapes[i] - add(area,li[1],li[2]-ry) - end - finish(area) - for i=1,#area do - local a = area[i] - area[i] = f_pair(a[1],a[2]) + local area = shape("last",b,p,realpage,rx,rw,rd,rh,false,ed) + if not area then + if b.k == 2 then + area = { + { rw, rh }, + { rw, ed }, + { rx, ed }, + { rx, rh }, + } + else + area = { + { rw, rh }, -- { rw, bh }, + { rw, eh }, + { ex, eh }, + { ex, ed }, + { rx, ed }, + { rx, rh }, -- { rx, bd }, + } + end end return { location = "last", region = r, - area = area, + area = finish(area), } end -graphics = graphics or { } -local backgrounds = { } - -graphics.backgrounds = backgrounds - -local function calculatemultipar(tag,obeyhang) +local function calculatemultipar(tag) local collected = jobpositions.collected local b = collected[f_b_tag(tag)] local e = collected[f_e_tag(tag)] if not b or not e then - report_graphics("invalid tag %a",tag) + report_shapes("invalid tag %a",tag) return { } end local br = b.r local er = e.r if not br or not er then - report_graphics("invalid region for %a",tag) + report_shapes("invalid region for %a",tag) return { } end local btag, bindex = lpegmatch(splitter,br) local etag, eindex = lpegmatch(splitter,er) if not bindex or not eindex or btag ~= etag then - report_graphics("invalid indices for %a",tag) + report_shapes("invalid indices for %a",tag) return { } end local bindex = tonumber(bindex) @@ -415,40 +716,42 @@ local function calculatemultipar(tag,obeyhang) -- entries and these are shared. We compensate left/right based on the columns -- x and w but need to take the region into acount where the specification was -- flushed and not the begin pos's region, because otherwise we get the wrong - -- compensation for assymetrical doublesided layouts. - local left = 0 + -- compensation for asymetrical doublesided layouts. + local left = 0 local right = 0 - local rc = b.c + local bc = b.c + local rc = bc and collected[bc] if rc then - rc = collected[rc] - if rc then - local tb = collected[rc.r] - if tb then - left = -(tb.x - rc.x) - right = (tb.w - rc.w - left) -- tb.x - rc.x - end + local tb = collected[rc.r] + if tb then + left = -(tb.x - rc.x) + right = (tb.w - rc.w - left) end end -- Obeying intermediate changes of left/rightskip makes no sense as it will -- look bad, so we only look at the begin situation. local bn = b.n - if bn then - local bp = collected[f_p_tag(bn)] - if bp then - left = left + bp.ls - right = right + bp.rs - end + local p = bn and collected[f_p_tag(bn)] -- par + if p then + left = left + (p.ls or 0) + right = right + (p.rs or 0) + end + -- + local bp = b.p -- page + if trace_shapes then + report_shapes("tag %a, left %p, right %p, par %s, page %s, column %s", + left,right,bn or "-",bp or "-",bc or "-") end -- if bindex == eindex then return { - list = { [b.p] = { singlepart(b,e,collected[br],left,right,obeyhang) } }, + list = { [bp] = { singlepart(b,e,p,bp,collected[br],left,right) } }, bpos = b, epos = e, } else local list = { - [b.p] = { firstpart(b,collected[br],left,right,obeyhang) }, + [bp] = { firstpart(b,e,p,bp,collected[br],left,right) }, } for i=bindex+1,eindex-1 do br = f_tag_two(btag,i) @@ -456,21 +759,23 @@ local function calculatemultipar(tag,obeyhang) if not r then report_graphics("invalid middle for %a",br) else - local p = r.p - local pp = list[p] + local rp = r.p -- page + local pp = list[rp] + local mp = middlepart(b,e,p,rp,r,left,right) if pp then - pp[#pp+1] = middlepart(r,left,right,obeyhang) + pp[#pp+1] = mp else - list[p] = { middlepart(r,left,right,obeyhang) } + list[rp] = { mp } end end end - local p = e.p - local pp = list[p] + local ep = e.p -- page + local pp = list[ep] + local lp = lastpart(b,e,p,ep,collected[er],left,right) if pp then - pp[#pp+1] = lastpart(e,collected[er],left,right,obeyhang) + pp[#pp+1] = lp else - list[p] = { lastpart(e,collected[er],left,right,obeyhang) } + list[ep] = { lp } end return { list = list, @@ -480,41 +785,8 @@ local function calculatemultipar(tag,obeyhang) end end --- local pending = { } -- needs gc --- --- local function register(data,n,anchor) --- local pa = pending[anchor] --- if not pa then --- pa = { } --- pending[anchor] = pa --- end --- for page, pagedata in next, data do --- local pap = pa[page] --- if pap then --- pap[#pap+1] = n --- else --- pa[page] = { n } --- end --- end --- end --- --- function backgrounds.registered(anchor,page) --- local pa = pending[anchor] --- if pa then --- concat(pa,",") --- else --- return "" --- end --- end - local pbg = { } -- will move to pending -function backgrounds.calculatemultipar(n) - if not pbg[n] then - pbg[n] = calculatemultipar("pbg",n) or { } - end -end - local multilocs = { single = 1, -- maybe 0 first = 1, @@ -524,7 +796,7 @@ local multilocs = { -- if unknown context_abck : input mp-abck.mpiv ; fi ; -local f_template_a = [[ +local f_template_a = formatters[ [[ path multiregs[], multipars[], multibox ; string multikind[] ; numeric multilocs[], nofmultipars ; @@ -534,69 +806,340 @@ numeric par_strut_height, par_strut_depth, par_line_height ; par_strut_height := %p ; par_strut_depth := %p ; par_line_height := %p ; -]] +]] ] -local f_template_b = [[ +local f_template_b = formatters[ [[ multilocs[%s] := %s ; multikind[%s] := "%s" ; multipars[%s] := (%--t--cycle) shifted - (%p,%p) ; -]] +]] ] -local f_template_c = [[ -multiregs[%s] := (%--t--cycle) shifted - %s ; -]] +-- unspiked(simplified(%--t--cycle)) shifted - (%p,%p) ; -local f_template_d = [[ +local f_template_c = formatters[ [[ setbounds currentpicture to multibox ; -]] - -f_template_a = formatters[f_template_a] -f_template_b = formatters[f_template_b] -f_template_c = formatters[f_template_c] -f_template_d = formatters[f_template_d] - -local function fetchmultipar(n,anchor,page,obeyhang) - local data = pbg[n] - if not data then - data = calculatemultipar(n,obeyhang) - pbg[n] = data -- can be replaced by register - -- register(data.list,n,anchor) - end - if data then - local list = data.list +]] ] + +local function freemultipar(pagedata,frees) -- ,k + -- if k == 3 then + -- -- tables have local regions + -- return + -- end + if not frees then + return + end + local nfree = #frees + if nfree == 0 then + return + end + for i=1,#pagedata do + local data = pagedata[i] + local area = data.area + + if area then + + local region = data.region + local y = 0 -- region.y + -- local x = region.x + local areas = { } + data.areas = areas + + local f_1, n_1 = { }, 0 + local f_2, n_2 = { }, 0 + for i=1,#frees do + local f = frees[i] + local k = f.k + if k == 1 then -- pag + n_1 = n_1 + 1 + f_1[n_1] = f + elseif k == 2 or k == 3 then -- par + n_2 = n_2 + 1 + f_2[n_2] = f + end + end + + local lineheight = tex.dimen.lineheight + + -- page floats + + local function check_one(free1,free2) + local temp = { } + local some = false + local top = (free2 and (y + free2.y + free2.h + (free2.to or 0))) or false + local bot = (free1 and (y + free1.y - free1.d - (free1.bo or 0))) or false + for i=1,#area do + local a = area[i] + local x = a[1] + local y = a[2] + if free2 and y <= top then + y = top + end + if free1 and y >= bot then + y = bot + end + if not some then + some = y + elseif some == true then + -- done + elseif y ~= some then + some = true + end + temp[i] = { x, y } + end + if some == true then + areas[#areas+1] = temp + end + end + + if n_1 > 0 then + check_one(false,f_1[1]) + for i=2,n_1 do + check_one(f_1[i-1],f_1[i]) + end + check_one(f_1[n_1],false) + end + + -- par floats + + if #areas == 0 then + areas[1] = area + end + + -- we can collect the coordinates first + + local function check_two(area,frees) + local ul = area[1] + local ur = area[2] + local lr = area[3] + local ll = area[4] + local ulx, uly = ul[1], ul[2] + local urx, ury = ur[1], ur[2] + local lrx, lry = lr[1], lr[2] + local llx, lly = ll[1], ll[2] + + local temp = { } + local n = 0 + local done = false + + for i=1,#frees do + local free = frees[i] + local fx = free.x + local fy = free.y + local ymax = y + fy + free.h + (free.to or 0) + local ymin = y + fy - free.d - (free.bo or 0) + local xmin = fx - (free.lo or 0) + local xmax = fx + free.w + (free.ro or 0) + if free.k == 3 then + if uly <= ymax and uly >= ymin and lly <= ymin then + if trace_free then + report_free("case 1, top, right") -- ok + end + n = n + 1 temp[n] = { xmin, ury } + n = n + 1 temp[n] = { xmin, ymin } + n = n + 1 temp[n] = { lrx, ymin } + n = n + 1 temp[n] = { lrx, lry } + done = true + elseif uly >= ymax and lly <= ymin then + if trace_free then + report_free("case 2, outside, right") -- ok + end + if uly - ymax < lineheight then + n = n + 1 temp[n] = { xmin, ury } + else + n = n + 1 temp[n] = { urx, ury } + n = n + 1 temp[n] = { urx, ymax } + end + n = n + 1 temp[n] = { xmin, ymax } + n = n + 1 temp[n] = { xmin, ymin } + n = n + 1 temp[n] = { lrx, ymin } + n = n + 1 temp[n] = { lrx, lry } + done = true + elseif lly <= ymax and lly >= ymin and uly >= ymax then + if trace_free then + report_free("case 3, bottom, right") + end + if uly - ymax < lineheight then + n = n + 1 temp[n] = { xmin, ury } + else + n = n + 1 temp[n] = { urx, ury } + n = n + 1 temp[n] = { urx, ymax } + end + n = n + 1 temp[n] = { xmin, ymax } + n = n + 1 temp[n] = { xmin, lry } + done = true + elseif uly <= ymax and lly >= ymin then + if trace_free then + report_free("case 4, inside, right") + end + n = n + 1 temp[n] = { xmin, lly } + n = n + 1 temp[n] = { xmin, uly } + done = true + else + -- case 0 + if trace_free then + report_free("case 0, nothing") + end + end + end + end + + if not done then + if trace_free then + report_free("no right shape") + end + n = n + 1 temp[n] = { urx, ury } + n = n + 1 temp[n] = { lrx, lry } + n = n + 1 temp[n] = { llx, lly } + else + done = false + end + + for i=#frees,1,-1 do + local free = frees[i] + local fx = free.x + local fy = free.y + local ymax = y + fy + free.h + (free.to or 0) + local ymin = y + fy - free.d - (free.bo or 0) + local xmin = fx - (free.lo or 0) + local xmax = fx + free.w + (free.ro or 0) + if free.k == 2 then + if uly <= ymax and uly >= ymin and lly <= ymin then + if trace_free then + report_free("case 1, top, left") -- ok + end + n = n + 1 temp[n] = { ulx, ymin } + n = n + 1 temp[n] = { xmax, ymin } + n = n + 1 temp[n] = { xmax, uly } + done = true + elseif uly >= ymax and lly <= ymin then + if trace_free then + report_free("case 2, outside, left") -- ok + end + n = n + 1 temp[n] = { llx, lly } + n = n + 1 temp[n] = { llx, ymin } + n = n + 1 temp[n] = { xmax, ymin } + n = n + 1 temp[n] = { xmax, ymax } + if uly - ymax < lineheight then + n = n + 1 temp[n] = { xmax, uly } + else + n = n + 1 temp[n] = { llx, ymax } + n = n + 1 temp[n] = { llx, uly } + end + done = true + elseif lly <= ymax and lly >= ymin and uly >= ymax then + if trace_free then + report_free("case 3, bottom, left") + end + n = n + 1 temp[n] = { xmax, lly } + n = n + 1 temp[n] = { xmax, ymax } + if uly - ymax < lineheight then + n = n + 1 temp[n] = { xmax, uly } + else + n = n + 1 temp[n] = { llx, ymax } + n = n + 1 temp[n] = { llx, uly } + end + done = true + elseif uly <= ymax and lly >= ymin then + if trace_free then + report_free("case 4, inside, left") + end + n = n + 1 temp[n] = { xmax, lly } + n = n + 1 temp[n] = { xmax, uly } + done = true + else + -- case 0 + end + end + end + + if not done then + if trace_free then + report_free("no left shape") + end + n = n + 1 temp[n] = { llx, lly } + end + n = n + 1 temp[n] = { ulx, uly } + + return temp + end + + if n_2 > 0 then + for i=1,#areas do + local area = areas[i] + if #area == 4 then -- and also check type, must be pargaraph + areas[i] = check_two(area,f_2) + else + -- message that not yet supported + end + end + end + + for i=1,#areas do + finish(areas[i]) -- again + end + + end + + end +end + +local function fetchmultipar(n,anchor,page) + local a = jobpositions.collected[anchor] + if not a then + report_graphics("missing anchor %a",anchor) + else + local data = pbg[n] + if not data then + data = calculatemultipar(n) + pbg[n] = data -- can be replaced by register + -- register(data.list,n,anchor) + end + local list = data and data.list if list then local pagedata = list[page] if pagedata then + local k = data.bpos.k + if k ~= 3 then + -- to be checked: no need in txt mode + freemultipar(pagedata,jobpositions.free[page]) + end local nofmultipars = #pagedata - -- report_graphics("fetching %a at page %s using anchor %a containing %s multipars",n,page,anchor,nofmultipars) - local a = jobpositions.collected[anchor] - if not a then - report_graphics("missing anchor %a",anchor) - else - local trace = false - local x, y, w, h, d = a.x, a.y, a.w, a.h, a.d - local bpos = data.bpos - local bh, bd = bpos.h, bpos.d - local result = { f_template_a(nofmultipars,w,h+d,bh,bd,bh+bd) } - for i=1,nofmultipars do - local region = pagedata[i] - result[#result+1] = f_template_b( - i, multilocs[region.location], - i, region.location, - i, region.area, x, y-region.region.y) - if trace then - result[#result+1] = f_template_c(i, regionarea(region.region), offset) + if trace_shapes then + report_graphics("fetching %a at page %s using anchor %a containing %s multipars", + n,page,anchor,nofmultipars) + end + local x, y = a.x, a.y + local w, h, d = a.w, a.h, a.d + local bpos = data.bpos + local bh, bd = bpos.h, bpos.d + local result = { false } -- slot 1 will be set later + local n = 0 + for i=1,nofmultipars do + local data = pagedata[i] + local location = data.location + local region = data.region + local areas = data.areas + if not areas then + areas = { data.area } + end + for i=1,#areas do + local area = areas[i] + for i=1,#area do + local a = area[i] + area[i] = f_pair(a[1],a[2]) end + n = n + 1 + result[n+1] = f_template_b(n,multilocs[location],n,location,n,area,x,y) end - data[page] = nil - result[#result+1] = f_template_d() - result = concat(result,"\n") - return result end + data[page] = nil + result[1] = f_template_a(n,w,h+d,bh,bd,bh+bd) -- was delayed + result[n+2] = f_template_c() + return concat(result,"\n") end end end - return f_template_a(0,"origin",0,0,0) + return f_template_a(0,0,0,0,0,0); end backgrounds.fetchmultipar = fetchmultipar @@ -613,28 +1156,19 @@ implement { arguments = { "string", "string", "integer" } } -implement { - name = "fetchmultishape", - actions = { fetchmultipar, context }, - arguments = { "string", "string", "integer", true } -} - -local f_template_a = [[ +local f_template_a = formatters[ [[ path posboxes[], posregions[] ; numeric pospages[] ; numeric nofposboxes ; nofposboxes := %s ; %t ; -]] +]] ] -local f_template_b = [[ +local f_template_b = formatters[ [[ pospages[%s] := %s ; posboxes[%s] := (%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle ; posregions[%s] := (%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle ; -]] - -f_template_a = formatters[f_template_a] -f_template_b = formatters[f_template_b] +]] ] implement { name = "fetchposboxes", @@ -655,7 +1189,7 @@ implement { if r then local rx, ry, rw, rh, rd = r.x, r.y, r.w, r.h, r.d local cx = c.x - rx - local cy = c.y - ry + local cy = c.y local cw = cx + c.w local ch = cy + c.h local cd = cy - c.d @@ -668,7 +1202,7 @@ implement { end end else - print("\n missing",tag) + -- print("\n missing",tag) end end context(f_template_a(nofboxes,list)) @@ -681,17 +1215,19 @@ implement { name = "doifelserangeonpage", arguments = { "string", "string", "integer" }, actions = function(first,last,page) - local collected = jobpositions.collected - local f = collected[first] - if not f or f.p == true then - doifelse(false) - return - end - local l = collected[last] - if not l or l.p == true then - doifelse(false) - return + local c = jobpositions.collected + local f = c[first] + if f then + f = f.p + if f and f ~= true and page >= f then + local l = c[last] + if l then + l = l.p + doifelse(l and l ~= true and page <= l) + return + end + end end - doifelse(page >= f.p and page <= l.p) + doifelse(false) end } diff --git a/tex/context/base/mkiv/anch-pgr.mkiv b/tex/context/base/mkiv/anch-pgr.mkiv index a7ad26dff..1a583142e 100644 --- a/tex/context/base/mkiv/anch-pgr.mkiv +++ b/tex/context/base/mkiv/anch-pgr.mkiv @@ -13,18 +13,16 @@ \writestatus{loading}{ConTeXt Anchoring Macros / Grapics} -%D Before we come to graphics support, we have to make sure of -%D the reference point on the page. The next macros do so and -%D are hooked into the page building routine. +%D Before we come to graphics support, we have to make sure of the reference point +%D on the page. The next macros do so and are hooked into the page building routine. \registerctxluafile{anch-pgr}{1.001} \unprotect -%D A few more low level macros take care of defining and recalling -%D actions. Actions are saved globally! The lists can become quite -%D long because there can be lots of parameters passed on so we -%D clean up the list afterwards. +%D A few more low level macros take care of defining and recalling actions. Actions +%D are saved globally! The lists can become quite long because there can be lots of +%D parameters passed on so we clean up the list afterwards. \newtoks\everypositionaction \newtoks\everyinsertpositionaction @@ -91,22 +89,15 @@ \let\anch_positions_trace_action_yes\anch_positions_trace_action_yes_indeed \to \t_anch_positions_tracers -%D Here the complication has to do with collecting actions -%D for later execution. This collection is especially handy -%D when we want to move actions to a specific layer. Such -%D series of actions are stored in a macro that is cleaned up -%D after each invocation. +%D Here the complication has to do with collecting actions for later execution. This +%D collection is especially handy when we want to move actions to a specific layer. +%D Such series of actions are stored in a macro that is cleaned up after each +%D invocation. \def\anch_positions_cleanup_action % not in trialtypesetting {\ifcsname\??positioncleanup\currentpositionaction\endcsname \the\everycleanpositionaction - % \iflocalpositioning - % % erase - % \expandafter\let\csname\??positioncleanup\currentpositionaction\endcsname\empty - % \else - % globalize expansion cleans up - \setxvalue{\??positioncleanup\currentpositionaction}{\csname\??positioncleanup\currentpositionaction\endcsname}% - % \fi + \setxvalue{\??positioncleanup\currentpositionaction}{\csname\??positioncleanup\currentpositionaction\endcsname}% \fi} \def\handlepositionaction#1\with#2\on#3% ugly @@ -124,10 +115,9 @@ \fi \endgroup} -%D The first version of this module implemented head and tail -%D anchors. Currently we stick to just one anchor and derive -%D the head and tail anchors from this one. We set these -%D anchors before and after each page. +%D The first version of this module implemented head and tail anchors. Currently we +%D stick to just one anchor and derive the head and tail anchors from this one. We +%D set these anchors before and after each page. \newdimen\c_anch_page_width \newdimen\c_anch_page_height @@ -160,7 +150,7 @@ {\begingroup \setbox\scratchbox\emptyhbox \ht\scratchbox\textheight - \dp\scratchbox\zeropoint + \dp\scratchbox\zeropoint % redundant \wd\scratchbox\makeupwidth \anch_mark_text_box\scratchbox \box\scratchbox @@ -172,9 +162,8 @@ %D \macros %D {positionoverlay,startpositionoverlay} %D -%D As long as we're dealing with graphics it makes much sense -%D to use the available overlay mechanism. For this purpose, we -%D define some dedicated overlay extensions. +%D As long as we're dealing with graphics it makes much sense to use the available +%D overlay mechanism. For this purpose, we define some dedicated overlay extensions. %D %D \startbuffer[sample] %D \defineoverlay [sample] [\positionoverlay{sample}] @@ -213,27 +202,18 @@ %D %\getbuffer[graphic,sample,text] %D \stoplinecorrection %D -%D The graphic is defined in the following way, using some -%D macros defined in an auxiliary \METAPOST\ module that is -%D preloaded. +%D The graphic is defined in the following way, using some macros defined in an +%D auxiliary \METAPOST\ module that is preloaded. %D %D \typebuffer[graphic] \def\MPanchoridentifier{mpa} % {mp-anchor} -%D The rest of the definitions concerning such overlays may -%D look complicated, +%D The rest of the definitions concerning such overlays may look complicated, \let\currentpositionoverlay\empty -%D Position actions are automatically executed when a position -%D is set. - -% \newcount\localpositionnumber % incremented elsewhere -% \newif\iflocalpositioning -% -% \def\textbackgroundoverlay#1{\iflocalpositioning\v!local\else\v!text\fi#1} -% \def\MPanchornumber {\the\iflocalpositioning\localpositionnumber\else\realpageno\fi} +%D Position actions are automatically executed when a position is set. \def\textbackgroundoverlay#1{\v!text#1} \def\MPanchornumber {\the\realpageno} @@ -327,35 +307,8 @@ \unexpanded\def\stoppositionoverlay {\let\currentpositionoverlay\empty} -% needs checking if still needed -% -% \def\resetpositionoverlay#1% -% {\anch_positions_set_action{#1::\MPanchoridentifier::}{}} -% -% \def\handlepositionboxes#1#2#3% -% {\handlepositionaction\dohandlepositionboxes\with{#1}{#2}{#3}\on{#2}} -% -% \def\doinsertpositionboxes#1#2#3% pos tag setups -% {\ifnum\MPp{#1}=\realpageno\relax % can be sped up -% \executeifdefined{\MPoverlayposprefix#1}\gobblethreearguments{#1}{#2}{#3}% not used -% \fi} -% -% \appendtoks -% \let\dohandlepositionboxes\doinsertpositionboxes % was handle ? -% \to \everyinsertpositionaction -% -% \def\docleanpositionboxes#1#2#3% pos tag setups -% {\ifnum\MPp{#1}<\realpageno \else -% \noexpand \dohandlepositionboxes{#1}{#2}{#3}% reinsert -% \fi} -% -% \appendtoks -% \let\dohandlepositionboxes\docleanpositionboxes -% \to \everycleanpositionaction - -%D A position graphic is a normal (non||reused) \METAPOST\ -%D graphic, used immediately, with zero dimensions, so that a -%D sequence of them does not harm. +%D A position graphic is a normal (non||reused) \METAPOST\ graphic, used +%D immediately, with zero dimensions, so that a sequence of them does not harm. \installcorenamespace{positiongraphic} \installcorenamespace{positionmethod} @@ -505,8 +458,7 @@ % Helpers: -\def\MPgetposboxes #1#2{\clf_fetchposboxes {#1}{#2}\realpageno} -\def\MPgetmultipars #1#2{\clf_fetchmultipar {#1}{#2}\realpageno} -\def\MPgetmultishapes#1#2{\clf_fetchmultishape{#1}{#2}\realpageno} +\def\MPgetposboxes #1#2{\clf_fetchposboxes{#1}{#2}\realpageno} +\def\MPgetmultipars#1#2{\clf_fetchmultipar{#1}{#2}\realpageno} \protect \endinput diff --git a/tex/context/base/mkiv/anch-pos.lua b/tex/context/base/mkiv/anch-pos.lua index 2d36c53e6..2ba9e2420 100644 --- a/tex/context/base/mkiv/anch-pos.lua +++ b/tex/context/base/mkiv/anch-pos.lua @@ -14,21 +14,22 @@ more efficient.</p> -- plus (extra) is obsolete but we will keep it for a while --- context(new_latelua_node(f_enhance(tag))) --- => --- context.lateluafunction(function() f_enhance(tag) end) - -- maybe replace texsp by our own converter (stay at the lua end) -- eventually mp will have large numbers so we can use sp there too -local tostring, next, rawget, setmetatable = tostring, next, rawget, setmetatable -local sort = table.sort -local format, gmatch, match = string.format, string.gmatch, string.match +-- this is one of the first modules using scanners and we need to replace +-- it by implement and friends + +local tostring, next, rawget, rawset, setmetatable, tonumber = tostring, next, rawget, rawset, setmetatable, tonumber +local sort, sortedhash, sortedkeys = table.sort, table.sortedhash, table.sortedkeys +local format, gmatch, match, find = string.format, string.gmatch, string.match, string.find local rawget = rawget local lpegmatch = lpeg.match local insert, remove = table.insert, table.remove local allocate, mark = utilities.storage.allocate, utilities.storage.mark +local report = logs.reporter("positions") + local scanners = tokens.scanners local scanstring = scanners.string local scaninteger = scanners.integer @@ -39,6 +40,7 @@ local scanners = interfaces.scanners local commands = commands local context = context +local ctxnode = context.nodes.flush local tex = tex local texgetcount = tex.getcount @@ -49,7 +51,8 @@ local texsp = tex.sp local pdf = pdf -- h and v are variables -local setmetatableindex = table.setmetatableindex +local setmetatableindex = table.setmetatableindex +local setmetatablenewindex = table.setmetatablenewindex local nuts = nodes.nuts @@ -59,7 +62,10 @@ local setlink = nuts.setlink local getlist = nuts.getlist local setlist = nuts.setlist local getbox = nuts.getbox -local getskip = nuts.getskip +local getid = nuts.getid +local getwhd = nuts.getwhd + +----- hlist_code = nodes.listcodes.hlist local find_tail = nuts.tail @@ -84,24 +90,23 @@ local jobpositions = { job.positions = jobpositions -_plib_ = jobpositions -- might go - local default = { -- not r and paragraphs etc __index = { - x = 0, -- x position baseline - y = 0, -- y position baseline - w = 0, -- width - h = 0, -- height - d = 0, -- depth - p = 0, -- page - n = 0, -- paragraph - ls = 0, -- leftskip - rs = 0, -- rightskip - hi = 0, -- hangindent - ha = 0, -- hangafter - hs = 0, -- hsize - pi = 0, -- parindent - ps = false, -- parshape + x = 0, -- x position baseline + y = 0, -- y position baseline + w = 0, -- width + h = 0, -- height + d = 0, -- depth + p = 0, -- page + n = 0, -- paragraph + ls = 0, -- leftskip + rs = 0, -- rightskip + hi = 0, -- hangindent + ha = 0, -- hangafter + hs = 0, -- hsize + pi = 0, -- parindent + ps = false, -- parshape + dir = 0, } } @@ -115,87 +120,201 @@ local f_region = formatters["region:%s"] local f_tag_three = formatters["%s:%s:%s"] local f_tag_two = formatters["%s:%s"] ------ f_enhance = formatters["_plib_.enhance(%q)"] - ------ f_b_column = formatters["_plib_.b_column(%q)"] ------ f_e_column = formatters["_plib_.e_column()"] +jobpositions.used = false ------ f_b_region = formatters["_plib_.b_region(%q)"] ------ f_e_region = formatters["_plib_.e_region(%s)"] - -local function sorter(a,b) - return a.y > b.y -end - -local nofusedregions = 0 -local nofmissingregions = 0 -local nofregular = 0 - -jobpositions.used = false - --- todo: register subsets and count them indepently +local nofregular = 0 +local nofspecial = 0 +local splitter = lpeg.splitat(":",true) local function initializer() tobesaved = jobpositions.tobesaved collected = jobpositions.collected - -- add sparse regions + local pagedata = { } + local freedata = setmetatableindex("table") + for tag, data in next, collected do + local prefix, rest = lpegmatch(splitter,tag) + if prefix == "p" then + nofregular = nofregular + 1 + elseif prefix == "page" then + nofregular = nofregular + 1 + pagedata[tonumber(rest) or 0] = data + elseif prefix == "free" then + nofspecial = nofspecial + 1 + local t = freedata[data.p or 0] + t[#t+1] = data + end + setmetatable(data,default) + end + -- local pages = structures.pages.collected - if pages then + if pages then local last = nil for p=1,#pages do local region = "page:" .. p - local data = collected[region] + local data = pagedata[p] + local free = freedata[p] + if free then + sort(free,function(a,b) return b.y < a.y end) -- order matters ! + end if data then - last = data - last.p = nil -- no need for a page + last = data + last.free = free elseif last then - collected[region] = last - end - end - end - -- enhance regions with paragraphs - for tag, data in next, collected do - local region = data.r - if region then - local r = collected[region] - if r then - local paragraphs = r.paragraphs - if not paragraphs then - r.paragraphs = { data } + local t = setmetatableindex({ free = free, p = p },last) + if not collected[region] then + collected[region] = t else - paragraphs[#paragraphs+1] = data + -- something is wrong end - nofusedregions = nofusedregions + 1 - else - nofmissingregions = nofmissingregions + 1 + pagedata[p] = t end - else - nofregular = nofregular + 1 end - setmetatable(data,default) end - -- add metatable - -- for tag, data in next, collected do - -- setmetatable(data,default) - -- end - -- sort this data - for tag, data in next, collected do - local region = data.r - if region then - local r = collected[region] - if r then - local paragraphs = r.paragraphs - if paragraphs and #paragraphs > 1 then - sort(paragraphs,sorter) + jobpositions.page = pagedata + jobpositions.free = freedata + jobpositions.used = next(collected) +end + +-- -- we can gain a little when we group positions but then we still have to +-- -- deal with regions and cells so we either end up with lots of extra small +-- -- tables pointing to them and/or assembling/disassembling so in the end +-- -- it makes no sense to do it (now) and still have such a mix +-- +-- local splitter = lpeg.splitat(":",true) +-- +-- local function setpos(t,k,v) +-- local class, tag = lpegmatch(splitter,k) +-- if tag then +-- local c = rawget(t,class) +-- if c then +-- c[tonumber(tag) or tag] = v +-- else +-- rawset(t,class,{ [tonumber(tag) or tag] = v }) +-- end +-- else +-- t.default[tonumber(k) or k] = v +-- end +-- end +-- +-- local function getpos(t,k) +-- local class, tag = lpegmatch(splitter,k) +-- if tag then +-- local c = rawget(t,class) +-- if c then +-- return c[tonumber(tag) or tag] +-- end +-- else +-- return c.default[tonumber(k) or k] +-- end +-- end +-- +-- tobesaved.default = tobesaved.default or { } +-- setmetatablenewindex(tobesaved,setpos) +-- setmetatableindex (tobesaved,getpos) +-- +-- local function initializer() +-- tobesaved = jobpositions.tobesaved +-- collected = jobpositions.collected +-- +-- tobesaved.default = tobesaved.default or { } +-- collected.default = collected.default or { } +-- +-- setmetatablenewindex(tobesaved,setpos) +-- setmetatableindex (collected,getpos) +-- setmetatableindex (tobesaved,getpos) +-- +-- for class, list in next, collected do +-- for tag, data in next, list do +-- setmetatable(data,default) +-- nofregular = nofregular + 1 +-- end +-- end +-- +-- local pagedata = collected.page or { } +-- local freedata = setmetatableindex("table") +-- +-- for tag, data in next, collected.free or { } do +-- local t = freedata[data.p or 0] +-- t[#t+1] = data +-- end +-- +-- -- +-- local pages = structures.pages.collected +-- if pages then +-- local last = nil +-- for p=1,#pages do +-- local data = pagedata[p] +-- local free = freedata[p] +-- if free then +-- sort(free,function(a,b) return b.y < a.y end) -- order matters ! +-- end +-- if data then +-- last = data +-- last.free = free +-- elseif last then +-- local t = setmetatableindex({ free = free, p = p },last) +-- if not pagedata[p] then +-- pagedata[p] = t +-- end +-- end +-- end +-- end +-- jobpositions.page = pagedata +-- jobpositions.free = freedata +-- jobpositions.used = next(collected) +-- end +-- +-- function jobpositions.getcollected(class,tag) if tag then return collected[class..tag] else return collected[class] end end +-- function jobpositions.gettobesaved(class,tag) if tag then return tobesaved[class..tag] else return tobesaved[class] end end + +local function finalizer() + -- We make the (possible extensive) shape lists sparse working + -- from the end. We could also drop entries here that have l and + -- r the same which saves testing later on. + for k, v in next, tobesaved do + local s = v.s + if s then + for p, data in next, s do + local n = #data + if n > 1 then + local ph = data[1][2] + local pd = data[1][3] + local xl = data[1][4] + local xr = data[1][5] + for i=2,n do + local di = data[i] + local h = di[2] + local d = di[3] + local l = di[4] + local r = di[5] + if r == xr then + di[5] = nil + if l == xl then + di[4] = nil + if d == pd then + di[3] = nil + if h == ph then + di[2] = nil + else + ph = h + end + else + pd, ph = d, h + end + else + ph, pd, xl = h, d, l + end + else + ph, pd, xl, xr = h, d, l, r + end + end end end end - -- so, we can be sparse and don't need 'or 0' code end - jobpositions.used = next(collected) end -job.register('job.positions.collected', tobesaved, initializer) +job.register('job.positions.collected', tobesaved, initializer, finalizer) local regions = { } local nofregions = 0 @@ -213,46 +332,18 @@ local getpos = function() getpos = backends.codeinjections.getpos return getp local gethpos = function() gethpos = backends.codeinjections.gethpos return gethpos() end local getvpos = function() getvpos = backends.codeinjections.getvpos return getvpos() end -local function setdim(name,w,h,d,extra) -- will be used when we move to sp allover - local x, y = getpos() - if x == 0 then x = nil end - if y == 0 then y = nil end - if w == 0 then w = nil end - if h == 0 then h = nil end - if d == 0 then d = nil end - if extra == "" then extra = nil end - -- todo: sparse - tobesaved[name] = { - p = texgetcount("realpageno"), - x = x, - y = y, - w = w, - h = h, - d = d, - e = extra, - r = region, - c = column, - } -end - local function setall(name,p,x,y,w,h,d,extra) - if x == 0 then x = nil end - if y == 0 then y = nil end - if w == 0 then w = nil end - if h == 0 then h = nil end - if d == 0 then d = nil end - if extra == "" then extra = nil end - -- todo: sparse tobesaved[name] = { p = p, - x = x, - y = y, - w = w, - h = h, - d = d, - e = extra, + x = x ~= 0 and x or nil, + y = y ~= 0 and y or nil, + w = w ~= 0 and w or nil, + h = h ~= 0 and h or nil, + d = d ~= 0 and d or nil, + e = extra ~= "" and extra or nil, r = region, c = column, + r2l = texgetcount("inlinelefttoright") == 1 and true or nil, } end @@ -265,12 +356,16 @@ local function enhance(data) end if data.x == true then if data.y == true then - data.x, data.y = getpos() + local x, y = getpos() + data.x = x ~= 0 and x or nil + data.y = y ~= 0 and y or nil else - data.x = gethpos() + local x = gethpos() + data.x = x ~= 0 and x or nil end elseif data.y == true then - data.y = getvpos() + local y = getvpos() + data.y = y ~= 0 and y or nil end if data.p == true then data.p = texgetcount("realpageno") -- we should use a variable set in otr @@ -296,9 +391,6 @@ end local function set(name,index,val) -- ,key local data = enhance(val or index) if val then --- if data[key] and not next(next(data)) then --- data = data[key] --- end container = tobesaved[name] if not container then tobesaved[name] = { @@ -321,7 +413,7 @@ local function get(id,index) end end -jobpositions.setdim = setdim +------------.setdim = setdim jobpositions.setall = setall jobpositions.set = set jobpositions.get = get @@ -353,10 +445,11 @@ scanners.dosavepositionplus = compilescanner { -- not much gain in keeping stack (inc/dec instead of insert/remove) local function b_column(tag) + local x = gethpos() tobesaved[tag] = { r = true, - x = gethpos(), - w = 0, + x = x ~= 0 and x or nil, + -- w = 0, } insert(columns,tag) column = tag @@ -367,7 +460,8 @@ local function e_column(tag) if not t then -- something's wrong else - t.w = gethpos() - t.x + local x = gethpos() - t.x + t.w = x ~= 0 and x or nil t.r = region end remove(columns) @@ -387,8 +481,7 @@ scanners.bposcolumnregistered = function() -- tag local tag = scanstring() insert(columns,tag) column = tag - -- context(new_latelua_node(f_b_column(tag))) - context(new_latelua_node(function() b_column(tag) end)) + ctxnode(new_latelua_node(function() b_column(tag) end)) end scanners.eposcolumn = function() @@ -397,8 +490,7 @@ scanners.eposcolumn = function() end scanners.eposcolumnregistered = function() - -- context(new_latelua_node(f_e_column())) - context(new_latelua_node(e_column)) + ctxnode(new_latelua_node(e_column)) remove(columns) column = columns[#columns] end @@ -407,7 +499,9 @@ end local function b_region(tag) local last = tobesaved[tag] - last.x, last.y = getpos() + local x, y = getpos() + last.x = x ~= 0 and x or nil + last.y = y ~= 0 and y or nil last.p = texgetcount("realpageno") insert(regions,tag) region = tag @@ -415,11 +509,12 @@ end local function e_region(correct) local last = tobesaved[region] - local v = getvpos() + local y = getvpos() if correct then - last.h = last.y - v + local h = (last.y or 0) - y + last.h = h ~= 0 and h or nil end - last.y = v + last.y = y ~= 0 and y or nil remove(regions) region = regions[#regions] end @@ -427,35 +522,42 @@ end jobpositions.b_region = b_region jobpositions.e_region = e_region -local function setregionbox(n,tag) +local function setregionbox(n,tag,k,lo,ro,to,bo) -- kind if not tag or tag == "" then nofregions = nofregions + 1 tag = f_region(nofregions) end local box = getbox(n) - local w = getfield(box,"width") - local h = getfield(box,"height") - local d = getfield(box,"depth") + local w, h, d = getwhd(box) + local x, y = getpos() -- hm, makes no sense here tobesaved[tag] = { - p = true, -- not enhanced - x = true, -- not enhanced - y = getvpos(), -- true, + -- p = texgetcount("realpageno"), -- we copy them + x = x ~= 0 and x or nil, -- was true + y = y ~= 0 and y or nil, w = w ~= 0 and w or nil, h = h ~= 0 and h or nil, d = d ~= 0 and d or nil, + k = k ~= 0 and k or nil, + lo = lo ~= 0 and lo or nil, + ro = ro ~= 0 and ro or nil, + to = to ~= 0 and to or nil, + bo = bo ~= 0 and bo or nil, } return tag, box end -local function markregionbox(n,tag,correct) -- correct needs checking - local tag, box = setregionbox(n,tag) +local function markregionbox(n,tag,correct,...) -- correct needs checking + local tag, box = setregionbox(n,tag,...) -- todo: check if tostring is needed with formatter - -- local push = new_latelua(f_b_region(tag)) - -- local pop = new_latelua(f_e_region(tostring(correct))) local push = new_latelua(function() b_region(tag) end) - local pop = new_latelua(function() e_region(tostring(correct)) end) + local pop = new_latelua(function() e_region(correct) end) -- maybe we should construct a hbox first (needs experimenting) so that we can avoid some at the tex end local head = getlist(box) + -- no : + -- if getid(box) ~= hlist_code then + -- -- report("mark region box assumes a hlist, fix this for %a",tag) + -- head = nuts.hpack(head) + -- end if head then local tail = find_tail(head) setlink(push,head) @@ -473,30 +575,34 @@ function jobpositions.enhance(name) enhance(tobesaved[name]) end --- scanners.pos = function(name,t) -- name t --- local name = scanstring() --- tobesaved[name] = scanstring() --- context(new_latelua_node(f_enhance(name))) --- end +function jobpositions.gettobesaved(name,tag) + local t = tobesaved[name] + if t and tag then + return t[tag] + else + return t + end +end local nofparagraphs = 0 scanners.parpos = function() -- todo: relate to localpar (so this is an intermediate variant) nofparagraphs = nofparagraphs + 1 texsetcount("global","c_anch_positions_paragraph",nofparagraphs) - local strutbox = getbox("strutbox") + local box = getbox("strutbox") + local w, h, d = getwhd(box) local t = { p = true, c = true, r = true, x = true, y = true, - h = getfield(strutbox,"height"), - d = getfield(strutbox,"depth"), - hs = texget("hsize"), + h = h, + d = d, + hs = texget("hsize"), -- never 0 } - local leftskip = getfield(getskip("leftskip"),"width") - local rightskip = getfield(getskip("rightskip"),"width") + local leftskip = texget("leftskip",false) + local rightskip = texget("rightskip",false) local hangindent = texget("hangindent") local hangafter = texget("hangafter") local parindent = texget("parindent") @@ -521,8 +627,7 @@ scanners.parpos = function() -- todo: relate to localpar (so this is an intermed end local tag = f_p_tag(nofparagraphs) tobesaved[tag] = t - -- context(new_latelua_node(f_enhance(tag))) - context(new_latelua_node(function() enhance(tobesaved[tag]) end)) + ctxnode(new_latelua_node(function() enhance(tobesaved[tag]) end)) end scanners.dosetposition = function() -- name @@ -534,79 +639,107 @@ scanners.dosetposition = function() -- name x = true, y = true, n = nofparagraphs > 0 and nofparagraphs or nil, + r2l = texgetcount("inlinelefttoright") == 1 or nil, } - -- context(new_latelua_node(f_enhance(name))) - context(new_latelua_node(function() enhance(tobesaved[name]) end)) + ctxnode(new_latelua_node(function() enhance(tobesaved[name]) end)) end scanners.dosetpositionwhd = function() -- name w h d extra local name = scanstring() + local w = scandimen() + local h = scandimen() + local d = scandimen() tobesaved[name] = { p = true, c = column, r = true, x = true, y = true, - w = scandimen(), - h = scandimen(), - d = scandimen(), + w = w ~= 0 and w or nil, + h = h ~= 0 and h or nil, + d = d ~= 0 and d or nil, n = nofparagraphs > 0 and nofparagraphs or nil, + r2l = texgetcount("inlinelefttoright") == 1 or nil, } - -- context(new_latelua_node(f_enhance(name))) - context(new_latelua_node(function() enhance(tobesaved[name]) end)) + ctxnode(new_latelua_node(function() enhance(tobesaved[name]) end)) end scanners.dosetpositionbox = function() -- name box local name = scanstring() local box = getbox(scaninteger()) + local w, h, d = getwhd(box) tobesaved[name] = { p = true, c = column, r = true, x = true, y = true, - w = getfield(box,"width"), - h = getfield(box,"height"), - d = getfield(box,"depth"), + w = w ~= 0 and w or nil, + h = h ~= 0 and h or nil, + d = d ~= 0 and d or nil, n = nofparagraphs > 0 and nofparagraphs or nil, + r2l = texgetcount("inlinelefttoright") == 1 or nil, } - -- context(new_latelua_node(f_enhance(name))) - context(new_latelua_node(function() enhance(tobesaved[name]) end)) + ctxnode(new_latelua_node(function() enhance(tobesaved[name]) end)) end scanners.dosetpositionplus = function() -- name w h d extra local name = scanstring() + local w = scandimen() + local h = scandimen() + local d = scandimen() tobesaved[name] = { p = true, c = column, r = true, x = true, y = true, - w = scandimen(), - h = scandimen(), - d = scandimen(), + w = w ~= 0 and w or nil, + h = h ~= 0 and h or nil, + d = d ~= 0 and d or nil, n = nofparagraphs > 0 and nofparagraphs or nil, e = scanstring(), + r2l = texgetcount("inlinelefttoright") == 1 or nil, } - -- context(new_latelua_node(f_enhance(name))) - context(new_latelua_node(function() enhance(tobesaved[name]) end)) + ctxnode(new_latelua_node(function() enhance(tobesaved[name]) end)) end scanners.dosetpositionstrut = function() -- name local name = scanstring() - local strutbox = getbox("strutbox") + local box = getbox("strutbox") + local w, h, d = getwhd(box) + tobesaved[name] = { + p = true, + c = column, + r = true, + x = true, + y = true, + h = h ~= 0 and h or nil, + d = d ~= 0 and d or nil, + n = nofparagraphs > 0 and nofparagraphs or nil, + r2l = texgetcount("inlinelefttoright") == 1 or nil, + } + ctxnode(new_latelua_node(function() enhance(tobesaved[name]) end)) +end + +scanners.dosetpositionstrutkind = function() -- name + local name = scanstring() + local kind = scaninteger() + local box = getbox("strutbox") + local w, h, d = getwhd(box) tobesaved[name] = { + k = kind, p = true, c = column, r = true, x = true, y = true, - h = getfield(strutbox,"height"), - d = getfield(strutbox,"depth"), + h = h ~= 0 and h or nil, + d = d ~= 0 and d or nil, n = nofparagraphs > 0 and nofparagraphs or nil, + r2l = texgetcount("inlinelefttoright") == 1 or nil, } - -- context(new_latelua_node(f_enhance(name))) - context(new_latelua_node(function() enhance(tobesaved[name]) end)) + ctxnode(new_latelua_node(function() enhance(tobesaved[name]) end)) end function jobpositions.getreserved(tag,n) @@ -693,6 +826,13 @@ function jobpositions.depth(id) return jpi and jpi.d end +function jobpositions.whd(id) + local jpi = collected[id] + if jpi then + return jpi.h, jpi.h, jpi.d + end +end + function jobpositions.leftskip(id) local jpi = collected[id] return jpi and jpi.ls @@ -777,6 +917,8 @@ function jobpositions.position(id) end end +local splitter = lpeg.splitat(",") + function jobpositions.extra(id,n,default) -- assume numbers local jpi = collected[id] if jpi then @@ -955,6 +1097,20 @@ scanners.MPxy = function() -- name end end +scanners.MPwhd = function() -- name + local jpi = collected[scanstring()] + if jpi then + local w = jpi.w or 0 + local h = jpi.h or 0 + local d = jpi.d or 0 + if w ~= 0 or h ~= 0 or d ~= 0 then + context("%.5Fpt,%.5Fpt,%.5Fpt",w*pt,h*pt,d*pt) + return + end + end + context('0pt,0pt,0pt') +end + scanners.MPll = function() -- name local jpi = collected[scanstring()] if jpi then @@ -1056,6 +1212,7 @@ scanners.MPr = function() -- name local r = jpi.r if r and r ~= true then context(r) + return end local p = jpi.p if p then @@ -1168,6 +1325,13 @@ scanners.doifposition = function() -- name doif(collected[scanstring()]) end +-- local ctx_iftrue = context.protected.cs.iftrue +-- local ctx_iffalse = context.protected.cs.iffalse +-- +-- scanners.ifknownposition = function() -- name +-- (collected[scanstring()] and ctx_iftrue or ctx_iffalse)() +-- end + scanners.doifelsepositiononpage = function() -- name page -- probably always realpageno local c = collected[scanstring()] local p = scaninteger() @@ -1210,13 +1374,27 @@ scanners.markregionboxcorrected = function() -- box tag markregionbox(scaninteger(),scanstring(),true) end +scanners.markregionboxtaggedkind = function() -- box tag kind + markregionbox(scaninteger(),scanstring(),nil, + scaninteger(),scandimen(),scandimen(),scandimen(),scandimen()) +end + -- statistics (at least for the moment, when testing) +-- statistics.register("positions", function() +-- local total = nofregular + nofusedregions + nofmissingregions +-- if total > 0 then +-- return format("%s collected, %s regulars, %s regions, %s unresolved regions", +-- total, nofregular, nofusedregions, nofmissingregions) +-- else +-- return nil +-- end +-- end) + statistics.register("positions", function() - local total = nofregular + nofusedregions + nofmissingregions + local total = nofregular + nofspecial if total > 0 then - return format("%s collected, %s regulars, %s regions, %s unresolved regions", - total, nofregular, nofusedregions, nofmissingregions) + return format("%s collected, %s regular, %s special",total,nofregular,nofspecial) else return nil end diff --git a/tex/context/base/mkiv/anch-pos.mkiv b/tex/context/base/mkiv/anch-pos.mkiv index 5d9c2fd34..8b33dfce8 100644 --- a/tex/context/base/mkiv/anch-pos.mkiv +++ b/tex/context/base/mkiv/anch-pos.mkiv @@ -36,11 +36,12 @@ \def\dosavepositionwhd #1#2#3#4#5#6#7{\clf_dosavepositionwhd {#1}#2 #3 #4 #5 #6 #7\relax} \def\dosavepositionplus#1#2#3#4#5#6#7#8{\clf_dosavepositionplus{#1}#2 #3 #4 #5 #6 #7{#8}} -\def\dosetposition #1{\clf_dosetposition {#1}} % {} expands -\def\dosetpositionwhd #1#2#3#4{\clf_dosetpositionwhd {#1}#2 #3 #4\relax} -\def\dosetpositionplus#1#2#3#4#5{\clf_dosetpositionplus {#1}#2 #3 #4{#5}} -\def\dosetpositionbox #1#2{\clf_dosetpositionbox {#1}#2\relax} -\def\dosetpositionstrut #1{\clf_dosetpositionstrut{#1}} +\def\dosetposition #1{\clf_dosetposition {#1}} % {} expands +\def\dosetpositionwhd #1#2#3#4{\clf_dosetpositionwhd {#1}#2 #3 #4\relax} +\def\dosetpositionplus#1#2#3#4#5{\clf_dosetpositionplus {#1}#2 #3 #4{#5}} +\def\dosetpositionbox #1#2{\clf_dosetpositionbox {#1}#2\relax} +\def\dosetpositionstrut #1{\clf_dosetpositionstrut {#1}} +\def\dosetpositionstrutkind #1#2{\clf_dosetpositionstrutkind{#1}#2\relax} % #2 = number \newbox\b_anch_position \newif \ifpositioning % sort of public @@ -66,6 +67,7 @@ \def\MPh #1{\clf_MPh {#1}} \def\MPd #1{\clf_MPd {#1}} \def\MPxy #1{\clf_MPxy {#1}} +\def\MPwhd #1{\clf_MPwhd {#1}} \def\MPll #1{\clf_MPll {#1}} \def\MPlr #1{\clf_MPlr {#1}} \def\MPur #1{\clf_MPur {#1}} @@ -204,6 +206,26 @@ \strut \hss}} +\unexpanded\def\setpositionstrutkind + {\iftrialtypesetting + \expandafter\anch_positions_set_strut_kind_nop + \else + \expandafter\anch_positions_set_strut_kind_yes + \fi} + +\def\anch_positions_set_strut_kind_yes#1#2% + {\anch_positions_initialize + \hbox to \zeropoint + {\edef\currentposition{#1}% + \dosetpositionstrutkind\currentposition{#2}% + \anch_positions_trace_left + \dopositionaction\currentposition + \strut + \hss}} + +\def\anch_positions_set_strut_kind_nop#1#2% + {\strut} + \unexpanded\def\setpositiondataplus {\iftrialtypesetting \expandafter\gobblefivearguments @@ -293,6 +315,21 @@ \unexpanded\def\anch_mark_text_box#1% {\clf_markregionboxtagged#1{text:\the\realpageno}} % needs an hbox +\newcount\c_anch_free + +\unexpanded\def\anch_mark_tagged_box_free#1#2#3#4#5#6% only needed when positions + {\ifpositioning + \global\advance\c_anch_free\plusone % could be done at the lua end + \clf_markregionboxtaggedkind + #1% + {free:\number\c_anch_free}% + #2\space % kind + #3\space % leftoffset + #4\space % rightoffset + #5\space % topoffset + #6\relax % bottomoffset + \fi} + %D We can copy a position with: %D %D \starttyping @@ -337,10 +374,12 @@ \let\xypos\setpositiononly -\unexpanded\def\hpos#1{\dontleavehmode\setpositionbox{#1}\hbox} -\unexpanded\def\vpos#1{\setpositionbox{#1}\vbox} -\unexpanded\def\bpos#1{\dontleavehmode \setpositionstrut{b:#1}\ignorespaces} -\unexpanded\def\epos#1{\removeunwantedspaces\setpositionstrut{e:#1}} +\unexpanded\def\hpos #1{\dontleavehmode\setpositionbox{#1}\hbox} +\unexpanded\def\vpos #1{\setpositionbox{#1}\vbox} +\unexpanded\def\bpos #1{\dontleavehmode\setpositionstrut{b:#1}\ignorespaces} +\unexpanded\def\epos #1{\removeunwantedspaces\setpositionstrut{e:#1}} +\unexpanded\def\bposkind#1#2{\dontleavehmode\setpositionstrutkind{b:#1}{#2}\ignorespaces} % not public, used in backgrounds +\unexpanded\def\eposkind#1#2{\removeunwantedspaces\setpositionstrutkind{e:#1}{#2}} % not public, used in backgrounds %D When we want to calculate more complex backgrounds, we need to know what the %D current indentation scheme is. At the cost of many positions and memory, we diff --git a/tex/context/base/mkiv/anch-snc.mkiv b/tex/context/base/mkiv/anch-snc.mkiv index d0d3a58d1..3e99da8a6 100644 --- a/tex/context/base/mkiv/anch-snc.mkiv +++ b/tex/context/base/mkiv/anch-snc.mkiv @@ -168,7 +168,6 @@ \definesyncpositions[1] \startuseMPgraphic{sync} - if unknown context_abck : input mp-abck.mpiv ; fi ; StartPage ; \getsyncpositions{1} ; SyncThreshold := 2LineHeight ; diff --git a/tex/context/base/mkiv/anch-tab.mkiv b/tex/context/base/mkiv/anch-tab.mkiv index 7e0116cbf..afa87c7b2 100644 --- a/tex/context/base/mkiv/anch-tab.mkiv +++ b/tex/context/base/mkiv/anch-tab.mkiv @@ -23,22 +23,26 @@ \unexpanded\def\tabl_tabulate_hook_b {\iftrialtypesetting\else \ifpositioning +\ifconditional\tablehaspositions \ifcase\c_tabl_tabulate_noflines % \ifnum\c_tabl_tabulate_noflines=\c_tabl_tabulate_totalnoflines \tabl_tabulate_hook_b_first \else \tabl_tabulate_hook_b_next \fi +\fi \fi \fi} \unexpanded\def\tabl_tabulate_hook_e {\iftrialtypesetting\else \ifpositioning +\ifconditional\tablehaspositions \ifcase\c_tabl_tabulate_noflines % \ifnum\c_tabl_tabulate_noflines=\c_tabl_tabulate_totalnoflines \tabl_tabulate_hook_e_first \else \tabl_tabulate_hook_e_next \fi +\fi \fi \fi} @@ -60,6 +64,12 @@ \global\advance\c_anch_tabs\plusone \to \everytabulate +% for text backgrounds + +\appendtoks + \settrue\c_anch_backgrounds_pos_no_shape +\to \everytabulate + %D Beware, the following code is somewhat weird and experimental and might be %D dropped or become a loadable module. @@ -98,7 +108,7 @@ \firstargumentfalse \fi} -\def\anch_tables_XC [#1]{\anch_table_check_state\iffirstargument\anch_tables_indeed_XC [#1]\else\expandafter\fi\NC} +\def\anch_tables_XC [#1]{\anch_table_check_state\iffirstargument\anch_tables_indeed_XC [#1]\else\expandafter\NC\fi} \def\anch_tables_GSC[#1]{\anch_table_check_state\iffirstargument\anch_tables_indeed_GSC[#1]\else\expandafter\NC\fi} \def\anch_tables_GFC[#1]{\anch_table_check_state\iffirstargument\anch_tables_indeed_GFC[#1]\else\expandafter\NC\fi} \def\anch_tables_GTC[#1]{\anch_table_check_state\iffirstargument\anch_tables_indeed_GTC[#1]\else\expandafter\NC\fi} diff --git a/tex/context/base/mkiv/attr-col.lua b/tex/context/base/mkiv/attr-col.lua index 6b11333a7..c3b644bda 100644 --- a/tex/context/base/mkiv/attr-col.lua +++ b/tex/context/base/mkiv/attr-col.lua @@ -12,10 +12,9 @@ if not modules then modules = { } end modules ['attr-col'] = { -- list could as well refer to the tables (instead of numbers that -- index into another table) .. depends on what we need -local type = type -local format = string.format +local type, tonumber = type, tonumber local concat = table.concat -local min, max, floor = math.min, math.max, math.floor +local min, max, floor, mod = math.min, math.max, math.floor, math.mod local attributes = attributes local nodes = nodes @@ -26,6 +25,14 @@ local storage = storage local context = context local tex = tex +local variables = interfaces.variables +local v_yes = variables.yes +local v_no = variables.no + +local p_split_comma = lpeg.tsplitat(",") +local p_split_colon = lpeg.splitat(":") +local lpegmatch = lpeg.match + local allocate = utilities.storage.allocate local setmetatableindex = table.setmetatableindex @@ -40,11 +47,13 @@ local report_transparencies = logs.reporter("transparencies","support") -- nb. too many "0 g"s local states = attributes.states -local tasks = nodes.tasks local nodeinjections = backends.nodeinjections local registrations = backends.registrations local unsetvalue = attributes.unsetvalue +local enableaction = nodes.tasks.enableaction +local setaction = nodes.tasks.setaction + local registerstorage = storage.register local formatters = string.formatters @@ -145,10 +154,14 @@ end local function rgbtogray(r,g,b) if not r then return 0 - elseif colors.weightgray then + end + local w = colors.weightgray + if w == true then return .30*r + .59*g + .11*b - else + elseif not w then return r/3 + g/3 + b/3 + else + return w[1]*r + w[2]*g + w[3]*b end end @@ -156,27 +169,34 @@ local function cmyktogray(c,m,y,k) return rgbtogray(cmyktorgb(c,m,y,k)) end --- not critical so not needed: --- --- local function cmyktogray(c,m,y,k) --- local r, g, b = 1.0 - min(1.0,c+k), 1.0 - min(1.0,m+k), 1.0 - min(1.0,y+k) --- if colors.weightgray then --- return .30*r + .59*g + .11*b --- else --- return r/3 + g/3 + b/3 --- end --- end - -- http://en.wikipedia.org/wiki/HSI_color_space -- http://nl.wikipedia.org/wiki/HSV_(kleurruimte) +-- h /= 60; // sector 0 to 5 +-- i = floor( h ); +-- f = h - i; // factorial part of h + local function hsvtorgb(h,s,v) - -- h = h % 360 - local hd = h/60 - local hf = floor(hd) - local hi = hf % 6 - -- local f = hd - hi - local f = hd - hf + if s > 1 then + s = 1 + elseif s < 0 then + s = 0 + elseif s == 0 then + return v, v, v + end + if v > 1 then + s = 1 + elseif v < 0 then + v = 0 + end + if h < 0 then + h = 0 + elseif h >= 360 then + h = mod(h,360) + end + local hd = h / 60 + local hi = floor(hd) + local f = hd - hi local p = v * (1 - s) local q = v * (1 - f * s) local t = v * (1 - (1 - f) * s) @@ -193,7 +213,8 @@ local function hsvtorgb(h,s,v) elseif hi == 5 then return v, p, q else - print("error in hsv -> rgb",hi,h,s,v) + print("error in hsv -> rgb",h,s,v) + return 0, 0, 0 end end @@ -264,9 +285,6 @@ end --~ return { 5, .5, .5, .5, .5, 0, 0, 0, .5, parent, f, d, p } --~ end -local p_split = lpeg.tsplitat(",") -local lpegmatch = lpeg.match - function colors.spot(parent,f,d,p) -- inspect(parent) inspect(f) inspect(d) inspect(p) if type(p) == "number" then @@ -283,8 +301,8 @@ function colors.spot(parent,f,d,p) end else -- todo, multitone (maybe p should be a table) - local ps = lpegmatch(p_split,p) - local ds = lpegmatch(p_split,d) + local ps = lpegmatch(p_split_comma,p) + local ds = lpegmatch(p_split_comma,d) local c, m, y, k = 0, 0, 0, 0 local done = false for i=1,#ps do @@ -364,10 +382,31 @@ function colors.filter(n) return concat(data[n],":",5) end +-- unweighted (flat) gray could be another model but a bit work as we need to check: +-- +-- attr-col colo-ini colo-run +-- grph-inc grph-wnd +-- lpdf-col lpdf-fmt lpdf-fld lpdf-grp +-- meta-pdf meta-pdh mlib-pps +-- +-- but as we never needed it we happily delay that. + function colors.setmodel(name,weightgray) - colors.model = name - colors.default = models[name] or 1 - colors.weightgray = weightgray ~= false + if weightgray == true or weightgray == v_yes then + weightgray = true + elseif weightgray == false or weightgray == v_no then + weightgray = false + else + local r, g, b = lpegmatch(p_split_colon,weightgray) + if r and g and b then + weightgray = { r, g, b } + else + weightgray = true + end + end + colors.model = name -- global, not useful that way + colors.default = models[name] or 1 -- global + colors.weightgray = weightgray -- global return colors.default end @@ -400,11 +439,7 @@ attributes.colors.handler = nodes.installattributehandler { } function colors.enable(value) - if value == false or not colors.supported then - tasks.disableaction("shipouts","attributes.colors.handler") - else - tasks.enableaction("shipouts","attributes.colors.handler") - end + setaction("shipouts","attributes.colors.handler",not (value == false or not colors.supported)) end function colors.forcesupport(value) -- can move to attr-div @@ -492,8 +527,8 @@ local function reviver(data,n) end end -setmetatableindex(transparencies, extender) -setmetatableindex(transparencies.data, reviver) -- register if used +setmetatableindex(transparencies,extender) +setmetatableindex(transparencies.data,reviver) -- register if used -- check if there is an identity @@ -510,11 +545,7 @@ attributes.transparencies.handler = nodes.installattributehandler { } function transparencies.enable(value) -- nil is enable - if value == false or not transparencies.supported then - tasks.disableaction("shipouts","attributes.transparencies.handler") - else - tasks.enableaction("shipouts","attributes.transparencies.handler") - end + setaction("shipouts","attributes.transparencies.handler",not (value == false or not transparencies.supported)) end function transparencies.forcesupport(value) -- can move to attr-div @@ -573,7 +604,7 @@ colorintents.handler = nodes.installattributehandler { } function colorintents.enable() - tasks.enableaction("shipouts","attributes.colorintents.handler") + enableaction("shipouts","attributes.colorintents.handler") end -- interface diff --git a/tex/context/base/mkiv/attr-eff.lua b/tex/context/base/mkiv/attr-eff.lua index ff41e12de..d04408fb9 100644 --- a/tex/context/base/mkiv/attr-eff.lua +++ b/tex/context/base/mkiv/attr-eff.lua @@ -10,7 +10,7 @@ local attributes, nodes, backends, utilities = attributes, nodes, backends, util local tex = tex local states = attributes.states -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction local nodeinjections = backends.nodeinjections local texsetattribute = tex.setattribute local allocate = utilities.storage.allocate @@ -97,7 +97,7 @@ local enabled = false local function enable() if not enabled then - tasks.enableaction("shipouts","attributes.effects.handler") + enableaction("shipouts","attributes.effects.handler") enabled = true end end diff --git a/tex/context/base/mkiv/attr-ini.lua b/tex/context/base/mkiv/attr-ini.lua index df7404d11..2a11558a5 100644 --- a/tex/context/base/mkiv/attr-ini.lua +++ b/tex/context/base/mkiv/attr-ini.lua @@ -25,7 +25,6 @@ local attributes = attributes local sharedstorage = storage.shared -local texgetcount = tex.getcount local texsetattribute = tex.setattribute attributes.names = attributes.names or { } @@ -131,7 +130,7 @@ function attributes.ofnode(n) showlist(n,n.attr) end --- rather special +-- rather special (can be optimized) local store = { } diff --git a/tex/context/base/mkiv/attr-ini.mkiv b/tex/context/base/mkiv/attr-ini.mkiv index 3f0b7fb27..77959c988 100644 --- a/tex/context/base/mkiv/attr-ini.mkiv +++ b/tex/context/base/mkiv/attr-ini.mkiv @@ -38,7 +38,9 @@ \expandafter\newcount\csname\??attributestack\string#1\endcsname \fi} -\newtoks \attributesresetlist +\newtoks \t_attr_list_global +\newtoks \t_attr_list_local +\newtoks \t_attr_list_nomath \ifdefined \s!global \else \def\s!global {global} \fi % for metatex % or hard check later \ifdefined \s!public \else \def\s!public {public} \fi % for metatex % or hard check later @@ -59,9 +61,14 @@ \expandafter\newconstant \csname\??attributeid#2\endcsname \csname\??attributeid#2\endcsname\scratchcounter % some attributes are always global - \doifnotinset\s!global{#3}{\appendetoks\csname\??attributecount#2\endcsname\attributeunsetvalue\to\attributesresetlist}% + \doifelseinset\s!global{#3}% + {\appendetoks\csname\??attributecount#2\endcsname\attributeunsetvalue\to\t_attr_list_global}% + {\appendetoks\csname\??attributecount#2\endcsname\attributeunsetvalue\to\t_attr_list_local }% + \doifinset\s!nomath{#3}% + {\appendetoks\csname\??attributecount#2\endcsname\attributeunsetvalue\to\t_attr_list_nomath}% % here public means 'visible' so it's not to be confused with 'public' at the lua end - \doifinset \s!public{#3}{\expandafter\let\csname#2\s!attribute\expandafter\endcsname\csname\??attributeid#2\endcsname}% + \doifinset\s!public{#3}% + {\expandafter\let\csname#2\s!attribute\expandafter\endcsname\csname\??attributeid#2\endcsname}% \fi} \unexpanded\def\newattribute#1% @@ -77,30 +84,37 @@ \let\dompattribute\gobbletwoarguments -\unexpanded\def\resetallattributes{\the\attributesresetlist} +\unexpanded\def\resetglobalattributes{\the\t_attr_list_global} +\unexpanded\def\resetlocalattributes {\the\t_attr_list_local } + +\let\resetallattributes\resetlocalattributes %D Rather special. \unexpanded\def\savecurrentattributes #1{\clf_savecurrentattributes {#1}} \unexpanded\def\restorecurrentattributes#1{\clf_restorecurrentattributes{#1}} -%D For the moment we put this here (later it will move to where it's used): +%D For the moment we put this here. The order of definition matters a bit because +%D performance is better when we put frequently accessed attributes at the front. +%D So, we might move more here. -\definesystemattribute [state] -\definesystemattribute [color] [public] % global +\definesystemattribute [state] % nomath +\definesystemattribute [color] [public] % global \definesystemattribute [colormodel] [public,global] -\definesystemattribute [skip] -\definesystemattribute [penalty] +% \definesystemattribute [skip] +% \definesystemattribute [penalty] \definesystemattribute [transparency] [public] +\definesystemattribute [reference] [public] +\definesystemattribute [destination] [public] +\definesystemattribute [case] [public] +\definesystemattribute [visual] [public,global] +\definesystemattribute [viewerlayer] [public] \definesystemattribute [background] [public] \definesystemattribute [alignbackground] [public] \definesystemattribute [colorintent] [public] \definesystemattribute [negative] [public] \definesystemattribute [effect] [public] -\definesystemattribute [viewerlayer] [public] \definesystemattribute [layoutcomponent] [public] -\definesystemattribute [reference] [public] -\definesystemattribute [destination] [public] \definesystemattribute [internal] [public] \definesystemattribute [ruled] [public] \definesystemattribute [shifted] [public] diff --git a/tex/context/base/mkiv/attr-lay.lua b/tex/context/base/mkiv/attr-lay.lua index 0d43979c8..ff9d1c38f 100644 --- a/tex/context/base/mkiv/attr-lay.lua +++ b/tex/context/base/mkiv/attr-lay.lua @@ -62,7 +62,8 @@ viewerlayers.supported = true viewerlayers.hasorder = true local states = attributes.states -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction +local disableaction = nodes.tasks.disableaction local nodeinjections = backends.nodeinjections local codeinjections = backends.codeinjections @@ -71,8 +72,6 @@ local texgetattribute = tex.getattribute local texsettokenlist = tex.settoks local unsetvalue = attributes.unsetvalue -local nodepool = nodes.pool - local data = viewerlayers.data local values = viewerlayers.values local listwise = viewerlayers.listwise @@ -148,12 +147,12 @@ local stack, enabled, global = { }, false, false function viewerlayers.enable(value) if value == false or not viewerlayers.supported then if enabled then - tasks.disableaction("shipouts","attributes.viewerlayers.handler") + disableaction("shipouts","attributes.viewerlayers.handler") end enabled = false else if not enabled then - tasks.enableaction("shipouts","attributes.viewerlayers.handler") + enableaction("shipouts","attributes.viewerlayers.handler") end enabled = true end diff --git a/tex/context/base/mkiv/attr-neg.lua b/tex/context/base/mkiv/attr-neg.lua index 1347c3d1a..c20df1d16 100644 --- a/tex/context/base/mkiv/attr-neg.lua +++ b/tex/context/base/mkiv/attr-neg.lua @@ -16,7 +16,7 @@ local commands, context, interfaces = commands, context, interfaces local tex = tex local states = attributes.states -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction local nodeinjections = backends.nodeinjections local texsetattribute = tex.setattribute local variables = interfaces.variables @@ -79,7 +79,7 @@ local function register(stamp) end local function enable() - tasks.enableaction("shipouts","attributes.negatives.handler") + enableaction("shipouts","attributes.negatives.handler") end negatives.register = register diff --git a/tex/context/base/mkiv/back-exp.lua b/tex/context/base/mkiv/back-exp.lua index 681996d48..da7ec202f 100644 --- a/tex/context/base/mkiv/back-exp.lua +++ b/tex/context/base/mkiv/back-exp.lua @@ -38,7 +38,7 @@ local sub, gsub = string.sub, string.gsub local validstring = string.valid local lpegmatch = lpeg.match local utfchar, utfvalues = utf.char, utf.values -local concat, insert, remove, merge = table.concat, table.insert, table.remove, table.merge +local concat, insert, remove, merge, sort = table.concat, table.insert, table.remove, table.merge, table.sort local sortedhash = table.sortedhash local formatters = string.formatters local todimen = number.todimen @@ -71,6 +71,8 @@ local v_hidden = variables.hidden local implement = interfaces.implement +local included = backends.included + local settings_to_array = utilities.parsers.settings_to_array local setmetatableindex = table.setmetatableindex @@ -89,7 +91,6 @@ local glyph_code = nodecodes.glyph local glue_code = nodecodes.glue local kern_code = nodecodes.kern local disc_code = nodecodes.disc -local insert_code = nodecodes.insert local userskip_code = skipcodes.userskip local rightskip_code = skipcodes.rightskip @@ -117,12 +118,16 @@ local getnext = nuts.getnext local getsubtype = nuts.getsubtype local getfont = nuts.getfont local getdisc = nuts.getdisc +local getcomponents = nuts.getcomponents local getlist = nuts.getlist local getid = nuts.getid local getfield = nuts.getfield local getattr = nuts.getattr -local setattr = nuts.setattr +local setattr = nuts.setattr -- maybe use properties local isglyph = nuts.isglyph +local getkern = nuts.getkern +local getwidth = nuts.getwidth + local traverse_id = nuts.traverse_id local traverse_nodes = nuts.traverse @@ -543,27 +548,6 @@ local function makebreaknode(attributes) -- maybe no fulltag } end -local function ignorebreaks(di,element,n,fulltag) - local data = di.data - for i=1,#data do - local d = data[i] - if d.content == " " then - d.content = "" - end - end -end - -local function ignorespaces(di,element,n,fulltag) - local data = di.data - for i=1,#data do - local d = data[i] - local c = d.content - if type(c) == "string" then - d.content = lpegmatch(p_stripper,c) - end - end -end - do local fields = { "title", "subtitle", "author", "keywords" } @@ -605,7 +589,9 @@ do setattribute(di,"language",languagenames[texgetcount("mainlanguagenumber")]) if not less_state then setattribute(di,"file",tex.jobname) - setattribute(di,"date",os.date()) + if included.date then + setattribute(di,"date",backends.timestamp()) + end setattribute(di,"context",environment.version) setattribute(di,"version",exportversion) setattribute(di,"xmlns:m",mathmlns) @@ -772,7 +758,7 @@ do function finalizers.descriptions(tree) local n = 0 - for id, tag in next, descriptions do + for id, tag in sortedhash(descriptions) do local sym = symbols[id] if sym then n = n + 1 @@ -1716,6 +1702,27 @@ do end end + local function ignorebreaks(di,element,n,fulltag) + local data = di.data + for i=1,#data do + local d = data[i] + if d.content == " " then + d.content = "" + end + end + end + + local function ignorespaces(di,element,n,fulltag) + local data = di.data + for i=1,#data do + local d = data[i] + local c = d.content + if type(c) == "string" then + d.content = lpegmatch(p_stripper,c) + end + end + end + extras.registerpages = ignorebreaks extras.registerseparator = ignorespaces @@ -1859,16 +1866,26 @@ do local f_metadata = formatters["%w<metavariable name=%q>%s</metavariable>\n"] local f_metadata_end = formatters["%w</metadata>\n"] - --- we could share the r tables ... but it's fast enough anyway - local function attributes(a) - local r = { } -- can be shared + local r = { } local n = 0 for k, v in next, a do n = n + 1 r[n] = f_attribute(k,v) -- lpegmatch(p_escaped,v) end - return concat(r,"",1,n) + sort(r) + return concat(r,"") + end + + local function properties(a) + local r = { } + local n = 0 + for k, v in next, a do + n = n + 1 + r[n] = f_property(exportproperties,k,v) + end + sort(r) + return concat(r,"") end local depth = 0 @@ -1960,23 +1977,15 @@ do if not p then -- skip elseif exportproperties == v_yes then - for k, v in next, p do - n = n + 1 - r[n] = f_attribute(k,v) - end + r[n] = attributes(p) else - for k, v in next, p do - n = n + 1 - r[n] = f_property(exportproperties,k,v) - end + r[n] = properties(p) end end local a = di.attributes if a then - for k, v in next, a do - n = n + 1 - r[n] = f_attribute(k,v) - end + n = n + 1 + r[n] = attributes(a) end if n == 0 then if nature == "inline" or inline > 0 then @@ -2228,7 +2237,7 @@ do for i=2,#trees do local currenttree = trees[i] local currentdata = currenttree.data - local currentpar = currenttree.parnumber + local currentpar = currenttree.parnumber local previouspar = trees[i-1].parnumber currenttree.collapsed = true -- is the next ok? @@ -2544,7 +2553,7 @@ local function collectresults(head,list,pat,pap) -- is last used (we also have c -- report_export("skipping character: %C (no attribute)",n.char) else -- we could add tonunicodes for ligatures (todo) - local components = getfield(n,"components") + local components = getcomponents(n) if components and (not characterdata[c] or overloads[c]) then -- we loose data collectresults(components,nil,at) -- this assumes that components have the same attribute as the glyph ... we should be more tolerant (see math) else @@ -2694,7 +2703,7 @@ local function collectresults(head,list,pat,pap) -- is last used (we also have c else local subtype = getsubtype(n) if subtype == userskip_code then - if getfield(n,"width") > threshold then + if getwidth(n) > threshold then if last and not somespace[currentcontent[nofcurrentcontent]] then local a = getattr(n,a_tagged) or pat if a == last then @@ -2802,7 +2811,7 @@ local function collectresults(head,list,pat,pap) -- is last used (we also have c end end elseif id == kern_code then - local kern = getfield(n,"kern") + local kern = getkern(n) if kern > 0 then local limit = threshold if p and getid(p) == glyph_code then @@ -2906,7 +2915,7 @@ local xmlpreamble = [[ return replacetemplate(xmlpreamble, { standalone = standalone and "yes" or "no", filename = tex.jobname, - date = os.date(), + date = included.date and backends.timestamp(), contextversion = environment.version, exportversion = exportversion, }) @@ -3157,40 +3166,50 @@ local htmltemplate = [[ end) local function makeclass(tg,at) - local detail = at.detail - local chain = at.chain - local result - at.detail = nil - at.chain = nil + local detail = at.detail + local chain = at.chain + local extra = nil + local classes = { } + local nofclasses = 0 + at.detail = nil + at.chain = nil + for k, v in next, at do + if not private[k] then + nofclasses = nofclasses + 1 + classes[nofclasses] = k .. "-" .. v + end + end if detail and detail ~= "" then if chain and chain ~= "" then if chain ~= detail then - result = { classes[tg .. " " .. chain .. " " .. detail] } -- we need to remove duplicates + extra = classes[tg .. " " .. chain .. " " .. detail] elseif tg ~= detail then - result = { tg, detail } - else - result = { tg } + extra = detail end elseif tg ~= detail then - result = { tg, detail } - else - result = { tg } + extra = detail end elseif chain and chain ~= "" then if tg ~= chain then - result = { tg, chain } + extra = chain + end + end + -- in this order + if nofclasses > 0 then + sort(classes) + classes = concat(classes," ") + if extra then + return tg .. " " .. extra .. " " .. classes else - result = { tg } + return tg .. " " .. classes end else - result = { tg } - end - for k, v in next, at do - if not private[k] then - result[#result+1] = k .. "-" .. v + if extra then + return tg .. " " .. extra + else + return tg end end - return concat(result, " ") end local function remap(specification,source,target) @@ -3315,7 +3334,6 @@ local htmltemplate = [[ -- ./jobname-export/styles/jobname-templates.css local basename = file.basename(v) - local corename = file.removesuffix(basename) local basepath = basename .. "-export" local imagepath = joinfile(basepath,"images") local stylepath = joinfile(basepath,"styles") diff --git a/tex/context/base/mkiv/back-ini.lua b/tex/context/base/mkiv/back-ini.lua index e8af4d9d9..fd33d5ddc 100644 --- a/tex/context/base/mkiv/back-ini.lua +++ b/tex/context/base/mkiv/back-ini.lua @@ -16,15 +16,15 @@ if not modules then modules = { } end modules ['back-ini'] = { local next, type = next, type local format = string.format -backends = backends or { } -local backends = backends +backends = backends or { } +local backends = backends -local trace_backend = false trackers.register("backend.initializers", function(v) trace_finalizers = v end) - -local report_backend = logs.reporter("backend","initializing") +local trace_backend = false trackers.register("backend.initializers", function(v) trace_finalizers = v end) +local report_backend = logs.reporter("backend","initializing") local allocate = utilities.storage.allocate local setmetatableindex = table.setmetatableindex +local setaction = nodes.tasks.setaction local function nothing() return nil end @@ -117,6 +117,25 @@ interfaces.implement { name = "setrealspaces", arguments = "string", actions = function(v) - nodes.tasks.setaction("shipouts","nodes.handlers.accessibility",v == interfaces.variables.yes) + setaction("shipouts","nodes.handlers.accessibility",v == interfaces.variables.yes) end } + +-- moved to here + +local included = table.setmetatableindex( { + context = true, + id = true, + metadata = true, + date = true, + id = true, + pdf = true, +}, function(t,k) + return true +end) + +backends.included = included + +function backends.timestamp() + return os.date("%Y-%m-%dT%X") .. os.timezone(true) +end diff --git a/tex/context/base/mkiv/back-pdf.lua b/tex/context/base/mkiv/back-pdf.lua index 323f1d57f..a3f7ffff7 100644 --- a/tex/context/base/mkiv/back-pdf.lua +++ b/tex/context/base/mkiv/back-pdf.lua @@ -17,10 +17,11 @@ local codeinjections = backends.pdf.codeinjections local context = context local scanners = tokens.scanners -local scanstring = scanners.string local scannumber = scanners.number -local scaninteger = scanners.integer local scankeyword = scanners.keyword +local scandimen = scanners.dimen +local scancount = scanners.count +local scanstring = scanners.string local scanners = interfaces.scanners local implement = interfaces.implement @@ -180,3 +181,136 @@ implement { pdf.setobjcompresslevel(o) end } + +local report = logs.reporter("backend","pdftex primitives") +local trace = false + +scanners.pdfannot = function() + if scankeyword("reserveobjectnum") then + report("\\pdfannot reserveobjectnum is not (yet) supported") + -- if trace then + -- report() + -- report("\\pdfannot: reserved number (not supported yet)") + -- report() + -- end + else + local width = false + local height = false + local depth = false + local data = false + local object = false + local attr = false + -- + if scankeyword("useobjnum") then + object = scancount() + report("\\pdfannot useobjectnum is not (yet) supported") + end + while true do + if scankeyword("width") then + width = scandimen() + elseif scankeyword("height") then + height = scandimen() + elseif scankeyword("depth") then + depth = scandimen() + else + break + end + end + if scankeyword("attr") then + attr = scanstring() + end + data = scanstring() + -- + -- less strict variant: + -- + -- while true do + -- if scankeyword("width") then + -- width = scandimen() + -- elseif scankeyword("height") then + -- height = scandimen() + -- elseif scankeyword("depth") then + -- depth = scandimen() + -- elseif scankeyword("useobjnum") then + -- object = scancount() + -- elseif scankeyword("attr") then + -- attr = scanstring() + -- else + -- data = scanstring() + -- break + -- end + -- end + -- + -- if trace then + -- report() + -- report("\\pdfannot:") + -- report() + -- report(" object: %s",object or "<unset> (not supported yet)") + -- report(" width : %p",width or "<unset>") + -- report(" height: %p",height or "<unset>") + -- report(" depth : %p",depth or "<unset>") + -- report(" attr : %s",attr or "<unset>") + -- report(" data : %s",data or "<unset>") + -- report() + -- end + context(backends.nodeinjections.annotation(width or 0,height or 0,depth or 0,data or "")) + end +end + +scanners.pdfdest = function() + local name = false + local zoom = false + local view = false + local width = false + local height = false + local depth = false + if scankeyword("num") then + report("\\pdfdest num is not (yet) supported") + elseif scankeyword("name") then + name = scanstring() + end + if scankeyword("xyz") then + view = "xyz" + if scankeyword("zoom") then + report("\\pdfdest zoom is ignored") + zoom = scancount() + end + elseif scankeyword("fitbh") then + view = "fitbh" + elseif scankeyword("fitbv") then + view = "fitbv" + elseif scankeyword("fitb") then + view = "fitb" + elseif scankeyword("fith") then + view = "fith" + elseif scankeyword("fitv") then + view = "fitv" + elseif scankeyword("fitr") then + view = "fitr" + while true do + if scankeyword("width") then + width = scandimen() + elseif scankeyword("height") then + height = scandimen() + elseif scankeyword("depth") then + depth = scandimen() + else + break + end + end + elseif scankeyword("fit") then + view = "fit" + end + -- if trace then + -- report() + -- report("\\pdfdest:") + -- report() + -- report(" name : %s",name or "<unset>") + -- report(" view : %s",view or "<unset>") + -- report(" zoom : %s",zoom or "<unset> (not supported)") + -- report(" width : %p",width or "<unset>") + -- report(" height: %p",height or "<unset>") + -- report(" depth : %p",depth or "<unset>") + -- report() + -- end + context(backends.nodeinjections.destination(width or 0,height or 0,depth or 0,{ name or "" },view or "fit")) +end diff --git a/tex/context/base/mkiv/back-pdf.mkiv b/tex/context/base/mkiv/back-pdf.mkiv index 3e055ea83..f59b59c29 100644 --- a/tex/context/base/mkiv/back-pdf.mkiv +++ b/tex/context/base/mkiv/back-pdf.mkiv @@ -52,31 +52,37 @@ %D These are no-ops and don't even intercept what comes next. Maybe some day %D I'll write a parser that maps onto \CONTEXT. -\let\pdfcolorstack \relax -\let\pdfcolorstackinit \relax -\let\pdfannot \relax -\let\pdfstartlink \relax -\let\pdfendlink \relax -\let\pdfoutline \relax -\let\pdfdest \relax -\let\pdfthread \relax -\let\pdfstartthread \relax -\let\pdfendthread \relax -\let\pdffontattr \relax -\let\pdfglyphtounicode \relax +\unexpanded\def\unsupportedpdfprimitive#1% + {\writestatus{error}{the primitive \string#1\space is not supported}} + +\unexpanded\def\pdfcolorstack {\unsupportedpdfprimitive\pdfcolorstack} +\unexpanded\def\pdfcolorstackinit{\unsupportedpdfprimitive\pdfcolorstackinit} +%unexpanded\def\pdfannot {\unsupportedpdfprimitive\pdfannot} +\unexpanded\def\pdfstartlink {\unsupportedpdfprimitive\pdfstartlink} +\unexpanded\def\pdfendlink {\unsupportedpdfprimitive\pdfendlink} +\unexpanded\def\pdfoutline {\unsupportedpdfprimitive\pdfoutline} +%unexpanded\def\pdfdest {\unsupportedpdfprimitive\pdfdest} +\unexpanded\def\pdfthread {\unsupportedpdfprimitive\pdfthread} +\unexpanded\def\pdfstartthread {\unsupportedpdfprimitive\pdfstartthread} +\unexpanded\def\pdfendthread {\unsupportedpdfprimitive\pdfendthread} +\unexpanded\def\pdffontattr {\unsupportedpdfprimitive\pdffontattr} +\unexpanded\def\pdfglyphtounicode{\unsupportedpdfprimitive\pdfglyphtounicode} + +\unexpanded\def\pdfannot{\clf_pdfannot} +\unexpanded\def\pdfdest {\clf_pdfdest} %D Here we do intercept (silently) what gets passed. One should use the %D \CONTEXT\ interfaces instead. -\let\pdfcatalog \relax \newtoks \pdfcatalog -\let\pdfinfo \relax \newtoks \pdfinfo -\let\pdfnames \relax \newtoks \pdfnames -\let\pdftrailer \relax \newtoks \pdftrailer -\let\pdfpageresources \relax \newtoks \pdfpageresources -\let\pdfpageattr \relax \newtoks \pdfpageattr -\let\pdfpagesattr \relax \newtoks \pdfpagesattr -\let\pdfxformattr \relax \newtoks \pdfxformattr -\let\pdfxformresources \relax \newtoks \pdfxformresources +\let\pdfcatalog \relax \newtoks\pdfcatalog +\let\pdfinfo \relax \newtoks\pdfinfo +\let\pdfnames \relax \newtoks\pdfnames +\let\pdftrailer \relax \newtoks\pdftrailer +\let\pdfpageresources \relax \newtoks\pdfpageresources +\let\pdfpageattr \relax \newtoks\pdfpageattr +\let\pdfpagesattr \relax \newtoks\pdfpagesattr +\let\pdfxformattr \relax \newtoks\pdfxformattr +\let\pdfxformresources\relax \newtoks\pdfxformresources %D We use the \LUA\ interface (which then permits more control over %D possible pdf/x extensions). @@ -86,9 +92,9 @@ %D But we still provide: -\unexpanded\def\nopdfcompression {\clf_setpdfcompression\zerocount\zerocount} -\unexpanded\def\maximumpdfcompression{\clf_setpdfcompression\plusnine \plusnine } -\unexpanded\def\normalpdfcompression {\clf_setpdfcompression\plusthree\plusthree} +\unexpanded\def\nopdfcompression {\clf_setpdfcompression\zerocount\zerocount} +\unexpanded\def\maximumpdfcompression {\clf_setpdfcompression\plusnine \plusnine } +\unexpanded\def\normalpdfcompression {\clf_setpdfcompression\plusthree\plusthree} %D These might even become no-ops as we don't need them in \CONTEXT: @@ -296,7 +302,8 @@ % clipping \unexpanded\def\dostartclipping#1#2#3% we can move this to lua and only set a box here - {\PointsToBigPoints{#2}\width + {\forcecolorhack + \PointsToBigPoints{#2}\width \PointsToBigPoints{#3}\height \meta_grab_clip_path{#1}\width\height{% 0 0 m % @@ -587,3 +594,14 @@ % \stoptext \protect \endinput + +% \chapter{FIRST} +% +% \goto{bar}[bar] +% +% HERE \pdfannot width 20pt height 20pt depth 20pt {/Subtype /Link /Dest (bar) /Border [1 1 1] /F 4}\par +% HERE \pdfannot width 20pt height 20pt depth 20pt {/Subtype /Link /Dest (foo) /Border [1 1 1] /F 4}\par +% +% \chapter[bar]{SECOND} +% +% THERE \pdfdest name {foo} \par diff --git a/tex/context/base/mkiv/bibl-bib.mkiv b/tex/context/base/mkiv/bibl-bib.mkiv index 80d04099b..f5d911ea7 100644 --- a/tex/context/base/mkiv/bibl-bib.mkiv +++ b/tex/context/base/mkiv/bibl-bib.mkiv @@ -140,7 +140,7 @@ \def\doregisterbibtexfile [#1][#2]{\ctxcommand{registerbibtexfile("#1","#2")}} \def\doregisterbibtexentry [#1][#2]{\ctxcommand{registerbibtexentry("#1","#2")}} -\def\doapplytobibtexsession[#1][#2]{\xmlprocessregistered{bibtex:#1}{#2}{#2}} +\def\doapplytobibtexsession[#1][#2]{\xmlprocess{bibtex:#1}{#2}{#2}} \unexpanded\def\bibtexcommand#1% {\ifcsname\??pb:c:#1\endcsname \else diff --git a/tex/context/base/mkiv/bibl-tra.lua b/tex/context/base/mkiv/bibl-tra.lua index 223554b4d..76171cb7f 100644 --- a/tex/context/base/mkiv/bibl-tra.lua +++ b/tex/context/base/mkiv/bibl-tra.lua @@ -21,7 +21,9 @@ end -- end of hack -local match, gmatch, format, concat, sort = string.match, string.gmatch, string.format, table.concat, table.sort +local gmatch, format = string.gmatch, string.format +local sort = table.sort +local savedata = io.savedata bibtex = bibtex or { } local bibtex = bibtex @@ -61,10 +63,31 @@ local template = [[ \bibdata{%s} ]] -local bibtexbin = environment.arguments.mlbibtex and "mlbibcontext" or "bibtex" +local runners = { + bibtex = sandbox.registerrunner { + name = "bibtex", + method = "execute", + program = "bibtex", + template = [["%filename%"]], + checkers = { + filename = "readable", + } + }, + mlbibtex = sandbox.registerrunner { + name = "mlbibtex", + method = "execute", + program = "mlbibcontext", + template = [["%filename%"]], + checkers = { + filename = "readable", + } + } +} + +local runner = environment.arguments.mlbibtex and runners.mlbibtex or runners.bibtex directives.register("publications.usemlbibtex", function(v) - bibtexbin = v and "mlbibcontext" or "bibtex" + runner = v and runners.mlbibtex or runners.bibtex end) function hacks.process(settings) @@ -74,11 +97,11 @@ function hacks.process(settings) if database ~= "" then local targetfile = file.addsuffix(jobname,"aux") interfaces.showmessage("publications",3,targetfile) - io.savedata(targetfile,format(template,style,database)) + savedata(targetfile,format(template,style,database)) if trace_bibtex then report_tex("processing bibtex file %a using %a",jobname,bibtexbin) end - os.execute(format("%s %q",bibtexbin,jobname)) + runner { filename = jobname } -- purge 'm end end diff --git a/tex/context/base/mkiv/bibl-tra.mkiv b/tex/context/base/mkiv/bibl-tra.mkiv index 4c9e83fdf..93f84872a 100644 --- a/tex/context/base/mkiv/bibl-tra.mkiv +++ b/tex/context/base/mkiv/bibl-tra.mkiv @@ -959,10 +959,10 @@ {#1}% {\getparameters[LO][\c!alternative=,\c!extras=,#1]% \edef\@@currentalternative{\LOalternative}% - \ifx\@@currentalternative\empty + \ifx\@@currentalternative\empty \edef\@@currentalternative{\@@citedefault}% \fi - \ifx\LOextras\empty + \ifx\LOextras\empty \setupcite[\@@currentalternative][#1]% \else \expandafter\ifx\csname \??pv \@@currentalternative\c!right\endcsname\relax diff --git a/tex/context/base/mkiv/blob-ini.lua b/tex/context/base/mkiv/blob-ini.lua index 106c10f4f..f825b7aa3 100644 --- a/tex/context/base/mkiv/blob-ini.lua +++ b/tex/context/base/mkiv/blob-ini.lua @@ -29,7 +29,7 @@ local report_blobs = logs.reporter("blobs") local flush_node_list = node.flush_list local hpack_node_list = node.hpack -local vpack_node_list = node.vpack +----- vpack_node_list = node.vpack local write_node = node.write local typesetters = nodes.typesetters diff --git a/tex/context/base/mkiv/buff-imp-parsed-xml.lua b/tex/context/base/mkiv/buff-imp-parsed-xml.lua index 22611ac8a..b18fb65aa 100644 --- a/tex/context/base/mkiv/buff-imp-parsed-xml.lua +++ b/tex/context/base/mkiv/buff-imp-parsed-xml.lua @@ -92,7 +92,7 @@ local function parsedxml(root,pattern) end local function parser(str,settings) - parsedxml(xml.convert(str),settings and settings.pattern) + parsedxml(xml.convert(string.strip(str)),settings and settings.pattern) end visualizers.parsedxml = parsedxml -- for use at the lua end (maybe namespace needed) diff --git a/tex/context/base/mkiv/buff-ini.lua b/tex/context/base/mkiv/buff-ini.lua index c41c51607..fd5b047af 100644 --- a/tex/context/base/mkiv/buff-ini.lua +++ b/tex/context/base/mkiv/buff-ini.lua @@ -12,7 +12,11 @@ local sub, format = string.sub, string.format local splitlines, validstring, replacenewlines = string.splitlines, string.valid, string.replacenewlines local P, Cs, patterns, lpegmatch = lpeg.P, lpeg.Cs, lpeg.patterns, lpeg.match local utfchar = utf.char +local nameonly = file.nameonly local totable = string.totable +local md5hex = md5.hex +local isfile = lfs.isfile +local savedata = io.savedata local trace_run = false trackers.register("buffers.run", function(v) trace_run = v end) local trace_grab = false trackers.register("buffers.grab", function(v) trace_grab = v end) @@ -20,7 +24,7 @@ local trace_visualize = false trackers.register("buffers.visualize", function local report_buffers = logs.reporter("buffers","usage") local report_typeset = logs.reporter("buffers","typeset") -local report_grabbing = logs.reporter("buffers","grabbing") +----- report_grabbing = logs.reporter("buffers","grabbing") local context = context local commands = commands @@ -32,12 +36,11 @@ local scanstring = scanners.string local scaninteger = scanners.integer local scanboolean = scanners.boolean local scancode = scanners.code -local scantoken = scanners.token +----- scantoken = scanners.token local getters = tokens.getters local gettoken = getters.token -local compilescanner = tokens.compile local scanners = interfaces.scanners local variables = interfaces.variables @@ -62,6 +65,9 @@ local catcodenumbers = catcodes.numbers local ctxcatcodes = catcodenumbers.ctxcatcodes local txtcatcodes = catcodenumbers.txtcatcodes +local setdata = job.datasets.setdata +local getdata = job.datasets.getdata + buffers = buffers or { } local buffers = buffers @@ -484,24 +490,85 @@ implement { -- we can consider adding a size to avoid unlikely clashes -local oldhashes = nil -local newhashes = nil +local olddata = nil +local newdata = nil +local getrunner = sandbox.getrunner + +local runner = sandbox.registerrunner { + name = "run buffer", + program = "context", + method = "execute", + template = "--purgeall " .. (jit and "--jit" or "") .. " %filename%", + reporter = report_typeset, + checkers = { + filename = "readable", + } +} -local function runbuffer(name,encapsulate) - if not oldhashes then - oldhashes = job.datasets.getdata("typeset buffers","hashes") or { } - for hash, n in next, oldhashes do - local tag = formatters["%s-t-b-%s"](tex.jobname,hash) - registertempfile(addsuffix(tag,"tmp")) -- to be sure - registertempfile(addsuffix(tag,"pdf")) +local function runbuffer(name,encapsulate,runnername,suffixes) + if not runnername or runnername == "" then + runnername = "run buffer" + end + local suffix = "pdf" + if type(suffixes) == "table" then + suffix = suffixes[1] + elseif type(suffixes) == "string" and suffixes ~= "" then + suffix = suffixes + suffixes = { suffix } + else + suffixes = { suffix } + end + local runner = getrunner(runnername) + if not runner then + report_typeset("unknown runner %a",runnername) + return + end + if not olddata then + olddata = getdata("buffers","runners") or { } + local suffixes = olddata.suffixes + local hashes = olddata.hashes + if hashes and suffixes then + for k, hash in next, hashes do + for h, v in next, hash do + for s, v in next, suffixes do + local tmp = addsuffix(h,s) + -- report_typeset("mark for deletion: %s",tmp) + registertempfile(tmp) + end + end + end end - newhashes = { } - job.datasets.setdata { - name = "typeset buffers", - tag = "hashes", - data = newhashes, + end + if not newdata then + newdata = { + version = environment.version, + suffixes = { }, + hashes = { }, + } + setdata { + name = "buffers", + tag = "runners", + data = newdata, } end + local oldhashes = olddata.hashes or { } + local newhashes = newdata.hashes or { } + local old = oldhashes[suffix] + local new = newhashes[suffix] + if not old then + old = { } + oldhashes[suffix] = old + for hash, n in next, old do + local tag = formatters["%s-t-b-%s"](tex.jobname,hash) + local tmp = addsuffix(tag,"tmp") + -- report_typeset("mark for deletion: %s",tmp) + registertempfile(tmp) -- to be sure + end + end + if not new then + new = { } + newhashes[suffix] = new + end local names = getnames(name) local content = collectcontent(names,nil) or "" if content == "" then @@ -511,29 +578,35 @@ local function runbuffer(name,encapsulate) content = formatters["\\starttext\n%s\n\\stoptext\n"](content) end -- - local hash = md5.hex(content) - local tag = formatters["%s-t-b-%s"](tex.jobname,hash) + local hash = md5hex(content) + local tag = formatters["%s-t-b-%s"](nameonly(tex.jobname),hash) -- make sure we run on the local path -- local filename = addsuffix(tag,"tmp") - local resultname = addsuffix(tag,"pdf") + local resultname = addsuffix(tag,suffix) -- - if newhashes[hash] then + if new[tag] then -- done - elseif not oldhashes[hash] or not lfs.isfile(resultname) then + elseif not old[tag] or olddata.version ~= newdata.version or not isfile(resultname) then if trace_run then report_typeset("changes in %a, processing forced",name) end - io.savedata(filename,content) - local command = formatters["context --purgeall %s %s"](jit and "--jit" or "",filename) - report_typeset("running: %s\n",command) - os.execute(command) + savedata(filename,content) + report_typeset("processing saved buffer %a\n",filename) + runner { filename = filename } end - newhashes[hash] = (newhashes[hash] or 0) + 1 + new[tag] = (new[tag] or 0) + 1 report_typeset("no changes in %a, processing skipped",name) registertempfile(filename) - registertempfile(resultname,nil,true) + -- report_typeset("mark for persistence: %s",filename) + for i=1,#suffixes do + local suffix = suffixes[i] + newdata.suffixes[suffix] = true + local tmp = addsuffix(tag,suffix) + -- report_typeset("mark for persistance: %s",tmp) + registertempfile(tmp,nil,true) + end -- - return resultname + return resultname -- first result end local function getbuffer(name) @@ -563,18 +636,26 @@ local function gettexbuffer(name) end end +buffers.run = runbuffer + implement { name = "getbufferctxlua", actions = loadcontent, arguments = "string" } implement { name = "getbuffer", actions = getbuffer, arguments = "string" } implement { name = "getbuffermkvi", actions = getbuffermkvi, arguments = "string" } implement { name = "gettexbuffer", actions = gettexbuffer, arguments = "string" } implement { - name = "runbuffer", + name = "typesetbuffer", actions = { runbuffer, context }, arguments = { "string", true } } implement { + name = "runbuffer", + actions = { runbuffer, context }, + arguments = { "string", false, "string" } +} + +implement { name = "doifelsebuffer", actions = { exists, commands.doifelse }, arguments = "string" @@ -590,18 +671,25 @@ implement { arguments = "string" } -local startbuffer = context.startbuffer -local stopbuffer = context.stopbuffer +do -local startcollecting = context.startcollecting -local stopcollecting = context.stopcollecting + local context = context + local ctxcore = context.core -function context.startbuffer(...) - startcollecting() - startbuffer(...) -end + local startbuffer = ctxcore.startbuffer + local stopbuffer = ctxcore.stopbuffer + + local startcollecting = context.startcollecting + local stopcollecting = context.stopcollecting + + function ctxcore.startbuffer(...) + startcollecting() + startbuffer(...) + end + + function ctxcore.stopbuffer() + stopbuffer() + stopcollecting() + end -function context.stopbuffer() - stopbuffer() - stopcollecting() end diff --git a/tex/context/base/mkiv/buff-par.lua b/tex/context/base/mkiv/buff-par.lua index 58ea9ab9d..9c75b90e7 100644 --- a/tex/context/base/mkiv/buff-par.lua +++ b/tex/context/base/mkiv/buff-par.lua @@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['buff-par'] = { license = "see context related readme files" } -local insert, remove, find, gmatch = table.insert, table.remove, string.find, string.gmatch +local insert, remove, find, gmatch, match = table.insert, table.remove, string.find, string.gmatch, string.match local fullstrip, formatters = string.fullstrip, string.formatters local trace_parallel = false trackers.register("buffers.parallel", function(v) trace_parallel = v end) @@ -90,18 +90,31 @@ function parallel.save(category,tag,content,frombuffer) -- use lpeg if find(content,"%s*%[") then local done = false - for label, content in gmatch(content,"%s*%[(.-)%]%s*([^%[]+)") do + + local function flush(content,label) if done then line = { } insert(lines,line) else done = true end + line.content = fullstrip(content) + line.label = label + end + + + local leading, rest = match(content,"^%s*([^%[]+)(.*)$") + if leading then + if leading ~= "" then + flush(leading) + end + content = rest + end + for label, content in gmatch(content,"%s*%[(.-)%]%s*([^%[]+)") do if trace_parallel and label ~= "" then report_parallel("reference found of category %a, tag %a, label %a",category,tag,label) end - line.content = fullstrip(content) - line.label = label + flush(content,label) end else line.content = fullstrip(content) diff --git a/tex/context/base/mkiv/buff-par.mkvi b/tex/context/base/mkiv/buff-par.mkvi index b17edb173..189e68eec 100644 --- a/tex/context/base/mkiv/buff-par.mkvi +++ b/tex/context/base/mkiv/buff-par.mkvi @@ -15,24 +15,40 @@ \registerctxluafile{buff-par}{1.001} -%D This module is developped for Thomas Schmitz as part of a project. There is -%D no documentation yet. +%D This module is made for Thomas Schmitz as part of a project. There is +%D no documentation yet. Also, this code is unfinished and not tested well. %D %D \starttyping %D \defineparallel[main][one,two] %D %D \startmain %D \startone -%D first 1 -%D [reference] first 2 +%D first 0 +%D [reference] first 1 +%D first 2 %D first 3 %D \stopone %D \starttwo %D second 1 +%D second 2 %D \stoptwo %D \stopmain %D -%D \placeparallel[main][one,two][criterium=all] +%D \startmain +%D \startone +%D first 4 +%D first 4 +%D \stopone +%D \starttwo +%D second 3 +%D second 4 +%D \stoptwo +%D \stopmain +%D +%D \placeparallel[main][one][criterium=all] +%D +%D \placeparallel[main][two][criterium=all] +%D \stoptyping %D criterium=all start=<number> n=<number> @@ -134,7 +150,8 @@ {} \def\buff_parallel_flush_yes - {\directsetup{\namedparallelparameter{\currentparallel:\currentparallelinstance}\c!setups}} + %{\directsetup{\namedparallelparameter{\currentparallel:\currentparallelinstance}\c!setups}} + {\directsetup{\namedparallelparameter{\currentparallelinstance}\c!setups}} \unexpanded\def\doifelseparallel#name#instance% {\clf_doifelseparallel{#name}{#instance}} diff --git a/tex/context/base/mkiv/buff-ver.lua b/tex/context/base/mkiv/buff-ver.lua index 448d1a60c..ed0e327a1 100644 --- a/tex/context/base/mkiv/buff-ver.lua +++ b/tex/context/base/mkiv/buff-ver.lua @@ -40,7 +40,6 @@ local variables = interfaces.variables local findfile = resolvers.findfile local addsuffix = file.addsuffix -local v_auto = variables.auto local v_yes = variables.yes local v_last = variables.last local v_all = variables.all @@ -555,7 +554,7 @@ local beginline = C(patterns.beginline) * CargOne / f_beginline local anything = C(patterns.somecontent) * CargOne / f_default ----- verbosed = (space + newline * (emptyline^0) * beginline + anything)^0 -local verbosed = (space + newline * (emptyline^0) * beginline + emptyline + newline + anything)^0 +local verbosed = (space + newline * (emptyline^0) * beginline + newline * emptyline + newline + anything)^0 local function write(s,settings) -- bad name lpegmatch(verbosed,s,1,settings or false) diff --git a/tex/context/base/mkiv/buff-ver.mkiv b/tex/context/base/mkiv/buff-ver.mkiv index 5b3ed6f2a..27535dba9 100644 --- a/tex/context/base/mkiv/buff-ver.mkiv +++ b/tex/context/base/mkiv/buff-ver.mkiv @@ -751,6 +751,10 @@ \definetyping[\v!typing] +% the \zeropoint forces the number to the margin but also works ok in text + +\setuplinenumbering[\v!typing][\c!location=\v!left,\c!width=\zeropoint] + \setuptyping [\v!file] [\s!parent=\??typing \v!typing] % we don't want \start..\stop overload \setuplinenumbering[\v!file] [\s!parent=\??linenumbering\v!typing] @@ -970,7 +974,8 @@ \fi\fi\fi} \unexpanded\def\dodisplayverbatiminitialize#1% - {\c_buff_verbatim_noflines#1\relax + {\forgetparindent % maybe more + \c_buff_verbatim_noflines#1\relax \c_buff_verbatim_current\zerocount} \loadmarkfile{buff-imp-default} % preloaded as otherwise spurious spaces inline due to loading diff --git a/tex/context/base/mkiv/char-cjk.lua b/tex/context/base/mkiv/char-cjk.lua index 9d6b28a60..3db90386e 100644 --- a/tex/context/base/mkiv/char-cjk.lua +++ b/tex/context/base/mkiv/char-cjk.lua @@ -10,7 +10,6 @@ local setmetatable, next = setmetatable, next local insert = table.insert local floor = math.floor local formatters = string.formatters -local utfchar = utf.char local setmetatableindex = table.setmetatableindex diff --git a/tex/context/base/mkiv/char-def.lua b/tex/context/base/mkiv/char-def.lua index f112f2b67..76c51a6b4 100644 --- a/tex/context/base/mkiv/char-def.lua +++ b/tex/context/base/mkiv/char-def.lua @@ -18,6 +18,11 @@ differences. We could save some bytes by sharing variant tables but it's not wor the trouble. Some additional data is kept in other files. ]]-- +local variants_emoji={ + [0xFE0E]="text style", + [0xFE0F]="emoji style", +} + characters = characters or { } characters.data={ @@ -98,6 +103,7 @@ characters.data={ description="CHARACTER TABULATION", direction="s", linebreak="ba", + synonyms={ "horizontal tabulation", "ht", "tab" }, unicodeslot=0x9, }, { @@ -106,6 +112,7 @@ characters.data={ description="LINE FEED (LF)", direction="b", linebreak="lf", + synonyms={ "end of line", "eol", "lf", "new line", "nl" }, unicodeslot=0xA, }, { @@ -114,6 +121,7 @@ characters.data={ description="LINE TABULATION", direction="s", linebreak="bk", + synonyms={ "vertical tabulation", "vt" }, unicodeslot=0xB, }, { @@ -122,6 +130,7 @@ characters.data={ description="FORM FEED (FF)", direction="ws", linebreak="bk", + synonyms={ "ff" }, unicodeslot=0xC, }, { @@ -130,6 +139,7 @@ characters.data={ description="CARRIAGE RETURN (CR)", direction="b", linebreak="cr", + synonyms={ "cr" }, unicodeslot=0xD, }, { @@ -250,6 +260,7 @@ characters.data={ description="INFORMATION SEPARATOR FOUR", direction="b", linebreak="cm", + synonyms={ "file separator" }, unicodeslot=0x1C, }, { @@ -258,6 +269,7 @@ characters.data={ description="INFORMATION SEPARATOR THREE", direction="b", linebreak="cm", + synonyms={ "group separator" }, unicodeslot=0x1D, }, { @@ -266,6 +278,7 @@ characters.data={ description="INFORMATION SEPARATOR TWO", direction="b", linebreak="cm", + synonyms={ "record separator" }, unicodeslot=0x1E, }, { @@ -274,6 +287,7 @@ characters.data={ description="INFORMATION SEPARATOR ONE", direction="s", linebreak="cm", + synonyms={ "unit separator" }, unicodeslot=0x1F, }, { @@ -293,6 +307,7 @@ characters.data={ direction="on", linebreak="ex", mathclass="close", + synonyms={ "bang", "factorial" }, unicodeslot=0x21, }, { @@ -304,6 +319,7 @@ characters.data={ direction="on", linebreak="qu", mathclass="default", + synonyms={ "neutral quotation mark" }, unicodeslot=0x22, }, { @@ -316,11 +332,9 @@ characters.data={ linebreak="al", mathclass="binary", mathname="mathhash", + synonyms={ "crosshatch", "hash", "octothorpe", "pound sign" }, unicodeslot=0x23, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, { adobename="dollar", @@ -332,6 +346,7 @@ characters.data={ linebreak="pr", mathclass="binary", mathname="mathdollar", + synonyms={ "escudo", "milreis" }, unicodeslot=0x24, }, { @@ -367,6 +382,7 @@ characters.data={ direction="on", linebreak="qu", mathclass="default", + synonyms={ "apl quote", "apostrophe-quote", "neutral single quotation mark" }, unicodeslot=0x27, }, { @@ -379,6 +395,7 @@ characters.data={ mathclass="open", mathname="lparent", mirror=0x29, + synonyms={ "opening parenthesis" }, textclass="open", unicodeslot=0x28, }, @@ -392,6 +409,7 @@ characters.data={ mathclass="close", mathname="rparent", mirror=0x28, + synonyms={ "closing parenthesis" }, textclass="close", unicodeslot=0x29, }, @@ -405,7 +423,9 @@ characters.data={ mathclass="binary", mathname="ast", mathsymbol=0x2217, + synonyms={ "star" }, unicodeslot=0x2A, + variants=variants_emoji, }, { adobename="plus", @@ -426,18 +446,23 @@ characters.data={ direction="cs", linebreak="is", mathclass="punctuation", + synonyms={ "decimal separator" }, unicodeslot=0x2C, }, { adobename="hyphen", category="pd", cjkwd="na", + contextname="texthyphen", description="HYPHEN-MINUS", direction="es", linebreak="hy", + mathclass="nothing", mathextensible="h", mathfiller="relfill", + mathname="mathhyphen", mathsymbol=0x2212, + synonyms={ "hyphen or minus sign", "hyphus" }, unicodeslot=0x2D, }, { @@ -456,6 +481,7 @@ characters.data={ name="ldotp", }, }, + synonyms={ "decimal point", "dot", "period" }, unicodeslot=0x2E, }, { @@ -474,6 +500,7 @@ characters.data={ class="ordinary", }, }, + synonyms={ "slash", "virgule" }, unicodeslot=0x2F, }, { @@ -486,6 +513,7 @@ characters.data={ mathclass="number", unicodeslot=0x30, variants={ + [0xFE00]="short diagonal stroke form", [0xFE0E]="text style", [0xFE0F]="emoji style", }, @@ -499,10 +527,7 @@ characters.data={ linebreak="nu", mathclass="number", unicodeslot=0x31, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, { adobename="two", @@ -513,10 +538,7 @@ characters.data={ linebreak="nu", mathclass="number", unicodeslot=0x32, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, { adobename="three", @@ -527,10 +549,7 @@ characters.data={ linebreak="nu", mathclass="number", unicodeslot=0x33, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, { adobename="four", @@ -541,10 +560,7 @@ characters.data={ linebreak="nu", mathclass="number", unicodeslot=0x34, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, { adobename="five", @@ -555,10 +571,7 @@ characters.data={ linebreak="nu", mathclass="number", unicodeslot=0x35, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, { adobename="six", @@ -569,10 +582,7 @@ characters.data={ linebreak="nu", mathclass="number", unicodeslot=0x36, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, { adobename="seven", @@ -583,10 +593,7 @@ characters.data={ linebreak="nu", mathclass="number", unicodeslot=0x37, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, { adobename="eight", @@ -597,10 +604,7 @@ characters.data={ linebreak="nu", mathclass="number", unicodeslot=0x38, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, { adobename="nine", @@ -611,10 +615,7 @@ characters.data={ linebreak="nu", mathclass="number", unicodeslot=0x39, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, { adobename="colon", @@ -635,6 +636,7 @@ characters.data={ direction="on", linebreak="is", mathclass="punctuation", + synonyms={ "greek question mark" }, unicodeslot=0x3B, }, { @@ -703,6 +705,7 @@ characters.data={ description="COMMERCIAL AT", direction="on", linebreak="al", + synonyms={ "at sign" }, unicodeslot=0x40, }, { @@ -1003,6 +1006,7 @@ characters.data={ mathclass="open", mathname="lbracket", mirror=0x5D, + synonyms={ "opening square bracket" }, textclass="open", unicodeslot=0x5B, }, @@ -1016,6 +1020,7 @@ characters.data={ linebreak="pr", mathclass="nothing", mathname="backslash", + synonyms={ "backslash" }, unicodeslot=0x5C, }, { @@ -1028,6 +1033,7 @@ characters.data={ mathclass="close", mathname="rbracket", mirror=0x5B, + synonyms={ "closing square bracket" }, textclass="close", unicodeslot=0x5D, }, @@ -1041,6 +1047,7 @@ characters.data={ linebreak="al", mathclass="topaccent", mathname="Hat", + synonyms={ "spacing circumflex accent" }, unicodeslot=0x5E, }, { @@ -1051,6 +1058,7 @@ characters.data={ description="LOW LINE", direction="on", linebreak="al", + synonyms={ "spacing underscore" }, unicodeslot=0x5F, }, { @@ -1063,6 +1071,7 @@ characters.data={ linebreak="al", mathclass="topaccent", mathname="grave", + synonyms={ "spacing grave accent" }, unicodeslot=0x60, }, { @@ -1363,6 +1372,7 @@ characters.data={ mathclass="open", mathname="lbrace", mirror=0x7D, + synonyms={ "opening brace", "opening curly bracket" }, textclass="open", unicodeslot=0x7B, }, @@ -1401,6 +1411,7 @@ characters.data={ name="singleverticalbar", }, }, + synonyms={ "absolute value", "vertical bar" }, unicodeslot=0x7C, }, { @@ -1414,6 +1425,7 @@ characters.data={ mathclass="close", mathname="rbrace", mirror=0x7B, + synonyms={ "closing brace", "closing curly bracket" }, textclass="close", unicodeslot=0x7D, }, @@ -1425,6 +1437,7 @@ characters.data={ description="TILDE", direction="on", linebreak="al", + synonyms={ "spacing tilde" }, unicodeslot=0x7E, }, { @@ -1475,6 +1488,7 @@ characters.data={ description="NEXT LINE (NEL)", direction="b", linebreak="nl", + synonyms={ "nel" }, unicodeslot=0x85, }, { @@ -1667,6 +1681,7 @@ characters.data={ direction="cs", linebreak="gl", specials={ "nobreak", 0x20 }, + synonyms={ "nbsp", "non-breaking space" }, unicodeslot=0xA0, }, { @@ -1697,6 +1712,7 @@ characters.data={ description="POUND SIGN", direction="et", linebreak="pr", + synonyms={ "irish punt", "italian lira", "pound sterling" }, unicodeslot=0xA3, }, { @@ -1719,6 +1735,7 @@ characters.data={ linebreak="pr", mathclass="nothing", mathname="yen", + synonyms={ "yuan sign" }, unicodeslot=0xA5, }, { @@ -1729,6 +1746,7 @@ characters.data={ description="BROKEN BAR", direction="on", linebreak="al", + synonyms={ "broken vertical bar", "parted rule" }, unicodeslot=0xA6, }, { @@ -1741,6 +1759,7 @@ characters.data={ linebreak="ai", mathclass="box", mathname="S", + synonyms={ "european paragraph sign" }, unicodeslot=0xA7, }, { @@ -1754,6 +1773,7 @@ characters.data={ mathclass="topaccent", mathname="ddot", specials={ "compat", 0x20, 0x308 }, + synonyms={ "spacing diaeresis" }, unicodeslot=0xA8, }, { @@ -1764,10 +1784,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0xA9, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, { adobename="ordfeminine", @@ -1788,6 +1805,7 @@ characters.data={ direction="on", linebreak="qu", mirror=0xBB, + synonyms={ "chevrons", "left pointing guillemet" }, textclass="open", unicodeslot=0xAB, }, @@ -1809,6 +1827,7 @@ characters.data={ name="neg", }, }, + synonyms={ "angled dash" }, unicodeslot=0xAC, }, { @@ -1819,6 +1838,7 @@ characters.data={ description="SOFT HYPHEN", direction="bn", linebreak="ba", + synonyms={ "discretionary hyphen", "shy" }, unicodeslot=0xAD, }, { @@ -1829,11 +1849,9 @@ characters.data={ description="REGISTERED SIGN", direction="on", linebreak="al", + synonyms={ "registered trade mark sign" }, unicodeslot=0xAE, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, { adobename="macron", @@ -1848,6 +1866,7 @@ characters.data={ mathmleq=0x203E, mathname="bar", specials={ "compat", 0x20, 0x304 }, + synonyms={ "apl overbar", "overline", "spacing macron" }, unicodeslot=0xAF, }, { @@ -1881,6 +1900,7 @@ characters.data={ direction="en", linebreak="ai", specials={ "super", 0x32 }, + synonyms={ "squared" }, unicodeslot=0xB2, }, { @@ -1892,6 +1912,7 @@ characters.data={ direction="en", linebreak="ai", specials={ "super", 0x33 }, + synonyms={ "cubed" }, unicodeslot=0xB3, }, { @@ -1905,6 +1926,7 @@ characters.data={ mathclass="topaccent", mathname="acute", specials={ "compat", 0x20, 0x301 }, + synonyms={ "spacing acute accent" }, unicodeslot=0xB4, }, { @@ -1928,6 +1950,7 @@ characters.data={ linebreak="ai", mathclass="box", mathname="P", + synonyms={ "european section sign", "paragraph sign" }, unicodeslot=0xB6, }, { @@ -1940,6 +1963,7 @@ characters.data={ linebreak="ai", mathclass="binary", mathname="centerdot", + synonyms={ "georgian comma", "greek ano teleia", "greek middle dot", "midpoint" }, unicodeslot=0xB7, }, { @@ -1951,6 +1975,7 @@ characters.data={ direction="on", linebreak="ai", specials={ "compat", 0x20, 0x327 }, + synonyms={ "spacing cedilla" }, unicodeslot=0xB8, }, { @@ -1983,6 +2008,7 @@ characters.data={ direction="on", linebreak="qu", mirror=0xAB, + synonyms={ "right pointing guillemet" }, textclass="close", unicodeslot=0xBB, }, @@ -2027,6 +2053,7 @@ characters.data={ description="INVERTED QUESTION MARK", direction="on", linebreak="op", + synonyms={ "turned question mark" }, unicodeslot=0xBF, }, { @@ -2111,6 +2138,7 @@ characters.data={ lccode=0xE6, linebreak="al", shcode={ 0x41, 0x45 }, + synonyms={ "latin capital ligature ae" }, unicodeslot=0xC6, }, { @@ -2314,6 +2342,7 @@ characters.data={ linebreak="ai", mathclass="binary", mathname="times", + synonyms={ "cartesian product" }, unicodeslot=0xD7, }, { @@ -2326,6 +2355,7 @@ characters.data={ lccode=0xF8, linebreak="al", shcode=0x4F, + synonyms={ "latin capital letter o slash" }, unicodeslot=0xD8, }, { @@ -2409,6 +2439,7 @@ characters.data={ direction="l", linebreak="al", shcode={ 0x73, 0x73 }, + synonyms={ "eszett" }, uccode={ 0x53, 0x53 }, unicodeslot=0xDF, }, @@ -2495,6 +2526,7 @@ characters.data={ direction="l", linebreak="al", shcode={ 0x61, 0x65 }, + synonyms={ "ash", "latin small ligature ae" }, uccode=0xC6, unicodeslot=0xE6, }, @@ -2708,6 +2740,7 @@ characters.data={ linebreak="ai", mathclass="binary", mathname="div", + synonyms={ "obelus" }, unicodeslot=0xF7, }, { @@ -2719,6 +2752,7 @@ characters.data={ direction="l", linebreak="al", shcode=0x6F, + synonyms={ "latin small letter o slash" }, uccode=0xD8, unicodeslot=0xF8, }, @@ -3397,6 +3431,7 @@ characters.data={ linebreak="al", shcode=0x49, specials={ "char", 0x49, 0x307 }, + synonyms={ "latin capital letter i dot" }, unicodeslot=0x130, }, { @@ -3817,6 +3852,7 @@ characters.data={ direction="l", linebreak="al", shcode={ 0x6F, 0x65 }, + synonyms={ "ethel", "latin small letter o e" }, uccode=0x152, unicodeslot=0x153, }, @@ -4495,6 +4531,7 @@ characters.data={ direction="l", lccode=0x1DD, linebreak="al", + synonyms={ "latin capital letter turned e" }, unicodeslot=0x18E, }, { @@ -4514,6 +4551,7 @@ characters.data={ direction="l", lccode=0x25B, linebreak="al", + synonyms={ "latin capital letter epsilon" }, unicodeslot=0x190, }, { @@ -4535,6 +4573,7 @@ characters.data={ direction="l", linebreak="al", shcode=0x66, + synonyms={ "florin currency symbol", "folder", "function symbol", "latin small letter script f" }, uccode=0x191, unicodeslot=0x192, }, @@ -4585,6 +4624,7 @@ characters.data={ lccode=0x268, linebreak="al", shcode=0x49, + synonyms={ "latin capital letter i bar" }, unicodeslot=0x197, }, { @@ -4628,6 +4668,7 @@ characters.data={ linebreak="al", mathclass="variable", mathname="lambdabar", + synonyms={ "latin letter lambda bar" }, unicodeslot=0x19B, }, { @@ -4667,6 +4708,7 @@ characters.data={ lccode=0x275, linebreak="al", shcode=0x4F, + synonyms={ "latin capital letter barred o", "latin capital letter o bar" }, unicodeslot=0x19F, }, { @@ -4860,6 +4902,7 @@ characters.data={ lccode=0x28B, linebreak="al", shcode=0x56, + synonyms={ "latin capital letter script v" }, unicodeslot=0x1B2, }, { @@ -4903,6 +4946,7 @@ characters.data={ direction="l", linebreak="al", shcode=0x7A, + synonyms={ "latin small letter z bar" }, uccode=0x1B5, unicodeslot=0x1B6, }, @@ -4991,6 +5035,7 @@ characters.data={ description="LATIN LETTER DENTAL CLICK", direction="l", linebreak="al", + synonyms={ "pipe" }, unicodeslot=0x1C0, }, { @@ -4999,6 +5044,7 @@ characters.data={ description="LATIN LETTER LATERAL CLICK", direction="l", linebreak="al", + synonyms={ "double pipe" }, unicodeslot=0x1C1, }, { @@ -5007,6 +5053,7 @@ characters.data={ description="LATIN LETTER ALVEOLAR CLICK", direction="l", linebreak="al", + synonyms={ "double-barred pipe" }, unicodeslot=0x1C2, }, { @@ -5015,6 +5062,7 @@ characters.data={ description="LATIN LETTER RETROFLEX CLICK", direction="l", linebreak="al", + synonyms={ "latin letter exclamation mark" }, unicodeslot=0x1C3, }, { @@ -6572,6 +6620,7 @@ characters.data={ description="LATIN SMALL LETTER ALPHA", direction="l", linebreak="al", + synonyms={ "latin small letter script a" }, unicodeslot=0x251, }, { @@ -6620,6 +6669,7 @@ characters.data={ direction="l", linebreak="al", shcode=0x64, + synonyms={ "latin small letter d retroflex hook" }, uccode=0x189, unicodeslot=0x256, }, @@ -6668,6 +6718,7 @@ characters.data={ description="LATIN SMALL LETTER OPEN E", direction="l", linebreak="al", + synonyms={ "latin small letter epsilon" }, uccode=0x190, unicodeslot=0x25B, }, @@ -6693,6 +6744,7 @@ characters.data={ description="LATIN SMALL LETTER CLOSED REVERSED OPEN E", direction="l", linebreak="al", + synonyms={ "latin small letter closed reversed epsilon" }, unicodeslot=0x25E, }, { @@ -6745,6 +6797,7 @@ characters.data={ description="LATIN SMALL LETTER RAMS HORN", direction="l", linebreak="al", + synonyms={ "latin small letter baby gamma" }, unicodeslot=0x264, }, { @@ -6892,6 +6945,7 @@ characters.data={ description="LATIN SMALL LETTER BARRED O", direction="l", linebreak="al", + synonyms={ "latin small letter o bar" }, uccode=0x19F, unicodeslot=0x275, }, @@ -7080,6 +7134,7 @@ characters.data={ direction="l", linebreak="al", shcode=0x76, + synonyms={ "latin small letter script v" }, uccode=0x1B2, unicodeslot=0x28B, }, @@ -7089,6 +7144,7 @@ characters.data={ description="LATIN SMALL LETTER TURNED V", direction="l", linebreak="al", + synonyms={ "caret" }, uccode=0x245, unicodeslot=0x28C, }, @@ -7139,6 +7195,7 @@ characters.data={ description="LATIN SMALL LETTER EZH", direction="l", linebreak="al", + synonyms={ "dram" }, uccode=0x1B7, unicodeslot=0x292, }, @@ -7165,6 +7222,7 @@ characters.data={ description="LATIN LETTER PHARYNGEAL VOICED FRICATIVE", direction="l", linebreak="al", + synonyms={ "latin letter reversed glottal stop" }, unicodeslot=0x295, }, { @@ -7189,6 +7247,7 @@ characters.data={ description="LATIN LETTER BILABIAL CLICK", direction="l", linebreak="al", + synonyms={ "latin letter bullseye" }, unicodeslot=0x298, }, { @@ -7204,6 +7263,7 @@ characters.data={ description="LATIN SMALL LETTER CLOSED OPEN E", direction="l", linebreak="al", + synonyms={ "latin small letter closed epsilon" }, unicodeslot=0x29A, }, { @@ -7477,6 +7537,7 @@ characters.data={ description="MODIFIER LETTER APOSTROPHE", direction="l", linebreak="al", + synonyms={ "glottal stop", "neutral apostrophe" }, unicodeslot=0x2BC, }, { @@ -7577,6 +7638,7 @@ characters.data={ mathclass="topaccent", mathname="check", specials={ "compat", 0x20, 0x30C }, + synonyms={ "mandarin chinese third tone", "modifier letter hacek" }, unicodeslot=0x2C7, }, { @@ -7594,6 +7656,7 @@ characters.data={ description="MODIFIER LETTER MACRON", direction="on", linebreak="ai", + synonyms={ "mandarin chinese first tone" }, unicodeslot=0x2C9, }, { @@ -7603,6 +7666,7 @@ characters.data={ description="MODIFIER LETTER ACUTE ACCENT", direction="on", linebreak="ai", + synonyms={ "mandarin chinese second tone" }, unicodeslot=0x2CA, }, { @@ -7612,6 +7676,7 @@ characters.data={ description="MODIFIER LETTER GRAVE ACCENT", direction="on", linebreak="ai", + synonyms={ "mandarin chinese fourth tone" }, unicodeslot=0x2CB, }, { @@ -7736,6 +7801,7 @@ characters.data={ mathclass="topaccent", mathname="dot", specials={ "compat", 0x20, 0x307 }, + synonyms={ "mandarin chinese fifth or neutral tone" }, unicodeslot=0x2D9, }, { @@ -7799,6 +7865,7 @@ characters.data={ description="MODIFIER LETTER CROSS ACCENT", direction="on", linebreak="bb", + synonyms={ "swedish grave accent" }, unicodeslot=0x2DF, }, { @@ -8046,6 +8113,7 @@ characters.data={ description="COMBINING GRAVE ACCENT", direction="nsm", linebreak="cm", + synonyms={ "greek varia" }, unicodeslot=0x300, }, { @@ -8056,6 +8124,7 @@ characters.data={ description="COMBINING ACUTE ACCENT", direction="nsm", linebreak="cm", + synonyms={ "greek oxia", "greek tonos", "stress mark" }, unicodeslot=0x301, }, { @@ -8092,6 +8161,7 @@ characters.data={ description="COMBINING MACRON", direction="nsm", linebreak="cm", + synonyms={ "long" }, unicodeslot=0x304, }, { @@ -8102,6 +8172,7 @@ characters.data={ description="COMBINING OVERLINE", direction="nsm", linebreak="cm", + synonyms={ "overscore", "vinculum" }, unicodeslot=0x305, }, { @@ -8112,6 +8183,7 @@ characters.data={ description="COMBINING BREVE", direction="nsm", linebreak="cm", + synonyms={ "greek vrachy", "short" }, unicodeslot=0x306, }, { @@ -8122,6 +8194,7 @@ characters.data={ description="COMBINING DOT ABOVE", direction="nsm", linebreak="cm", + synonyms={ "derivative" }, unicodeslot=0x307, }, { @@ -8132,6 +8205,7 @@ characters.data={ description="COMBINING DIAERESIS", direction="nsm", linebreak="cm", + synonyms={ "double derivative", "double dot above", "greek dialytika", "umlaut" }, unicodeslot=0x308, }, { @@ -8172,6 +8246,7 @@ characters.data={ description="COMBINING CARON", direction="nsm", linebreak="cm", + synonyms={ "combining hacek", "v above" }, unicodeslot=0x30C, }, { @@ -8232,6 +8307,7 @@ characters.data={ description="COMBINING TURNED COMMA ABOVE", direction="nsm", linebreak="cm", + synonyms={ "cedilla above" }, unicodeslot=0x312, }, { @@ -8242,6 +8318,7 @@ characters.data={ description="COMBINING COMMA ABOVE", direction="nsm", linebreak="cm", + synonyms={ "greek psili", "greek smooth breathing mark" }, unicodeslot=0x313, }, { @@ -8252,6 +8329,7 @@ characters.data={ description="COMBINING REVERSED COMMA ABOVE", direction="nsm", linebreak="cm", + synonyms={ "greek dasia", "greek rough breathing mark" }, unicodeslot=0x314, }, { @@ -8453,6 +8531,7 @@ characters.data={ description="COMBINING OGONEK", direction="nsm", linebreak="cm", + synonyms={ "nasal hook" }, unicodeslot=0x328, }, { @@ -8553,6 +8632,7 @@ characters.data={ description="COMBINING LOW LINE", direction="nsm", linebreak="cm", + synonyms={ "underline", "underscore" }, unicodeslot=0x332, }, { @@ -8563,6 +8643,7 @@ characters.data={ description="COMBINING DOUBLE LOW LINE", direction="nsm", linebreak="cm", + synonyms={ "double underline", "double underscore" }, unicodeslot=0x333, }, { @@ -8603,6 +8684,7 @@ characters.data={ description="COMBINING SHORT SOLIDUS OVERLAY", direction="nsm", linebreak="cm", + synonyms={ "short slash overlay" }, unicodeslot=0x337, }, { @@ -8615,6 +8697,7 @@ characters.data={ linebreak="cm", mathclass="relation", mathname="not", + synonyms={ "long slash overlay" }, unicodeslot=0x338, }, { @@ -8749,6 +8832,7 @@ characters.data={ description="COMBINING GREEK YPOGEGRAMMENI", direction="nsm", linebreak="cm", + synonyms={ "greek iota subscript", "greek non-spacing iota below" }, uccode=0x399, unicodeslot=0x345, }, @@ -8839,6 +8923,7 @@ characters.data={ description="COMBINING GRAPHEME JOINER", direction="nsm", linebreak="gl", + synonyms={ "cgj" }, unicodeslot=0x34F, }, { @@ -8956,6 +9041,7 @@ characters.data={ description="COMBINING DOUBLE BREVE BELOW", direction="nsm", linebreak="gl", + synonyms={ "ligature tie below", "papyrological hyphen" }, unicodeslot=0x35C, }, { @@ -9003,6 +9089,7 @@ characters.data={ description="COMBINING DOUBLE INVERTED BREVE", direction="nsm", linebreak="gl", + synonyms={ "ligature tie" }, unicodeslot=0x361, }, { @@ -9400,6 +9487,7 @@ characters.data={ linebreak="al", mathclass="variable", mathname="Gamma", + synonyms={ "gamma function" }, unicodeslot=0x393, }, [0x394]={ @@ -9963,6 +10051,7 @@ characters.data={ linebreak="al", mathclass="variable", mathname="pi", + synonyms={ "mathematical constant 3.141592... pi", "mathematical constant pi" }, uccode=0x3A0, unicodeslot=0x3C0, }, @@ -10156,6 +10245,7 @@ characters.data={ direction="l", linebreak="al", specials={ "compat", 0x3B2 }, + synonyms={ "curled beta" }, uccode=0x392, unicodeslot=0x3D0, }, @@ -10169,6 +10259,7 @@ characters.data={ mathclass="variable", mathname="varTheta", specials={ "compat", 0x3B8 }, + synonyms={ "script theta" }, uccode=0x398, unicodeslot=0x3D1, }, @@ -10222,6 +10313,7 @@ characters.data={ mathclass="variable", mathname="varpi", specials={ "compat", 0x3C0 }, + synonyms={ "omega pi" }, uccode=0x3A0, unicodeslot=0x3D6, }, @@ -10480,6 +10572,7 @@ characters.data={ direction="l", linebreak="al", specials={ "compat", 0x3C2 }, + synonyms={ "greek small letter lunate sigma" }, uccode=0x3F9, unicodeslot=0x3F2, }, @@ -10509,6 +10602,7 @@ characters.data={ mathclass="variable", mathname="epsilon", specials={ "compat", 0x3B5 }, + synonyms={ "straight epsilon" }, uccode=0x395, unicodeslot=0x3F5, }, @@ -10519,6 +10613,7 @@ characters.data={ linebreak="al", mathclass="variable", mathname="backepsilon", + synonyms={ "reversed straight epsilon" }, unicodeslot=0x3F6, }, [0x3F7]={ @@ -14030,6 +14125,7 @@ characters.data={ description="ARMENIAN APOSTROPHE", direction="l", linebreak="al", + synonyms={ "armenian modifier letter right half ring" }, unicodeslot=0x55A, }, [0x55B]={ @@ -14038,6 +14134,7 @@ characters.data={ description="ARMENIAN EMPHASIS MARK", direction="l", linebreak="al", + synonyms={ "armenian shesht" }, unicodeslot=0x55B, }, [0x55C]={ @@ -14046,6 +14143,7 @@ characters.data={ description="ARMENIAN EXCLAMATION MARK", direction="l", linebreak="al", + synonyms={ "armenian batsaganchakan nshan" }, unicodeslot=0x55C, }, [0x55D]={ @@ -14054,6 +14152,7 @@ characters.data={ description="ARMENIAN COMMA", direction="l", linebreak="al", + synonyms={ "armenian bowt" }, unicodeslot=0x55D, }, [0x55E]={ @@ -14062,6 +14161,7 @@ characters.data={ description="ARMENIAN QUESTION MARK", direction="l", linebreak="al", + synonyms={ "armenian hartsakan nshan" }, unicodeslot=0x55E, }, [0x55F]={ @@ -14070,6 +14170,7 @@ characters.data={ description="ARMENIAN ABBREVIATION MARK", direction="l", linebreak="al", + synonyms={ "armenian patiw" }, unicodeslot=0x55F, }, [0x561]={ @@ -14429,6 +14530,7 @@ characters.data={ description="ARMENIAN FULL STOP", direction="l", linebreak="is", + synonyms={ "armenian vertsaket", "georgian full stop" }, unicodeslot=0x589, }, [0x58A]={ @@ -14436,6 +14538,7 @@ characters.data={ description="ARMENIAN HYPHEN", direction="on", linebreak="ba", + synonyms={ "armenian yentamna" }, unicodeslot=0x58A, }, [0x58D]={ @@ -14457,6 +14560,7 @@ characters.data={ description="ARMENIAN DRAM SIGN", direction="et", linebreak="pr", + synonyms={ "armenian currency" }, unicodeslot=0x58F, }, [0x591]={ @@ -15770,6 +15874,7 @@ characters.data={ description="ARABIC TATWEEL", direction="al", linebreak="al", + synonyms={ "arabic kashida" }, unicodeslot=0x640, }, [0x641]={ @@ -16140,6 +16245,7 @@ characters.data={ description="ARABIC THOUSANDS SEPARATOR", direction="an", linebreak="nu", + synonyms={ "arabic phrase separator" }, unicodeslot=0x66C, }, [0x66D]={ @@ -16873,6 +16979,7 @@ characters.data={ linebreak="al", shcode=0x647, specials={ "char", 0x6D5, 0x654 }, + synonyms={ "arabic letter hamzah on ha", "izafet" }, unicodeslot=0x6C0, }, [0x6C1]={ @@ -17494,6 +17601,7 @@ characters.data={ description="SYRIAC ABBREVIATION MARK", direction="al", linebreak="al", + synonyms={ "syriac sam" }, unicodeslot=0x70F, visible="yes", }, @@ -20060,6 +20168,190 @@ characters.data={ linebreak="al", unicodeslot=0x8B4, }, + [0x8B6]={ + arabic="d", + category="lo", + description="ARABIC LETTER BEH WITH SMALL MEEM ABOVE", + direction="al", + linebreak="al", + unicodeslot=0x8B6, + }, + [0x8B7]={ + arabic="d", + category="lo", + description="ARABIC LETTER PEH WITH SMALL MEEM ABOVE", + direction="al", + linebreak="al", + unicodeslot=0x8B7, + }, + [0x8B8]={ + arabic="d", + category="lo", + description="ARABIC LETTER TEH WITH SMALL TEH ABOVE", + direction="al", + linebreak="al", + unicodeslot=0x8B8, + }, + [0x8B9]={ + arabic="r", + category="lo", + description="ARABIC LETTER REH WITH SMALL NOON ABOVE", + direction="al", + linebreak="al", + unicodeslot=0x8B9, + }, + [0x8BA]={ + arabic="d", + category="lo", + description="ARABIC LETTER YEH WITH TWO DOTS BELOW AND SMALL NOON ABOVE", + direction="al", + linebreak="al", + unicodeslot=0x8BA, + }, + [0x8BB]={ + arabic="d", + category="lo", + description="ARABIC LETTER AFRICAN FEH", + direction="al", + linebreak="al", + unicodeslot=0x8BB, + }, + [0x8BC]={ + arabic="d", + category="lo", + description="ARABIC LETTER AFRICAN QAF", + direction="al", + linebreak="al", + unicodeslot=0x8BC, + }, + [0x8BD]={ + arabic="d", + category="lo", + description="ARABIC LETTER AFRICAN NOON", + direction="al", + linebreak="al", + unicodeslot=0x8BD, + }, + [0x8D4]={ + category="mn", + combining=0xE6, + description="ARABIC SMALL HIGH WORD AR-RUB", + direction="nsm", + linebreak="cm", + unicodeslot=0x8D4, + }, + [0x8D5]={ + category="mn", + combining=0xE6, + description="ARABIC SMALL HIGH SAD", + direction="nsm", + linebreak="cm", + unicodeslot=0x8D5, + }, + [0x8D6]={ + category="mn", + combining=0xE6, + description="ARABIC SMALL HIGH AIN", + direction="nsm", + linebreak="cm", + unicodeslot=0x8D6, + }, + [0x8D7]={ + category="mn", + combining=0xE6, + description="ARABIC SMALL HIGH QAF", + direction="nsm", + linebreak="cm", + unicodeslot=0x8D7, + }, + [0x8D8]={ + category="mn", + combining=0xE6, + description="ARABIC SMALL HIGH NOON WITH KASRA", + direction="nsm", + linebreak="cm", + unicodeslot=0x8D8, + }, + [0x8D9]={ + category="mn", + combining=0xE6, + description="ARABIC SMALL LOW NOON WITH KASRA", + direction="nsm", + linebreak="cm", + unicodeslot=0x8D9, + }, + [0x8DA]={ + category="mn", + combining=0xE6, + description="ARABIC SMALL HIGH WORD ATH-THALATHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x8DA, + }, + [0x8DB]={ + category="mn", + combining=0xE6, + description="ARABIC SMALL HIGH WORD AS-SAJDA", + direction="nsm", + linebreak="cm", + unicodeslot=0x8DB, + }, + [0x8DC]={ + category="mn", + combining=0xE6, + description="ARABIC SMALL HIGH WORD AN-NISF", + direction="nsm", + linebreak="cm", + unicodeslot=0x8DC, + }, + [0x8DD]={ + category="mn", + combining=0xE6, + description="ARABIC SMALL HIGH WORD SAKTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x8DD, + }, + [0x8DE]={ + category="mn", + combining=0xE6, + description="ARABIC SMALL HIGH WORD QIF", + direction="nsm", + linebreak="cm", + unicodeslot=0x8DE, + }, + [0x8DF]={ + category="mn", + combining=0xE6, + description="ARABIC SMALL HIGH WORD WAQFA", + direction="nsm", + linebreak="cm", + unicodeslot=0x8DF, + }, + [0x8E0]={ + category="mn", + combining=0xE6, + description="ARABIC SMALL HIGH FOOTNOTE MARKER", + direction="nsm", + linebreak="cm", + unicodeslot=0x8E0, + }, + [0x8E1]={ + category="mn", + combining=0xE6, + description="ARABIC SMALL HIGH SIGN SAFHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x8E1, + }, + [0x8E2]={ + arabic="u", + category="cf", + description="ARABIC DISPUTED END OF AYAH", + direction="an", + linebreak="al", + unicodeslot=0x8E2, + }, [0x8E3]={ category="mn", combining=0xDC, @@ -20305,6 +20597,7 @@ characters.data={ description="DEVANAGARI SIGN CANDRABINDU", direction="nsm", linebreak="cm", + synonyms={ "devanagari anunasika" }, unicodeslot=0x901, }, [0x902]={ @@ -20313,6 +20606,7 @@ characters.data={ description="DEVANAGARI SIGN ANUSVARA", direction="nsm", linebreak="cm", + synonyms={ "devanagari bindu" }, unicodeslot=0x902, }, [0x903]={ @@ -20915,6 +21209,7 @@ characters.data={ description="DEVANAGARI SIGN VIRAMA", direction="nsm", linebreak="cm", + synonyms={ "halant" }, unicodeslot=0x94D, }, [0x94E]={ @@ -21106,6 +21401,7 @@ characters.data={ description="DEVANAGARI DANDA", direction="l", linebreak="ba", + synonyms={ "devanagari phrase separator", "devanagari purna viram" }, unicodeslot=0x964, }, [0x965]={ @@ -21114,6 +21410,7 @@ characters.data={ description="DEVANAGARI DOUBLE DANDA", direction="l", linebreak="ba", + synonyms={ "devanagari deergh viram" }, unicodeslot=0x965, }, [0x966]={ @@ -21805,6 +22102,7 @@ characters.data={ description="BENGALI SIGN VIRAMA", direction="nsm", linebreak="cm", + synonyms={ "bengali hasant" }, unicodeslot=0x9CD, }, [0x9CE]={ @@ -24016,6 +24314,7 @@ characters.data={ description="TAMIL SIGN VISARGA", direction="l", linebreak="al", + synonyms={ "tamil aytham" }, unicodeslot=0xB83, }, [0xB85]={ @@ -24462,6 +24761,7 @@ characters.data={ description="TAMIL DAY SIGN", direction="on", linebreak="al", + synonyms={ "tamil naal" }, unicodeslot=0xBF3, }, [0xBF4]={ @@ -24469,6 +24769,7 @@ characters.data={ description="TAMIL MONTH SIGN", direction="on", linebreak="al", + synonyms={ "tamil maatham" }, unicodeslot=0xBF4, }, [0xBF5]={ @@ -24476,6 +24777,7 @@ characters.data={ description="TAMIL YEAR SIGN", direction="on", linebreak="al", + synonyms={ "tamil varudam" }, unicodeslot=0xBF5, }, [0xBF6]={ @@ -24483,6 +24785,7 @@ characters.data={ description="TAMIL DEBIT SIGN", direction="on", linebreak="al", + synonyms={ "tamil patru" }, unicodeslot=0xBF6, }, [0xBF7]={ @@ -24490,6 +24793,7 @@ characters.data={ description="TAMIL CREDIT SIGN", direction="on", linebreak="al", + synonyms={ "tamil varavu" }, unicodeslot=0xBF7, }, [0xBF8]={ @@ -24497,6 +24801,7 @@ characters.data={ description="TAMIL AS ABOVE SIGN", direction="on", linebreak="al", + synonyms={ "tamil merpadi" }, unicodeslot=0xBF8, }, [0xBF9]={ @@ -24504,6 +24809,7 @@ characters.data={ description="TAMIL RUPEE SIGN", direction="et", linebreak="pr", + synonyms={ "tamil rupai" }, unicodeslot=0xBF9, }, [0xBFA]={ @@ -24511,6 +24817,7 @@ characters.data={ description="TAMIL NUMBER SIGN", direction="on", linebreak="al", + synonyms={ "tamil enn" }, unicodeslot=0xBFA, }, [0xC00]={ @@ -24532,6 +24839,7 @@ characters.data={ description="TELUGU SIGN ANUSVARA", direction="l", linebreak="cm", + synonyms={ "telugu sunna" }, unicodeslot=0xC02, }, [0xC03]={ @@ -25189,6 +25497,13 @@ characters.data={ linebreak="al", unicodeslot=0xC7F, }, + [0xC80]={ + category="lo", + description="KANNADA SIGN SPACING CANDRABINDU", + direction="l", + linebreak="al", + unicodeslot=0xC80, + }, [0xC81]={ category="mn", description="KANNADA SIGN CANDRABINDU", @@ -26297,6 +26612,7 @@ characters.data={ description="MALAYALAM SIGN VIRAMA", direction="nsm", linebreak="cm", + synonyms={ "malayalam chandrakkala", "malayalam vowel half-u" }, unicodeslot=0xD4D, }, [0xD4E]={ @@ -26306,6 +26622,34 @@ characters.data={ linebreak="al", unicodeslot=0xD4E, }, + [0xD4F]={ + category="so", + description="MALAYALAM SIGN PARA", + direction="l", + linebreak="al", + unicodeslot=0xD4F, + }, + [0xD54]={ + category="lo", + description="MALAYALAM LETTER CHILLU M", + direction="l", + linebreak="al", + unicodeslot=0xD54, + }, + [0xD55]={ + category="lo", + description="MALAYALAM LETTER CHILLU Y", + direction="l", + linebreak="al", + unicodeslot=0xD55, + }, + [0xD56]={ + category="lo", + description="MALAYALAM LETTER CHILLU LLL", + direction="l", + linebreak="al", + unicodeslot=0xD56, + }, [0xD57]={ category="mc", description="MALAYALAM AU LENGTH MARK", @@ -26313,6 +26657,55 @@ characters.data={ linebreak="cm", unicodeslot=0xD57, }, + [0xD58]={ + category="no", + description="MALAYALAM FRACTION ONE ONE-HUNDRED-AND-SIXTIETH", + direction="l", + linebreak="al", + unicodeslot=0xD58, + }, + [0xD59]={ + category="no", + description="MALAYALAM FRACTION ONE FORTIETH", + direction="l", + linebreak="al", + unicodeslot=0xD59, + }, + [0xD5A]={ + category="no", + description="MALAYALAM FRACTION THREE EIGHTIETHS", + direction="l", + linebreak="al", + unicodeslot=0xD5A, + }, + [0xD5B]={ + category="no", + description="MALAYALAM FRACTION ONE TWENTIETH", + direction="l", + linebreak="al", + unicodeslot=0xD5B, + }, + [0xD5C]={ + category="no", + description="MALAYALAM FRACTION ONE TENTH", + direction="l", + linebreak="al", + unicodeslot=0xD5C, + }, + [0xD5D]={ + category="no", + description="MALAYALAM FRACTION THREE TWENTIETHS", + direction="l", + linebreak="al", + unicodeslot=0xD5D, + }, + [0xD5E]={ + category="no", + description="MALAYALAM FRACTION ONE FIFTH", + direction="l", + linebreak="al", + unicodeslot=0xD5E, + }, [0xD5F]={ category="lo", description="MALAYALAM LETTER ARCHAIC II", @@ -26460,6 +26853,27 @@ characters.data={ linebreak="al", unicodeslot=0xD75, }, + [0xD76]={ + category="no", + description="MALAYALAM FRACTION ONE SIXTEENTH", + direction="l", + linebreak="al", + unicodeslot=0xD76, + }, + [0xD77]={ + category="no", + description="MALAYALAM FRACTION ONE EIGHTH", + direction="l", + linebreak="al", + unicodeslot=0xD77, + }, + [0xD78]={ + category="no", + description="MALAYALAM FRACTION THREE SIXTEENTHS", + direction="l", + linebreak="al", + unicodeslot=0xD78, + }, [0xD79]={ category="so", description="MALAYALAM DATE MARK", @@ -26942,6 +27356,7 @@ characters.data={ description="SINHALA SIGN AL-LAKUNA", direction="nsm", linebreak="cm", + synonyms={ "sinhala virama" }, unicodeslot=0xDCA, }, [0xDCF]={ @@ -29207,6 +29622,7 @@ characters.data={ description="TIBETAN SIGN RJES SU NGA RO", direction="nsm", linebreak="cm", + synonyms={ "tibetan anusvara" }, unicodeslot=0xF7E, }, [0xF7F]={ @@ -29214,6 +29630,7 @@ characters.data={ description="TIBETAN SIGN RNAM BCAD", direction="l", linebreak="ba", + synonyms={ "tibetan visarga" }, unicodeslot=0xF7F, }, [0xF80]={ @@ -29254,6 +29671,7 @@ characters.data={ description="TIBETAN MARK HALANTA", direction="nsm", linebreak="cm", + synonyms={ "tibetan srog med" }, unicodeslot=0xF84, }, [0xF85]={ @@ -29852,6 +30270,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x1000, + variants={ + [0xFE00]="dotted form", + }, }, [0x1001]={ category="lo", @@ -29866,6 +30287,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x1002, + variants={ + [0xFE00]="dotted form", + }, }, [0x1003]={ category="lo", @@ -29880,6 +30304,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x1004, + variants={ + [0xFE00]="dotted form", + }, }, [0x1005]={ category="lo", @@ -29964,6 +30391,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x1010, + variants={ + [0xFE00]="dotted form", + }, }, [0x1011]={ category="lo", @@ -29971,6 +30401,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x1011, + variants={ + [0xFE00]="dotted form", + }, }, [0x1012]={ category="lo", @@ -29999,6 +30432,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x1015, + variants={ + [0xFE00]="dotted form", + }, }, [0x1016]={ category="lo", @@ -30027,6 +30463,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x1019, + variants={ + [0xFE00]="dotted form", + }, }, [0x101A]={ category="lo", @@ -30034,6 +30473,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x101A, + variants={ + [0xFE00]="dotted form", + }, }, [0x101B]={ category="lo", @@ -30048,6 +30490,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x101C, + variants={ + [0xFE00]="dotted form", + }, }, [0x101D]={ category="lo", @@ -30055,6 +30500,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x101D, + variants={ + [0xFE00]="dotted form", + }, }, [0x101E]={ category="lo", @@ -30090,6 +30538,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x1022, + variants={ + [0xFE00]="dotted form", + }, }, [0x1023]={ category="lo", @@ -30196,6 +30647,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x1031, + variants={ + [0xFE00]="dotted form", + }, }, [0x1032]={ category="mn", @@ -30253,6 +30707,7 @@ characters.data={ description="MYANMAR SIGN VIRAMA", direction="nsm", linebreak="sa", + synonyms={ "myanmar killer" }, unicodeslot=0x1039, }, [0x103A]={ @@ -30675,6 +31130,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x1075, + variants={ + [0xFE00]="dotted form", + }, }, [0x1076]={ category="lo", @@ -30696,6 +31154,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x1078, + variants={ + [0xFE00]="dotted form", + }, }, [0x1079]={ category="lo", @@ -30710,6 +31171,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x107A, + variants={ + [0xFE00]="dotted form", + }, }, [0x107B]={ category="lo", @@ -30752,6 +31216,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0x1080, + variants={ + [0xFE00]="dotted form", + }, }, [0x1081]={ category="lo", @@ -43221,6 +43688,7 @@ characters.data={ description="KHMER SIGN NIKAHIT", direction="nsm", linebreak="sa", + synonyms={ "khmer anusvara", "khmer srak am" }, unicodeslot=0x17C6, }, [0x17C7]={ @@ -43228,6 +43696,7 @@ characters.data={ description="KHMER SIGN REAHMUK", direction="l", linebreak="sa", + synonyms={ "khmer srak ah", "khmer visarga" }, unicodeslot=0x17C7, }, [0x17C8]={ @@ -43611,6 +44080,7 @@ characters.data={ description="MONGOLIAN FREE VARIATION SELECTOR ONE", direction="nsm", linebreak="cm", + synonyms={ "fvs1" }, unicodeslot=0x180B, }, [0x180C]={ @@ -44579,19 +45049,19 @@ characters.data={ unicodeslot=0x1884, }, [0x1885]={ - arabic="u", + arabic="t", category="lo", description="MONGOLIAN LETTER ALI GALI BALUDA", - direction="l", - linebreak="al", + direction="nsm", + linebreak="cm", unicodeslot=0x1885, }, [0x1886]={ - arabic="u", + arabic="t", category="lo", description="MONGOLIAN LETTER ALI GALI THREE BALUDA", - direction="l", - linebreak="al", + direction="nsm", + linebreak="cm", unicodeslot=0x1886, }, [0x1887]={ @@ -50711,6 +51181,69 @@ characters.data={ linebreak="ba", unicodeslot=0x1C7F, }, + [0x1C80]={ + category="ll", + description="CYRILLIC SMALL LETTER ROUNDED VE", + direction="l", + linebreak="al", + unicodeslot=0x1C80, + }, + [0x1C81]={ + category="ll", + description="CYRILLIC SMALL LETTER LONG-LEGGED DE", + direction="l", + linebreak="al", + unicodeslot=0x1C81, + }, + [0x1C82]={ + category="ll", + description="CYRILLIC SMALL LETTER NARROW O", + direction="l", + linebreak="al", + unicodeslot=0x1C82, + }, + [0x1C83]={ + category="ll", + description="CYRILLIC SMALL LETTER WIDE ES", + direction="l", + linebreak="al", + unicodeslot=0x1C83, + }, + [0x1C84]={ + category="ll", + description="CYRILLIC SMALL LETTER TALL TE", + direction="l", + linebreak="al", + unicodeslot=0x1C84, + }, + [0x1C85]={ + category="ll", + description="CYRILLIC SMALL LETTER THREE-LEGGED TE", + direction="l", + linebreak="al", + unicodeslot=0x1C85, + }, + [0x1C86]={ + category="ll", + description="CYRILLIC SMALL LETTER TALL HARD SIGN", + direction="l", + linebreak="al", + unicodeslot=0x1C86, + }, + [0x1C87]={ + category="ll", + description="CYRILLIC SMALL LETTER TALL YAT", + direction="l", + linebreak="al", + unicodeslot=0x1C87, + }, + [0x1C88]={ + category="ll", + description="CYRILLIC SMALL LETTER UNBLENDED UK", + direction="l", + linebreak="al", + unicodeslot=0x1C88, + }, [0x1CC0]={ category="po", description="SUNDANESE PUNCTUATION BINDU SURYA", @@ -52994,6 +53527,14 @@ characters.data={ linebreak="cm", unicodeslot=0x1DF5, }, + [0x1DFB]={ + category="mn", + combining=0xE6, + description="COMBINING DELETION MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x1DFB, + }, [0x1DFC]={ category="mn", combining=0xE9, @@ -58409,6 +58950,7 @@ characters.data={ direction="ws", linebreak="ba", specials={ "char", 0x2003 }, + synonyms={ "mutton quad" }, unicodeslot=0x2001, }, [0x2002]={ @@ -58419,6 +58961,7 @@ characters.data={ direction="ws", linebreak="ba", specials={ "compat", 0x20 }, + synonyms={ "nut" }, unicodeslot=0x2002, }, [0x2003]={ @@ -58428,6 +58971,7 @@ characters.data={ direction="ws", linebreak="ba", specials={ "compat", 0x20 }, + synonyms={ "mutton" }, unicodeslot=0x2003, }, [0x2004]={ @@ -58437,6 +58981,7 @@ characters.data={ direction="ws", linebreak="ba", specials={ "compat", 0x20 }, + synonyms={ "thick space" }, unicodeslot=0x2004, }, [0x2005]={ @@ -58446,6 +58991,7 @@ characters.data={ direction="ws", linebreak="ba", specials={ "compat", 0x20 }, + synonyms={ "mid space" }, unicodeslot=0x2005, }, [0x2006]={ @@ -58500,6 +59046,7 @@ characters.data={ description="ZERO WIDTH SPACE", direction="bn", linebreak="zw", + synonyms={ "zwsp" }, unicodeslot=0x200B, }, [0x200C]={ @@ -58510,6 +59057,7 @@ characters.data={ description="ZERO WIDTH NON-JOINER", direction="bn", linebreak="cm", + synonyms={ "zwnj" }, unicodeslot=0x200C, }, [0x200D]={ @@ -58519,7 +59067,8 @@ characters.data={ contextname="zwj", description="ZERO WIDTH JOINER", direction="bn", - linebreak="cm", + linebreak="zwj", + synonyms={ "zwj" }, unicodeslot=0x200D, }, [0x200E]={ @@ -58528,6 +59077,7 @@ characters.data={ description="LEFT-TO-RIGHT MARK", direction="l", linebreak="cm", + synonyms={ "lrm" }, unicodeslot=0x200E, }, [0x200F]={ @@ -58536,6 +59086,7 @@ characters.data={ description="RIGHT-TO-LEFT MARK", direction="r", linebreak="cm", + synonyms={ "rlm" }, unicodeslot=0x200F, }, [0x2010]={ @@ -58592,6 +59143,7 @@ characters.data={ description="HORIZONTAL BAR", direction="on", linebreak="ai", + synonyms={ "quotation dash" }, unicodeslot=0x2015, }, [0x2016]={ @@ -58632,6 +59184,7 @@ characters.data={ direction="on", linebreak="al", specials={ "compat", 0x20, 0x333 }, + synonyms={ "spacing double underscore" }, unicodeslot=0x2017, }, [0x2018]={ @@ -58642,6 +59195,7 @@ characters.data={ description="LEFT SINGLE QUOTATION MARK", direction="on", linebreak="qu", + synonyms={ "single turned comma quotation mark" }, unicodeslot=0x2018, }, [0x2019]={ @@ -58652,6 +59206,7 @@ characters.data={ description="RIGHT SINGLE QUOTATION MARK", direction="on", linebreak="qu", + synonyms={ "apostrophe", "single comma quotation mark" }, unicodeslot=0x2019, }, [0x201A]={ @@ -58661,6 +59216,7 @@ characters.data={ description="SINGLE LOW-0x0009 QUOTATION MARK", direction="on", linebreak="op", + synonyms={ "low single comma quotation mark" }, unicodeslot=0x201A, }, [0x201B]={ @@ -58669,6 +59225,7 @@ characters.data={ description="SINGLE HIGH-REVERSED-0x0009 QUOTATION MARK", direction="on", linebreak="qu", + synonyms={ "single reversed comma quotation mark" }, unicodeslot=0x201B, }, [0x201C]={ @@ -58679,6 +59236,7 @@ characters.data={ description="LEFT DOUBLE QUOTATION MARK", direction="on", linebreak="qu", + synonyms={ "double turned comma quotation mark" }, unicodeslot=0x201C, }, [0x201D]={ @@ -58689,6 +59247,7 @@ characters.data={ description="RIGHT DOUBLE QUOTATION MARK", direction="on", linebreak="qu", + synonyms={ "double comma quotation mark" }, unicodeslot=0x201D, }, [0x201E]={ @@ -58698,6 +59257,7 @@ characters.data={ description="DOUBLE LOW-0x0009 QUOTATION MARK", direction="on", linebreak="op", + synonyms={ "low double comma quotation mark" }, unicodeslot=0x201E, }, [0x201F]={ @@ -58705,6 +59265,7 @@ characters.data={ description="DOUBLE HIGH-REVERSED-0x0009 QUOTATION MARK", direction="on", linebreak="qu", + synonyms={ "double reversed comma quotation mark" }, unicodeslot=0x201F, }, [0x2020]={ @@ -58725,6 +59286,7 @@ characters.data={ name="dag", }, }, + synonyms={ "long cross" }, unicodeslot=0x2020, }, [0x2021]={ @@ -58745,6 +59307,7 @@ characters.data={ name="ddag", }, }, + synonyms={ "diesis" }, unicodeslot=0x2021, }, [0x2022]={ @@ -58757,6 +59320,7 @@ characters.data={ linebreak="al", mathclass="binary", mathname="bullet", + synonyms={ "black small circle" }, unicodeslot=0x2022, }, [0x2023]={ @@ -58805,6 +59369,7 @@ characters.data={ }, }, specials={ "compat", 0x2E, 0x2E, 0x2E }, + synonyms={ "three dot leader" }, unicodeslot=0x2026, }, [0x2027]={ @@ -58834,6 +59399,7 @@ characters.data={ description="LEFT-TO-RIGHT EMBEDDING", direction="lre", linebreak="cm", + synonyms={ "lre" }, unicodeslot=0x202A, }, [0x202B]={ @@ -58841,6 +59407,7 @@ characters.data={ description="RIGHT-TO-LEFT EMBEDDING", direction="rle", linebreak="cm", + synonyms={ "rle" }, unicodeslot=0x202B, }, [0x202C]={ @@ -58849,6 +59416,7 @@ characters.data={ description="POP DIRECTIONAL FORMATTING", direction="pdf", linebreak="cm", + synonyms={ "pdf" }, unicodeslot=0x202C, }, [0x202D]={ @@ -58857,6 +59425,7 @@ characters.data={ description="LEFT-TO-RIGHT OVERRIDE", direction="lro", linebreak="cm", + synonyms={ "lro" }, unicodeslot=0x202D, }, [0x202E]={ @@ -58865,15 +59434,18 @@ characters.data={ description="RIGHT-TO-LEFT OVERRIDE", direction="rlo", linebreak="cm", + synonyms={ "rlo" }, unicodeslot=0x202E, }, [0x202F]={ + arabic="u", category="zs", contextname="narrownobreakspace", description="NARROW NO-BREAK SPACE", direction="cs", linebreak="gl", specials={ "nobreak", 0x20 }, + synonyms={ "nnbsp" }, unicodeslot=0x202F, }, [0x2030]={ @@ -58884,6 +59456,7 @@ characters.data={ description="PER MILLE SIGN", direction="et", linebreak="po", + synonyms={ "per thousand" }, unicodeslot=0x2030, }, [0x2031]={ @@ -58902,6 +59475,7 @@ characters.data={ linebreak="po", mathclass="nothing", mathname="prime", + synonyms={ "feet", "minutes" }, unicodeslot=0x2032, }, [0x2033]={ @@ -58914,6 +59488,7 @@ characters.data={ mathclass="nothing", mathname="doubleprime", specials={ "compat", 0x2032, 0x2032 }, + synonyms={ "inches", "seconds" }, unicodeslot=0x2033, }, [0x2034]={ @@ -58972,6 +59547,7 @@ characters.data={ direction="on", linebreak="qu", mirror=0x203A, + synonyms={ "left pointing single guillemet" }, textclass="open", unicodeslot=0x2039, }, @@ -58983,6 +59559,7 @@ characters.data={ direction="on", linebreak="qu", mirror=0x2039, + synonyms={ "right pointing single guillemet" }, textclass="close", unicodeslot=0x203A, }, @@ -58993,6 +59570,7 @@ characters.data={ description="REFERENCE MARK", direction="on", linebreak="ai", + synonyms={ "japanese kome", "urdu paragraph separator" }, unicodeslot=0x203B, }, [0x203C]={ @@ -59003,10 +59581,7 @@ characters.data={ linebreak="ns", specials={ "compat", 0x21, 0x21 }, unicodeslot=0x203C, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x203D]={ category="po", @@ -59037,6 +59612,7 @@ characters.data={ }, mathstretch="h", specials={ "compat", 0x20, 0x305 }, + synonyms={ "spacing overscore" }, unicodeslot=0x203E, }, [0x203F]={ @@ -59044,6 +59620,7 @@ characters.data={ description="UNDERTIE", direction="on", linebreak="al", + synonyms={ "greek enotikon" }, unicodeslot=0x203F, }, [0x2040]={ @@ -59051,6 +59628,7 @@ characters.data={ description="CHARACTER TIE", direction="on", linebreak="al", + synonyms={ "sequence concatenation" }, unicodeslot=0x2040, }, [0x2041]={ @@ -59092,6 +59670,7 @@ characters.data={ name="solidus", }, }, + synonyms={ "solidus" }, unicodeslot=0x2044, }, [0x2045]={ @@ -59133,10 +59712,7 @@ characters.data={ linebreak="ns", specials={ "compat", 0x21, 0x3F }, unicodeslot=0x2049, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x204A]={ category="po", @@ -59199,6 +59775,7 @@ characters.data={ description="COMMERCIAL MINUS SIGN", direction="on", linebreak="al", + synonyms={ "med avdrag av", "piska" }, unicodeslot=0x2052, }, [0x2053]={ @@ -59220,6 +59797,7 @@ characters.data={ description="FLOWER PUNCTUATION MARK", direction="on", linebreak="al", + synonyms={ "phul", "puspika" }, unicodeslot=0x2055, }, [0x2056]={ @@ -59251,6 +59829,7 @@ characters.data={ description="FIVE DOT PUNCTUATION", direction="on", linebreak="ba", + synonyms={ "greek pentonkion" }, unicodeslot=0x2059, }, [0x205A]={ @@ -59279,6 +59858,7 @@ characters.data={ description="TRICOLON", direction="on", linebreak="ba", + synonyms={ "epidaurean acrophonic symbol three" }, unicodeslot=0x205D, }, [0x205E]={ @@ -59295,6 +59875,7 @@ characters.data={ direction="ws", linebreak="ba", specials={ "compat", 0x20 }, + synonyms={ "mmsp" }, unicodeslot=0x205F, }, [0x2060]={ @@ -59302,6 +59883,7 @@ characters.data={ description="WORD JOINER", direction="bn", linebreak="wj", + synonyms={ "wj" }, unicodeslot=0x2060, }, [0x2061]={ @@ -59326,6 +59908,7 @@ characters.data={ linebreak="al", mathclass="binary", mathname="invisibletimes", + synonyms={ "invisible comma" }, unicodeslot=0x2063, }, [0x2064]={ @@ -59800,6 +60383,7 @@ characters.data={ description="COLON SIGN", direction="et", linebreak="pr", + synonyms={ "costa rican currency", "el salvadorian currency" }, unicodeslot=0x20A1, }, [0x20A2]={ @@ -59808,6 +60392,7 @@ characters.data={ description="CRUZEIRO SIGN", direction="et", linebreak="pr", + synonyms={ "brazilian currency" }, unicodeslot=0x20A2, }, [0x20A3]={ @@ -59816,6 +60401,7 @@ characters.data={ description="FRENCH FRANC SIGN", direction="et", linebreak="pr", + synonyms={ "french currency" }, unicodeslot=0x20A3, }, [0x20A4]={ @@ -59824,6 +60410,7 @@ characters.data={ description="LIRA SIGN", direction="et", linebreak="pr", + synonyms={ "italian currency", "turkish currency" }, unicodeslot=0x20A4, }, [0x20A5]={ @@ -59838,6 +60425,7 @@ characters.data={ description="NAIRA SIGN", direction="et", linebreak="pr", + synonyms={ "nigerian currency" }, unicodeslot=0x20A6, }, [0x20A7]={ @@ -59846,6 +60434,7 @@ characters.data={ description="PESETA SIGN", direction="et", linebreak="po", + synonyms={ "spanish currency" }, unicodeslot=0x20A7, }, [0x20A8]={ @@ -59854,6 +60443,7 @@ characters.data={ direction="et", linebreak="pr", specials={ "compat", 0x52, 0x73 }, + synonyms={ "indian currency" }, unicodeslot=0x20A8, }, [0x20A9]={ @@ -59863,6 +60453,7 @@ characters.data={ description="WON SIGN", direction="et", linebreak="pr", + synonyms={ "korean currency" }, unicodeslot=0x20A9, }, [0x20AA]={ @@ -59871,6 +60462,7 @@ characters.data={ description="NEW SHEQEL SIGN", direction="et", linebreak="pr", + synonyms={ "israeli currency" }, unicodeslot=0x20AA, }, [0x20AB]={ @@ -59880,6 +60472,7 @@ characters.data={ description="DONG SIGN", direction="et", linebreak="pr", + synonyms={ "vietnamese currency" }, unicodeslot=0x20AB, }, [0x20AC]={ @@ -59890,6 +60483,7 @@ characters.data={ description="EURO SIGN", direction="et", linebreak="pr", + synonyms={ "euro european currency" }, unicodeslot=0x20AC, }, [0x20AD]={ @@ -59897,6 +60491,7 @@ characters.data={ description="KIP SIGN", direction="et", linebreak="pr", + synonyms={ "laotian currency" }, unicodeslot=0x20AD, }, [0x20AE]={ @@ -59904,6 +60499,7 @@ characters.data={ description="TUGRIK SIGN", direction="et", linebreak="pr", + synonyms={ "mongolian currency" }, unicodeslot=0x20AE, }, [0x20AF]={ @@ -59911,6 +60507,7 @@ characters.data={ description="DRACHMA SIGN", direction="et", linebreak="pr", + synonyms={ "greek currency" }, unicodeslot=0x20AF, }, [0x20B0]={ @@ -59925,6 +60522,7 @@ characters.data={ description="PESO SIGN", direction="et", linebreak="pr", + synonyms={ "phillipine currency" }, unicodeslot=0x20B1, }, [0x20B2]={ @@ -59932,6 +60530,7 @@ characters.data={ description="GUARANI SIGN", direction="et", linebreak="pr", + synonyms={ "paraguayan currency" }, unicodeslot=0x20B2, }, [0x20B3]={ @@ -59939,6 +60538,7 @@ characters.data={ description="AUSTRAL SIGN", direction="et", linebreak="pr", + synonyms={ "argentinian former currency" }, unicodeslot=0x20B3, }, [0x20B4]={ @@ -59946,6 +60546,7 @@ characters.data={ description="HRYVNIA SIGN", direction="et", linebreak="pr", + synonyms={ "ukrainian currency" }, unicodeslot=0x20B4, }, [0x20B5]={ @@ -59953,6 +60554,7 @@ characters.data={ description="CEDI SIGN", direction="et", linebreak="pr", + synonyms={ "ghana currency" }, unicodeslot=0x20B5, }, [0x20B6]={ @@ -60002,6 +60604,7 @@ characters.data={ description="MANAT SIGN", direction="et", linebreak="pr", + synonyms={ "azerbaijani currency" }, unicodeslot=0x20BC, }, [0x20BD]={ @@ -60009,6 +60612,7 @@ characters.data={ description="RUBLE SIGN", direction="et", linebreak="pr", + synonyms={ "russian currency" }, unicodeslot=0x20BD, }, [0x20BE]={ @@ -60016,6 +60620,7 @@ characters.data={ description="LARI SIGN", direction="et", linebreak="po", + synonyms={ "georgian currency" }, unicodeslot=0x20BE, }, [0x20D0]={ @@ -60056,6 +60661,7 @@ characters.data={ description="COMBINING ANTICLOCKWISE ARROW ABOVE", direction="nsm", linebreak="cm", + synonyms={ "combining counterclockwise arrow above" }, unicodeslot=0x20D4, }, [0x20D5]={ @@ -60082,6 +60688,7 @@ characters.data={ linebreak="cm", mathclass="topaccent", mathname="vec", + synonyms={ "vector" }, unicodeslot=0x20D7, }, [0x20D8]={ @@ -60106,6 +60713,7 @@ characters.data={ description="COMBINING ANTICLOCKWISE RING OVERLAY", direction="nsm", linebreak="cm", + synonyms={ "combining counterclockwise ring overlay" }, unicodeslot=0x20DA, }, [0x20DB]={ @@ -60116,6 +60724,7 @@ characters.data={ linebreak="cm", mathclass="topaccent", mathname="dddot", + synonyms={ "third derivative" }, unicodeslot=0x20DB, }, [0x20DC]={ @@ -60124,6 +60733,7 @@ characters.data={ description="COMBINING FOUR DOTS ABOVE", direction="nsm", linebreak="cm", + synonyms={ "fourth derivative" }, unicodeslot=0x20DC, }, [0x20DD]={ @@ -60141,6 +60751,7 @@ characters.data={ name="bigcircle", }, }, + synonyms={ "jis composition circle" }, unicodeslot=0x20DD, }, [0x20DE]={ @@ -60166,6 +60777,7 @@ characters.data={ description="COMBINING ENCLOSING CIRCLE BACKSLASH", direction="nsm", linebreak="cm", + synonyms={ "no", "prohibition" }, unicodeslot=0x20E0, }, [0x20E1]={ @@ -60211,6 +60823,7 @@ characters.data={ description="COMBINING DOUBLE VERTICAL STROKE OVERLAY", direction="nsm", linebreak="cm", + synonyms={ "finite function diacritic" }, unicodeslot=0x20E6, }, [0x20E7]={ @@ -60221,6 +60834,7 @@ characters.data={ linebreak="cm", mathclass="topaccent", mathname="actuarial", + synonyms={ "actuarial bend" }, unicodeslot=0x20E7, }, [0x20E8]={ @@ -60238,6 +60852,7 @@ characters.data={ direction="nsm", linebreak="cm", mathclass="topaccent", + synonyms={ "contraction operator" }, unicodeslot=0x20E9, }, [0x20EA]={ @@ -60254,6 +60869,7 @@ characters.data={ description="COMBINING LONG DOUBLE SOLIDUS OVERLAY", direction="nsm", linebreak="cm", + synonyms={ "long double slash overlay" }, unicodeslot=0x20EB, }, [0x20EC]={ @@ -60320,6 +60936,7 @@ characters.data={ mathclass="variable", mathname="complexes", specials={ "font", 0x43 }, + synonyms={ "complex numbers", "the set of complex numbers" }, unicodeslot=0x2102, }, [0x2103]={ @@ -60331,6 +60948,7 @@ characters.data={ direction="on", linebreak="po", specials={ "compat", 0xB0, 0x43 }, + synonyms={ "degrees centigrade" }, unicodeslot=0x2103, }, [0x2104]={ @@ -60338,6 +60956,7 @@ characters.data={ description="CENTRE LINE SYMBOL", direction="on", linebreak="al", + synonyms={ "clone" }, unicodeslot=0x2104, }, [0x2105]={ @@ -60391,6 +61010,7 @@ characters.data={ direction="l", linebreak="al", specials={ "font", 0x67 }, + synonyms={ "real number symbol" }, unicodeslot=0x210A, }, [0x210B]={ @@ -60407,6 +61027,7 @@ characters.data={ direction="l", linebreak="al", specials={ "font", 0x48 }, + synonyms={ "hilbert space" }, unicodeslot=0x210C, }, [0x210D]={ @@ -60462,6 +61083,7 @@ characters.data={ mathclass="default", mathname="Im", specials={ "font", 0x49 }, + synonyms={ "imaginary part" }, unicodeslot=0x2111, }, [0x2112]={ @@ -60470,6 +61092,7 @@ characters.data={ direction="l", linebreak="al", specials={ "font", 0x4C }, + synonyms={ "laplace transform" }, unicodeslot=0x2112, }, [0x2113]={ @@ -60482,6 +61105,7 @@ characters.data={ mathclass="default", mathname="ell", specials={ "font", 0x6C }, + synonyms={ "liter" }, unicodeslot=0x2113, }, [0x2114]={ @@ -60489,6 +61113,7 @@ characters.data={ description="L B BAR SYMBOL", direction="on", linebreak="al", + synonyms={ "pounds" }, unicodeslot=0x2114, }, [0x2115]={ @@ -60499,6 +61124,7 @@ characters.data={ mathclass="variable", mathname="naturalnumbers", specials={ "font", 0x4E }, + synonyms={ "natural number" }, unicodeslot=0x2115, }, [0x2116]={ @@ -60518,6 +61144,7 @@ characters.data={ description="SOUND RECORDING COPYRIGHT", direction="on", linebreak="al", + synonyms={ "phonorecord sign", "published" }, unicodeslot=0x2117, }, [0x2118]={ @@ -60528,6 +61155,7 @@ characters.data={ linebreak="al", mathclass="default", mathname="wp", + synonyms={ "weierstrass elliptic function" }, unicodeslot=0x2118, }, [0x2119]={ @@ -60548,6 +61176,7 @@ characters.data={ mathclass="variable", mathname="rationals", specials={ "font", 0x51 }, + synonyms={ "rational numbers", "the set of rational numbers" }, unicodeslot=0x211A, }, [0x211B]={ @@ -60556,6 +61185,7 @@ characters.data={ direction="l", linebreak="al", specials={ "font", 0x52 }, + synonyms={ "riemann integral" }, unicodeslot=0x211B, }, [0x211C]={ @@ -60567,6 +61197,7 @@ characters.data={ mathclass="default", mathname="Re", specials={ "font", 0x52 }, + synonyms={ "real part" }, unicodeslot=0x211C, }, [0x211D]={ @@ -60577,6 +61208,7 @@ characters.data={ mathclass="variable", mathname="reals", specials={ "font", 0x52 }, + synonyms={ "real numbers", "the set of real numbers" }, unicodeslot=0x211D, }, [0x211E]={ @@ -60585,6 +61217,7 @@ characters.data={ description="PRESCRIPTION TAKE", direction="on", linebreak="al", + synonyms={ "cross ratio", "recipe" }, unicodeslot=0x211E, }, [0x211F]={ @@ -60622,10 +61255,7 @@ characters.data={ linebreak="ai", specials={ "super", 0x54, 0x4D }, unicodeslot=0x2122, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2123]={ category="so", @@ -60642,6 +61272,7 @@ characters.data={ mathclass="variable", mathname="integers", specials={ "font", 0x5A }, + synonyms={ "integers", "the set of integers" }, unicodeslot=0x2124, }, [0x2125]={ @@ -60674,6 +61305,7 @@ characters.data={ linebreak="al", mathclass="variable", mathname="mho", + synonyms={ "mho" }, unicodeslot=0x2127, }, [0x2128]={ @@ -60691,6 +61323,7 @@ characters.data={ linebreak="al", mathclass="variable", mathname="turnediota", + synonyms={ "unique element" }, unicodeslot=0x2129, }, [0x212A]={ @@ -60723,6 +61356,7 @@ characters.data={ direction="l", linebreak="al", specials={ "font", 0x42 }, + synonyms={ "bernoulli function" }, unicodeslot=0x212C, }, [0x212D]={ @@ -60747,6 +61381,7 @@ characters.data={ direction="l", linebreak="al", specials={ "font", 0x65 }, + synonyms={ "error", "natural exponent" }, unicodeslot=0x212F, }, [0x2130]={ @@ -60755,6 +61390,7 @@ characters.data={ direction="l", linebreak="al", specials={ "font", 0x45 }, + synonyms={ "electromotive force", "emf" }, unicodeslot=0x2130, }, [0x2131]={ @@ -60763,6 +61399,7 @@ characters.data={ direction="l", linebreak="al", specials={ "font", 0x46 }, + synonyms={ "fourier transform" }, unicodeslot=0x2131, }, [0x2132]={ @@ -60773,6 +61410,7 @@ characters.data={ linebreak="al", mathclass="ordinary", mathname="Finv", + synonyms={ "claudian digamma inversum" }, unicodeslot=0x2132, }, [0x2133]={ @@ -60781,6 +61419,7 @@ characters.data={ direction="l", linebreak="al", specials={ "font", 0x4D }, + synonyms={ "german mark pre-wwii", "m-matrix" }, unicodeslot=0x2133, }, [0x2134]={ @@ -60789,6 +61428,7 @@ characters.data={ direction="l", linebreak="al", specials={ "font", 0x6F }, + synonyms={ "order" }, unicodeslot=0x2134, }, [0x2135]={ @@ -60800,6 +61440,7 @@ characters.data={ mathclass="default", mathname="aleph", specials={ "compat", 0x5D0 }, + synonyms={ "first transfinite cardinal", "first transfinite cardinal countable" }, unicodeslot=0x2135, }, [0x2136]={ @@ -60810,6 +61451,7 @@ characters.data={ mathclass="default", mathname="beth", specials={ "compat", 0x5D1 }, + synonyms={ "second transfinite cardinal", "second transfinite cardinal continuum" }, unicodeslot=0x2136, }, [0x2137]={ @@ -60820,6 +61462,7 @@ characters.data={ mathclass="default", mathname="gimel", specials={ "compat", 0x5D2 }, + synonyms={ "third transfinite cardinal" }, unicodeslot=0x2137, }, [0x2138]={ @@ -60830,6 +61473,7 @@ characters.data={ mathclass="default", mathname="daleth", specials={ "compat", 0x5D3 }, + synonyms={ "fourth transfinite cardinal" }, unicodeslot=0x2138, }, [0x2139]={ @@ -60839,10 +61483,7 @@ characters.data={ linebreak="al", specials={ "font", 0x69 }, unicodeslot=0x2139, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x213A]={ category="so", @@ -60906,6 +61547,7 @@ characters.data={ linebreak="al", mathclass="ordinary", mathname="Game", + synonyms={ "game" }, unicodeslot=0x2141, }, [0x2142]={ @@ -61577,6 +62219,7 @@ characters.data={ direction="l", lccode=0x2184, linebreak="al", + synonyms={ "apostrophic c", "claudian antisigma" }, unicodeslot=0x2183, }, [0x2184]={ @@ -61678,6 +62321,7 @@ characters.data={ mathclass="relation", mathextensible="u", mathname="uparrow", + synonyms={ "egressive airflow" }, unicodeslot=0x2191, }, [0x2192]={ @@ -61708,6 +62352,7 @@ characters.data={ }, }, mathstretch="h", + synonyms={ "total function" }, unicodeslot=0x2192, }, [0x2193]={ @@ -61720,6 +62365,7 @@ characters.data={ mathclass="relation", mathextensible="d", mathname="downarrow", + synonyms={ "ingressive airflow" }, unicodeslot=0x2193, }, [0x2194]={ @@ -61732,11 +62378,9 @@ characters.data={ mathclass="relation", mathextensible="h", mathname="leftrightarrow", + synonyms={ "relation" }, unicodeslot=0x2194, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2195]={ adobename="arrowupdn", @@ -61749,10 +62393,7 @@ characters.data={ mathextensible="v", mathname="updownarrow", unicodeslot=0x2195, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2196]={ adobename="arrowupleft", @@ -61764,10 +62405,7 @@ characters.data={ mathclass="relation", mathname="nwarrow", unicodeslot=0x2196, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2197]={ adobename="arrowupright", @@ -61779,10 +62417,7 @@ characters.data={ mathclass="relation", mathname="nearrow", unicodeslot=0x2197, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2198]={ adobename="arrowdownright", @@ -61794,10 +62429,7 @@ characters.data={ mathclass="relation", mathname="searrow", unicodeslot=0x2198, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2199]={ adobename="arrowdownleft", @@ -61809,10 +62441,7 @@ characters.data={ mathclass="relation", mathname="swarrow", unicodeslot=0x2199, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x219A]={ category="sm", @@ -61865,6 +62494,7 @@ characters.data={ mathextensible="l", mathfiller="twoheadleftarrowfill", mathname="twoheadleftarrow", + synonyms={ "fast cursor left" }, unicodeslot=0x219E, }, [0x219F]={ @@ -61875,6 +62505,7 @@ characters.data={ mathclass="relation", mathextensible="u", mathname="twoheaduparrow", + synonyms={ "fast cursor up" }, unicodeslot=0x219F, }, [0x21A0]={ @@ -61886,6 +62517,7 @@ characters.data={ mathextensible="r", mathfiller="twoheadrightarrowfill", mathname="twoheadrightarrow", + synonyms={ "fast cursor right", "total surjection" }, unicodeslot=0x21A0, }, [0x21A1]={ @@ -61896,6 +62528,7 @@ characters.data={ mathclass="relation", mathextensible="d", mathname="twoheaddownarrow", + synonyms={ "fast cursor down", "form feed" }, unicodeslot=0x21A1, }, [0x21A2]={ @@ -61916,6 +62549,7 @@ characters.data={ mathclass="relation", mathextensible="r", mathname="rightarrowtail", + synonyms={ "total injection" }, unicodeslot=0x21A3, }, [0x21A4]={ @@ -61947,6 +62581,7 @@ characters.data={ mathextensible="r", mathfiller="mapstofill", mathname="mapsto", + synonyms={ "maplet" }, unicodeslot=0x21A6, }, [0x21A7]={ @@ -61957,6 +62592,7 @@ characters.data={ mathclass="relation", mathextensible="d", mathname="mapsdown", + synonyms={ "depth symbol" }, unicodeslot=0x21A7, }, [0x21A8]={ @@ -61980,10 +62616,7 @@ characters.data={ mathfiller="hookleftarrowfill", mathname="hookleftarrow", unicodeslot=0x21A9, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x21AA]={ category="so", @@ -61995,10 +62628,7 @@ characters.data={ mathfiller="hookrightarrowfill", mathname="hookrightarrow", unicodeslot=0x21AA, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x21AB]={ category="so", @@ -62049,6 +62679,7 @@ characters.data={ mathclass="relation", mathextensible="d", mathname="downzigzagarrow", + synonyms={ "electrolysis" }, unicodeslot=0x21AF, }, [0x21B0]={ @@ -62099,6 +62730,7 @@ characters.data={ mathclass="ordinary", mathextensible="m", mathname="linefeed", + synonyms={ "line feed" }, unicodeslot=0x21B4, }, [0x21B5]={ @@ -62150,6 +62782,7 @@ characters.data={ mathclass="relation", mathextensible="h", mathname="barleftarrowrightarrowbar", + synonyms={ "tab with shift tab" }, unicodeslot=0x21B9, }, [0x21BA]={ @@ -62575,6 +63208,7 @@ characters.data={ mathclass="relation", mathextensible="u", mathname="nHuparrow", + synonyms={ "page up" }, unicodeslot=0x21DE, }, [0x21DF]={ @@ -62648,6 +63282,7 @@ characters.data={ mathclass="relation", mathextensible="l", mathname="barleftarrow", + synonyms={ "leftward tab" }, unicodeslot=0x21E4, }, [0x21E5]={ @@ -62659,6 +63294,7 @@ characters.data={ mathclass="relation", mathextensible="r", mathname="rightarrowbar", + synonyms={ "rightward tab" }, unicodeslot=0x21E5, }, [0x21E6]={ @@ -62682,6 +63318,7 @@ characters.data={ mathclass="ordinary", mathextensible="u", mathname="upwhitearrow", + synonyms={ "shift" }, unicodeslot=0x21E7, }, [0x21E8]={ @@ -62722,6 +63359,7 @@ characters.data={ mathclass="ordinary", mathextensible="u", mathname="whitearrowupfrombar", + synonyms={ "level 2 lock" }, unicodeslot=0x21EB, }, [0x21EC]={ @@ -62729,6 +63367,7 @@ characters.data={ description="UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR", direction="on", linebreak="al", + synonyms={ "caps lock" }, unicodeslot=0x21EC, }, [0x21ED]={ @@ -62736,6 +63375,7 @@ characters.data={ description="UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR", direction="on", linebreak="al", + synonyms={ "numerics lock" }, unicodeslot=0x21ED, }, [0x21EE]={ @@ -62743,6 +63383,7 @@ characters.data={ description="UPWARDS WHITE DOUBLE ARROW", direction="on", linebreak="al", + synonyms={ "level 3 select" }, unicodeslot=0x21EE, }, [0x21EF]={ @@ -62750,6 +63391,7 @@ characters.data={ description="UPWARDS WHITE DOUBLE ARROW ON PEDESTAL", direction="on", linebreak="al", + synonyms={ "level 3 lock" }, unicodeslot=0x21EF, }, [0x21F0]={ @@ -62757,6 +63399,7 @@ characters.data={ description="RIGHTWARDS WHITE ARROW FROM WALL", direction="on", linebreak="al", + synonyms={ "group lock" }, unicodeslot=0x21F0, }, [0x21F1]={ @@ -62764,6 +63407,7 @@ characters.data={ description="NORTH WEST ARROW TO CORNER", direction="on", linebreak="al", + synonyms={ "home" }, unicodeslot=0x21F1, }, [0x21F2]={ @@ -62771,6 +63415,7 @@ characters.data={ description="SOUTH EAST ARROW TO CORNER", direction="on", linebreak="al", + synonyms={ "end" }, unicodeslot=0x21F2, }, [0x21F3]={ @@ -62778,6 +63423,7 @@ characters.data={ description="UP DOWN WHITE ARROW", direction="on", linebreak="al", + synonyms={ "scrolling" }, unicodeslot=0x21F3, }, [0x21F4]={ @@ -62828,6 +63474,7 @@ characters.data={ mathclass="relation", mathextensible="r", mathname="nvrightarrow", + synonyms={ "partial function" }, unicodeslot=0x21F8, }, [0x21F9]={ @@ -62838,6 +63485,7 @@ characters.data={ mathclass="relation", mathextensible="h", mathname="nvleftrightarrow", + synonyms={ "partial relation" }, unicodeslot=0x21F9, }, [0x21FA]={ @@ -62858,6 +63506,7 @@ characters.data={ mathclass="relation", mathextensible="r", mathname="nVrightarrow", + synonyms={ "finite function" }, unicodeslot=0x21FB, }, [0x21FC]={ @@ -62868,6 +63517,7 @@ characters.data={ mathclass="relation", mathextensible="h", mathname="nVleftrightarrow", + synonyms={ "finite relation" }, unicodeslot=0x21FC, }, [0x21FD]={ @@ -62909,6 +63559,7 @@ characters.data={ linebreak="ai", mathclass="ordinary", mathname="forall", + synonyms={ "universal quantifier" }, unicodeslot=0x2200, }, [0x2201]={ @@ -62940,6 +63591,7 @@ characters.data={ linebreak="ai", mathclass="ordinary", mathname="exists", + synonyms={ "existential quantifier" }, unicodeslot=0x2203, }, [0x2204]={ @@ -62960,7 +63612,11 @@ characters.data={ linebreak="al", mathclass="default", mathname="emptyset", + synonyms={ "null set" }, unicodeslot=0x2205, + variants={ + [0xFE00]="zero with long diagonal stroke overlay form", + }, }, [0x2206]={ adobename="increment", @@ -62968,6 +63624,7 @@ characters.data={ description="INCREMENT", direction="on", linebreak="al", + synonyms={ "forward difference", "laplace operator" }, unicodeslot=0x2206, }, [0x2207]={ @@ -62979,6 +63636,7 @@ characters.data={ linebreak="ai", mathclass="default", mathname="nabla", + synonyms={ "backward difference", "del" }, unicodeslot=0x2207, }, [0x2208]={ @@ -63074,6 +63732,7 @@ characters.data={ description="END OF PROOF", direction="on", linebreak="al", + synonyms={ "q.e.d." }, unicodeslot=0x220E, }, [0x220F]={ @@ -63085,6 +63744,7 @@ characters.data={ linebreak="ai", mathclass="limop", mathname="prod", + synonyms={ "product sign" }, unicodeslot=0x220F, }, [0x2210]={ @@ -63094,6 +63754,7 @@ characters.data={ linebreak="al", mathclass="limop", mathname="coprod", + synonyms={ "coproduct sign" }, unicodeslot=0x2210, }, [0x2211]={ @@ -63105,6 +63766,7 @@ characters.data={ linebreak="ai", mathclass="limop", mathname="sum", + synonyms={ "summation sign" }, unicodeslot=0x2211, }, [0x2212]={ @@ -63186,6 +63848,7 @@ characters.data={ linebreak="al", mathclass="binary", mathname="circ", + synonyms={ "apl jot", "composite function" }, unicodeslot=0x2218, }, [0x2219]={ @@ -63219,6 +63882,7 @@ characters.data={ name="surd", }, }, + synonyms={ "radical sign" }, unicodeslot=0x221A, }, [0x221B]={ @@ -63295,6 +63959,7 @@ characters.data={ linebreak="al", mathclass="ordinary", mathname="sphericalangle", + synonyms={ "angle arc" }, unicodeslot=0x2222, }, [0x2223]={ @@ -63306,6 +63971,7 @@ characters.data={ linebreak="ai", mathclass="binary", mathname="divides", + synonyms={ "apl stile", "such that" }, unicodeslot=0x2223, }, [0x2224]={ @@ -63369,6 +64035,7 @@ characters.data={ name="land", }, }, + synonyms={ "conjunction", "wedge" }, unicodeslot=0x2227, }, [0x2228]={ @@ -63388,6 +64055,7 @@ characters.data={ name="lor", }, }, + synonyms={ "disjunction", "vee" }, unicodeslot=0x2228, }, [0x2229]={ @@ -63399,6 +64067,7 @@ characters.data={ linebreak="ai", mathclass="binary", mathname="cap", + synonyms={ "cap", "hat" }, unicodeslot=0x2229, variants={ [0xFE00]="with serifs", @@ -63413,6 +64082,7 @@ characters.data={ linebreak="ai", mathclass="binary", mathname="cup", + synonyms={ "cup" }, unicodeslot=0x222A, variants={ [0xFE00]="with serifs", @@ -63534,6 +64204,7 @@ characters.data={ linebreak="al", mathclass="limop", mathname="ointctrclockwise", + synonyms={ "counterclockwise contour integral" }, unicodeslot=0x2233, }, [0x2234]={ @@ -63587,6 +64258,7 @@ characters.data={ linebreak="al", mathclass="binary", mathname="dotminus", + synonyms={ "saturating subtraction" }, unicodeslot=0x2238, }, [0x2239]={ @@ -63622,6 +64294,7 @@ characters.data={ mathclass="relation", mathname="sim", mirror=0x223D, + synonyms={ "apl tilde", "cycle", "difference between", "not", "proportional to", "similar to", "varies with" }, unicodeslot=0x223C, }, [0x223D]={ @@ -63634,6 +64307,7 @@ characters.data={ mathclass="relation", mathname="backsim", mirror=0x223C, + synonyms={ "lazy s" }, unicodeslot=0x223D, }, [0x223E]={ @@ -63641,6 +64315,7 @@ characters.data={ description="INVERTED LAZY S", direction="on", linebreak="al", + synonyms={ "most positive" }, unicodeslot=0x223E, }, [0x223F]={ @@ -63648,6 +64323,7 @@ characters.data={ description="SINE WAVE", direction="on", linebreak="al", + synonyms={ "alternating current" }, unicodeslot=0x223F, }, [0x2240]={ @@ -63753,6 +64429,7 @@ characters.data={ linebreak="ai", mathclass="relation", mathname="approx", + synonyms={ "asymptotic to" }, unicodeslot=0x2248, }, [0x2249]={ @@ -63854,6 +64531,7 @@ characters.data={ mathclass="relation", mathname="fallingdotseq", mirror=0x2253, + synonyms={ "nearly equals" }, unicodeslot=0x2252, }, [0x2253]={ @@ -63905,6 +64583,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="circeq", + synonyms={ "approximately equal to" }, unicodeslot=0x2257, }, [0x2258]={ @@ -63921,6 +64600,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="wedgeeq", + synonyms={ "corresponds to" }, unicodeslot=0x2259, }, [0x225A]={ @@ -63948,6 +64628,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="triangleq", + synonyms={ "equal to by definition", "equiangular" }, unicodeslot=0x225C, }, [0x225D]={ @@ -64154,6 +64835,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="between", + synonyms={ "plaintiff", "quantic" }, unicodeslot=0x226C, }, [0x226D]={ @@ -64320,6 +65002,7 @@ characters.data={ mathclass="relation", mathname="prec", mirror=0x227B, + synonyms={ "lower rank than" }, unicodeslot=0x227A, }, [0x227B]={ @@ -64331,6 +65014,7 @@ characters.data={ mathclass="relation", mathname="succ", mirror=0x227A, + synonyms={ "higher rank than" }, unicodeslot=0x227B, }, [0x227C]={ @@ -64407,6 +65091,7 @@ characters.data={ mathclass="relation", mathname="subset", mirror=0x2283, + synonyms={ "included in set" }, unicodeslot=0x2282, }, [0x2283]={ @@ -64419,6 +65104,7 @@ characters.data={ mathclass="relation", mathname="supset", mirror=0x2282, + synonyms={ "includes in set" }, unicodeslot=0x2283, }, [0x2284]={ @@ -64540,6 +65226,7 @@ characters.data={ linebreak="al", mathclass="binary", mathname="uplus", + synonyms={ "bag addition" }, unicodeslot=0x228E, }, [0x228F]={ @@ -64615,6 +65302,7 @@ characters.data={ linebreak="ai", mathclass="binary", mathname="oplus", + synonyms={ "direct sum" }, unicodeslot=0x2295, variants={ [0xFE00]="with white rim", @@ -64628,6 +65316,7 @@ characters.data={ linebreak="al", mathclass="binary", mathname="ominus", + synonyms={ "symmetric difference" }, unicodeslot=0x2296, }, [0x2297]={ @@ -64638,6 +65327,7 @@ characters.data={ linebreak="al", mathclass="binary", mathname="otimes", + synonyms={ "tensor product", "vector pointing into page" }, unicodeslot=0x2297, variants={ [0xFE00]="with white rim", @@ -64662,6 +65352,7 @@ characters.data={ linebreak="ai", mathclass="binary", mathname="odot", + synonyms={ "direct product", "vector pointing out of page" }, unicodeslot=0x2299, }, [0x229A]={ @@ -64747,6 +65438,7 @@ characters.data={ mathclass="relation", mathname="vdash", mirror=0x22A3, + synonyms={ "implies", "proves", "reducible", "turnstile", "yields" }, unicodeslot=0x22A2, }, [0x22A3]={ @@ -64758,6 +65450,7 @@ characters.data={ mathclass="relation", mathname="dashv", mirror=0x22A2, + synonyms={ "does not yield", "non-theorem", "reverse turnstile" }, unicodeslot=0x22A3, }, [0x22A4]={ @@ -64768,6 +65461,7 @@ characters.data={ linebreak="al", mathclass="default", mathname="top", + synonyms={ "top" }, unicodeslot=0x22A4, }, [0x22A5]={ @@ -64787,6 +65481,7 @@ characters.data={ name="perp", }, }, + synonyms={ "base", "bottom", "orthogonal to", "perpendicular" }, unicodeslot=0x22A5, }, [0x22A6]={ @@ -64795,6 +65490,7 @@ characters.data={ direction="on", linebreak="al", mirror=0x2ADE, + synonyms={ "reduces to" }, unicodeslot=0x22A6, }, [0x22A7]={ @@ -64814,6 +65510,7 @@ characters.data={ mathclass="relation", mathname="vDash", mirror=0x2AE4, + synonyms={ "results in", "satisfies", "statement is true", "tautology", "valid" }, unicodeslot=0x22A8, }, [0x22A9]={ @@ -65044,6 +65741,7 @@ characters.data={ linebreak="al", mathclass="limop", mathname="bigcap", + synonyms={ "generalized intersection" }, unicodeslot=0x22C2, }, [0x22C3]={ @@ -65053,6 +65751,7 @@ characters.data={ linebreak="al", mathclass="limop", mathname="bigcup", + synonyms={ "generalized union" }, unicodeslot=0x22C3, }, [0x22C4]={ @@ -65246,6 +65945,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="pitchfork", + synonyms={ "proper intersection" }, unicodeslot=0x22D4, }, [0x22D5]={ @@ -65696,6 +66396,7 @@ characters.data={ description="ELECTRIC ARROW", direction="on", linebreak="al", + synonyms={ "end of transmission symbol" }, unicodeslot=0x2301, }, [0x2302]={ @@ -65751,6 +66452,7 @@ characters.data={ mathclass="open", mathname="lceil", mirror=0x2309, + synonyms={ "apl upstile" }, unicodeslot=0x2308, }, [0x2309]={ @@ -65771,6 +66473,7 @@ characters.data={ mathclass="open", mathname="lfloor", mirror=0x230B, + synonyms={ "apl downstile" }, unicodeslot=0x230A, }, [0x230B]={ @@ -65817,6 +66520,7 @@ characters.data={ description="REVERSED NOT SIGN", direction="on", linebreak="al", + synonyms={ "beginning of line" }, unicodeslot=0x2310, }, [0x2311]={ @@ -65824,6 +66528,7 @@ characters.data={ description="SQUARE LOZENGE", direction="on", linebreak="al", + synonyms={ "kissen", "pillow" }, unicodeslot=0x2311, }, [0x2312]={ @@ -65876,6 +66581,7 @@ characters.data={ description="PLACE OF INTEREST SIGN", direction="on", linebreak="al", + synonyms={ "command key" }, unicodeslot=0x2318, }, [0x2319]={ @@ -65883,29 +66589,26 @@ characters.data={ description="TURNED NOT SIGN", direction="on", linebreak="al", + synonyms={ "line marker" }, unicodeslot=0x2319, }, [0x231A]={ category="so", + cjkwd="w", description="WATCH", direction="on", linebreak="id", unicodeslot=0x231A, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x231B]={ category="so", + cjkwd="w", description="HOURGLASS", direction="on", linebreak="id", unicodeslot=0x231B, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x231C]={ category="so", @@ -65982,6 +66685,7 @@ characters.data={ description="UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS", direction="on", linebreak="al", + synonyms={ "enter key" }, unicodeslot=0x2324, }, [0x2325]={ @@ -65998,6 +66702,7 @@ characters.data={ description="ERASE TO THE RIGHT", direction="on", linebreak="al", + synonyms={ "delete to the right key" }, unicodeslot=0x2326, }, [0x2327]={ @@ -66006,6 +66711,7 @@ characters.data={ description="X IN A RECTANGLE BOX", direction="on", linebreak="al", + synonyms={ "clear key" }, unicodeslot=0x2327, }, [0x2328]={ @@ -66014,6 +66720,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2328, + variants=variants_emoji, }, [0x2329]={ adobename="angleleft", @@ -66043,6 +66750,7 @@ characters.data={ description="ERASE TO THE LEFT", direction="on", linebreak="al", + synonyms={ "delete to the left key" }, unicodeslot=0x232B, }, [0x232C]={ @@ -66442,6 +67150,7 @@ characters.data={ description="APL FUNCTIONAL SYMBOL JOT DIAERESIS", direction="l", linebreak="al", + synonyms={ "hoot" }, unicodeslot=0x2364, }, [0x2365]={ @@ -66449,6 +67158,7 @@ characters.data={ description="APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS", direction="l", linebreak="al", + synonyms={ "holler" }, unicodeslot=0x2365, }, [0x2366]={ @@ -66470,6 +67180,7 @@ characters.data={ description="APL FUNCTIONAL SYMBOL TILDE DIAERESIS", direction="l", linebreak="al", + synonyms={ "smirk" }, unicodeslot=0x2368, }, [0x2369]={ @@ -66617,6 +67328,7 @@ characters.data={ description="SHOULDERED OPEN BOX", direction="on", linebreak="al", + synonyms={ "keyboard symbol for no break space" }, unicodeslot=0x237D, }, [0x237E]={ @@ -66631,6 +67343,7 @@ characters.data={ description="VERTICAL LINE WITH MIDDLE DOT", direction="on", linebreak="al", + synonyms={ "symbol for end of medium" }, unicodeslot=0x237F, }, [0x2380]={ @@ -66673,6 +67386,7 @@ characters.data={ description="WHITE SQUARE WITH CENTRE VERTICAL LINE", direction="on", linebreak="al", + synonyms={ "center" }, unicodeslot=0x2385, }, [0x2386]={ @@ -66694,6 +67408,7 @@ characters.data={ description="HELM SYMBOL", direction="on", linebreak="al", + synonyms={ "control" }, unicodeslot=0x2388, }, [0x2389]={ @@ -66701,6 +67416,7 @@ characters.data={ description="CIRCLED HORIZONTAL BAR WITH NOTCH", direction="on", linebreak="al", + synonyms={ "pause" }, unicodeslot=0x2389, }, [0x238A]={ @@ -66708,6 +67424,7 @@ characters.data={ description="CIRCLED TRIANGLE DOWN", direction="on", linebreak="al", + synonyms={ "interrupt" }, unicodeslot=0x238A, }, [0x238B]={ @@ -66976,6 +67693,7 @@ characters.data={ linebreak="al", mathclass="open", mathname="lmoustache", + synonyms={ "left moustache" }, unicodeslot=0x23B0, }, [0x23B1]={ @@ -66985,6 +67703,7 @@ characters.data={ linebreak="al", mathclass="close", mathname="rmoustache", + synonyms={ "right moustache" }, unicodeslot=0x23B1, }, [0x23B2]={ @@ -67203,7 +67922,9 @@ characters.data={ description="EJECT SYMBOL", direction="on", linebreak="al", + synonyms={ "eject media" }, unicodeslot=0x23CF, + variants=variants_emoji, }, [0x23D0]={ category="so", @@ -67400,20 +68121,25 @@ characters.data={ }, [0x23E9]={ category="so", + cjkwd="w", description="BLACK RIGHT-POINTING DOUBLE TRIANGLE", direction="on", linebreak="al", + synonyms={ "fast forward" }, unicodeslot=0x23E9, }, [0x23EA]={ category="so", + cjkwd="w", description="BLACK LEFT-POINTING DOUBLE TRIANGLE", direction="on", linebreak="al", + synonyms={ "fast rewind" }, unicodeslot=0x23EA, }, [0x23EB]={ category="so", + cjkwd="w", description="BLACK UP-POINTING DOUBLE TRIANGLE", direction="on", linebreak="al", @@ -67421,6 +68147,7 @@ characters.data={ }, [0x23EC]={ category="so", + cjkwd="w", description="BLACK DOWN-POINTING DOUBLE TRIANGLE", direction="on", linebreak="al", @@ -67432,6 +68159,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x23ED, + variants=variants_emoji, }, [0x23EE]={ category="so", @@ -67439,6 +68167,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x23EE, + variants=variants_emoji, }, [0x23EF]={ category="so", @@ -67446,9 +68175,11 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x23EF, + variants=variants_emoji, }, [0x23F0]={ category="so", + cjkwd="w", description="ALARM CLOCK", direction="on", linebreak="id", @@ -67460,6 +68191,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x23F1, + variants=variants_emoji, }, [0x23F2]={ category="so", @@ -67467,9 +68199,11 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x23F2, + variants=variants_emoji, }, [0x23F3]={ category="so", + cjkwd="w", description="HOURGLASS WITH FLOWING SAND", direction="on", linebreak="id", @@ -67480,6 +68214,7 @@ characters.data={ description="BLACK MEDIUM LEFT-POINTING TRIANGLE", direction="on", linebreak="al", + synonyms={ "reverse play" }, unicodeslot=0x23F4, }, [0x23F5]={ @@ -67487,6 +68222,7 @@ characters.data={ description="BLACK MEDIUM RIGHT-POINTING TRIANGLE", direction="on", linebreak="al", + synonyms={ "forward play" }, unicodeslot=0x23F5, }, [0x23F6]={ @@ -67494,6 +68230,7 @@ characters.data={ description="BLACK MEDIUM UP-POINTING TRIANGLE", direction="on", linebreak="al", + synonyms={ "increase" }, unicodeslot=0x23F6, }, [0x23F7]={ @@ -67501,6 +68238,7 @@ characters.data={ description="BLACK MEDIUM DOWN-POINTING TRIANGLE", direction="on", linebreak="al", + synonyms={ "decrease" }, unicodeslot=0x23F7, }, [0x23F8]={ @@ -67508,21 +68246,55 @@ characters.data={ description="DOUBLE VERTICAL BAR", direction="on", linebreak="al", + synonyms={ "pause play" }, unicodeslot=0x23F8, + variants=variants_emoji, }, [0x23F9]={ category="so", description="BLACK SQUARE FOR STOP", direction="on", linebreak="al", + synonyms={ "stop play" }, unicodeslot=0x23F9, + variants=variants_emoji, }, [0x23FA]={ category="so", description="BLACK CIRCLE FOR RECORD", direction="on", linebreak="al", + synonyms={ "record" }, unicodeslot=0x23FA, + variants=variants_emoji, + }, + [0x23FB]={ + category="so", + description="POWER SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x23FB, + }, + [0x23FC]={ + category="so", + description="POWER ON-OFF SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x23FC, + }, + [0x23FD]={ + category="so", + description="POWER ON SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x23FD, + }, + [0x23FE]={ + category="so", + description="POWER SLEEP SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x23FE, }, [0x2400]={ category="so", @@ -67775,6 +68547,7 @@ characters.data={ description="OPEN BOX", direction="on", linebreak="al", + synonyms={ "graphic for space" }, unicodeslot=0x2423, }, [0x2424]={ @@ -68877,10 +69650,7 @@ characters.data={ linebreak="ai", specials={ "circle", 0x4D }, unicodeslot=0x24C2, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x24C3]={ adobename="Ncircle", @@ -70612,6 +71382,7 @@ characters.data={ description="FULL BLOCK", direction="on", linebreak="ai", + synonyms={ "solid" }, unicodeslot=0x2588, }, [0x2589]={ @@ -70819,6 +71590,7 @@ characters.data={ name="Box", }, }, + synonyms={ "quadrature" }, unicodeslot=0x25A1, }, [0x25A2]={ @@ -70899,10 +71671,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x25AA, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x25AB]={ adobename="whitesmallsquare", @@ -70911,10 +71680,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x25AB, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x25AC]={ adobename="filledrect", @@ -70936,6 +71702,7 @@ characters.data={ description="BLACK VERTICAL RECTANGLE", direction="on", linebreak="al", + synonyms={ "histogram marker" }, unicodeslot=0x25AE, }, [0x25AF]={ @@ -70987,6 +71754,7 @@ characters.data={ name="bigtriangleup", }, }, + synonyms={ "trine" }, unicodeslot=0x25B3, }, [0x25B4]={ @@ -71015,10 +71783,7 @@ characters.data={ mathclass="binary", mathname="blacktriangleright", unicodeslot=0x25B6, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x25B7]={ adobename="whiterightpointingtriangle", @@ -71029,6 +71794,7 @@ characters.data={ linebreak="ai", mathclass="binary", mathname="triangleright", + synonyms={ "range restriction" }, unicodeslot=0x25B7, }, [0x25B8]={ @@ -71059,6 +71825,7 @@ characters.data={ description="WHITE RIGHT-POINTING POINTER", direction="on", linebreak="al", + synonyms={ "forward arrow indicator" }, unicodeslot=0x25BB, }, [0x25BC]={ @@ -71089,6 +71856,7 @@ characters.data={ name="bigtriangledown", }, }, + synonyms={ "hamilton operator" }, unicodeslot=0x25BD, }, [0x25BE]={ @@ -71116,10 +71884,7 @@ characters.data={ mathclass="binary", mathname="blacktriangleleft", unicodeslot=0x25C0, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x25C1]={ adobename="whiteleftpointingtriangle", @@ -71130,6 +71895,7 @@ characters.data={ linebreak="ai", mathclass="binary", mathname="triangleleft", + synonyms={ "domain restriction" }, unicodeslot=0x25C1, }, [0x25C2]={ @@ -71160,6 +71926,7 @@ characters.data={ description="WHITE LEFT-POINTING POINTER", direction="on", linebreak="al", + synonyms={ "backward arrow indicator" }, unicodeslot=0x25C5, }, [0x25C6]={ @@ -71195,6 +71962,7 @@ characters.data={ description="FISHEYE", direction="on", linebreak="al", + synonyms={ "tainome japanese bullet" }, unicodeslot=0x25C9, }, [0x25CA]={ @@ -71574,11 +72342,9 @@ characters.data={ description="WHITE MEDIUM SQUARE", direction="on", linebreak="al", + synonyms={ "always" }, unicodeslot=0x25FB, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x25FC]={ category="sm", @@ -71586,32 +72352,25 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x25FC, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x25FD]={ category="sm", + cjkwd="w", description="WHITE MEDIUM SMALL SQUARE", direction="on", linebreak="al", unicodeslot=0x25FD, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x25FE]={ category="sm", + cjkwd="w", description="BLACK MEDIUM SMALL SQUARE", direction="on", linebreak="al", unicodeslot=0x25FE, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x25FF]={ category="sm", @@ -71625,36 +72384,36 @@ characters.data={ description="BLACK SUN WITH RAYS", direction="on", linebreak="id", + synonyms={ "clear weather" }, unicodeslot=0x2600, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2601]={ category="so", description="CLOUD", direction="on", linebreak="id", + synonyms={ "cloudy weather" }, unicodeslot=0x2601, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2602]={ category="so", description="UMBRELLA", direction="on", linebreak="id", + synonyms={ "rainy weather" }, unicodeslot=0x2602, + variants=variants_emoji, }, [0x2603]={ category="so", description="SNOWMAN", direction="on", linebreak="id", + synonyms={ "snowy weather" }, unicodeslot=0x2603, + variants=variants_emoji, }, [0x2604]={ category="so", @@ -71662,6 +72421,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2604, + variants=variants_emoji, }, [0x2605]={ adobename="blackstar", @@ -71741,10 +72501,7 @@ characters.data={ direction="on", linebreak="ai", unicodeslot=0x260E, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x260F]={ adobename="whitetelephone", @@ -71768,10 +72525,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2611, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2612]={ category="so", @@ -71785,31 +72539,28 @@ characters.data={ description="SALTIRE", direction="on", linebreak="al", + synonyms={ "st. andrew's cross" }, unicodeslot=0x2613, }, [0x2614]={ category="so", - cjkwd="a", + cjkwd="w", description="UMBRELLA WITH RAIN DROPS", direction="on", linebreak="id", + synonyms={ "showery weather" }, unicodeslot=0x2614, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2615]={ category="so", - cjkwd="a", + cjkwd="w", description="HOT BEVERAGE", direction="on", linebreak="id", + synonyms={ "cup of coffee", "cup of tea" }, unicodeslot=0x2615, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2616]={ category="so", @@ -71831,6 +72582,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x2618, + variants=variants_emoji, }, [0x2619]={ category="so", @@ -71867,12 +72619,9 @@ characters.data={ category="so", description="WHITE UP POINTING INDEX", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x261D, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x261E]={ adobename="pointingindexrightwhite", @@ -71881,6 +72630,7 @@ characters.data={ description="WHITE RIGHT POINTING INDEX", direction="on", linebreak="id", + synonyms={ "fist" }, unicodeslot=0x261E, }, [0x261F]={ @@ -71896,7 +72646,9 @@ characters.data={ description="SKULL AND CROSSBONES", direction="on", linebreak="al", + synonyms={ "jolly roger", "poison" }, unicodeslot=0x2620, + variants=variants_emoji, }, [0x2621]={ category="so", @@ -71911,6 +72663,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2622, + variants=variants_emoji, }, [0x2623]={ category="so", @@ -71918,6 +72671,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2623, + variants=variants_emoji, }, [0x2624]={ category="so", @@ -71939,12 +72693,14 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2626, + variants=variants_emoji, }, [0x2627]={ category="so", description="CHI RHO", direction="on", linebreak="al", + synonyms={ "christogram", "constantine's cross" }, unicodeslot=0x2627, }, [0x2628]={ @@ -71967,6 +72723,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x262A, + variants=variants_emoji, }, [0x262B]={ category="so", @@ -71980,6 +72737,7 @@ characters.data={ description="ADI SHAKTI", direction="on", linebreak="al", + synonyms={ "gurmukhi khanda" }, unicodeslot=0x262C, }, [0x262D]={ @@ -71995,6 +72753,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x262E, + variants=variants_emoji, }, [0x262F]={ adobename="yinyang", @@ -72003,6 +72762,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x262F, + variants=variants_emoji, }, [0x2630]={ category="so", @@ -72066,6 +72826,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2638, + variants=variants_emoji, }, [0x2639]={ category="so", @@ -72073,6 +72834,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x2639, + variants=variants_emoji, }, [0x263A]={ adobename="whitesmilingface", @@ -72080,11 +72842,9 @@ characters.data={ description="WHITE SMILING FACE", direction="on", linebreak="id", + synonyms={ "have a nice day!" }, unicodeslot=0x263A, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x263B]={ adobename="invsmileface", @@ -72100,6 +72860,7 @@ characters.data={ description="WHITE SUN WITH RAYS", direction="on", linebreak="al", + synonyms={ "compass" }, unicodeslot=0x263C, }, [0x263D]={ @@ -72130,6 +72891,7 @@ characters.data={ description="FEMALE SIGN", direction="on", linebreak="ai", + synonyms={ "venus" }, unicodeslot=0x2640, }, [0x2641]={ @@ -72147,6 +72909,7 @@ characters.data={ description="MALE SIGN", direction="on", linebreak="ai", + synonyms={ "mars" }, unicodeslot=0x2642, }, [0x2643]={ @@ -72186,135 +72949,113 @@ characters.data={ }, [0x2648]={ category="so", + cjkwd="w", description="ARIES", direction="on", linebreak="al", unicodeslot=0x2648, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2649]={ category="so", + cjkwd="w", description="TAURUS", direction="on", linebreak="al", unicodeslot=0x2649, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x264A]={ category="so", + cjkwd="w", description="GEMINI", direction="on", linebreak="al", unicodeslot=0x264A, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x264B]={ category="so", + cjkwd="w", description="CANCER", direction="on", linebreak="al", unicodeslot=0x264B, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x264C]={ category="so", + cjkwd="w", description="LEO", direction="on", linebreak="al", unicodeslot=0x264C, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x264D]={ category="so", + cjkwd="w", description="VIRGO", direction="on", linebreak="al", + synonyms={ "minim alternate glyph" }, unicodeslot=0x264D, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x264E]={ category="so", + cjkwd="w", description="LIBRA", direction="on", linebreak="al", unicodeslot=0x264E, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x264F]={ category="so", + cjkwd="w", description="SCORPIUS", direction="on", linebreak="al", + synonyms={ "drop", "minim" }, unicodeslot=0x264F, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2650]={ category="so", + cjkwd="w", description="SAGITTARIUS", direction="on", linebreak="al", unicodeslot=0x2650, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2651]={ category="so", + cjkwd="w", description="CAPRICORN", direction="on", linebreak="al", unicodeslot=0x2651, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2652]={ category="so", + cjkwd="w", description="AQUARIUS", direction="on", linebreak="al", unicodeslot=0x2652, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2653]={ category="so", + cjkwd="w", description="PISCES", direction="on", linebreak="al", unicodeslot=0x2653, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2654]={ category="so", @@ -72410,10 +73151,7 @@ characters.data={ mathclass="default", mathname="spadesuit", unicodeslot=0x2660, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2661]={ adobename="heartsuitwhite", @@ -72445,11 +73183,9 @@ characters.data={ linebreak="ai", mathclass="default", mathname="clubsuit", + synonyms={ "shamrock" }, unicodeslot=0x2663, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2664]={ adobename="spadesuitwhite", @@ -72467,11 +73203,9 @@ characters.data={ description="BLACK HEART SUIT", direction="on", linebreak="ai", + synonyms={ "valentine" }, unicodeslot=0x2665, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2666]={ adobename="diamond", @@ -72482,10 +73216,7 @@ characters.data={ mathclass="ordinary", mathname="blacklozenge", unicodeslot=0x2666, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2667]={ adobename="clubsuitwhite", @@ -72504,10 +73235,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x2668, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2669]={ adobename="quarternote", @@ -72516,6 +73244,7 @@ characters.data={ description="QUARTER NOTE", direction="on", linebreak="ai", + synonyms={ "crotchet" }, unicodeslot=0x2669, }, [0x266A]={ @@ -72525,6 +73254,7 @@ characters.data={ description="EIGHTH NOTE", direction="on", linebreak="ai", + synonyms={ "quaver" }, unicodeslot=0x266A, }, [0x266B]={ @@ -72533,6 +73263,7 @@ characters.data={ description="BEAMED EIGHTH NOTES", direction="on", linebreak="al", + synonyms={ "beamed quavers" }, unicodeslot=0x266B, }, [0x266C]={ @@ -72542,6 +73273,7 @@ characters.data={ description="BEAMED SIXTEENTH NOTES", direction="on", linebreak="ai", + synonyms={ "beamed semiquavers" }, unicodeslot=0x266C, }, [0x266D]={ @@ -72573,6 +73305,7 @@ characters.data={ linebreak="ai", mathclass="default", mathname="sharp", + synonyms={ "infix bag count" }, unicodeslot=0x266F, }, [0x2670]={ @@ -72658,10 +73391,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x267B, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x267C]={ category="so", @@ -72686,14 +73416,12 @@ characters.data={ }, [0x267F]={ category="so", + cjkwd="w", description="WHEELCHAIR SYMBOL", direction="on", linebreak="id", unicodeslot=0x267F, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2680]={ category="so", @@ -72826,25 +73554,28 @@ characters.data={ description="HAMMER AND PICK", direction="on", linebreak="al", + synonyms={ "mining symbol", "working day symbol" }, unicodeslot=0x2692, + variants=variants_emoji, }, [0x2693]={ category="so", + cjkwd="w", description="ANCHOR", direction="on", linebreak="al", + synonyms={ "harbor symbol" }, unicodeslot=0x2693, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2694]={ category="so", description="CROSSED SWORDS", direction="on", linebreak="al", + synonyms={ "battleground symbol" }, unicodeslot=0x2694, + variants=variants_emoji, }, [0x2695]={ category="so", @@ -72858,7 +73589,9 @@ characters.data={ description="SCALES", direction="on", linebreak="al", + synonyms={ "jurisprudence symbol" }, unicodeslot=0x2696, + variants=variants_emoji, }, [0x2697]={ category="so", @@ -72866,6 +73599,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2697, + variants=variants_emoji, }, [0x2698]={ category="so", @@ -72880,6 +73614,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2699, + variants=variants_emoji, }, [0x269A]={ category="so", @@ -72894,6 +73629,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x269B, + variants=variants_emoji, }, [0x269C]={ category="so", @@ -72901,6 +73637,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x269C, + variants=variants_emoji, }, [0x269D]={ category="so", @@ -72931,21 +73668,17 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x26A0, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x26A1]={ category="so", + cjkwd="w", description="HIGH VOLTAGE SIGN", direction="on", linebreak="al", + synonyms={ "lightning", "thunder" }, unicodeslot=0x26A1, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x26A2]={ category="so", @@ -73005,25 +73738,21 @@ characters.data={ }, [0x26AA]={ category="so", + cjkwd="w", description="MEDIUM WHITE CIRCLE", direction="on", linebreak="al", unicodeslot=0x26AA, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x26AB]={ category="so", + cjkwd="w", description="MEDIUM BLACK CIRCLE", direction="on", linebreak="al", unicodeslot=0x26AB, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x26AC]={ category="so", @@ -73058,14 +73787,18 @@ characters.data={ description="COFFIN", direction="on", linebreak="al", + synonyms={ "buried symbol" }, unicodeslot=0x26B0, + variants=variants_emoji, }, [0x26B1]={ category="so", description="FUNERAL URN", direction="on", linebreak="al", + synonyms={ "cremated symbol" }, unicodeslot=0x26B1, + variants=variants_emoji, }, [0x26B2]={ category="so", @@ -73146,26 +73879,21 @@ characters.data={ }, [0x26BD]={ category="so", + cjkwd="w", description="SOCCER BALL", direction="on", linebreak="id", unicodeslot=0x26BD, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x26BE]={ category="so", - cjkwd="a", + cjkwd="w", description="BASEBALL", direction="on", linebreak="id", unicodeslot=0x26BE, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x26BF]={ category="so", @@ -73173,6 +73901,7 @@ characters.data={ description="SQUARED KEY", direction="on", linebreak="id", + synonyms={ "parental lock" }, unicodeslot=0x26BF, }, [0x26C0]={ @@ -73205,27 +73934,23 @@ characters.data={ }, [0x26C4]={ category="so", - cjkwd="a", + cjkwd="w", description="SNOWMAN WITHOUT SNOW", direction="on", linebreak="id", + synonyms={ "light snow" }, unicodeslot=0x26C4, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x26C5]={ category="so", - cjkwd="a", + cjkwd="w", description="SUN BEHIND CLOUD", direction="on", linebreak="id", + synonyms={ "partly cloudy" }, unicodeslot=0x26C5, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x26C6]={ category="so", @@ -73241,6 +73966,7 @@ characters.data={ description="BLACK SNOWMAN", direction="on", linebreak="id", + synonyms={ "heavy snow" }, unicodeslot=0x26C7, }, [0x26C8]={ @@ -73249,7 +73975,9 @@ characters.data={ description="THUNDER CLOUD AND RAIN", direction="on", linebreak="id", + synonyms={ "thunderstorm" }, unicodeslot=0x26C8, + variants=variants_emoji, }, [0x26C9]={ category="so", @@ -73281,6 +74009,7 @@ characters.data={ description="CROSSING LANES", direction="on", linebreak="ai", + synonyms={ "accident" }, unicodeslot=0x26CC, }, [0x26CD]={ @@ -73293,6 +74022,7 @@ characters.data={ }, [0x26CE]={ category="so", + cjkwd="w", description="OPHIUCHUS", direction="on", linebreak="al", @@ -73304,7 +74034,9 @@ characters.data={ description="PICK", direction="on", linebreak="id", + synonyms={ "construction" }, unicodeslot=0x26CF, + variants=variants_emoji, }, [0x26D0]={ category="so", @@ -73312,6 +74044,7 @@ characters.data={ description="CAR SLIDING", direction="on", linebreak="id", + synonyms={ "icy road" }, unicodeslot=0x26D0, }, [0x26D1]={ @@ -73321,6 +74054,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x26D1, + variants=variants_emoji, }, [0x26D2]={ category="so", @@ -73328,6 +74062,7 @@ characters.data={ description="CIRCLED CROSSING LANES", direction="on", linebreak="ai", + synonyms={ "road closed" }, unicodeslot=0x26D2, }, [0x26D3]={ @@ -73337,18 +74072,17 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x26D3, + variants=variants_emoji, }, [0x26D4]={ category="so", - cjkwd="a", + cjkwd="w", description="NO ENTRY", direction="on", linebreak="id", + synonyms={ "do not enter" }, unicodeslot=0x26D4, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x26D5]={ category="so", @@ -73404,6 +74138,7 @@ characters.data={ description="HEAVY WHITE DOWN-POINTING TRIANGLE", direction="on", linebreak="ai", + synonyms={ "yield" }, unicodeslot=0x26DB, }, [0x26DC]={ @@ -73436,6 +74171,7 @@ characters.data={ description="BLACK TRUCK", direction="on", linebreak="id", + synonyms={ "black lorry" }, unicodeslot=0x26DF, }, [0x26E0]={ @@ -73459,6 +74195,7 @@ characters.data={ description="ASTRONOMICAL SYMBOL FOR URANUS", direction="on", linebreak="al", + synonyms={ "uranus" }, unicodeslot=0x26E2, }, [0x26E3]={ @@ -73474,6 +74211,7 @@ characters.data={ description="PENTAGRAM", direction="on", linebreak="al", + synonyms={ "pentangle pentalpha" }, unicodeslot=0x26E4, }, [0x26E5]={ @@ -73503,6 +74241,7 @@ characters.data={ description="BLACK CROSS ON SHIELD", direction="on", linebreak="ai", + synonyms={ "hospital" }, unicodeslot=0x26E8, }, [0x26E9]={ @@ -73511,19 +74250,18 @@ characters.data={ description="SHINTO SHRINE", direction="on", linebreak="ai", + synonyms={ "torii" }, unicodeslot=0x26E9, + variants=variants_emoji, }, [0x26EA]={ category="so", - cjkwd="a", + cjkwd="w", description="CHURCH", direction="on", linebreak="id", unicodeslot=0x26EA, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x26EB]={ category="so", @@ -73547,6 +74285,7 @@ characters.data={ description="GEAR WITHOUT HUB", direction="on", linebreak="ai", + synonyms={ "factory" }, unicodeslot=0x26ED, }, [0x26EE]={ @@ -73555,6 +74294,7 @@ characters.data={ description="GEAR WITH HANDLES", direction="on", linebreak="ai", + synonyms={ "power plant" }, unicodeslot=0x26EE, }, [0x26EF]={ @@ -73572,6 +74312,7 @@ characters.data={ direction="on", linebreak="ai", unicodeslot=0x26F0, + variants=variants_emoji, }, [0x26F1]={ category="so", @@ -73579,31 +74320,29 @@ characters.data={ description="UMBRELLA ON GROUND", direction="on", linebreak="id", + synonyms={ "bathing beach" }, unicodeslot=0x26F1, + variants=variants_emoji, }, [0x26F2]={ category="so", - cjkwd="a", + cjkwd="w", description="FOUNTAIN", direction="on", linebreak="id", + synonyms={ "park" }, unicodeslot=0x26F2, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x26F3]={ category="so", - cjkwd="a", + cjkwd="w", description="FLAG IN HOLE", direction="on", linebreak="id", + synonyms={ "golf course" }, unicodeslot=0x26F3, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x26F4]={ category="so", @@ -73611,19 +74350,18 @@ characters.data={ description="FERRY", direction="on", linebreak="id", + synonyms={ "boat terminal", "marina or yacht harbour" }, unicodeslot=0x26F4, + variants=variants_emoji, }, [0x26F5]={ category="so", - cjkwd="a", + cjkwd="w", description="SAILBOAT", direction="on", linebreak="id", unicodeslot=0x26F5, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x26F6]={ category="so", @@ -73640,6 +74378,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x26F7, + variants=variants_emoji, }, [0x26F8]={ category="so", @@ -73648,26 +74387,26 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x26F8, + variants=variants_emoji, }, [0x26F9]={ category="so", cjkwd="a", description="PERSON WITH BALL", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x26F9, + variants=variants_emoji, }, [0x26FA]={ category="so", - cjkwd="a", + cjkwd="w", description="TENT", direction="on", linebreak="id", + synonyms={ "camping site" }, unicodeslot=0x26FA, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x26FB]={ category="so", @@ -73683,19 +74422,18 @@ characters.data={ description="HEADSTONE GRAVEYARD SYMBOL", direction="on", linebreak="ai", + synonyms={ "cemetery", "graveyard" }, unicodeslot=0x26FC, }, [0x26FD]={ category="so", - cjkwd="a", + cjkwd="w", description="FUEL PUMP", direction="on", linebreak="id", + synonyms={ "gas station", "petrol station" }, unicodeslot=0x26FD, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x26FE]={ category="so", @@ -73703,6 +74441,7 @@ characters.data={ description="CUP ON BLACK SQUARE", direction="on", linebreak="id", + synonyms={ "drive-in restaurant" }, unicodeslot=0x26FE, }, [0x26FF]={ @@ -73733,10 +74472,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x2702, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2703]={ category="so", @@ -73754,6 +74490,7 @@ characters.data={ }, [0x2705]={ category="so", + cjkwd="w", description="WHITE HEAVY CHECK MARK", direction="on", linebreak="al", @@ -73779,10 +74516,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x2708, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2709]={ category="so", @@ -73790,42 +74524,42 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x2709, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x270A]={ category="so", + cjkwd="w", description="RAISED FIST", direction="on", - linebreak="id", + linebreak="eb", + synonyms={ "paper, scissors game rock in rock" }, unicodeslot=0x270A, }, [0x270B]={ category="so", + cjkwd="w", description="RAISED HAND", direction="on", - linebreak="id", + linebreak="eb", + synonyms={ "paper, scissors game paper in rock" }, unicodeslot=0x270B, }, [0x270C]={ category="so", description="VICTORY HAND", direction="on", - linebreak="id", + linebreak="eb", + synonyms={ "paper, scissors game scissors in rock" }, unicodeslot=0x270C, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x270D]={ category="so", description="WRITING HAND", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x270D, + variants=variants_emoji, }, [0x270E]={ category="so", @@ -73840,10 +74574,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x270F, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2710]={ category="so", @@ -73865,10 +74596,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2712, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2713]={ adobename="checkmark", @@ -73886,10 +74614,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2714, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2715]={ category="so", @@ -73904,10 +74629,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2716, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2717]={ category="so", @@ -73957,6 +74679,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x271D, + variants=variants_emoji, }, [0x271E]={ category="so", @@ -73987,6 +74710,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2721, + variants=variants_emoji, }, [0x2722]={ category="so", @@ -74032,6 +74756,7 @@ characters.data={ }, [0x2728]={ category="so", + cjkwd="w", description="SPARKLES", direction="on", linebreak="al", @@ -74113,10 +74838,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2733, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2734]={ category="so", @@ -74124,10 +74846,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2734, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2735]={ category="so", @@ -74141,6 +74860,7 @@ characters.data={ description="SIX POINTED BLACK STAR", direction="on", linebreak="al", + synonyms={ "sextile" }, unicodeslot=0x2736, }, [0x2737]={ @@ -74169,6 +74889,7 @@ characters.data={ description="SIXTEEN POINTED ASTERISK", direction="on", linebreak="al", + synonyms={ "starburst" }, unicodeslot=0x273A, }, [0x273B]={ @@ -74241,10 +74962,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2744, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2745]={ category="so", @@ -74266,10 +74984,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2747, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2748]={ category="so", @@ -74283,6 +74998,7 @@ characters.data={ description="BALLOON-SPOKED ASTERISK", direction="on", linebreak="al", + synonyms={ "jack" }, unicodeslot=0x2749, }, [0x274A]={ @@ -74297,10 +75013,12 @@ characters.data={ description="HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK", direction="on", linebreak="al", + synonyms={ "turbofan" }, unicodeslot=0x274B, }, [0x274C]={ category="so", + cjkwd="w", description="CROSS MARK", direction="on", linebreak="al", @@ -74315,6 +75033,7 @@ characters.data={ }, [0x274E]={ category="so", + cjkwd="w", description="NEGATIVE SQUARED CROSS MARK", direction="on", linebreak="al", @@ -74350,6 +75069,7 @@ characters.data={ }, [0x2753]={ category="so", + cjkwd="w", description="BLACK QUESTION MARK ORNAMENT", direction="on", linebreak="al", @@ -74357,6 +75077,7 @@ characters.data={ }, [0x2754]={ category="so", + cjkwd="w", description="WHITE QUESTION MARK ORNAMENT", direction="on", linebreak="al", @@ -74364,6 +75085,7 @@ characters.data={ }, [0x2755]={ category="so", + cjkwd="w", description="WHITE EXCLAMATION MARK ORNAMENT", direction="on", linebreak="al", @@ -74378,15 +75100,12 @@ characters.data={ }, [0x2757]={ category="so", - cjkwd="a", + cjkwd="w", description="HEAVY EXCLAMATION MARK SYMBOL", direction="on", linebreak="ai", unicodeslot=0x2757, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2758]={ category="so", @@ -74471,17 +75190,15 @@ characters.data={ direction="on", linebreak="ex", unicodeslot=0x2763, + variants=variants_emoji, }, [0x2764]={ category="so", description="HEAVY BLACK HEART", direction="on", - linebreak="al", + linebreak="id", unicodeslot=0x2764, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2765]={ category="so", @@ -74495,6 +75212,7 @@ characters.data={ description="FLORAL HEART", direction="on", linebreak="al", + synonyms={ "aldus leaf" }, unicodeslot=0x2766, }, [0x2767]={ @@ -74502,6 +75220,7 @@ characters.data={ description="ROTATED FLORAL HEART BULLET", direction="on", linebreak="al", + synonyms={ "hedera", "ivy leaf" }, unicodeslot=0x2767, }, [0x2768]={ @@ -74854,6 +75573,7 @@ characters.data={ }, [0x2795]={ category="so", + cjkwd="w", description="HEAVY PLUS SIGN", direction="on", linebreak="al", @@ -74861,6 +75581,7 @@ characters.data={ }, [0x2796]={ category="so", + cjkwd="w", description="HEAVY MINUS SIGN", direction="on", linebreak="al", @@ -74868,6 +75589,7 @@ characters.data={ }, [0x2797]={ category="so", + cjkwd="w", description="HEAVY DIVISION SIGN", direction="on", linebreak="al", @@ -74943,10 +75665,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x27A1, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x27A2]={ category="so", @@ -75048,6 +75767,7 @@ characters.data={ }, [0x27B0]={ category="so", + cjkwd="w", description="CURLY LOOP", direction="on", linebreak="al", @@ -75153,6 +75873,7 @@ characters.data={ }, [0x27BF]={ category="so", + cjkwd="w", description="DOUBLE CURLY LOOP", direction="on", linebreak="al", @@ -75306,6 +76027,7 @@ characters.data={ description="LOWER RIGHT CORNER WITH DOT", direction="on", linebreak="al", + synonyms={ "pullback" }, unicodeslot=0x27D3, }, [0x27D4]={ @@ -75313,6 +76035,7 @@ characters.data={ description="UPPER LEFT CORNER WITH DOT", direction="on", linebreak="al", + synonyms={ "pushout" }, unicodeslot=0x27D4, }, [0x27D5]={ @@ -75394,6 +76117,7 @@ characters.data={ description="UP TACK WITH CIRCLE ABOVE", direction="on", linebreak="al", + synonyms={ "radial component" }, unicodeslot=0x27DF, }, [0x27E0]={ @@ -75451,6 +76175,7 @@ characters.data={ mathclass="open", mathname="llbracket", mirror=0x27E7, + synonyms={ "left bag bracket" }, unicodeslot=0x27E6, }, [0x27E7]={ @@ -75462,6 +76187,7 @@ characters.data={ mathclass="close", mathname="rrbracket", mirror=0x27E6, + synonyms={ "right bag bracket" }, unicodeslot=0x27E7, }, [0x27E8]={ @@ -75473,6 +76199,7 @@ characters.data={ mathclass="open", mathname="langle", mirror=0x27E9, + synonyms={ "bra", "left sequence bracket" }, unicodeslot=0x27E8, }, [0x27E9]={ @@ -75484,6 +76211,7 @@ characters.data={ mathclass="close", mathname="rangle", mirror=0x27E8, + synonyms={ "ket", "right sequence bracket" }, unicodeslot=0x27E9, }, [0x27EA]={ @@ -75495,6 +76223,7 @@ characters.data={ mathclass="open", mathname="llangle", mirror=0x27EB, + synonyms={ "left chevron bracket" }, unicodeslot=0x27EA, }, [0x27EB]={ @@ -75506,6 +76235,7 @@ characters.data={ mathclass="close", mathname="rrangle", mirror=0x27EA, + synonyms={ "right chevron bracket" }, unicodeslot=0x27EB, }, [0x27EC]={ @@ -75534,6 +76264,7 @@ characters.data={ mathclass="open", mathname="lgroup", mirror=0x27EF, + synonyms={ "lgroup" }, unicodeslot=0x27EE, }, [0x27EF]={ @@ -75544,6 +76275,7 @@ characters.data={ mathclass="close", mathname="rgroup", mirror=0x27EE, + synonyms={ "rgroup" }, unicodeslot=0x27EF, }, [0x27F0]={ @@ -77501,6 +78233,7 @@ characters.data={ direction="on", linebreak="al", mathextensible="r", + synonyms={ "partial surjection" }, unicodeslot=0x2900, }, [0x2901]={ @@ -77509,6 +78242,7 @@ characters.data={ direction="on", linebreak="al", mathextensible="r", + synonyms={ "finite surjection" }, unicodeslot=0x2901, }, [0x2902]={ @@ -77551,6 +78285,7 @@ characters.data={ mathclass="relation", mathextensible="l", mathname="Mapsfrom", + synonyms={ "maps from" }, unicodeslot=0x2906, }, [0x2907]={ @@ -77561,6 +78296,7 @@ characters.data={ mathclass="relation", mathextensible="r", mathname="Mapsto", + synonyms={ "maps to" }, unicodeslot=0x2907, }, [0x2908]={ @@ -77675,6 +78411,7 @@ characters.data={ direction="on", linebreak="al", mathextensible="r", + synonyms={ "partial injection" }, unicodeslot=0x2914, }, [0x2915]={ @@ -77683,6 +78420,7 @@ characters.data={ direction="on", linebreak="al", mathextensible="r", + synonyms={ "finite injection" }, unicodeslot=0x2915, }, [0x2916]={ @@ -77693,6 +78431,7 @@ characters.data={ mathclass="relation", mathextensible="r", mathname="twoheadrightarrowtail", + synonyms={ "bijection" }, unicodeslot=0x2916, }, [0x2917]={ @@ -77702,6 +78441,7 @@ characters.data={ linebreak="al", mathclass="relation", mathextensible="r", + synonyms={ "surjective injection" }, unicodeslot=0x2917, }, [0x2918]={ @@ -77710,6 +78450,7 @@ characters.data={ direction="on", linebreak="al", mathextensible="r", + synonyms={ "finite surjective injection" }, unicodeslot=0x2918, }, [0x2919]={ @@ -77929,10 +78670,7 @@ characters.data={ linebreak="al", mathextensible="m", unicodeslot=0x2934, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2935]={ category="sm", @@ -77941,10 +78679,7 @@ characters.data={ linebreak="al", mathextensible="m", unicodeslot=0x2935, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2936]={ category="sm", @@ -78668,7 +79403,26 @@ characters.data={ description="LEFT BLACK TORTOISE SHELL BRACKET", direction="on", linebreak="op", + mathspec={ + { + class="open", + name="linterval", + }, + { + class="close", + name="rointerval", + }, + { + class="open", + name="rlointerval", + }, + { + class="close", + name="rlointerval", + }, + }, mirror=0x2998, + textclass="open", unicodeslot=0x2997, }, [0x2998]={ @@ -78676,7 +79430,26 @@ characters.data={ description="RIGHT BLACK TORTOISE SHELL BRACKET", direction="on", linebreak="cl", + mathspec={ + { + class="close", + name="rinterval", + }, + { + class="open", + name="lointerval", + }, + { + class="open", + name="lrointerval", + }, + { + class="close", + name="rrointerval", + }, + }, mirror=0x2997, + textclass="close", unicodeslot=0x2998, }, [0x2999]={ @@ -79122,6 +79895,7 @@ characters.data={ description="WHITE HOURGLASS", direction="on", linebreak="al", + synonyms={ "vertical bowtie", "white framus" }, unicodeslot=0x29D6, }, [0x29D7]={ @@ -79168,6 +79942,7 @@ characters.data={ description="INCOMPLETE INFINITY", direction="on", linebreak="al", + synonyms={ "isotech entity ⧜" }, unicodeslot=0x29DC, }, [0x29DD]={ @@ -79196,6 +79971,7 @@ characters.data={ description="SQUARE WITH CONTOURED OUTLINE", direction="on", linebreak="al", + synonyms={ "d'alembertian" }, unicodeslot=0x29E0, }, [0x29E1]={ @@ -79238,6 +80014,7 @@ characters.data={ description="GLEICH STARK", direction="on", linebreak="al", + synonyms={ "tautological equivalent" }, unicodeslot=0x29E6, }, [0x29E7]={ @@ -79339,6 +80116,7 @@ characters.data={ description="RULE-DELAYED", direction="on", linebreak="al", + synonyms={ "colon right arrow" }, unicodeslot=0x29F4, }, [0x29F5]={ @@ -79377,6 +80155,7 @@ characters.data={ direction="on", linebreak="al", mirror=0x29F8, + synonyms={ "schema hiding" }, unicodeslot=0x29F9, }, [0x29FA]={ @@ -79491,6 +80270,7 @@ characters.data={ description="TWO LOGICAL AND OPERATOR", direction="on", linebreak="al", + synonyms={ "merge" }, unicodeslot=0x2A07, }, [0x2A08]={ @@ -79528,6 +80308,17 @@ characters.data={ description="QUADRUPLE INTEGRAL OPERATOR", direction="on", linebreak="al", + mathclass="limop", + mathspec={ + { + class="limop", + name="iiiint", + }, + { + class="nothing", + name="iiiintop", + }, + }, specials={ "compat", 0x222B, 0x222B, 0x222B, 0x222B }, unicodeslot=0x2A0C, }, @@ -79564,6 +80355,7 @@ characters.data={ description="ANTICLOCKWISE INTEGRATION", direction="on", linebreak="al", + synonyms={ "counterclockwise integration" }, unicodeslot=0x2A11, }, [0x2A12]={ @@ -79635,6 +80427,7 @@ characters.data={ description="INTEGRAL WITH OVERBAR", direction="on", linebreak="al", + synonyms={ "upper integral" }, unicodeslot=0x2A1B, }, [0x2A1C]={ @@ -79642,6 +80435,7 @@ characters.data={ description="INTEGRAL WITH UNDERBAR", direction="on", linebreak="al", + synonyms={ "lower integral" }, unicodeslot=0x2A1C, }, [0x2A1D]={ @@ -79649,6 +80443,7 @@ characters.data={ description="JOIN", direction="on", linebreak="al", + synonyms={ "large bowtie" }, unicodeslot=0x2A1D, }, [0x2A1E]={ @@ -79698,6 +80493,7 @@ characters.data={ description="PLUS SIGN WITH TILDE ABOVE", direction="on", linebreak="al", + synonyms={ "positive difference or sum" }, unicodeslot=0x2A24, }, [0x2A25]={ @@ -79712,6 +80508,7 @@ characters.data={ description="PLUS SIGN WITH TILDE BELOW", direction="on", linebreak="al", + synonyms={ "sum or positive difference" }, unicodeslot=0x2A26, }, [0x2A27]={ @@ -79719,6 +80516,7 @@ characters.data={ description="PLUS SIGN WITH SUBSCRIPT TWO", direction="on", linebreak="al", + synonyms={ "nim-addition" }, unicodeslot=0x2A27, }, [0x2A28]={ @@ -79917,6 +80715,7 @@ characters.data={ description="UNION WITH MINUS SIGN", direction="on", linebreak="al", + synonyms={ "bag subtraction" }, unicodeslot=0x2A41, }, [0x2A42]={ @@ -80651,6 +81450,7 @@ characters.data={ direction="on", linebreak="al", mirror=0x2AA2, + synonyms={ "absolute continuity" }, unicodeslot=0x2AA1, }, [0x2AA2]={ @@ -81144,6 +81944,7 @@ characters.data={ direction="on", linebreak="al", specials={ "char", 0x2ADD, 0x338 }, + synonyms={ "not independent" }, unicodeslot=0x2ADC, }, [0x2ADD]={ @@ -81151,6 +81952,7 @@ characters.data={ description="NONFORKING", direction="on", linebreak="al", + synonyms={ "independent" }, unicodeslot=0x2ADD, }, [0x2ADE]={ @@ -81187,6 +81989,7 @@ characters.data={ description="VERTICAL BAR TRIPLE RIGHT TURNSTILE", direction="on", linebreak="al", + synonyms={ "ordinarily satisfies" }, unicodeslot=0x2AE2, }, [0x2AE3]={ @@ -81253,6 +82056,7 @@ characters.data={ description="DOUBLE UP TACK", direction="on", linebreak="al", + synonyms={ "independence" }, unicodeslot=0x2AEB, }, [0x2AEC]={ @@ -81297,6 +82101,7 @@ characters.data={ description="DOWN TACK WITH CIRCLE BELOW", direction="on", linebreak="al", + synonyms={ "necessarily satisfies" }, unicodeslot=0x2AF1, }, [0x2AF2]={ @@ -81318,6 +82123,7 @@ characters.data={ description="TRIPLE VERTICAL BAR BINARY RELATION", direction="on", linebreak="al", + synonyms={ "interleave" }, unicodeslot=0x2AF4, }, [0x2AF5]={ @@ -81392,6 +82198,7 @@ characters.data={ description="WHITE VERTICAL BAR", direction="on", linebreak="al", + synonyms={ "dijkstra choice" }, unicodeslot=0x2AFE, }, [0x2AFF]={ @@ -81399,6 +82206,7 @@ characters.data={ description="N-ARY WHITE VERTICAL BAR", direction="on", linebreak="al", + synonyms={ "n-ary dijkstra choice" }, unicodeslot=0x2AFF, }, [0x2B00]={ @@ -81442,10 +82250,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2B05, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2B06]={ category="so", @@ -81453,10 +82258,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2B06, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2B07]={ category="so", @@ -81464,10 +82266,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x2B07, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2B08]={ category="so", @@ -81604,25 +82403,21 @@ characters.data={ }, [0x2B1B]={ category="so", + cjkwd="w", description="BLACK LARGE SQUARE", direction="on", linebreak="al", unicodeslot=0x2B1B, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2B1C]={ category="so", + cjkwd="w", description="WHITE LARGE SQUARE", direction="on", linebreak="al", unicodeslot=0x2B1C, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2B1D]={ category="so", @@ -81998,14 +82793,12 @@ characters.data={ }, [0x2B50]={ category="so", + cjkwd="w", description="WHITE MEDIUM STAR", direction="on", linebreak="al", unicodeslot=0x2B50, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2B51]={ category="so", @@ -82037,15 +82830,12 @@ characters.data={ }, [0x2B55]={ category="so", - cjkwd="a", + cjkwd="w", description="HEAVY LARGE CIRCLE", direction="on", linebreak="ai", unicodeslot=0x2B55, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x2B56]={ category="so", @@ -82238,6 +83028,7 @@ characters.data={ description="LEFTWARDS TRIANGLE-HEADED ARROW TO BAR", direction="on", linebreak="al", + synonyms={ "left tab" }, unicodeslot=0x2B70, }, [0x2B71]={ @@ -82245,6 +83036,7 @@ characters.data={ description="UPWARDS TRIANGLE-HEADED ARROW TO BAR", direction="on", linebreak="al", + synonyms={ "up tab" }, unicodeslot=0x2B71, }, [0x2B72]={ @@ -82252,6 +83044,7 @@ characters.data={ description="RIGHTWARDS TRIANGLE-HEADED ARROW TO BAR", direction="on", linebreak="al", + synonyms={ "right tab" }, unicodeslot=0x2B72, }, [0x2B73]={ @@ -82259,6 +83052,7 @@ characters.data={ description="DOWNWARDS TRIANGLE-HEADED ARROW TO BAR", direction="on", linebreak="al", + synonyms={ "down tab" }, unicodeslot=0x2B73, }, [0x2B76]={ @@ -82315,6 +83109,7 @@ characters.data={ description="DOWNWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE", direction="on", linebreak="al", + synonyms={ "page down" }, unicodeslot=0x2B7D, }, [0x2B7E]={ @@ -82721,6 +83516,7 @@ characters.data={ description="UP ARROWHEAD IN A RECTANGLE BOX", direction="on", linebreak="al", + synonyms={ "escape" }, unicodeslot=0x2BB9, }, [0x2BBD]={ @@ -86585,6 +87381,7 @@ characters.data={ description="INVERTED INTERROBANG", direction="on", linebreak="op", + synonyms={ "gnaborretni" }, unicodeslot=0x2E18, }, [0x2E19]={ @@ -86835,6 +87632,7 @@ characters.data={ description="TWO-EM DASH", direction="on", linebreak="b2", + synonyms={ "omission dash" }, unicodeslot=0x2E3A, }, [0x2E3B]={ @@ -86893,6 +87691,20 @@ characters.data={ linebreak="op", unicodeslot=0x2E42, }, + [0x2E43]={ + category="po", + description="DASH WITH LEFT UPTURN", + direction="on", + linebreak="ba", + unicodeslot=0x2E43, + }, + [0x2E44]={ + category="po", + description="DOUBLE SUSPENSION MARK", + direction="on", + linebreak="ba", + unicodeslot=0x2E44, + }, [0x2E80]={ category="so", cjkwd="w", @@ -90096,6 +90908,7 @@ characters.data={ direction="on", linebreak="op", mirror=0x301B, + synonyms={ "left abstract syntax bracket" }, unicodeslot=0x301A, }, [0x301B]={ @@ -90105,6 +90918,7 @@ characters.data={ direction="on", linebreak="cl", mirror=0x301A, + synonyms={ "right abstract syntax bracket" }, unicodeslot=0x301B, }, [0x301C]={ @@ -90293,10 +91107,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x3030, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x3031]={ category="lm", @@ -90406,10 +91217,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x303D, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x303E]={ category="so", @@ -91491,6 +92299,7 @@ characters.data={ direction="nsm", linebreak="cm", sound="voiced", + synonyms={ "combining japanese daku-on" }, unicodeslot=0x3099, }, [0x309A]={ @@ -91501,6 +92310,7 @@ characters.data={ direction="nsm", linebreak="cm", sound="semivoiced", + synonyms={ "combining japanese han-daku-on" }, unicodeslot=0x309A, }, [0x309B]={ @@ -91512,6 +92322,7 @@ characters.data={ linebreak="ns", sound="voiced", specials={ "compat", 0x20, 0x3099 }, + synonyms={ "japanese daku-on" }, unicodeslot=0x309B, }, [0x309C]={ @@ -91523,6 +92334,7 @@ characters.data={ linebreak="ns", sound="semivoiced", specials={ "compat", 0x20, 0x309A }, + synonyms={ "japanese han-daku-on" }, unicodeslot=0x309C, }, [0x309D]={ @@ -96289,10 +97101,7 @@ characters.data={ linebreak="id", specials={ "circle", 0x795D }, unicodeslot=0x3297, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x3298]={ adobename="ideographiclaborcircle", @@ -96313,10 +97122,7 @@ characters.data={ linebreak="id", specials={ "circle", 0x79D8 }, unicodeslot=0x3299, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x329A]={ category="so", @@ -98419,6 +99225,7 @@ characters.data={ direction="l", linebreak="id", specials={ "square", 0x682A, 0x5F0F, 0x4F1A, 0x793E }, + synonyms={ "japanese incorporated", "kabusiki-gaisya" }, unicodeslot=0x337F, }, [0x3380]={ @@ -114831,6 +115638,13 @@ characters.data={ linebreak="al", unicodeslot=0xA7AD, }, + [0xA7AE]={ + category="lu", + description="LATIN CAPITAL LETTER SMALL CAPITAL I", + direction="l", + linebreak="al", + unicodeslot=0xA7AE, + }, [0xA7B0]={ category="lu", description="LATIN CAPITAL LETTER TURNED K", @@ -116277,6 +117091,13 @@ characters.data={ linebreak="cm", unicodeslot=0xA8C4, }, + [0xA8C5]={ + category="mn", + description="SAURASHTRA SIGN CANDRABINDU", + direction="nsm", + linebreak="cm", + unicodeslot=0xA8C5, + }, [0xA8CE]={ category="po", description="SAURASHTRA DANDA", @@ -118863,6 +119684,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0xAA60, + variants={ + [0xFE00]="dotted form", + }, }, [0xAA61]={ category="lo", @@ -118870,6 +119694,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0xAA61, + variants={ + [0xFE00]="dotted form", + }, }, [0xAA62]={ category="lo", @@ -118877,6 +119704,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0xAA62, + variants={ + [0xFE00]="dotted form", + }, }, [0xAA63]={ category="lo", @@ -118884,6 +119714,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0xAA63, + variants={ + [0xFE00]="dotted form", + }, }, [0xAA64]={ category="lo", @@ -118891,6 +119724,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0xAA64, + variants={ + [0xFE00]="dotted form", + }, }, [0xAA65]={ category="lo", @@ -118898,6 +119734,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0xAA65, + variants={ + [0xFE00]="dotted form", + }, }, [0xAA66]={ category="lo", @@ -118905,6 +119744,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0xAA66, + variants={ + [0xFE00]="dotted form", + }, }, [0xAA67]={ category="lo", @@ -118940,6 +119782,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0xAA6B, + variants={ + [0xFE00]="dotted form", + }, }, [0xAA6C]={ category="lo", @@ -118947,6 +119792,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0xAA6C, + variants={ + [0xFE00]="dotted form", + }, }, [0xAA6D]={ category="lo", @@ -118968,6 +119816,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0xAA6F, + variants={ + [0xFE00]="dotted form", + }, }, [0xAA70]={ category="lm", @@ -119045,6 +119896,9 @@ characters.data={ direction="l", linebreak="sa", unicodeslot=0xAA7A, + variants={ + [0xFE00]="dotted form", + }, }, [0xAA7B]={ category="mc", @@ -131580,6 +132434,7 @@ characters.data={ direction="al", linebreak="po", specials={ "isolated", 0x631, 0x6CC, 0x627, 0x644 }, + synonyms={ "iranian currency" }, unicodeslot=0xFDFC, }, [0xFDFD]={ @@ -131589,6 +132444,11 @@ characters.data={ linebreak="al", unicodeslot=0xFDFD, }, + [0xFE00]={ + description="VARIATION SELECTOR-0x0001", + synonyms={ "vs1" }, + unicodeslot=0xFE00, + }, [0xFE10]={ category="po", cjkwd="w", @@ -133623,6 +134483,7 @@ characters.data={ description="ZERO WIDTH NO-BREAK SPACE", direction="bn", linebreak="wj", + synonyms={ "bom", "byte order mark", "zwnbsp" }, unicodeslot=0xFEFF, }, [0xFF01]={ @@ -134715,7 +135576,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER WO", direction="l", - linebreak="al", + linebreak="id", shcode=0x3092, specials={ "narrow", 0x30F2 }, unicodeslot=0xFF66, @@ -134830,7 +135691,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER A", direction="l", - linebreak="al", + linebreak="id", shcode=0x3042, specials={ "narrow", 0x30A2 }, unicodeslot=0xFF71, @@ -134841,7 +135702,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER I", direction="l", - linebreak="al", + linebreak="id", shcode=0x3044, specials={ "narrow", 0x30A4 }, unicodeslot=0xFF72, @@ -134852,7 +135713,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER U", direction="l", - linebreak="al", + linebreak="id", shcode=0x3046, specials={ "narrow", 0x30A6 }, unicodeslot=0xFF73, @@ -134863,7 +135724,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER E", direction="l", - linebreak="al", + linebreak="id", shcode=0x3048, specials={ "narrow", 0x30A8 }, unicodeslot=0xFF74, @@ -134874,7 +135735,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER O", direction="l", - linebreak="al", + linebreak="id", shcode=0x304A, specials={ "narrow", 0x30AA }, unicodeslot=0xFF75, @@ -134885,7 +135746,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER KA", direction="l", - linebreak="al", + linebreak="id", shcode=0x304B, specials={ "narrow", 0x30AB }, unicodeslot=0xFF76, @@ -134896,7 +135757,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER KI", direction="l", - linebreak="al", + linebreak="id", shcode=0x304D, specials={ "narrow", 0x30AD }, unicodeslot=0xFF77, @@ -134907,7 +135768,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER KU", direction="l", - linebreak="al", + linebreak="id", shcode=0x304F, specials={ "narrow", 0x30AF }, unicodeslot=0xFF78, @@ -134918,7 +135779,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER KE", direction="l", - linebreak="al", + linebreak="id", shcode=0x3051, specials={ "narrow", 0x30B1 }, unicodeslot=0xFF79, @@ -134929,7 +135790,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER KO", direction="l", - linebreak="al", + linebreak="id", shcode=0x3053, specials={ "narrow", 0x30B3 }, unicodeslot=0xFF7A, @@ -134940,7 +135801,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER SA", direction="l", - linebreak="al", + linebreak="id", shcode=0x3055, specials={ "narrow", 0x30B5 }, unicodeslot=0xFF7B, @@ -134951,7 +135812,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER SI", direction="l", - linebreak="al", + linebreak="id", shcode=0x3057, specials={ "narrow", 0x30B7 }, unicodeslot=0xFF7C, @@ -134962,7 +135823,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER SU", direction="l", - linebreak="al", + linebreak="id", shcode=0x3059, specials={ "narrow", 0x30B9 }, unicodeslot=0xFF7D, @@ -134973,7 +135834,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER SE", direction="l", - linebreak="al", + linebreak="id", shcode=0x305B, specials={ "narrow", 0x30BB }, unicodeslot=0xFF7E, @@ -134984,7 +135845,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER SO", direction="l", - linebreak="al", + linebreak="id", shcode=0x305D, specials={ "narrow", 0x30BD }, unicodeslot=0xFF7F, @@ -134995,7 +135856,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER TA", direction="l", - linebreak="al", + linebreak="id", shcode=0x305F, specials={ "narrow", 0x30BF }, unicodeslot=0xFF80, @@ -135006,7 +135867,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER TI", direction="l", - linebreak="al", + linebreak="id", shcode=0x3061, specials={ "narrow", 0x30C1 }, unicodeslot=0xFF81, @@ -135017,7 +135878,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER TU", direction="l", - linebreak="al", + linebreak="id", shcode=0x3064, specials={ "narrow", 0x30C4 }, unicodeslot=0xFF82, @@ -135028,7 +135889,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER TE", direction="l", - linebreak="al", + linebreak="id", shcode=0x3066, specials={ "narrow", 0x30C6 }, unicodeslot=0xFF83, @@ -135039,7 +135900,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER TO", direction="l", - linebreak="al", + linebreak="id", shcode=0x3068, specials={ "narrow", 0x30C8 }, unicodeslot=0xFF84, @@ -135050,7 +135911,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER NA", direction="l", - linebreak="al", + linebreak="id", shcode=0x306A, specials={ "narrow", 0x30CA }, unicodeslot=0xFF85, @@ -135061,7 +135922,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER NI", direction="l", - linebreak="al", + linebreak="id", shcode=0x306B, specials={ "narrow", 0x30CB }, unicodeslot=0xFF86, @@ -135072,7 +135933,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER NU", direction="l", - linebreak="al", + linebreak="id", shcode=0x306C, specials={ "narrow", 0x30CC }, unicodeslot=0xFF87, @@ -135083,7 +135944,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER NE", direction="l", - linebreak="al", + linebreak="id", shcode=0x306D, specials={ "narrow", 0x30CD }, unicodeslot=0xFF88, @@ -135094,7 +135955,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER NO", direction="l", - linebreak="al", + linebreak="id", shcode=0x306E, specials={ "narrow", 0x30CE }, unicodeslot=0xFF89, @@ -135105,7 +135966,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER HA", direction="l", - linebreak="al", + linebreak="id", shcode=0x306F, specials={ "narrow", 0x30CF }, unicodeslot=0xFF8A, @@ -135116,7 +135977,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER HI", direction="l", - linebreak="al", + linebreak="id", shcode=0x3072, specials={ "narrow", 0x30D2 }, unicodeslot=0xFF8B, @@ -135127,7 +135988,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER HU", direction="l", - linebreak="al", + linebreak="id", shcode=0x3075, specials={ "narrow", 0x30D5 }, unicodeslot=0xFF8C, @@ -135138,7 +135999,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER HE", direction="l", - linebreak="al", + linebreak="id", shcode=0x3078, specials={ "narrow", 0x30D8 }, unicodeslot=0xFF8D, @@ -135149,7 +136010,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER HO", direction="l", - linebreak="al", + linebreak="id", shcode=0x307B, specials={ "narrow", 0x30DB }, unicodeslot=0xFF8E, @@ -135160,7 +136021,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER MA", direction="l", - linebreak="al", + linebreak="id", shcode=0x307E, specials={ "narrow", 0x30DE }, unicodeslot=0xFF8F, @@ -135171,7 +136032,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER MI", direction="l", - linebreak="al", + linebreak="id", shcode=0x307F, specials={ "narrow", 0x30DF }, unicodeslot=0xFF90, @@ -135182,7 +136043,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER MU", direction="l", - linebreak="al", + linebreak="id", shcode=0x3080, specials={ "narrow", 0x30E0 }, unicodeslot=0xFF91, @@ -135193,7 +136054,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER ME", direction="l", - linebreak="al", + linebreak="id", shcode=0x3081, specials={ "narrow", 0x30E1 }, unicodeslot=0xFF92, @@ -135204,7 +136065,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER MO", direction="l", - linebreak="al", + linebreak="id", shcode=0x3082, specials={ "narrow", 0x30E2 }, unicodeslot=0xFF93, @@ -135215,7 +136076,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER YA", direction="l", - linebreak="al", + linebreak="id", shcode=0x3084, specials={ "narrow", 0x30E4 }, unicodeslot=0xFF94, @@ -135226,7 +136087,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER YU", direction="l", - linebreak="al", + linebreak="id", shcode=0x3086, specials={ "narrow", 0x30E6 }, unicodeslot=0xFF95, @@ -135237,7 +136098,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER YO", direction="l", - linebreak="al", + linebreak="id", shcode=0x3088, specials={ "narrow", 0x30E8 }, unicodeslot=0xFF96, @@ -135248,7 +136109,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER RA", direction="l", - linebreak="al", + linebreak="id", shcode=0x3089, specials={ "narrow", 0x30E9 }, unicodeslot=0xFF97, @@ -135259,7 +136120,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER RI", direction="l", - linebreak="al", + linebreak="id", shcode=0x308A, specials={ "narrow", 0x30EA }, unicodeslot=0xFF98, @@ -135270,7 +136131,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER RU", direction="l", - linebreak="al", + linebreak="id", shcode=0x308B, specials={ "narrow", 0x30EB }, unicodeslot=0xFF99, @@ -135281,7 +136142,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER RE", direction="l", - linebreak="al", + linebreak="id", shcode=0x308C, specials={ "narrow", 0x30EC }, unicodeslot=0xFF9A, @@ -135292,7 +136153,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER RO", direction="l", - linebreak="al", + linebreak="id", shcode=0x308D, specials={ "narrow", 0x30ED }, unicodeslot=0xFF9B, @@ -135303,7 +136164,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER WA", direction="l", - linebreak="al", + linebreak="id", shcode=0x308F, specials={ "narrow", 0x30EF }, unicodeslot=0xFF9C, @@ -135314,7 +136175,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH KATAKANA LETTER N", direction="l", - linebreak="al", + linebreak="id", shcode=0x3093, specials={ "narrow", 0x30F3 }, unicodeslot=0xFF9D, @@ -135344,7 +136205,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL FILLER", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3164 }, unicodeslot=0xFFA0, }, @@ -135353,7 +136214,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER KIYEOK", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3131 }, unicodeslot=0xFFA1, }, @@ -135362,7 +136223,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER SSANGKIYEOK", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3132 }, unicodeslot=0xFFA2, }, @@ -135371,7 +136232,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER KIYEOK-SIOS", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3133 }, unicodeslot=0xFFA3, }, @@ -135380,7 +136241,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER NIEUN", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3134 }, unicodeslot=0xFFA4, }, @@ -135389,7 +136250,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER NIEUN-CIEUC", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3135 }, unicodeslot=0xFFA5, }, @@ -135398,7 +136259,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER NIEUN-HIEUH", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3136 }, unicodeslot=0xFFA6, }, @@ -135407,7 +136268,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER TIKEUT", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3137 }, unicodeslot=0xFFA7, }, @@ -135416,7 +136277,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER SSANGTIKEUT", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3138 }, unicodeslot=0xFFA8, }, @@ -135425,7 +136286,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER RIEUL", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3139 }, unicodeslot=0xFFA9, }, @@ -135434,7 +136295,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER RIEUL-KIYEOK", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x313A }, unicodeslot=0xFFAA, }, @@ -135443,7 +136304,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER RIEUL-MIEUM", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x313B }, unicodeslot=0xFFAB, }, @@ -135452,7 +136313,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER RIEUL-PIEUP", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x313C }, unicodeslot=0xFFAC, }, @@ -135461,7 +136322,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER RIEUL-SIOS", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x313D }, unicodeslot=0xFFAD, }, @@ -135470,7 +136331,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER RIEUL-THIEUTH", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x313E }, unicodeslot=0xFFAE, }, @@ -135479,7 +136340,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x313F }, unicodeslot=0xFFAF, }, @@ -135488,7 +136349,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER RIEUL-HIEUH", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3140 }, unicodeslot=0xFFB0, }, @@ -135497,7 +136358,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER MIEUM", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3141 }, unicodeslot=0xFFB1, }, @@ -135506,7 +136367,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER PIEUP", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3142 }, unicodeslot=0xFFB2, }, @@ -135515,7 +136376,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER SSANGPIEUP", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3143 }, unicodeslot=0xFFB3, }, @@ -135524,7 +136385,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER PIEUP-SIOS", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3144 }, unicodeslot=0xFFB4, }, @@ -135533,7 +136394,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER SIOS", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3145 }, unicodeslot=0xFFB5, }, @@ -135542,7 +136403,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER SSANGSIOS", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3146 }, unicodeslot=0xFFB6, }, @@ -135551,7 +136412,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER IEUNG", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3147 }, unicodeslot=0xFFB7, }, @@ -135560,7 +136421,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER CIEUC", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3148 }, unicodeslot=0xFFB8, }, @@ -135569,7 +136430,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER SSANGCIEUC", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3149 }, unicodeslot=0xFFB9, }, @@ -135578,7 +136439,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER CHIEUCH", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x314A }, unicodeslot=0xFFBA, }, @@ -135587,7 +136448,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER KHIEUKH", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x314B }, unicodeslot=0xFFBB, }, @@ -135596,7 +136457,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER THIEUTH", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x314C }, unicodeslot=0xFFBC, }, @@ -135605,7 +136466,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER PHIEUPH", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x314D }, unicodeslot=0xFFBD, }, @@ -135614,7 +136475,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER HIEUH", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x314E }, unicodeslot=0xFFBE, }, @@ -135623,7 +136484,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER A", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x314F }, unicodeslot=0xFFC2, }, @@ -135632,7 +136493,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER AE", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3150 }, unicodeslot=0xFFC3, }, @@ -135641,7 +136502,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER YA", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3151 }, unicodeslot=0xFFC4, }, @@ -135650,7 +136511,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER YAE", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3152 }, unicodeslot=0xFFC5, }, @@ -135659,7 +136520,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER EO", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3153 }, unicodeslot=0xFFC6, }, @@ -135668,7 +136529,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER E", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3154 }, unicodeslot=0xFFC7, }, @@ -135677,7 +136538,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER YEO", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3155 }, unicodeslot=0xFFCA, }, @@ -135686,7 +136547,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER YE", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3156 }, unicodeslot=0xFFCB, }, @@ -135695,7 +136556,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER O", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3157 }, unicodeslot=0xFFCC, }, @@ -135704,7 +136565,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER WA", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3158 }, unicodeslot=0xFFCD, }, @@ -135713,7 +136574,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER WAE", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3159 }, unicodeslot=0xFFCE, }, @@ -135722,7 +136583,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER OE", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x315A }, unicodeslot=0xFFCF, }, @@ -135731,7 +136592,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER YO", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x315B }, unicodeslot=0xFFD2, }, @@ -135740,7 +136601,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER U", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x315C }, unicodeslot=0xFFD3, }, @@ -135749,7 +136610,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER WEO", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x315D }, unicodeslot=0xFFD4, }, @@ -135758,7 +136619,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER WE", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x315E }, unicodeslot=0xFFD5, }, @@ -135767,7 +136628,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER WI", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x315F }, unicodeslot=0xFFD6, }, @@ -135776,7 +136637,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER YU", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3160 }, unicodeslot=0xFFD7, }, @@ -135785,7 +136646,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER EU", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3161 }, unicodeslot=0xFFDA, }, @@ -135794,7 +136655,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER YI", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3162 }, unicodeslot=0xFFDB, }, @@ -135803,7 +136664,7 @@ characters.data={ cjkwd="h", description="HALFWIDTH HANGUL LETTER I", direction="l", - linebreak="al", + linebreak="id", specials={ "narrow", 0x3163 }, unicodeslot=0xFFDC, }, @@ -138392,6 +139253,20 @@ characters.data={ linebreak="al", unicodeslot=0x1018C, }, + [0x1018D]={ + category="so", + description="GREEK INDICTION SIGN", + direction="l", + linebreak="al", + unicodeslot=0x1018D, + }, + [0x1018E]={ + category="so", + description="NOMISMA SIGN", + direction="l", + linebreak="al", + unicodeslot=0x1018E, + }, [0x10190]={ category="so", description="ROMAN SEXTANS SIGN", @@ -142119,6 +142994,510 @@ characters.data={ linebreak="nu", unicodeslot=0x104A9, }, + [0x104B0]={ + category="lu", + description="OSAGE CAPITAL LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x104B0, + }, + [0x104B1]={ + category="lu", + description="OSAGE CAPITAL LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x104B1, + }, + [0x104B2]={ + category="lu", + description="OSAGE CAPITAL LETTER AIN", + direction="l", + linebreak="al", + unicodeslot=0x104B2, + }, + [0x104B3]={ + category="lu", + description="OSAGE CAPITAL LETTER AH", + direction="l", + linebreak="al", + unicodeslot=0x104B3, + }, + [0x104B4]={ + category="lu", + description="OSAGE CAPITAL LETTER BRA", + direction="l", + linebreak="al", + unicodeslot=0x104B4, + }, + [0x104B5]={ + category="lu", + description="OSAGE CAPITAL LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x104B5, + }, + [0x104B6]={ + category="lu", + description="OSAGE CAPITAL LETTER EHCHA", + direction="l", + linebreak="al", + unicodeslot=0x104B6, + }, + [0x104B7]={ + category="lu", + description="OSAGE CAPITAL LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x104B7, + }, + [0x104B8]={ + category="lu", + description="OSAGE CAPITAL LETTER EIN", + direction="l", + linebreak="al", + unicodeslot=0x104B8, + }, + [0x104B9]={ + category="lu", + description="OSAGE CAPITAL LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x104B9, + }, + [0x104BA]={ + category="lu", + description="OSAGE CAPITAL LETTER HYA", + direction="l", + linebreak="al", + unicodeslot=0x104BA, + }, + [0x104BB]={ + category="lu", + description="OSAGE CAPITAL LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x104BB, + }, + [0x104BC]={ + category="lu", + description="OSAGE CAPITAL LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x104BC, + }, + [0x104BD]={ + category="lu", + description="OSAGE CAPITAL LETTER EHKA", + direction="l", + linebreak="al", + unicodeslot=0x104BD, + }, + [0x104BE]={ + category="lu", + description="OSAGE CAPITAL LETTER KYA", + direction="l", + linebreak="al", + unicodeslot=0x104BE, + }, + [0x104BF]={ + category="lu", + description="OSAGE CAPITAL LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x104BF, + }, + [0x104C0]={ + category="lu", + description="OSAGE CAPITAL LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x104C0, + }, + [0x104C1]={ + category="lu", + description="OSAGE CAPITAL LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x104C1, + }, + [0x104C2]={ + category="lu", + description="OSAGE CAPITAL LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x104C2, + }, + [0x104C3]={ + category="lu", + description="OSAGE CAPITAL LETTER OIN", + direction="l", + linebreak="al", + unicodeslot=0x104C3, + }, + [0x104C4]={ + category="lu", + description="OSAGE CAPITAL LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x104C4, + }, + [0x104C5]={ + category="lu", + description="OSAGE CAPITAL LETTER EHPA", + direction="l", + linebreak="al", + unicodeslot=0x104C5, + }, + [0x104C6]={ + category="lu", + description="OSAGE CAPITAL LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x104C6, + }, + [0x104C7]={ + category="lu", + description="OSAGE CAPITAL LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x104C7, + }, + [0x104C8]={ + category="lu", + description="OSAGE CAPITAL LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x104C8, + }, + [0x104C9]={ + category="lu", + description="OSAGE CAPITAL LETTER EHTA", + direction="l", + linebreak="al", + unicodeslot=0x104C9, + }, + [0x104CA]={ + category="lu", + description="OSAGE CAPITAL LETTER TSA", + direction="l", + linebreak="al", + unicodeslot=0x104CA, + }, + [0x104CB]={ + category="lu", + description="OSAGE CAPITAL LETTER EHTSA", + direction="l", + linebreak="al", + unicodeslot=0x104CB, + }, + [0x104CC]={ + category="lu", + description="OSAGE CAPITAL LETTER TSHA", + direction="l", + linebreak="al", + unicodeslot=0x104CC, + }, + [0x104CD]={ + category="lu", + description="OSAGE CAPITAL LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x104CD, + }, + [0x104CE]={ + category="lu", + description="OSAGE CAPITAL LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x104CE, + }, + [0x104CF]={ + category="lu", + description="OSAGE CAPITAL LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0x104CF, + }, + [0x104D0]={ + category="lu", + description="OSAGE CAPITAL LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x104D0, + }, + [0x104D1]={ + category="lu", + description="OSAGE CAPITAL LETTER GHA", + direction="l", + linebreak="al", + unicodeslot=0x104D1, + }, + [0x104D2]={ + category="lu", + description="OSAGE CAPITAL LETTER ZA", + direction="l", + linebreak="al", + unicodeslot=0x104D2, + }, + [0x104D3]={ + category="lu", + description="OSAGE CAPITAL LETTER ZHA", + direction="l", + linebreak="al", + unicodeslot=0x104D3, + }, + [0x104D8]={ + category="ll", + description="OSAGE SMALL LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x104D8, + }, + [0x104D9]={ + category="ll", + description="OSAGE SMALL LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x104D9, + }, + [0x104DA]={ + category="ll", + description="OSAGE SMALL LETTER AIN", + direction="l", + linebreak="al", + unicodeslot=0x104DA, + }, + [0x104DB]={ + category="ll", + description="OSAGE SMALL LETTER AH", + direction="l", + linebreak="al", + unicodeslot=0x104DB, + }, + [0x104DC]={ + category="ll", + description="OSAGE SMALL LETTER BRA", + direction="l", + linebreak="al", + unicodeslot=0x104DC, + }, + [0x104DD]={ + category="ll", + description="OSAGE SMALL LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x104DD, + }, + [0x104DE]={ + category="ll", + description="OSAGE SMALL LETTER EHCHA", + direction="l", + linebreak="al", + unicodeslot=0x104DE, + }, + [0x104DF]={ + category="ll", + description="OSAGE SMALL LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x104DF, + }, + [0x104E0]={ + category="ll", + description="OSAGE SMALL LETTER EIN", + direction="l", + linebreak="al", + unicodeslot=0x104E0, + }, + [0x104E1]={ + category="ll", + description="OSAGE SMALL LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x104E1, + }, + [0x104E2]={ + category="ll", + description="OSAGE SMALL LETTER HYA", + direction="l", + linebreak="al", + unicodeslot=0x104E2, + }, + [0x104E3]={ + category="ll", + description="OSAGE SMALL LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x104E3, + }, + [0x104E4]={ + category="ll", + description="OSAGE SMALL LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x104E4, + }, + [0x104E5]={ + category="ll", + description="OSAGE SMALL LETTER EHKA", + direction="l", + linebreak="al", + unicodeslot=0x104E5, + }, + [0x104E6]={ + category="ll", + description="OSAGE SMALL LETTER KYA", + direction="l", + linebreak="al", + unicodeslot=0x104E6, + }, + [0x104E7]={ + category="ll", + description="OSAGE SMALL LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x104E7, + }, + [0x104E8]={ + category="ll", + description="OSAGE SMALL LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x104E8, + }, + [0x104E9]={ + category="ll", + description="OSAGE SMALL LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x104E9, + }, + [0x104EA]={ + category="ll", + description="OSAGE SMALL LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x104EA, + }, + [0x104EB]={ + category="ll", + description="OSAGE SMALL LETTER OIN", + direction="l", + linebreak="al", + unicodeslot=0x104EB, + }, + [0x104EC]={ + category="ll", + description="OSAGE SMALL LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x104EC, + }, + [0x104ED]={ + category="ll", + description="OSAGE SMALL LETTER EHPA", + direction="l", + linebreak="al", + unicodeslot=0x104ED, + }, + [0x104EE]={ + category="ll", + description="OSAGE SMALL LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x104EE, + }, + [0x104EF]={ + category="ll", + description="OSAGE SMALL LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x104EF, + }, + [0x104F0]={ + category="ll", + description="OSAGE SMALL LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x104F0, + }, + [0x104F1]={ + category="ll", + description="OSAGE SMALL LETTER EHTA", + direction="l", + linebreak="al", + unicodeslot=0x104F1, + }, + [0x104F2]={ + category="ll", + description="OSAGE SMALL LETTER TSA", + direction="l", + linebreak="al", + unicodeslot=0x104F2, + }, + [0x104F3]={ + category="ll", + description="OSAGE SMALL LETTER EHTSA", + direction="l", + linebreak="al", + unicodeslot=0x104F3, + }, + [0x104F4]={ + category="ll", + description="OSAGE SMALL LETTER TSHA", + direction="l", + linebreak="al", + unicodeslot=0x104F4, + }, + [0x104F5]={ + category="ll", + description="OSAGE SMALL LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x104F5, + }, + [0x104F6]={ + category="ll", + description="OSAGE SMALL LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x104F6, + }, + [0x104F7]={ + category="ll", + description="OSAGE SMALL LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0x104F7, + }, + [0x104F8]={ + category="ll", + description="OSAGE SMALL LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x104F8, + }, + [0x104F9]={ + category="ll", + description="OSAGE SMALL LETTER GHA", + direction="l", + linebreak="al", + unicodeslot=0x104F9, + }, + [0x104FA]={ + category="ll", + description="OSAGE SMALL LETTER ZA", + direction="l", + linebreak="al", + unicodeslot=0x104FA, + }, + [0x104FB]={ + category="ll", + description="OSAGE SMALL LETTER ZHA", + direction="l", + linebreak="al", + unicodeslot=0x104FB, + }, [0x10500]={ category="lo", description="ELBASAN LETTER A", @@ -155010,6 +156389,13 @@ characters.data={ linebreak="al", unicodeslot=0x1123D, }, + [0x1123E]={ + category="mn", + description="KHOJKI SIGN SUKUN", + direction="nsm", + linebreak="cm", + unicodeslot=0x1123E, + }, [0x11280]={ category="lo", description="MULTANI LETTER A", @@ -156372,6 +157758,652 @@ characters.data={ linebreak="cm", unicodeslot=0x11374, }, + [0x11400]={ + category="lo", + description="NEWA LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x11400, + }, + [0x11401]={ + category="lo", + description="NEWA LETTER AA", + direction="l", + linebreak="al", + unicodeslot=0x11401, + }, + [0x11402]={ + category="lo", + description="NEWA LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x11402, + }, + [0x11403]={ + category="lo", + description="NEWA LETTER II", + direction="l", + linebreak="al", + unicodeslot=0x11403, + }, + [0x11404]={ + category="lo", + description="NEWA LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x11404, + }, + [0x11405]={ + category="lo", + description="NEWA LETTER UU", + direction="l", + linebreak="al", + unicodeslot=0x11405, + }, + [0x11406]={ + category="lo", + description="NEWA LETTER VOCALIC R", + direction="l", + linebreak="al", + unicodeslot=0x11406, + }, + [0x11407]={ + category="lo", + description="NEWA LETTER VOCALIC RR", + direction="l", + linebreak="al", + unicodeslot=0x11407, + }, + [0x11408]={ + category="lo", + description="NEWA LETTER VOCALIC L", + direction="l", + linebreak="al", + unicodeslot=0x11408, + }, + [0x11409]={ + category="lo", + description="NEWA LETTER VOCALIC LL", + direction="l", + linebreak="al", + unicodeslot=0x11409, + }, + [0x1140A]={ + category="lo", + description="NEWA LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x1140A, + }, + [0x1140B]={ + category="lo", + description="NEWA LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x1140B, + }, + [0x1140C]={ + category="lo", + description="NEWA LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x1140C, + }, + [0x1140D]={ + category="lo", + description="NEWA LETTER AU", + direction="l", + linebreak="al", + unicodeslot=0x1140D, + }, + [0x1140E]={ + category="lo", + description="NEWA LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x1140E, + }, + [0x1140F]={ + category="lo", + description="NEWA LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x1140F, + }, + [0x11410]={ + category="lo", + description="NEWA LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x11410, + }, + [0x11411]={ + category="lo", + description="NEWA LETTER GHA", + direction="l", + linebreak="al", + unicodeslot=0x11411, + }, + [0x11412]={ + category="lo", + description="NEWA LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x11412, + }, + [0x11413]={ + category="lo", + description="NEWA LETTER NGHA", + direction="l", + linebreak="al", + unicodeslot=0x11413, + }, + [0x11414]={ + category="lo", + description="NEWA LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x11414, + }, + [0x11415]={ + category="lo", + description="NEWA LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x11415, + }, + [0x11416]={ + category="lo", + description="NEWA LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x11416, + }, + [0x11417]={ + category="lo", + description="NEWA LETTER JHA", + direction="l", + linebreak="al", + unicodeslot=0x11417, + }, + [0x11418]={ + category="lo", + description="NEWA LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x11418, + }, + [0x11419]={ + category="lo", + description="NEWA LETTER NYHA", + direction="l", + linebreak="al", + unicodeslot=0x11419, + }, + [0x1141A]={ + category="lo", + description="NEWA LETTER TTA", + direction="l", + linebreak="al", + unicodeslot=0x1141A, + }, + [0x1141B]={ + category="lo", + description="NEWA LETTER TTHA", + direction="l", + linebreak="al", + unicodeslot=0x1141B, + }, + [0x1141C]={ + category="lo", + description="NEWA LETTER DDA", + direction="l", + linebreak="al", + unicodeslot=0x1141C, + }, + [0x1141D]={ + category="lo", + description="NEWA LETTER DDHA", + direction="l", + linebreak="al", + unicodeslot=0x1141D, + }, + [0x1141E]={ + category="lo", + description="NEWA LETTER NNA", + direction="l", + linebreak="al", + unicodeslot=0x1141E, + }, + [0x1141F]={ + category="lo", + description="NEWA LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x1141F, + }, + [0x11420]={ + category="lo", + description="NEWA LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0x11420, + }, + [0x11421]={ + category="lo", + description="NEWA LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x11421, + }, + [0x11422]={ + category="lo", + description="NEWA LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x11422, + }, + [0x11423]={ + category="lo", + description="NEWA LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x11423, + }, + [0x11424]={ + category="lo", + description="NEWA LETTER NHA", + direction="l", + linebreak="al", + unicodeslot=0x11424, + }, + [0x11425]={ + category="lo", + description="NEWA LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x11425, + }, + [0x11426]={ + category="lo", + description="NEWA LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0x11426, + }, + [0x11427]={ + category="lo", + description="NEWA LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x11427, + }, + [0x11428]={ + category="lo", + description="NEWA LETTER BHA", + direction="l", + linebreak="al", + unicodeslot=0x11428, + }, + [0x11429]={ + category="lo", + description="NEWA LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x11429, + }, + [0x1142A]={ + category="lo", + description="NEWA LETTER MHA", + direction="l", + linebreak="al", + unicodeslot=0x1142A, + }, + [0x1142B]={ + category="lo", + description="NEWA LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x1142B, + }, + [0x1142C]={ + category="lo", + description="NEWA LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x1142C, + }, + [0x1142D]={ + category="lo", + description="NEWA LETTER RHA", + direction="l", + linebreak="al", + unicodeslot=0x1142D, + }, + [0x1142E]={ + category="lo", + description="NEWA LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x1142E, + }, + [0x1142F]={ + category="lo", + description="NEWA LETTER LHA", + direction="l", + linebreak="al", + unicodeslot=0x1142F, + }, + [0x11430]={ + category="lo", + description="NEWA LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0x11430, + }, + [0x11431]={ + category="lo", + description="NEWA LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x11431, + }, + [0x11432]={ + category="lo", + description="NEWA LETTER SSA", + direction="l", + linebreak="al", + unicodeslot=0x11432, + }, + [0x11433]={ + category="lo", + description="NEWA LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x11433, + }, + [0x11434]={ + category="lo", + description="NEWA LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x11434, + }, + [0x11435]={ + category="mc", + description="NEWA VOWEL SIGN AA", + direction="l", + linebreak="cm", + unicodeslot=0x11435, + }, + [0x11436]={ + category="mc", + description="NEWA VOWEL SIGN I", + direction="l", + linebreak="cm", + unicodeslot=0x11436, + }, + [0x11437]={ + category="mc", + description="NEWA VOWEL SIGN II", + direction="l", + linebreak="cm", + unicodeslot=0x11437, + }, + [0x11438]={ + category="mn", + description="NEWA VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x11438, + }, + [0x11439]={ + category="mn", + description="NEWA VOWEL SIGN UU", + direction="nsm", + linebreak="cm", + unicodeslot=0x11439, + }, + [0x1143A]={ + category="mn", + description="NEWA VOWEL SIGN VOCALIC R", + direction="nsm", + linebreak="cm", + unicodeslot=0x1143A, + }, + [0x1143B]={ + category="mn", + description="NEWA VOWEL SIGN VOCALIC RR", + direction="nsm", + linebreak="cm", + unicodeslot=0x1143B, + }, + [0x1143C]={ + category="mn", + description="NEWA VOWEL SIGN VOCALIC L", + direction="nsm", + linebreak="cm", + unicodeslot=0x1143C, + }, + [0x1143D]={ + category="mn", + description="NEWA VOWEL SIGN VOCALIC LL", + direction="nsm", + linebreak="cm", + unicodeslot=0x1143D, + }, + [0x1143E]={ + category="mn", + description="NEWA VOWEL SIGN E", + direction="nsm", + linebreak="cm", + unicodeslot=0x1143E, + }, + [0x1143F]={ + category="mn", + description="NEWA VOWEL SIGN AI", + direction="nsm", + linebreak="cm", + unicodeslot=0x1143F, + }, + [0x11440]={ + category="mc", + description="NEWA VOWEL SIGN O", + direction="l", + linebreak="cm", + unicodeslot=0x11440, + }, + [0x11441]={ + category="mc", + description="NEWA VOWEL SIGN AU", + direction="l", + linebreak="cm", + unicodeslot=0x11441, + }, + [0x11442]={ + category="mn", + combining=0x9, + description="NEWA SIGN VIRAMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11442, + }, + [0x11443]={ + category="mn", + description="NEWA SIGN CANDRABINDU", + direction="nsm", + linebreak="cm", + unicodeslot=0x11443, + }, + [0x11444]={ + category="mn", + description="NEWA SIGN ANUSVARA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11444, + }, + [0x11445]={ + category="mc", + description="NEWA SIGN VISARGA", + direction="l", + linebreak="cm", + unicodeslot=0x11445, + }, + [0x11446]={ + category="mn", + combining=0x7, + description="NEWA SIGN NUKTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11446, + }, + [0x11447]={ + category="lo", + description="NEWA SIGN AVAGRAHA", + direction="l", + linebreak="al", + unicodeslot=0x11447, + }, + [0x11448]={ + category="lo", + description="NEWA SIGN FINAL ANUSVARA", + direction="l", + linebreak="al", + unicodeslot=0x11448, + }, + [0x11449]={ + category="lo", + description="NEWA OM", + direction="l", + linebreak="al", + unicodeslot=0x11449, + }, + [0x1144A]={ + category="lo", + description="NEWA SIDDHI", + direction="l", + linebreak="al", + unicodeslot=0x1144A, + }, + [0x1144B]={ + category="po", + description="NEWA DANDA", + direction="l", + linebreak="ba", + unicodeslot=0x1144B, + }, + [0x1144C]={ + category="po", + description="NEWA DOUBLE DANDA", + direction="l", + linebreak="ba", + unicodeslot=0x1144C, + }, + [0x1144D]={ + category="po", + description="NEWA COMMA", + direction="l", + linebreak="ba", + unicodeslot=0x1144D, + }, + [0x1144E]={ + category="po", + description="NEWA GAP FILLER", + direction="l", + linebreak="ba", + unicodeslot=0x1144E, + }, + [0x1144F]={ + category="po", + description="NEWA ABBREVIATION SIGN", + direction="l", + linebreak="al", + unicodeslot=0x1144F, + }, + [0x11450]={ + category="nd", + description="NEWA DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x11450, + }, + [0x11451]={ + category="nd", + description="NEWA DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x11451, + }, + [0x11452]={ + category="nd", + description="NEWA DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x11452, + }, + [0x11453]={ + category="nd", + description="NEWA DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x11453, + }, + [0x11454]={ + category="nd", + description="NEWA DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x11454, + }, + [0x11455]={ + category="nd", + description="NEWA DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x11455, + }, + [0x11456]={ + category="nd", + description="NEWA DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x11456, + }, + [0x11457]={ + category="nd", + description="NEWA DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x11457, + }, + [0x11458]={ + category="nd", + description="NEWA DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x11458, + }, + [0x11459]={ + category="nd", + description="NEWA DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x11459, + }, + [0x1145B]={ + category="po", + description="NEWA PLACEHOLDER MARK", + direction="l", + linebreak="ba", + unicodeslot=0x1145B, + }, + [0x1145D]={ + category="po", + description="NEWA INSERTION SIGN", + direction="l", + linebreak="al", + unicodeslot=0x1145D, + }, [0x11480]={ category="lo", description="TIRHUTA ANJI", @@ -158153,6 +160185,97 @@ characters.data={ linebreak="nu", unicodeslot=0x11659, }, + [0x11660]={ + category="po", + description="MONGOLIAN BIRGA WITH ORNAMENT", + direction="on", + linebreak="bb", + unicodeslot=0x11660, + }, + [0x11661]={ + category="po", + description="MONGOLIAN ROTATED BIRGA", + direction="on", + linebreak="bb", + unicodeslot=0x11661, + }, + [0x11662]={ + category="po", + description="MONGOLIAN DOUBLE BIRGA WITH ORNAMENT", + direction="on", + linebreak="bb", + unicodeslot=0x11662, + }, + [0x11663]={ + category="po", + description="MONGOLIAN TRIPLE BIRGA WITH ORNAMENT", + direction="on", + linebreak="bb", + unicodeslot=0x11663, + }, + [0x11664]={ + category="po", + description="MONGOLIAN BIRGA WITH DOUBLE ORNAMENT", + direction="on", + linebreak="bb", + unicodeslot=0x11664, + }, + [0x11665]={ + category="po", + description="MONGOLIAN ROTATED BIRGA WITH ORNAMENT", + direction="on", + linebreak="bb", + unicodeslot=0x11665, + }, + [0x11666]={ + category="po", + description="MONGOLIAN ROTATED BIRGA WITH DOUBLE ORNAMENT", + direction="on", + linebreak="bb", + unicodeslot=0x11666, + }, + [0x11667]={ + category="po", + description="MONGOLIAN INVERTED BIRGA", + direction="on", + linebreak="bb", + unicodeslot=0x11667, + }, + [0x11668]={ + category="po", + description="MONGOLIAN INVERTED BIRGA WITH DOUBLE ORNAMENT", + direction="on", + linebreak="bb", + unicodeslot=0x11668, + }, + [0x11669]={ + category="po", + description="MONGOLIAN SWIRL BIRGA", + direction="on", + linebreak="bb", + unicodeslot=0x11669, + }, + [0x1166A]={ + category="po", + description="MONGOLIAN SWIRL BIRGA WITH ORNAMENT", + direction="on", + linebreak="bb", + unicodeslot=0x1166A, + }, + [0x1166B]={ + category="po", + description="MONGOLIAN SWIRL BIRGA WITH DOUBLE ORNAMENT", + direction="on", + linebreak="bb", + unicodeslot=0x1166B, + }, + [0x1166C]={ + category="po", + description="MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT", + direction="on", + linebreak="bb", + unicodeslot=0x1166C, + }, [0x11680]={ category="lo", description="TAKRI LETTER A", @@ -160004,6 +162127,1162 @@ characters.data={ linebreak="al", unicodeslot=0x11AF8, }, + [0x11C00]={ + category="lo", + description="BHAIKSUKI LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x11C00, + }, + [0x11C01]={ + category="lo", + description="BHAIKSUKI LETTER AA", + direction="l", + linebreak="al", + unicodeslot=0x11C01, + }, + [0x11C02]={ + category="lo", + description="BHAIKSUKI LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x11C02, + }, + [0x11C03]={ + category="lo", + description="BHAIKSUKI LETTER II", + direction="l", + linebreak="al", + unicodeslot=0x11C03, + }, + [0x11C04]={ + category="lo", + description="BHAIKSUKI LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x11C04, + }, + [0x11C05]={ + category="lo", + description="BHAIKSUKI LETTER UU", + direction="l", + linebreak="al", + unicodeslot=0x11C05, + }, + [0x11C06]={ + category="lo", + description="BHAIKSUKI LETTER VOCALIC R", + direction="l", + linebreak="al", + unicodeslot=0x11C06, + }, + [0x11C07]={ + category="lo", + description="BHAIKSUKI LETTER VOCALIC RR", + direction="l", + linebreak="al", + unicodeslot=0x11C07, + }, + [0x11C08]={ + category="lo", + description="BHAIKSUKI LETTER VOCALIC L", + direction="l", + linebreak="al", + unicodeslot=0x11C08, + }, + [0x11C0A]={ + category="lo", + description="BHAIKSUKI LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x11C0A, + }, + [0x11C0B]={ + category="lo", + description="BHAIKSUKI LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x11C0B, + }, + [0x11C0C]={ + category="lo", + description="BHAIKSUKI LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x11C0C, + }, + [0x11C0D]={ + category="lo", + description="BHAIKSUKI LETTER AU", + direction="l", + linebreak="al", + unicodeslot=0x11C0D, + }, + [0x11C0E]={ + category="lo", + description="BHAIKSUKI LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x11C0E, + }, + [0x11C0F]={ + category="lo", + description="BHAIKSUKI LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x11C0F, + }, + [0x11C10]={ + category="lo", + description="BHAIKSUKI LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x11C10, + }, + [0x11C11]={ + category="lo", + description="BHAIKSUKI LETTER GHA", + direction="l", + linebreak="al", + unicodeslot=0x11C11, + }, + [0x11C12]={ + category="lo", + description="BHAIKSUKI LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x11C12, + }, + [0x11C13]={ + category="lo", + description="BHAIKSUKI LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x11C13, + }, + [0x11C14]={ + category="lo", + description="BHAIKSUKI LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x11C14, + }, + [0x11C15]={ + category="lo", + description="BHAIKSUKI LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x11C15, + }, + [0x11C16]={ + category="lo", + description="BHAIKSUKI LETTER JHA", + direction="l", + linebreak="al", + unicodeslot=0x11C16, + }, + [0x11C17]={ + category="lo", + description="BHAIKSUKI LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x11C17, + }, + [0x11C18]={ + category="lo", + description="BHAIKSUKI LETTER TTA", + direction="l", + linebreak="al", + unicodeslot=0x11C18, + }, + [0x11C19]={ + category="lo", + description="BHAIKSUKI LETTER TTHA", + direction="l", + linebreak="al", + unicodeslot=0x11C19, + }, + [0x11C1A]={ + category="lo", + description="BHAIKSUKI LETTER DDA", + direction="l", + linebreak="al", + unicodeslot=0x11C1A, + }, + [0x11C1B]={ + category="lo", + description="BHAIKSUKI LETTER DDHA", + direction="l", + linebreak="al", + unicodeslot=0x11C1B, + }, + [0x11C1C]={ + category="lo", + description="BHAIKSUKI LETTER NNA", + direction="l", + linebreak="al", + unicodeslot=0x11C1C, + }, + [0x11C1D]={ + category="lo", + description="BHAIKSUKI LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x11C1D, + }, + [0x11C1E]={ + category="lo", + description="BHAIKSUKI LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0x11C1E, + }, + [0x11C1F]={ + category="lo", + description="BHAIKSUKI LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x11C1F, + }, + [0x11C20]={ + category="lo", + description="BHAIKSUKI LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x11C20, + }, + [0x11C21]={ + category="lo", + description="BHAIKSUKI LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x11C21, + }, + [0x11C22]={ + category="lo", + description="BHAIKSUKI LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x11C22, + }, + [0x11C23]={ + category="lo", + description="BHAIKSUKI LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0x11C23, + }, + [0x11C24]={ + category="lo", + description="BHAIKSUKI LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x11C24, + }, + [0x11C25]={ + category="lo", + description="BHAIKSUKI LETTER BHA", + direction="l", + linebreak="al", + unicodeslot=0x11C25, + }, + [0x11C26]={ + category="lo", + description="BHAIKSUKI LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x11C26, + }, + [0x11C27]={ + category="lo", + description="BHAIKSUKI LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x11C27, + }, + [0x11C28]={ + category="lo", + description="BHAIKSUKI LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x11C28, + }, + [0x11C29]={ + category="lo", + description="BHAIKSUKI LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x11C29, + }, + [0x11C2A]={ + category="lo", + description="BHAIKSUKI LETTER VA", + direction="l", + linebreak="al", + unicodeslot=0x11C2A, + }, + [0x11C2B]={ + category="lo", + description="BHAIKSUKI LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x11C2B, + }, + [0x11C2C]={ + category="lo", + description="BHAIKSUKI LETTER SSA", + direction="l", + linebreak="al", + unicodeslot=0x11C2C, + }, + [0x11C2D]={ + category="lo", + description="BHAIKSUKI LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x11C2D, + }, + [0x11C2E]={ + category="lo", + description="BHAIKSUKI LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x11C2E, + }, + [0x11C2F]={ + category="mc", + description="BHAIKSUKI VOWEL SIGN AA", + direction="l", + linebreak="cm", + unicodeslot=0x11C2F, + }, + [0x11C30]={ + category="mn", + description="BHAIKSUKI VOWEL SIGN I", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C30, + }, + [0x11C31]={ + category="mn", + description="BHAIKSUKI VOWEL SIGN II", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C31, + }, + [0x11C32]={ + category="mn", + description="BHAIKSUKI VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C32, + }, + [0x11C33]={ + category="mn", + description="BHAIKSUKI VOWEL SIGN UU", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C33, + }, + [0x11C34]={ + category="mn", + description="BHAIKSUKI VOWEL SIGN VOCALIC R", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C34, + }, + [0x11C35]={ + category="mn", + description="BHAIKSUKI VOWEL SIGN VOCALIC RR", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C35, + }, + [0x11C36]={ + category="mn", + description="BHAIKSUKI VOWEL SIGN VOCALIC L", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C36, + }, + [0x11C38]={ + category="mn", + description="BHAIKSUKI VOWEL SIGN E", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C38, + }, + [0x11C39]={ + category="mn", + description="BHAIKSUKI VOWEL SIGN AI", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C39, + }, + [0x11C3A]={ + category="mn", + description="BHAIKSUKI VOWEL SIGN O", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C3A, + }, + [0x11C3B]={ + category="mn", + description="BHAIKSUKI VOWEL SIGN AU", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C3B, + }, + [0x11C3C]={ + category="mn", + description="BHAIKSUKI SIGN CANDRABINDU", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C3C, + }, + [0x11C3D]={ + category="mn", + description="BHAIKSUKI SIGN ANUSVARA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C3D, + }, + [0x11C3E]={ + category="mc", + description="BHAIKSUKI SIGN VISARGA", + direction="l", + linebreak="cm", + unicodeslot=0x11C3E, + }, + [0x11C3F]={ + category="mn", + combining=0x9, + description="BHAIKSUKI SIGN VIRAMA", + direction="l", + linebreak="cm", + unicodeslot=0x11C3F, + }, + [0x11C40]={ + category="lo", + description="BHAIKSUKI SIGN AVAGRAHA", + direction="l", + linebreak="al", + unicodeslot=0x11C40, + }, + [0x11C41]={ + category="po", + description="BHAIKSUKI DANDA", + direction="l", + linebreak="ba", + unicodeslot=0x11C41, + }, + [0x11C42]={ + category="po", + description="BHAIKSUKI DOUBLE DANDA", + direction="l", + linebreak="ba", + unicodeslot=0x11C42, + }, + [0x11C43]={ + category="po", + description="BHAIKSUKI WORD SEPARATOR", + direction="l", + linebreak="ba", + unicodeslot=0x11C43, + }, + [0x11C44]={ + category="po", + description="BHAIKSUKI GAP FILLER-1", + direction="l", + linebreak="ba", + unicodeslot=0x11C44, + }, + [0x11C45]={ + category="po", + description="BHAIKSUKI GAP FILLER-2", + direction="l", + linebreak="ba", + unicodeslot=0x11C45, + }, + [0x11C50]={ + category="nd", + description="BHAIKSUKI DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x11C50, + }, + [0x11C51]={ + category="nd", + description="BHAIKSUKI DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x11C51, + }, + [0x11C52]={ + category="nd", + description="BHAIKSUKI DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x11C52, + }, + [0x11C53]={ + category="nd", + description="BHAIKSUKI DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x11C53, + }, + [0x11C54]={ + category="nd", + description="BHAIKSUKI DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x11C54, + }, + [0x11C55]={ + category="nd", + description="BHAIKSUKI DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x11C55, + }, + [0x11C56]={ + category="nd", + description="BHAIKSUKI DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x11C56, + }, + [0x11C57]={ + category="nd", + description="BHAIKSUKI DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x11C57, + }, + [0x11C58]={ + category="nd", + description="BHAIKSUKI DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x11C58, + }, + [0x11C59]={ + category="nd", + description="BHAIKSUKI DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x11C59, + }, + [0x11C5A]={ + category="no", + description="BHAIKSUKI NUMBER ONE", + direction="l", + linebreak="al", + unicodeslot=0x11C5A, + }, + [0x11C5B]={ + category="no", + description="BHAIKSUKI NUMBER TWO", + direction="l", + linebreak="al", + unicodeslot=0x11C5B, + }, + [0x11C5C]={ + category="no", + description="BHAIKSUKI NUMBER THREE", + direction="l", + linebreak="al", + unicodeslot=0x11C5C, + }, + [0x11C5D]={ + category="no", + description="BHAIKSUKI NUMBER FOUR", + direction="l", + linebreak="al", + unicodeslot=0x11C5D, + }, + [0x11C5E]={ + category="no", + description="BHAIKSUKI NUMBER FIVE", + direction="l", + linebreak="al", + unicodeslot=0x11C5E, + }, + [0x11C5F]={ + category="no", + description="BHAIKSUKI NUMBER SIX", + direction="l", + linebreak="al", + unicodeslot=0x11C5F, + }, + [0x11C60]={ + category="no", + description="BHAIKSUKI NUMBER SEVEN", + direction="l", + linebreak="al", + unicodeslot=0x11C60, + }, + [0x11C61]={ + category="no", + description="BHAIKSUKI NUMBER EIGHT", + direction="l", + linebreak="al", + unicodeslot=0x11C61, + }, + [0x11C62]={ + category="no", + description="BHAIKSUKI NUMBER NINE", + direction="l", + linebreak="al", + unicodeslot=0x11C62, + }, + [0x11C63]={ + category="no", + description="BHAIKSUKI NUMBER TEN", + direction="l", + linebreak="al", + unicodeslot=0x11C63, + }, + [0x11C64]={ + category="no", + description="BHAIKSUKI NUMBER TWENTY", + direction="l", + linebreak="al", + unicodeslot=0x11C64, + }, + [0x11C65]={ + category="no", + description="BHAIKSUKI NUMBER THIRTY", + direction="l", + linebreak="al", + unicodeslot=0x11C65, + }, + [0x11C66]={ + category="no", + description="BHAIKSUKI NUMBER FORTY", + direction="l", + linebreak="al", + unicodeslot=0x11C66, + }, + [0x11C67]={ + category="no", + description="BHAIKSUKI NUMBER FIFTY", + direction="l", + linebreak="al", + unicodeslot=0x11C67, + }, + [0x11C68]={ + category="no", + description="BHAIKSUKI NUMBER SIXTY", + direction="l", + linebreak="al", + unicodeslot=0x11C68, + }, + [0x11C69]={ + category="no", + description="BHAIKSUKI NUMBER SEVENTY", + direction="l", + linebreak="al", + unicodeslot=0x11C69, + }, + [0x11C6A]={ + category="no", + description="BHAIKSUKI NUMBER EIGHTY", + direction="l", + linebreak="al", + unicodeslot=0x11C6A, + }, + [0x11C6B]={ + category="no", + description="BHAIKSUKI NUMBER NINETY", + direction="l", + linebreak="al", + unicodeslot=0x11C6B, + }, + [0x11C6C]={ + category="no", + description="BHAIKSUKI HUNDREDS UNIT MARK", + direction="l", + linebreak="al", + unicodeslot=0x11C6C, + }, + [0x11C70]={ + category="po", + description="MARCHEN HEAD MARK", + direction="l", + linebreak="bb", + unicodeslot=0x11C70, + }, + [0x11C71]={ + category="po", + description="MARCHEN MARK SHAD", + direction="l", + linebreak="ex", + unicodeslot=0x11C71, + }, + [0x11C72]={ + category="lo", + description="MARCHEN LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x11C72, + }, + [0x11C73]={ + category="lo", + description="MARCHEN LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x11C73, + }, + [0x11C74]={ + category="lo", + description="MARCHEN LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x11C74, + }, + [0x11C75]={ + category="lo", + description="MARCHEN LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x11C75, + }, + [0x11C76]={ + category="lo", + description="MARCHEN LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x11C76, + }, + [0x11C77]={ + category="lo", + description="MARCHEN LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x11C77, + }, + [0x11C78]={ + category="lo", + description="MARCHEN LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x11C78, + }, + [0x11C79]={ + category="lo", + description="MARCHEN LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x11C79, + }, + [0x11C7A]={ + category="lo", + description="MARCHEN LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x11C7A, + }, + [0x11C7B]={ + category="lo", + description="MARCHEN LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0x11C7B, + }, + [0x11C7C]={ + category="lo", + description="MARCHEN LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x11C7C, + }, + [0x11C7D]={ + category="lo", + description="MARCHEN LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x11C7D, + }, + [0x11C7E]={ + category="lo", + description="MARCHEN LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x11C7E, + }, + [0x11C7F]={ + category="lo", + description="MARCHEN LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0x11C7F, + }, + [0x11C80]={ + category="lo", + description="MARCHEN LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x11C80, + }, + [0x11C81]={ + category="lo", + description="MARCHEN LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x11C81, + }, + [0x11C82]={ + category="lo", + description="MARCHEN LETTER TSA", + direction="l", + linebreak="al", + unicodeslot=0x11C82, + }, + [0x11C83]={ + category="lo", + description="MARCHEN LETTER TSHA", + direction="l", + linebreak="al", + unicodeslot=0x11C83, + }, + [0x11C84]={ + category="lo", + description="MARCHEN LETTER DZA", + direction="l", + linebreak="al", + unicodeslot=0x11C84, + }, + [0x11C85]={ + category="lo", + description="MARCHEN LETTER WA", + direction="l", + linebreak="al", + unicodeslot=0x11C85, + }, + [0x11C86]={ + category="lo", + description="MARCHEN LETTER ZHA", + direction="l", + linebreak="al", + unicodeslot=0x11C86, + }, + [0x11C87]={ + category="lo", + description="MARCHEN LETTER ZA", + direction="l", + linebreak="al", + unicodeslot=0x11C87, + }, + [0x11C88]={ + category="lo", + description="MARCHEN LETTER -A", + direction="l", + linebreak="al", + unicodeslot=0x11C88, + }, + [0x11C89]={ + category="lo", + description="MARCHEN LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x11C89, + }, + [0x11C8A]={ + category="lo", + description="MARCHEN LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x11C8A, + }, + [0x11C8B]={ + category="lo", + description="MARCHEN LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x11C8B, + }, + [0x11C8C]={ + category="lo", + description="MARCHEN LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x11C8C, + }, + [0x11C8D]={ + category="lo", + description="MARCHEN LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x11C8D, + }, + [0x11C8E]={ + category="lo", + description="MARCHEN LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x11C8E, + }, + [0x11C8F]={ + category="lo", + description="MARCHEN LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x11C8F, + }, + [0x11C92]={ + category="mn", + description="MARCHEN SUBJOINED LETTER KA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C92, + }, + [0x11C93]={ + category="mn", + description="MARCHEN SUBJOINED LETTER KHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C93, + }, + [0x11C94]={ + category="mn", + description="MARCHEN SUBJOINED LETTER GA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C94, + }, + [0x11C95]={ + category="mn", + description="MARCHEN SUBJOINED LETTER NGA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C95, + }, + [0x11C96]={ + category="mn", + description="MARCHEN SUBJOINED LETTER CA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C96, + }, + [0x11C97]={ + category="mn", + description="MARCHEN SUBJOINED LETTER CHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C97, + }, + [0x11C98]={ + category="mn", + description="MARCHEN SUBJOINED LETTER JA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C98, + }, + [0x11C99]={ + category="mn", + description="MARCHEN SUBJOINED LETTER NYA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C99, + }, + [0x11C9A]={ + category="mn", + description="MARCHEN SUBJOINED LETTER TA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C9A, + }, + [0x11C9B]={ + category="mn", + description="MARCHEN SUBJOINED LETTER THA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C9B, + }, + [0x11C9C]={ + category="mn", + description="MARCHEN SUBJOINED LETTER DA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C9C, + }, + [0x11C9D]={ + category="mn", + description="MARCHEN SUBJOINED LETTER NA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C9D, + }, + [0x11C9E]={ + category="mn", + description="MARCHEN SUBJOINED LETTER PA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C9E, + }, + [0x11C9F]={ + category="mn", + description="MARCHEN SUBJOINED LETTER PHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11C9F, + }, + [0x11CA0]={ + category="mn", + description="MARCHEN SUBJOINED LETTER BA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CA0, + }, + [0x11CA1]={ + category="mn", + description="MARCHEN SUBJOINED LETTER MA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CA1, + }, + [0x11CA2]={ + category="mn", + description="MARCHEN SUBJOINED LETTER TSA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CA2, + }, + [0x11CA3]={ + category="mn", + description="MARCHEN SUBJOINED LETTER TSHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CA3, + }, + [0x11CA4]={ + category="mn", + description="MARCHEN SUBJOINED LETTER DZA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CA4, + }, + [0x11CA5]={ + category="mn", + description="MARCHEN SUBJOINED LETTER WA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CA5, + }, + [0x11CA6]={ + category="mn", + description="MARCHEN SUBJOINED LETTER ZHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CA6, + }, + [0x11CA7]={ + category="mn", + description="MARCHEN SUBJOINED LETTER ZA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CA7, + }, + [0x11CA9]={ + category="mc", + description="MARCHEN SUBJOINED LETTER YA", + direction="l", + linebreak="cm", + unicodeslot=0x11CA9, + }, + [0x11CAA]={ + category="mn", + description="MARCHEN SUBJOINED LETTER RA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CAA, + }, + [0x11CAB]={ + category="mn", + description="MARCHEN SUBJOINED LETTER LA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CAB, + }, + [0x11CAC]={ + category="mn", + description="MARCHEN SUBJOINED LETTER SHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CAC, + }, + [0x11CAD]={ + category="mn", + description="MARCHEN SUBJOINED LETTER SA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CAD, + }, + [0x11CAE]={ + category="mn", + description="MARCHEN SUBJOINED LETTER HA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CAE, + }, + [0x11CAF]={ + category="mn", + description="MARCHEN SUBJOINED LETTER A", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CAF, + }, + [0x11CB0]={ + category="mn", + description="MARCHEN VOWEL SIGN AA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CB0, + }, + [0x11CB1]={ + category="mc", + description="MARCHEN VOWEL SIGN I", + direction="l", + linebreak="cm", + unicodeslot=0x11CB1, + }, + [0x11CB2]={ + category="mn", + description="MARCHEN VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CB2, + }, + [0x11CB3]={ + category="mn", + description="MARCHEN VOWEL SIGN E", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CB3, + }, + [0x11CB4]={ + category="mc", + description="MARCHEN VOWEL SIGN O", + direction="l", + linebreak="cm", + unicodeslot=0x11CB4, + }, + [0x11CB5]={ + category="mn", + description="MARCHEN SIGN ANUSVARA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CB5, + }, + [0x11CB6]={ + category="mn", + description="MARCHEN SIGN CANDRABINDU", + direction="nsm", + linebreak="cm", + unicodeslot=0x11CB6, + }, [0x12000]={ category="lo", description="CUNEIFORM SIGN A", @@ -186590,6 +189869,6054 @@ characters.data={ linebreak="al", unicodeslot=0x16F9F, }, + [0x16FE0]={ + category="lm", + cjkwd="w", + description="TANGUT ITERATION MARK", + direction="l", + linebreak="ns", + unicodeslot=0x16FE0, + }, + [0x18800]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-001", + direction="l", + linebreak="id", + unicodeslot=0x18800, + }, + [0x18801]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-002", + direction="l", + linebreak="id", + unicodeslot=0x18801, + }, + [0x18802]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-003", + direction="l", + linebreak="id", + unicodeslot=0x18802, + }, + [0x18803]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-004", + direction="l", + linebreak="id", + unicodeslot=0x18803, + }, + [0x18804]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-005", + direction="l", + linebreak="id", + unicodeslot=0x18804, + }, + [0x18805]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-006", + direction="l", + linebreak="id", + unicodeslot=0x18805, + }, + [0x18806]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-007", + direction="l", + linebreak="id", + unicodeslot=0x18806, + }, + [0x18807]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-008", + direction="l", + linebreak="id", + unicodeslot=0x18807, + }, + [0x18808]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-009", + direction="l", + linebreak="id", + unicodeslot=0x18808, + }, + [0x18809]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-010", + direction="l", + linebreak="id", + unicodeslot=0x18809, + }, + [0x1880A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-011", + direction="l", + linebreak="id", + unicodeslot=0x1880A, + }, + [0x1880B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-012", + direction="l", + linebreak="id", + unicodeslot=0x1880B, + }, + [0x1880C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-013", + direction="l", + linebreak="id", + unicodeslot=0x1880C, + }, + [0x1880D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-014", + direction="l", + linebreak="id", + unicodeslot=0x1880D, + }, + [0x1880E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-015", + direction="l", + linebreak="id", + unicodeslot=0x1880E, + }, + [0x1880F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-016", + direction="l", + linebreak="id", + unicodeslot=0x1880F, + }, + [0x18810]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-017", + direction="l", + linebreak="id", + unicodeslot=0x18810, + }, + [0x18811]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-018", + direction="l", + linebreak="id", + unicodeslot=0x18811, + }, + [0x18812]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-019", + direction="l", + linebreak="id", + unicodeslot=0x18812, + }, + [0x18813]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-020", + direction="l", + linebreak="id", + unicodeslot=0x18813, + }, + [0x18814]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-021", + direction="l", + linebreak="id", + unicodeslot=0x18814, + }, + [0x18815]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-022", + direction="l", + linebreak="id", + unicodeslot=0x18815, + }, + [0x18816]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-023", + direction="l", + linebreak="id", + unicodeslot=0x18816, + }, + [0x18817]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-024", + direction="l", + linebreak="id", + unicodeslot=0x18817, + }, + [0x18818]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-025", + direction="l", + linebreak="id", + unicodeslot=0x18818, + }, + [0x18819]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-026", + direction="l", + linebreak="id", + unicodeslot=0x18819, + }, + [0x1881A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-027", + direction="l", + linebreak="id", + unicodeslot=0x1881A, + }, + [0x1881B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-028", + direction="l", + linebreak="id", + unicodeslot=0x1881B, + }, + [0x1881C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-029", + direction="l", + linebreak="id", + unicodeslot=0x1881C, + }, + [0x1881D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-030", + direction="l", + linebreak="id", + unicodeslot=0x1881D, + }, + [0x1881E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-031", + direction="l", + linebreak="id", + unicodeslot=0x1881E, + }, + [0x1881F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-032", + direction="l", + linebreak="id", + unicodeslot=0x1881F, + }, + [0x18820]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-033", + direction="l", + linebreak="id", + unicodeslot=0x18820, + }, + [0x18821]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-034", + direction="l", + linebreak="id", + unicodeslot=0x18821, + }, + [0x18822]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-035", + direction="l", + linebreak="id", + unicodeslot=0x18822, + }, + [0x18823]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-036", + direction="l", + linebreak="id", + unicodeslot=0x18823, + }, + [0x18824]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-037", + direction="l", + linebreak="id", + unicodeslot=0x18824, + }, + [0x18825]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-038", + direction="l", + linebreak="id", + unicodeslot=0x18825, + }, + [0x18826]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-039", + direction="l", + linebreak="id", + unicodeslot=0x18826, + }, + [0x18827]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-040", + direction="l", + linebreak="id", + unicodeslot=0x18827, + }, + [0x18828]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-041", + direction="l", + linebreak="id", + unicodeslot=0x18828, + }, + [0x18829]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-042", + direction="l", + linebreak="id", + unicodeslot=0x18829, + }, + [0x1882A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-043", + direction="l", + linebreak="id", + unicodeslot=0x1882A, + }, + [0x1882B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-044", + direction="l", + linebreak="id", + unicodeslot=0x1882B, + }, + [0x1882C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-045", + direction="l", + linebreak="id", + unicodeslot=0x1882C, + }, + [0x1882D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-046", + direction="l", + linebreak="id", + unicodeslot=0x1882D, + }, + [0x1882E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-047", + direction="l", + linebreak="id", + unicodeslot=0x1882E, + }, + [0x1882F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-048", + direction="l", + linebreak="id", + unicodeslot=0x1882F, + }, + [0x18830]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-049", + direction="l", + linebreak="id", + unicodeslot=0x18830, + }, + [0x18831]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-050", + direction="l", + linebreak="id", + unicodeslot=0x18831, + }, + [0x18832]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-051", + direction="l", + linebreak="id", + unicodeslot=0x18832, + }, + [0x18833]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-052", + direction="l", + linebreak="id", + unicodeslot=0x18833, + }, + [0x18834]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-053", + direction="l", + linebreak="id", + unicodeslot=0x18834, + }, + [0x18835]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-054", + direction="l", + linebreak="id", + unicodeslot=0x18835, + }, + [0x18836]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-055", + direction="l", + linebreak="id", + unicodeslot=0x18836, + }, + [0x18837]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-056", + direction="l", + linebreak="id", + unicodeslot=0x18837, + }, + [0x18838]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-057", + direction="l", + linebreak="id", + unicodeslot=0x18838, + }, + [0x18839]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-058", + direction="l", + linebreak="id", + unicodeslot=0x18839, + }, + [0x1883A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-059", + direction="l", + linebreak="id", + unicodeslot=0x1883A, + }, + [0x1883B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-060", + direction="l", + linebreak="id", + unicodeslot=0x1883B, + }, + [0x1883C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-061", + direction="l", + linebreak="id", + unicodeslot=0x1883C, + }, + [0x1883D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-062", + direction="l", + linebreak="id", + unicodeslot=0x1883D, + }, + [0x1883E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-063", + direction="l", + linebreak="id", + unicodeslot=0x1883E, + }, + [0x1883F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-064", + direction="l", + linebreak="id", + unicodeslot=0x1883F, + }, + [0x18840]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-065", + direction="l", + linebreak="id", + unicodeslot=0x18840, + }, + [0x18841]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-066", + direction="l", + linebreak="id", + unicodeslot=0x18841, + }, + [0x18842]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-067", + direction="l", + linebreak="id", + unicodeslot=0x18842, + }, + [0x18843]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-068", + direction="l", + linebreak="id", + unicodeslot=0x18843, + }, + [0x18844]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-069", + direction="l", + linebreak="id", + unicodeslot=0x18844, + }, + [0x18845]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-070", + direction="l", + linebreak="id", + unicodeslot=0x18845, + }, + [0x18846]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-071", + direction="l", + linebreak="id", + unicodeslot=0x18846, + }, + [0x18847]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-072", + direction="l", + linebreak="id", + unicodeslot=0x18847, + }, + [0x18848]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-073", + direction="l", + linebreak="id", + unicodeslot=0x18848, + }, + [0x18849]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-074", + direction="l", + linebreak="id", + unicodeslot=0x18849, + }, + [0x1884A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-075", + direction="l", + linebreak="id", + unicodeslot=0x1884A, + }, + [0x1884B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-076", + direction="l", + linebreak="id", + unicodeslot=0x1884B, + }, + [0x1884C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-077", + direction="l", + linebreak="id", + unicodeslot=0x1884C, + }, + [0x1884D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-078", + direction="l", + linebreak="id", + unicodeslot=0x1884D, + }, + [0x1884E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-079", + direction="l", + linebreak="id", + unicodeslot=0x1884E, + }, + [0x1884F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-080", + direction="l", + linebreak="id", + unicodeslot=0x1884F, + }, + [0x18850]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-081", + direction="l", + linebreak="id", + unicodeslot=0x18850, + }, + [0x18851]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-082", + direction="l", + linebreak="id", + unicodeslot=0x18851, + }, + [0x18852]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-083", + direction="l", + linebreak="id", + unicodeslot=0x18852, + }, + [0x18853]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-084", + direction="l", + linebreak="id", + unicodeslot=0x18853, + }, + [0x18854]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-085", + direction="l", + linebreak="id", + unicodeslot=0x18854, + }, + [0x18855]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-086", + direction="l", + linebreak="id", + unicodeslot=0x18855, + }, + [0x18856]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-087", + direction="l", + linebreak="id", + unicodeslot=0x18856, + }, + [0x18857]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-088", + direction="l", + linebreak="id", + unicodeslot=0x18857, + }, + [0x18858]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-089", + direction="l", + linebreak="id", + unicodeslot=0x18858, + }, + [0x18859]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-090", + direction="l", + linebreak="id", + unicodeslot=0x18859, + }, + [0x1885A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-091", + direction="l", + linebreak="id", + unicodeslot=0x1885A, + }, + [0x1885B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-092", + direction="l", + linebreak="id", + unicodeslot=0x1885B, + }, + [0x1885C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-093", + direction="l", + linebreak="id", + unicodeslot=0x1885C, + }, + [0x1885D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-094", + direction="l", + linebreak="id", + unicodeslot=0x1885D, + }, + [0x1885E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-095", + direction="l", + linebreak="id", + unicodeslot=0x1885E, + }, + [0x1885F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-096", + direction="l", + linebreak="id", + unicodeslot=0x1885F, + }, + [0x18860]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-097", + direction="l", + linebreak="id", + unicodeslot=0x18860, + }, + [0x18861]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-098", + direction="l", + linebreak="id", + unicodeslot=0x18861, + }, + [0x18862]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-099", + direction="l", + linebreak="id", + unicodeslot=0x18862, + }, + [0x18863]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-100", + direction="l", + linebreak="id", + unicodeslot=0x18863, + }, + [0x18864]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-101", + direction="l", + linebreak="id", + unicodeslot=0x18864, + }, + [0x18865]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-102", + direction="l", + linebreak="id", + unicodeslot=0x18865, + }, + [0x18866]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-103", + direction="l", + linebreak="id", + unicodeslot=0x18866, + }, + [0x18867]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-104", + direction="l", + linebreak="id", + unicodeslot=0x18867, + }, + [0x18868]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-105", + direction="l", + linebreak="id", + unicodeslot=0x18868, + }, + [0x18869]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-106", + direction="l", + linebreak="id", + unicodeslot=0x18869, + }, + [0x1886A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-107", + direction="l", + linebreak="id", + unicodeslot=0x1886A, + }, + [0x1886B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-108", + direction="l", + linebreak="id", + unicodeslot=0x1886B, + }, + [0x1886C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-109", + direction="l", + linebreak="id", + unicodeslot=0x1886C, + }, + [0x1886D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-110", + direction="l", + linebreak="id", + unicodeslot=0x1886D, + }, + [0x1886E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-111", + direction="l", + linebreak="id", + unicodeslot=0x1886E, + }, + [0x1886F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-112", + direction="l", + linebreak="id", + unicodeslot=0x1886F, + }, + [0x18870]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-113", + direction="l", + linebreak="id", + unicodeslot=0x18870, + }, + [0x18871]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-114", + direction="l", + linebreak="id", + unicodeslot=0x18871, + }, + [0x18872]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-115", + direction="l", + linebreak="id", + unicodeslot=0x18872, + }, + [0x18873]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-116", + direction="l", + linebreak="id", + unicodeslot=0x18873, + }, + [0x18874]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-117", + direction="l", + linebreak="id", + unicodeslot=0x18874, + }, + [0x18875]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-118", + direction="l", + linebreak="id", + unicodeslot=0x18875, + }, + [0x18876]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-119", + direction="l", + linebreak="id", + unicodeslot=0x18876, + }, + [0x18877]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-120", + direction="l", + linebreak="id", + unicodeslot=0x18877, + }, + [0x18878]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-121", + direction="l", + linebreak="id", + unicodeslot=0x18878, + }, + [0x18879]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-122", + direction="l", + linebreak="id", + unicodeslot=0x18879, + }, + [0x1887A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-123", + direction="l", + linebreak="id", + unicodeslot=0x1887A, + }, + [0x1887B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-124", + direction="l", + linebreak="id", + unicodeslot=0x1887B, + }, + [0x1887C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-125", + direction="l", + linebreak="id", + unicodeslot=0x1887C, + }, + [0x1887D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-126", + direction="l", + linebreak="id", + unicodeslot=0x1887D, + }, + [0x1887E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-127", + direction="l", + linebreak="id", + unicodeslot=0x1887E, + }, + [0x1887F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-128", + direction="l", + linebreak="id", + unicodeslot=0x1887F, + }, + [0x18880]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-129", + direction="l", + linebreak="id", + unicodeslot=0x18880, + }, + [0x18881]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-130", + direction="l", + linebreak="id", + unicodeslot=0x18881, + }, + [0x18882]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-131", + direction="l", + linebreak="id", + unicodeslot=0x18882, + }, + [0x18883]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-132", + direction="l", + linebreak="id", + unicodeslot=0x18883, + }, + [0x18884]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-133", + direction="l", + linebreak="id", + unicodeslot=0x18884, + }, + [0x18885]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-134", + direction="l", + linebreak="id", + unicodeslot=0x18885, + }, + [0x18886]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-135", + direction="l", + linebreak="id", + unicodeslot=0x18886, + }, + [0x18887]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-136", + direction="l", + linebreak="id", + unicodeslot=0x18887, + }, + [0x18888]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-137", + direction="l", + linebreak="id", + unicodeslot=0x18888, + }, + [0x18889]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-138", + direction="l", + linebreak="id", + unicodeslot=0x18889, + }, + [0x1888A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-139", + direction="l", + linebreak="id", + unicodeslot=0x1888A, + }, + [0x1888B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-140", + direction="l", + linebreak="id", + unicodeslot=0x1888B, + }, + [0x1888C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-141", + direction="l", + linebreak="id", + unicodeslot=0x1888C, + }, + [0x1888D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-142", + direction="l", + linebreak="id", + unicodeslot=0x1888D, + }, + [0x1888E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-143", + direction="l", + linebreak="id", + unicodeslot=0x1888E, + }, + [0x1888F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-144", + direction="l", + linebreak="id", + unicodeslot=0x1888F, + }, + [0x18890]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-145", + direction="l", + linebreak="id", + unicodeslot=0x18890, + }, + [0x18891]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-146", + direction="l", + linebreak="id", + unicodeslot=0x18891, + }, + [0x18892]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-147", + direction="l", + linebreak="id", + unicodeslot=0x18892, + }, + [0x18893]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-148", + direction="l", + linebreak="id", + unicodeslot=0x18893, + }, + [0x18894]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-149", + direction="l", + linebreak="id", + unicodeslot=0x18894, + }, + [0x18895]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-150", + direction="l", + linebreak="id", + unicodeslot=0x18895, + }, + [0x18896]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-151", + direction="l", + linebreak="id", + unicodeslot=0x18896, + }, + [0x18897]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-152", + direction="l", + linebreak="id", + unicodeslot=0x18897, + }, + [0x18898]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-153", + direction="l", + linebreak="id", + unicodeslot=0x18898, + }, + [0x18899]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-154", + direction="l", + linebreak="id", + unicodeslot=0x18899, + }, + [0x1889A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-155", + direction="l", + linebreak="id", + unicodeslot=0x1889A, + }, + [0x1889B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-156", + direction="l", + linebreak="id", + unicodeslot=0x1889B, + }, + [0x1889C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-157", + direction="l", + linebreak="id", + unicodeslot=0x1889C, + }, + [0x1889D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-158", + direction="l", + linebreak="id", + unicodeslot=0x1889D, + }, + [0x1889E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-159", + direction="l", + linebreak="id", + unicodeslot=0x1889E, + }, + [0x1889F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-160", + direction="l", + linebreak="id", + unicodeslot=0x1889F, + }, + [0x188A0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-161", + direction="l", + linebreak="id", + unicodeslot=0x188A0, + }, + [0x188A1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-162", + direction="l", + linebreak="id", + unicodeslot=0x188A1, + }, + [0x188A2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-163", + direction="l", + linebreak="id", + unicodeslot=0x188A2, + }, + [0x188A3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-164", + direction="l", + linebreak="id", + unicodeslot=0x188A3, + }, + [0x188A4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-165", + direction="l", + linebreak="id", + unicodeslot=0x188A4, + }, + [0x188A5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-166", + direction="l", + linebreak="id", + unicodeslot=0x188A5, + }, + [0x188A6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-167", + direction="l", + linebreak="id", + unicodeslot=0x188A6, + }, + [0x188A7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-168", + direction="l", + linebreak="id", + unicodeslot=0x188A7, + }, + [0x188A8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-169", + direction="l", + linebreak="id", + unicodeslot=0x188A8, + }, + [0x188A9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-170", + direction="l", + linebreak="id", + unicodeslot=0x188A9, + }, + [0x188AA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-171", + direction="l", + linebreak="id", + unicodeslot=0x188AA, + }, + [0x188AB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-172", + direction="l", + linebreak="id", + unicodeslot=0x188AB, + }, + [0x188AC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-173", + direction="l", + linebreak="id", + unicodeslot=0x188AC, + }, + [0x188AD]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-174", + direction="l", + linebreak="id", + unicodeslot=0x188AD, + }, + [0x188AE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-175", + direction="l", + linebreak="id", + unicodeslot=0x188AE, + }, + [0x188AF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-176", + direction="l", + linebreak="id", + unicodeslot=0x188AF, + }, + [0x188B0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-177", + direction="l", + linebreak="id", + unicodeslot=0x188B0, + }, + [0x188B1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-178", + direction="l", + linebreak="id", + unicodeslot=0x188B1, + }, + [0x188B2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-179", + direction="l", + linebreak="id", + unicodeslot=0x188B2, + }, + [0x188B3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-180", + direction="l", + linebreak="id", + unicodeslot=0x188B3, + }, + [0x188B4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-181", + direction="l", + linebreak="id", + unicodeslot=0x188B4, + }, + [0x188B5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-182", + direction="l", + linebreak="id", + unicodeslot=0x188B5, + }, + [0x188B6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-183", + direction="l", + linebreak="id", + unicodeslot=0x188B6, + }, + [0x188B7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-184", + direction="l", + linebreak="id", + unicodeslot=0x188B7, + }, + [0x188B8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-185", + direction="l", + linebreak="id", + unicodeslot=0x188B8, + }, + [0x188B9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-186", + direction="l", + linebreak="id", + unicodeslot=0x188B9, + }, + [0x188BA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-187", + direction="l", + linebreak="id", + unicodeslot=0x188BA, + }, + [0x188BB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-188", + direction="l", + linebreak="id", + unicodeslot=0x188BB, + }, + [0x188BC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-189", + direction="l", + linebreak="id", + unicodeslot=0x188BC, + }, + [0x188BD]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-190", + direction="l", + linebreak="id", + unicodeslot=0x188BD, + }, + [0x188BE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-191", + direction="l", + linebreak="id", + unicodeslot=0x188BE, + }, + [0x188BF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-192", + direction="l", + linebreak="id", + unicodeslot=0x188BF, + }, + [0x188C0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-193", + direction="l", + linebreak="id", + unicodeslot=0x188C0, + }, + [0x188C1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-194", + direction="l", + linebreak="id", + unicodeslot=0x188C1, + }, + [0x188C2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-195", + direction="l", + linebreak="id", + unicodeslot=0x188C2, + }, + [0x188C3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-196", + direction="l", + linebreak="id", + unicodeslot=0x188C3, + }, + [0x188C4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-197", + direction="l", + linebreak="id", + unicodeslot=0x188C4, + }, + [0x188C5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-198", + direction="l", + linebreak="id", + unicodeslot=0x188C5, + }, + [0x188C6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-199", + direction="l", + linebreak="id", + unicodeslot=0x188C6, + }, + [0x188C7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-200", + direction="l", + linebreak="id", + unicodeslot=0x188C7, + }, + [0x188C8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-201", + direction="l", + linebreak="id", + unicodeslot=0x188C8, + }, + [0x188C9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-202", + direction="l", + linebreak="id", + unicodeslot=0x188C9, + }, + [0x188CA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-203", + direction="l", + linebreak="id", + unicodeslot=0x188CA, + }, + [0x188CB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-204", + direction="l", + linebreak="id", + unicodeslot=0x188CB, + }, + [0x188CC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-205", + direction="l", + linebreak="id", + unicodeslot=0x188CC, + }, + [0x188CD]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-206", + direction="l", + linebreak="id", + unicodeslot=0x188CD, + }, + [0x188CE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-207", + direction="l", + linebreak="id", + unicodeslot=0x188CE, + }, + [0x188CF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-208", + direction="l", + linebreak="id", + unicodeslot=0x188CF, + }, + [0x188D0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-209", + direction="l", + linebreak="id", + unicodeslot=0x188D0, + }, + [0x188D1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-210", + direction="l", + linebreak="id", + unicodeslot=0x188D1, + }, + [0x188D2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-211", + direction="l", + linebreak="id", + unicodeslot=0x188D2, + }, + [0x188D3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-212", + direction="l", + linebreak="id", + unicodeslot=0x188D3, + }, + [0x188D4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-213", + direction="l", + linebreak="id", + unicodeslot=0x188D4, + }, + [0x188D5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-214", + direction="l", + linebreak="id", + unicodeslot=0x188D5, + }, + [0x188D6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-215", + direction="l", + linebreak="id", + unicodeslot=0x188D6, + }, + [0x188D7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-216", + direction="l", + linebreak="id", + unicodeslot=0x188D7, + }, + [0x188D8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-217", + direction="l", + linebreak="id", + unicodeslot=0x188D8, + }, + [0x188D9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-218", + direction="l", + linebreak="id", + unicodeslot=0x188D9, + }, + [0x188DA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-219", + direction="l", + linebreak="id", + unicodeslot=0x188DA, + }, + [0x188DB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-220", + direction="l", + linebreak="id", + unicodeslot=0x188DB, + }, + [0x188DC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-221", + direction="l", + linebreak="id", + unicodeslot=0x188DC, + }, + [0x188DD]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-222", + direction="l", + linebreak="id", + unicodeslot=0x188DD, + }, + [0x188DE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-223", + direction="l", + linebreak="id", + unicodeslot=0x188DE, + }, + [0x188DF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-224", + direction="l", + linebreak="id", + unicodeslot=0x188DF, + }, + [0x188E0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-225", + direction="l", + linebreak="id", + unicodeslot=0x188E0, + }, + [0x188E1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-226", + direction="l", + linebreak="id", + unicodeslot=0x188E1, + }, + [0x188E2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-227", + direction="l", + linebreak="id", + unicodeslot=0x188E2, + }, + [0x188E3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-228", + direction="l", + linebreak="id", + unicodeslot=0x188E3, + }, + [0x188E4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-229", + direction="l", + linebreak="id", + unicodeslot=0x188E4, + }, + [0x188E5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-230", + direction="l", + linebreak="id", + unicodeslot=0x188E5, + }, + [0x188E6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-231", + direction="l", + linebreak="id", + unicodeslot=0x188E6, + }, + [0x188E7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-232", + direction="l", + linebreak="id", + unicodeslot=0x188E7, + }, + [0x188E8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-233", + direction="l", + linebreak="id", + unicodeslot=0x188E8, + }, + [0x188E9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-234", + direction="l", + linebreak="id", + unicodeslot=0x188E9, + }, + [0x188EA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-235", + direction="l", + linebreak="id", + unicodeslot=0x188EA, + }, + [0x188EB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-236", + direction="l", + linebreak="id", + unicodeslot=0x188EB, + }, + [0x188EC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-237", + direction="l", + linebreak="id", + unicodeslot=0x188EC, + }, + [0x188ED]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-238", + direction="l", + linebreak="id", + unicodeslot=0x188ED, + }, + [0x188EE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-239", + direction="l", + linebreak="id", + unicodeslot=0x188EE, + }, + [0x188EF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-240", + direction="l", + linebreak="id", + unicodeslot=0x188EF, + }, + [0x188F0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-241", + direction="l", + linebreak="id", + unicodeslot=0x188F0, + }, + [0x188F1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-242", + direction="l", + linebreak="id", + unicodeslot=0x188F1, + }, + [0x188F2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-243", + direction="l", + linebreak="id", + unicodeslot=0x188F2, + }, + [0x188F3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-244", + direction="l", + linebreak="id", + unicodeslot=0x188F3, + }, + [0x188F4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-245", + direction="l", + linebreak="id", + unicodeslot=0x188F4, + }, + [0x188F5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-246", + direction="l", + linebreak="id", + unicodeslot=0x188F5, + }, + [0x188F6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-247", + direction="l", + linebreak="id", + unicodeslot=0x188F6, + }, + [0x188F7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-248", + direction="l", + linebreak="id", + unicodeslot=0x188F7, + }, + [0x188F8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-249", + direction="l", + linebreak="id", + unicodeslot=0x188F8, + }, + [0x188F9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-250", + direction="l", + linebreak="id", + unicodeslot=0x188F9, + }, + [0x188FA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-251", + direction="l", + linebreak="id", + unicodeslot=0x188FA, + }, + [0x188FB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-252", + direction="l", + linebreak="id", + unicodeslot=0x188FB, + }, + [0x188FC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-253", + direction="l", + linebreak="id", + unicodeslot=0x188FC, + }, + [0x188FD]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-254", + direction="l", + linebreak="id", + unicodeslot=0x188FD, + }, + [0x188FE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-255", + direction="l", + linebreak="id", + unicodeslot=0x188FE, + }, + [0x188FF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-256", + direction="l", + linebreak="id", + unicodeslot=0x188FF, + }, + [0x18900]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-257", + direction="l", + linebreak="id", + unicodeslot=0x18900, + }, + [0x18901]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-258", + direction="l", + linebreak="id", + unicodeslot=0x18901, + }, + [0x18902]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-259", + direction="l", + linebreak="id", + unicodeslot=0x18902, + }, + [0x18903]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-260", + direction="l", + linebreak="id", + unicodeslot=0x18903, + }, + [0x18904]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-261", + direction="l", + linebreak="id", + unicodeslot=0x18904, + }, + [0x18905]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-262", + direction="l", + linebreak="id", + unicodeslot=0x18905, + }, + [0x18906]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-263", + direction="l", + linebreak="id", + unicodeslot=0x18906, + }, + [0x18907]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-264", + direction="l", + linebreak="id", + unicodeslot=0x18907, + }, + [0x18908]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-265", + direction="l", + linebreak="id", + unicodeslot=0x18908, + }, + [0x18909]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-266", + direction="l", + linebreak="id", + unicodeslot=0x18909, + }, + [0x1890A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-267", + direction="l", + linebreak="id", + unicodeslot=0x1890A, + }, + [0x1890B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-268", + direction="l", + linebreak="id", + unicodeslot=0x1890B, + }, + [0x1890C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-269", + direction="l", + linebreak="id", + unicodeslot=0x1890C, + }, + [0x1890D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-270", + direction="l", + linebreak="id", + unicodeslot=0x1890D, + }, + [0x1890E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-271", + direction="l", + linebreak="id", + unicodeslot=0x1890E, + }, + [0x1890F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-272", + direction="l", + linebreak="id", + unicodeslot=0x1890F, + }, + [0x18910]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-273", + direction="l", + linebreak="id", + unicodeslot=0x18910, + }, + [0x18911]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-274", + direction="l", + linebreak="id", + unicodeslot=0x18911, + }, + [0x18912]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-275", + direction="l", + linebreak="id", + unicodeslot=0x18912, + }, + [0x18913]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-276", + direction="l", + linebreak="id", + unicodeslot=0x18913, + }, + [0x18914]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-277", + direction="l", + linebreak="id", + unicodeslot=0x18914, + }, + [0x18915]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-278", + direction="l", + linebreak="id", + unicodeslot=0x18915, + }, + [0x18916]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-279", + direction="l", + linebreak="id", + unicodeslot=0x18916, + }, + [0x18917]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-280", + direction="l", + linebreak="id", + unicodeslot=0x18917, + }, + [0x18918]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-281", + direction="l", + linebreak="id", + unicodeslot=0x18918, + }, + [0x18919]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-282", + direction="l", + linebreak="id", + unicodeslot=0x18919, + }, + [0x1891A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-283", + direction="l", + linebreak="id", + unicodeslot=0x1891A, + }, + [0x1891B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-284", + direction="l", + linebreak="id", + unicodeslot=0x1891B, + }, + [0x1891C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-285", + direction="l", + linebreak="id", + unicodeslot=0x1891C, + }, + [0x1891D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-286", + direction="l", + linebreak="id", + unicodeslot=0x1891D, + }, + [0x1891E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-287", + direction="l", + linebreak="id", + unicodeslot=0x1891E, + }, + [0x1891F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-288", + direction="l", + linebreak="id", + unicodeslot=0x1891F, + }, + [0x18920]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-289", + direction="l", + linebreak="id", + unicodeslot=0x18920, + }, + [0x18921]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-290", + direction="l", + linebreak="id", + unicodeslot=0x18921, + }, + [0x18922]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-291", + direction="l", + linebreak="id", + unicodeslot=0x18922, + }, + [0x18923]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-292", + direction="l", + linebreak="id", + unicodeslot=0x18923, + }, + [0x18924]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-293", + direction="l", + linebreak="id", + unicodeslot=0x18924, + }, + [0x18925]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-294", + direction="l", + linebreak="id", + unicodeslot=0x18925, + }, + [0x18926]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-295", + direction="l", + linebreak="id", + unicodeslot=0x18926, + }, + [0x18927]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-296", + direction="l", + linebreak="id", + unicodeslot=0x18927, + }, + [0x18928]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-297", + direction="l", + linebreak="id", + unicodeslot=0x18928, + }, + [0x18929]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-298", + direction="l", + linebreak="id", + unicodeslot=0x18929, + }, + [0x1892A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-299", + direction="l", + linebreak="id", + unicodeslot=0x1892A, + }, + [0x1892B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-300", + direction="l", + linebreak="id", + unicodeslot=0x1892B, + }, + [0x1892C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-301", + direction="l", + linebreak="id", + unicodeslot=0x1892C, + }, + [0x1892D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-302", + direction="l", + linebreak="id", + unicodeslot=0x1892D, + }, + [0x1892E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-303", + direction="l", + linebreak="id", + unicodeslot=0x1892E, + }, + [0x1892F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-304", + direction="l", + linebreak="id", + unicodeslot=0x1892F, + }, + [0x18930]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-305", + direction="l", + linebreak="id", + unicodeslot=0x18930, + }, + [0x18931]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-306", + direction="l", + linebreak="id", + unicodeslot=0x18931, + }, + [0x18932]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-307", + direction="l", + linebreak="id", + unicodeslot=0x18932, + }, + [0x18933]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-308", + direction="l", + linebreak="id", + unicodeslot=0x18933, + }, + [0x18934]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-309", + direction="l", + linebreak="id", + unicodeslot=0x18934, + }, + [0x18935]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-310", + direction="l", + linebreak="id", + unicodeslot=0x18935, + }, + [0x18936]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-311", + direction="l", + linebreak="id", + unicodeslot=0x18936, + }, + [0x18937]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-312", + direction="l", + linebreak="id", + unicodeslot=0x18937, + }, + [0x18938]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-313", + direction="l", + linebreak="id", + unicodeslot=0x18938, + }, + [0x18939]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-314", + direction="l", + linebreak="id", + unicodeslot=0x18939, + }, + [0x1893A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-315", + direction="l", + linebreak="id", + unicodeslot=0x1893A, + }, + [0x1893B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-316", + direction="l", + linebreak="id", + unicodeslot=0x1893B, + }, + [0x1893C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-317", + direction="l", + linebreak="id", + unicodeslot=0x1893C, + }, + [0x1893D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-318", + direction="l", + linebreak="id", + unicodeslot=0x1893D, + }, + [0x1893E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-319", + direction="l", + linebreak="id", + unicodeslot=0x1893E, + }, + [0x1893F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-320", + direction="l", + linebreak="id", + unicodeslot=0x1893F, + }, + [0x18940]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-321", + direction="l", + linebreak="id", + unicodeslot=0x18940, + }, + [0x18941]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-322", + direction="l", + linebreak="id", + unicodeslot=0x18941, + }, + [0x18942]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-323", + direction="l", + linebreak="id", + unicodeslot=0x18942, + }, + [0x18943]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-324", + direction="l", + linebreak="id", + unicodeslot=0x18943, + }, + [0x18944]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-325", + direction="l", + linebreak="id", + unicodeslot=0x18944, + }, + [0x18945]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-326", + direction="l", + linebreak="id", + unicodeslot=0x18945, + }, + [0x18946]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-327", + direction="l", + linebreak="id", + unicodeslot=0x18946, + }, + [0x18947]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-328", + direction="l", + linebreak="id", + unicodeslot=0x18947, + }, + [0x18948]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-329", + direction="l", + linebreak="id", + unicodeslot=0x18948, + }, + [0x18949]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-330", + direction="l", + linebreak="id", + unicodeslot=0x18949, + }, + [0x1894A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-331", + direction="l", + linebreak="id", + unicodeslot=0x1894A, + }, + [0x1894B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-332", + direction="l", + linebreak="id", + unicodeslot=0x1894B, + }, + [0x1894C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-333", + direction="l", + linebreak="id", + unicodeslot=0x1894C, + }, + [0x1894D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-334", + direction="l", + linebreak="id", + unicodeslot=0x1894D, + }, + [0x1894E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-335", + direction="l", + linebreak="id", + unicodeslot=0x1894E, + }, + [0x1894F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-336", + direction="l", + linebreak="id", + unicodeslot=0x1894F, + }, + [0x18950]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-337", + direction="l", + linebreak="id", + unicodeslot=0x18950, + }, + [0x18951]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-338", + direction="l", + linebreak="id", + unicodeslot=0x18951, + }, + [0x18952]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-339", + direction="l", + linebreak="id", + unicodeslot=0x18952, + }, + [0x18953]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-340", + direction="l", + linebreak="id", + unicodeslot=0x18953, + }, + [0x18954]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-341", + direction="l", + linebreak="id", + unicodeslot=0x18954, + }, + [0x18955]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-342", + direction="l", + linebreak="id", + unicodeslot=0x18955, + }, + [0x18956]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-343", + direction="l", + linebreak="id", + unicodeslot=0x18956, + }, + [0x18957]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-344", + direction="l", + linebreak="id", + unicodeslot=0x18957, + }, + [0x18958]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-345", + direction="l", + linebreak="id", + unicodeslot=0x18958, + }, + [0x18959]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-346", + direction="l", + linebreak="id", + unicodeslot=0x18959, + }, + [0x1895A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-347", + direction="l", + linebreak="id", + unicodeslot=0x1895A, + }, + [0x1895B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-348", + direction="l", + linebreak="id", + unicodeslot=0x1895B, + }, + [0x1895C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-349", + direction="l", + linebreak="id", + unicodeslot=0x1895C, + }, + [0x1895D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-350", + direction="l", + linebreak="id", + unicodeslot=0x1895D, + }, + [0x1895E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-351", + direction="l", + linebreak="id", + unicodeslot=0x1895E, + }, + [0x1895F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-352", + direction="l", + linebreak="id", + unicodeslot=0x1895F, + }, + [0x18960]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-353", + direction="l", + linebreak="id", + unicodeslot=0x18960, + }, + [0x18961]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-354", + direction="l", + linebreak="id", + unicodeslot=0x18961, + }, + [0x18962]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-355", + direction="l", + linebreak="id", + unicodeslot=0x18962, + }, + [0x18963]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-356", + direction="l", + linebreak="id", + unicodeslot=0x18963, + }, + [0x18964]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-357", + direction="l", + linebreak="id", + unicodeslot=0x18964, + }, + [0x18965]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-358", + direction="l", + linebreak="id", + unicodeslot=0x18965, + }, + [0x18966]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-359", + direction="l", + linebreak="id", + unicodeslot=0x18966, + }, + [0x18967]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-360", + direction="l", + linebreak="id", + unicodeslot=0x18967, + }, + [0x18968]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-361", + direction="l", + linebreak="id", + unicodeslot=0x18968, + }, + [0x18969]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-362", + direction="l", + linebreak="id", + unicodeslot=0x18969, + }, + [0x1896A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-363", + direction="l", + linebreak="id", + unicodeslot=0x1896A, + }, + [0x1896B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-364", + direction="l", + linebreak="id", + unicodeslot=0x1896B, + }, + [0x1896C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-365", + direction="l", + linebreak="id", + unicodeslot=0x1896C, + }, + [0x1896D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-366", + direction="l", + linebreak="id", + unicodeslot=0x1896D, + }, + [0x1896E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-367", + direction="l", + linebreak="id", + unicodeslot=0x1896E, + }, + [0x1896F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-368", + direction="l", + linebreak="id", + unicodeslot=0x1896F, + }, + [0x18970]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-369", + direction="l", + linebreak="id", + unicodeslot=0x18970, + }, + [0x18971]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-370", + direction="l", + linebreak="id", + unicodeslot=0x18971, + }, + [0x18972]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-371", + direction="l", + linebreak="id", + unicodeslot=0x18972, + }, + [0x18973]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-372", + direction="l", + linebreak="id", + unicodeslot=0x18973, + }, + [0x18974]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-373", + direction="l", + linebreak="id", + unicodeslot=0x18974, + }, + [0x18975]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-374", + direction="l", + linebreak="id", + unicodeslot=0x18975, + }, + [0x18976]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-375", + direction="l", + linebreak="id", + unicodeslot=0x18976, + }, + [0x18977]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-376", + direction="l", + linebreak="id", + unicodeslot=0x18977, + }, + [0x18978]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-377", + direction="l", + linebreak="id", + unicodeslot=0x18978, + }, + [0x18979]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-378", + direction="l", + linebreak="id", + unicodeslot=0x18979, + }, + [0x1897A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-379", + direction="l", + linebreak="id", + unicodeslot=0x1897A, + }, + [0x1897B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-380", + direction="l", + linebreak="id", + unicodeslot=0x1897B, + }, + [0x1897C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-381", + direction="l", + linebreak="id", + unicodeslot=0x1897C, + }, + [0x1897D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-382", + direction="l", + linebreak="id", + unicodeslot=0x1897D, + }, + [0x1897E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-383", + direction="l", + linebreak="id", + unicodeslot=0x1897E, + }, + [0x1897F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-384", + direction="l", + linebreak="id", + unicodeslot=0x1897F, + }, + [0x18980]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-385", + direction="l", + linebreak="id", + unicodeslot=0x18980, + }, + [0x18981]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-386", + direction="l", + linebreak="id", + unicodeslot=0x18981, + }, + [0x18982]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-387", + direction="l", + linebreak="id", + unicodeslot=0x18982, + }, + [0x18983]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-388", + direction="l", + linebreak="id", + unicodeslot=0x18983, + }, + [0x18984]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-389", + direction="l", + linebreak="id", + unicodeslot=0x18984, + }, + [0x18985]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-390", + direction="l", + linebreak="id", + unicodeslot=0x18985, + }, + [0x18986]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-391", + direction="l", + linebreak="id", + unicodeslot=0x18986, + }, + [0x18987]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-392", + direction="l", + linebreak="id", + unicodeslot=0x18987, + }, + [0x18988]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-393", + direction="l", + linebreak="id", + unicodeslot=0x18988, + }, + [0x18989]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-394", + direction="l", + linebreak="id", + unicodeslot=0x18989, + }, + [0x1898A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-395", + direction="l", + linebreak="id", + unicodeslot=0x1898A, + }, + [0x1898B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-396", + direction="l", + linebreak="id", + unicodeslot=0x1898B, + }, + [0x1898C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-397", + direction="l", + linebreak="id", + unicodeslot=0x1898C, + }, + [0x1898D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-398", + direction="l", + linebreak="id", + unicodeslot=0x1898D, + }, + [0x1898E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-399", + direction="l", + linebreak="id", + unicodeslot=0x1898E, + }, + [0x1898F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-400", + direction="l", + linebreak="id", + unicodeslot=0x1898F, + }, + [0x18990]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-401", + direction="l", + linebreak="id", + unicodeslot=0x18990, + }, + [0x18991]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-402", + direction="l", + linebreak="id", + unicodeslot=0x18991, + }, + [0x18992]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-403", + direction="l", + linebreak="id", + unicodeslot=0x18992, + }, + [0x18993]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-404", + direction="l", + linebreak="id", + unicodeslot=0x18993, + }, + [0x18994]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-405", + direction="l", + linebreak="id", + unicodeslot=0x18994, + }, + [0x18995]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-406", + direction="l", + linebreak="id", + unicodeslot=0x18995, + }, + [0x18996]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-407", + direction="l", + linebreak="id", + unicodeslot=0x18996, + }, + [0x18997]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-408", + direction="l", + linebreak="id", + unicodeslot=0x18997, + }, + [0x18998]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-409", + direction="l", + linebreak="id", + unicodeslot=0x18998, + }, + [0x18999]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-410", + direction="l", + linebreak="id", + unicodeslot=0x18999, + }, + [0x1899A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-411", + direction="l", + linebreak="id", + unicodeslot=0x1899A, + }, + [0x1899B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-412", + direction="l", + linebreak="id", + unicodeslot=0x1899B, + }, + [0x1899C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-413", + direction="l", + linebreak="id", + unicodeslot=0x1899C, + }, + [0x1899D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-414", + direction="l", + linebreak="id", + unicodeslot=0x1899D, + }, + [0x1899E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-415", + direction="l", + linebreak="id", + unicodeslot=0x1899E, + }, + [0x1899F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-416", + direction="l", + linebreak="id", + unicodeslot=0x1899F, + }, + [0x189A0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-417", + direction="l", + linebreak="id", + unicodeslot=0x189A0, + }, + [0x189A1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-418", + direction="l", + linebreak="id", + unicodeslot=0x189A1, + }, + [0x189A2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-419", + direction="l", + linebreak="id", + unicodeslot=0x189A2, + }, + [0x189A3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-420", + direction="l", + linebreak="id", + unicodeslot=0x189A3, + }, + [0x189A4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-421", + direction="l", + linebreak="id", + unicodeslot=0x189A4, + }, + [0x189A5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-422", + direction="l", + linebreak="id", + unicodeslot=0x189A5, + }, + [0x189A6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-423", + direction="l", + linebreak="id", + unicodeslot=0x189A6, + }, + [0x189A7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-424", + direction="l", + linebreak="id", + unicodeslot=0x189A7, + }, + [0x189A8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-425", + direction="l", + linebreak="id", + unicodeslot=0x189A8, + }, + [0x189A9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-426", + direction="l", + linebreak="id", + unicodeslot=0x189A9, + }, + [0x189AA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-427", + direction="l", + linebreak="id", + unicodeslot=0x189AA, + }, + [0x189AB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-428", + direction="l", + linebreak="id", + unicodeslot=0x189AB, + }, + [0x189AC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-429", + direction="l", + linebreak="id", + unicodeslot=0x189AC, + }, + [0x189AD]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-430", + direction="l", + linebreak="id", + unicodeslot=0x189AD, + }, + [0x189AE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-431", + direction="l", + linebreak="id", + unicodeslot=0x189AE, + }, + [0x189AF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-432", + direction="l", + linebreak="id", + unicodeslot=0x189AF, + }, + [0x189B0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-433", + direction="l", + linebreak="id", + unicodeslot=0x189B0, + }, + [0x189B1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-434", + direction="l", + linebreak="id", + unicodeslot=0x189B1, + }, + [0x189B2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-435", + direction="l", + linebreak="id", + unicodeslot=0x189B2, + }, + [0x189B3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-436", + direction="l", + linebreak="id", + unicodeslot=0x189B3, + }, + [0x189B4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-437", + direction="l", + linebreak="id", + unicodeslot=0x189B4, + }, + [0x189B5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-438", + direction="l", + linebreak="id", + unicodeslot=0x189B5, + }, + [0x189B6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-439", + direction="l", + linebreak="id", + unicodeslot=0x189B6, + }, + [0x189B7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-440", + direction="l", + linebreak="id", + unicodeslot=0x189B7, + }, + [0x189B8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-441", + direction="l", + linebreak="id", + unicodeslot=0x189B8, + }, + [0x189B9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-442", + direction="l", + linebreak="id", + unicodeslot=0x189B9, + }, + [0x189BA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-443", + direction="l", + linebreak="id", + unicodeslot=0x189BA, + }, + [0x189BB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-444", + direction="l", + linebreak="id", + unicodeslot=0x189BB, + }, + [0x189BC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-445", + direction="l", + linebreak="id", + unicodeslot=0x189BC, + }, + [0x189BD]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-446", + direction="l", + linebreak="id", + unicodeslot=0x189BD, + }, + [0x189BE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-447", + direction="l", + linebreak="id", + unicodeslot=0x189BE, + }, + [0x189BF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-448", + direction="l", + linebreak="id", + unicodeslot=0x189BF, + }, + [0x189C0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-449", + direction="l", + linebreak="id", + unicodeslot=0x189C0, + }, + [0x189C1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-450", + direction="l", + linebreak="id", + unicodeslot=0x189C1, + }, + [0x189C2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-451", + direction="l", + linebreak="id", + unicodeslot=0x189C2, + }, + [0x189C3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-452", + direction="l", + linebreak="id", + unicodeslot=0x189C3, + }, + [0x189C4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-453", + direction="l", + linebreak="id", + unicodeslot=0x189C4, + }, + [0x189C5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-454", + direction="l", + linebreak="id", + unicodeslot=0x189C5, + }, + [0x189C6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-455", + direction="l", + linebreak="id", + unicodeslot=0x189C6, + }, + [0x189C7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-456", + direction="l", + linebreak="id", + unicodeslot=0x189C7, + }, + [0x189C8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-457", + direction="l", + linebreak="id", + unicodeslot=0x189C8, + }, + [0x189C9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-458", + direction="l", + linebreak="id", + unicodeslot=0x189C9, + }, + [0x189CA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-459", + direction="l", + linebreak="id", + unicodeslot=0x189CA, + }, + [0x189CB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-460", + direction="l", + linebreak="id", + unicodeslot=0x189CB, + }, + [0x189CC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-461", + direction="l", + linebreak="id", + unicodeslot=0x189CC, + }, + [0x189CD]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-462", + direction="l", + linebreak="id", + unicodeslot=0x189CD, + }, + [0x189CE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-463", + direction="l", + linebreak="id", + unicodeslot=0x189CE, + }, + [0x189CF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-464", + direction="l", + linebreak="id", + unicodeslot=0x189CF, + }, + [0x189D0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-465", + direction="l", + linebreak="id", + unicodeslot=0x189D0, + }, + [0x189D1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-466", + direction="l", + linebreak="id", + unicodeslot=0x189D1, + }, + [0x189D2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-467", + direction="l", + linebreak="id", + unicodeslot=0x189D2, + }, + [0x189D3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-468", + direction="l", + linebreak="id", + unicodeslot=0x189D3, + }, + [0x189D4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-469", + direction="l", + linebreak="id", + unicodeslot=0x189D4, + }, + [0x189D5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-470", + direction="l", + linebreak="id", + unicodeslot=0x189D5, + }, + [0x189D6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-471", + direction="l", + linebreak="id", + unicodeslot=0x189D6, + }, + [0x189D7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-472", + direction="l", + linebreak="id", + unicodeslot=0x189D7, + }, + [0x189D8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-473", + direction="l", + linebreak="id", + unicodeslot=0x189D8, + }, + [0x189D9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-474", + direction="l", + linebreak="id", + unicodeslot=0x189D9, + }, + [0x189DA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-475", + direction="l", + linebreak="id", + unicodeslot=0x189DA, + }, + [0x189DB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-476", + direction="l", + linebreak="id", + unicodeslot=0x189DB, + }, + [0x189DC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-477", + direction="l", + linebreak="id", + unicodeslot=0x189DC, + }, + [0x189DD]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-478", + direction="l", + linebreak="id", + unicodeslot=0x189DD, + }, + [0x189DE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-479", + direction="l", + linebreak="id", + unicodeslot=0x189DE, + }, + [0x189DF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-480", + direction="l", + linebreak="id", + unicodeslot=0x189DF, + }, + [0x189E0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-481", + direction="l", + linebreak="id", + unicodeslot=0x189E0, + }, + [0x189E1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-482", + direction="l", + linebreak="id", + unicodeslot=0x189E1, + }, + [0x189E2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-483", + direction="l", + linebreak="id", + unicodeslot=0x189E2, + }, + [0x189E3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-484", + direction="l", + linebreak="id", + unicodeslot=0x189E3, + }, + [0x189E4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-485", + direction="l", + linebreak="id", + unicodeslot=0x189E4, + }, + [0x189E5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-486", + direction="l", + linebreak="id", + unicodeslot=0x189E5, + }, + [0x189E6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-487", + direction="l", + linebreak="id", + unicodeslot=0x189E6, + }, + [0x189E7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-488", + direction="l", + linebreak="id", + unicodeslot=0x189E7, + }, + [0x189E8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-489", + direction="l", + linebreak="id", + unicodeslot=0x189E8, + }, + [0x189E9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-490", + direction="l", + linebreak="id", + unicodeslot=0x189E9, + }, + [0x189EA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-491", + direction="l", + linebreak="id", + unicodeslot=0x189EA, + }, + [0x189EB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-492", + direction="l", + linebreak="id", + unicodeslot=0x189EB, + }, + [0x189EC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-493", + direction="l", + linebreak="id", + unicodeslot=0x189EC, + }, + [0x189ED]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-494", + direction="l", + linebreak="id", + unicodeslot=0x189ED, + }, + [0x189EE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-495", + direction="l", + linebreak="id", + unicodeslot=0x189EE, + }, + [0x189EF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-496", + direction="l", + linebreak="id", + unicodeslot=0x189EF, + }, + [0x189F0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-497", + direction="l", + linebreak="id", + unicodeslot=0x189F0, + }, + [0x189F1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-498", + direction="l", + linebreak="id", + unicodeslot=0x189F1, + }, + [0x189F2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-499", + direction="l", + linebreak="id", + unicodeslot=0x189F2, + }, + [0x189F3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-500", + direction="l", + linebreak="id", + unicodeslot=0x189F3, + }, + [0x189F4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-501", + direction="l", + linebreak="id", + unicodeslot=0x189F4, + }, + [0x189F5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-502", + direction="l", + linebreak="id", + unicodeslot=0x189F5, + }, + [0x189F6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-503", + direction="l", + linebreak="id", + unicodeslot=0x189F6, + }, + [0x189F7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-504", + direction="l", + linebreak="id", + unicodeslot=0x189F7, + }, + [0x189F8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-505", + direction="l", + linebreak="id", + unicodeslot=0x189F8, + }, + [0x189F9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-506", + direction="l", + linebreak="id", + unicodeslot=0x189F9, + }, + [0x189FA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-507", + direction="l", + linebreak="id", + unicodeslot=0x189FA, + }, + [0x189FB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-508", + direction="l", + linebreak="id", + unicodeslot=0x189FB, + }, + [0x189FC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-509", + direction="l", + linebreak="id", + unicodeslot=0x189FC, + }, + [0x189FD]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-510", + direction="l", + linebreak="id", + unicodeslot=0x189FD, + }, + [0x189FE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-511", + direction="l", + linebreak="id", + unicodeslot=0x189FE, + }, + [0x189FF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-512", + direction="l", + linebreak="id", + unicodeslot=0x189FF, + }, + [0x18A00]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-513", + direction="l", + linebreak="id", + unicodeslot=0x18A00, + }, + [0x18A01]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-514", + direction="l", + linebreak="id", + unicodeslot=0x18A01, + }, + [0x18A02]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-515", + direction="l", + linebreak="id", + unicodeslot=0x18A02, + }, + [0x18A03]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-516", + direction="l", + linebreak="id", + unicodeslot=0x18A03, + }, + [0x18A04]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-517", + direction="l", + linebreak="id", + unicodeslot=0x18A04, + }, + [0x18A05]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-518", + direction="l", + linebreak="id", + unicodeslot=0x18A05, + }, + [0x18A06]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-519", + direction="l", + linebreak="id", + unicodeslot=0x18A06, + }, + [0x18A07]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-520", + direction="l", + linebreak="id", + unicodeslot=0x18A07, + }, + [0x18A08]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-521", + direction="l", + linebreak="id", + unicodeslot=0x18A08, + }, + [0x18A09]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-522", + direction="l", + linebreak="id", + unicodeslot=0x18A09, + }, + [0x18A0A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-523", + direction="l", + linebreak="id", + unicodeslot=0x18A0A, + }, + [0x18A0B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-524", + direction="l", + linebreak="id", + unicodeslot=0x18A0B, + }, + [0x18A0C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-525", + direction="l", + linebreak="id", + unicodeslot=0x18A0C, + }, + [0x18A0D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-526", + direction="l", + linebreak="id", + unicodeslot=0x18A0D, + }, + [0x18A0E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-527", + direction="l", + linebreak="id", + unicodeslot=0x18A0E, + }, + [0x18A0F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-528", + direction="l", + linebreak="id", + unicodeslot=0x18A0F, + }, + [0x18A10]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-529", + direction="l", + linebreak="id", + unicodeslot=0x18A10, + }, + [0x18A11]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-530", + direction="l", + linebreak="id", + unicodeslot=0x18A11, + }, + [0x18A12]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-531", + direction="l", + linebreak="id", + unicodeslot=0x18A12, + }, + [0x18A13]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-532", + direction="l", + linebreak="id", + unicodeslot=0x18A13, + }, + [0x18A14]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-533", + direction="l", + linebreak="id", + unicodeslot=0x18A14, + }, + [0x18A15]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-534", + direction="l", + linebreak="id", + unicodeslot=0x18A15, + }, + [0x18A16]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-535", + direction="l", + linebreak="id", + unicodeslot=0x18A16, + }, + [0x18A17]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-536", + direction="l", + linebreak="id", + unicodeslot=0x18A17, + }, + [0x18A18]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-537", + direction="l", + linebreak="id", + unicodeslot=0x18A18, + }, + [0x18A19]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-538", + direction="l", + linebreak="id", + unicodeslot=0x18A19, + }, + [0x18A1A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-539", + direction="l", + linebreak="id", + unicodeslot=0x18A1A, + }, + [0x18A1B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-540", + direction="l", + linebreak="id", + unicodeslot=0x18A1B, + }, + [0x18A1C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-541", + direction="l", + linebreak="id", + unicodeslot=0x18A1C, + }, + [0x18A1D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-542", + direction="l", + linebreak="id", + unicodeslot=0x18A1D, + }, + [0x18A1E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-543", + direction="l", + linebreak="id", + unicodeslot=0x18A1E, + }, + [0x18A1F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-544", + direction="l", + linebreak="id", + unicodeslot=0x18A1F, + }, + [0x18A20]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-545", + direction="l", + linebreak="id", + unicodeslot=0x18A20, + }, + [0x18A21]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-546", + direction="l", + linebreak="id", + unicodeslot=0x18A21, + }, + [0x18A22]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-547", + direction="l", + linebreak="id", + unicodeslot=0x18A22, + }, + [0x18A23]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-548", + direction="l", + linebreak="id", + unicodeslot=0x18A23, + }, + [0x18A24]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-549", + direction="l", + linebreak="id", + unicodeslot=0x18A24, + }, + [0x18A25]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-550", + direction="l", + linebreak="id", + unicodeslot=0x18A25, + }, + [0x18A26]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-551", + direction="l", + linebreak="id", + unicodeslot=0x18A26, + }, + [0x18A27]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-552", + direction="l", + linebreak="id", + unicodeslot=0x18A27, + }, + [0x18A28]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-553", + direction="l", + linebreak="id", + unicodeslot=0x18A28, + }, + [0x18A29]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-554", + direction="l", + linebreak="id", + unicodeslot=0x18A29, + }, + [0x18A2A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-555", + direction="l", + linebreak="id", + unicodeslot=0x18A2A, + }, + [0x18A2B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-556", + direction="l", + linebreak="id", + unicodeslot=0x18A2B, + }, + [0x18A2C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-557", + direction="l", + linebreak="id", + unicodeslot=0x18A2C, + }, + [0x18A2D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-558", + direction="l", + linebreak="id", + unicodeslot=0x18A2D, + }, + [0x18A2E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-559", + direction="l", + linebreak="id", + unicodeslot=0x18A2E, + }, + [0x18A2F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-560", + direction="l", + linebreak="id", + unicodeslot=0x18A2F, + }, + [0x18A30]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-561", + direction="l", + linebreak="id", + unicodeslot=0x18A30, + }, + [0x18A31]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-562", + direction="l", + linebreak="id", + unicodeslot=0x18A31, + }, + [0x18A32]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-563", + direction="l", + linebreak="id", + unicodeslot=0x18A32, + }, + [0x18A33]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-564", + direction="l", + linebreak="id", + unicodeslot=0x18A33, + }, + [0x18A34]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-565", + direction="l", + linebreak="id", + unicodeslot=0x18A34, + }, + [0x18A35]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-566", + direction="l", + linebreak="id", + unicodeslot=0x18A35, + }, + [0x18A36]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-567", + direction="l", + linebreak="id", + unicodeslot=0x18A36, + }, + [0x18A37]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-568", + direction="l", + linebreak="id", + unicodeslot=0x18A37, + }, + [0x18A38]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-569", + direction="l", + linebreak="id", + unicodeslot=0x18A38, + }, + [0x18A39]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-570", + direction="l", + linebreak="id", + unicodeslot=0x18A39, + }, + [0x18A3A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-571", + direction="l", + linebreak="id", + unicodeslot=0x18A3A, + }, + [0x18A3B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-572", + direction="l", + linebreak="id", + unicodeslot=0x18A3B, + }, + [0x18A3C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-573", + direction="l", + linebreak="id", + unicodeslot=0x18A3C, + }, + [0x18A3D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-574", + direction="l", + linebreak="id", + unicodeslot=0x18A3D, + }, + [0x18A3E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-575", + direction="l", + linebreak="id", + unicodeslot=0x18A3E, + }, + [0x18A3F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-576", + direction="l", + linebreak="id", + unicodeslot=0x18A3F, + }, + [0x18A40]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-577", + direction="l", + linebreak="id", + unicodeslot=0x18A40, + }, + [0x18A41]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-578", + direction="l", + linebreak="id", + unicodeslot=0x18A41, + }, + [0x18A42]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-579", + direction="l", + linebreak="id", + unicodeslot=0x18A42, + }, + [0x18A43]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-580", + direction="l", + linebreak="id", + unicodeslot=0x18A43, + }, + [0x18A44]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-581", + direction="l", + linebreak="id", + unicodeslot=0x18A44, + }, + [0x18A45]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-582", + direction="l", + linebreak="id", + unicodeslot=0x18A45, + }, + [0x18A46]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-583", + direction="l", + linebreak="id", + unicodeslot=0x18A46, + }, + [0x18A47]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-584", + direction="l", + linebreak="id", + unicodeslot=0x18A47, + }, + [0x18A48]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-585", + direction="l", + linebreak="id", + unicodeslot=0x18A48, + }, + [0x18A49]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-586", + direction="l", + linebreak="id", + unicodeslot=0x18A49, + }, + [0x18A4A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-587", + direction="l", + linebreak="id", + unicodeslot=0x18A4A, + }, + [0x18A4B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-588", + direction="l", + linebreak="id", + unicodeslot=0x18A4B, + }, + [0x18A4C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-589", + direction="l", + linebreak="id", + unicodeslot=0x18A4C, + }, + [0x18A4D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-590", + direction="l", + linebreak="id", + unicodeslot=0x18A4D, + }, + [0x18A4E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-591", + direction="l", + linebreak="id", + unicodeslot=0x18A4E, + }, + [0x18A4F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-592", + direction="l", + linebreak="id", + unicodeslot=0x18A4F, + }, + [0x18A50]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-593", + direction="l", + linebreak="id", + unicodeslot=0x18A50, + }, + [0x18A51]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-594", + direction="l", + linebreak="id", + unicodeslot=0x18A51, + }, + [0x18A52]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-595", + direction="l", + linebreak="id", + unicodeslot=0x18A52, + }, + [0x18A53]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-596", + direction="l", + linebreak="id", + unicodeslot=0x18A53, + }, + [0x18A54]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-597", + direction="l", + linebreak="id", + unicodeslot=0x18A54, + }, + [0x18A55]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-598", + direction="l", + linebreak="id", + unicodeslot=0x18A55, + }, + [0x18A56]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-599", + direction="l", + linebreak="id", + unicodeslot=0x18A56, + }, + [0x18A57]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-600", + direction="l", + linebreak="id", + unicodeslot=0x18A57, + }, + [0x18A58]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-601", + direction="l", + linebreak="id", + unicodeslot=0x18A58, + }, + [0x18A59]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-602", + direction="l", + linebreak="id", + unicodeslot=0x18A59, + }, + [0x18A5A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-603", + direction="l", + linebreak="id", + unicodeslot=0x18A5A, + }, + [0x18A5B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-604", + direction="l", + linebreak="id", + unicodeslot=0x18A5B, + }, + [0x18A5C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-605", + direction="l", + linebreak="id", + unicodeslot=0x18A5C, + }, + [0x18A5D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-606", + direction="l", + linebreak="id", + unicodeslot=0x18A5D, + }, + [0x18A5E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-607", + direction="l", + linebreak="id", + unicodeslot=0x18A5E, + }, + [0x18A5F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-608", + direction="l", + linebreak="id", + unicodeslot=0x18A5F, + }, + [0x18A60]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-609", + direction="l", + linebreak="id", + unicodeslot=0x18A60, + }, + [0x18A61]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-610", + direction="l", + linebreak="id", + unicodeslot=0x18A61, + }, + [0x18A62]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-611", + direction="l", + linebreak="id", + unicodeslot=0x18A62, + }, + [0x18A63]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-612", + direction="l", + linebreak="id", + unicodeslot=0x18A63, + }, + [0x18A64]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-613", + direction="l", + linebreak="id", + unicodeslot=0x18A64, + }, + [0x18A65]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-614", + direction="l", + linebreak="id", + unicodeslot=0x18A65, + }, + [0x18A66]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-615", + direction="l", + linebreak="id", + unicodeslot=0x18A66, + }, + [0x18A67]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-616", + direction="l", + linebreak="id", + unicodeslot=0x18A67, + }, + [0x18A68]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-617", + direction="l", + linebreak="id", + unicodeslot=0x18A68, + }, + [0x18A69]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-618", + direction="l", + linebreak="id", + unicodeslot=0x18A69, + }, + [0x18A6A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-619", + direction="l", + linebreak="id", + unicodeslot=0x18A6A, + }, + [0x18A6B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-620", + direction="l", + linebreak="id", + unicodeslot=0x18A6B, + }, + [0x18A6C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-621", + direction="l", + linebreak="id", + unicodeslot=0x18A6C, + }, + [0x18A6D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-622", + direction="l", + linebreak="id", + unicodeslot=0x18A6D, + }, + [0x18A6E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-623", + direction="l", + linebreak="id", + unicodeslot=0x18A6E, + }, + [0x18A6F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-624", + direction="l", + linebreak="id", + unicodeslot=0x18A6F, + }, + [0x18A70]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-625", + direction="l", + linebreak="id", + unicodeslot=0x18A70, + }, + [0x18A71]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-626", + direction="l", + linebreak="id", + unicodeslot=0x18A71, + }, + [0x18A72]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-627", + direction="l", + linebreak="id", + unicodeslot=0x18A72, + }, + [0x18A73]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-628", + direction="l", + linebreak="id", + unicodeslot=0x18A73, + }, + [0x18A74]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-629", + direction="l", + linebreak="id", + unicodeslot=0x18A74, + }, + [0x18A75]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-630", + direction="l", + linebreak="id", + unicodeslot=0x18A75, + }, + [0x18A76]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-631", + direction="l", + linebreak="id", + unicodeslot=0x18A76, + }, + [0x18A77]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-632", + direction="l", + linebreak="id", + unicodeslot=0x18A77, + }, + [0x18A78]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-633", + direction="l", + linebreak="id", + unicodeslot=0x18A78, + }, + [0x18A79]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-634", + direction="l", + linebreak="id", + unicodeslot=0x18A79, + }, + [0x18A7A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-635", + direction="l", + linebreak="id", + unicodeslot=0x18A7A, + }, + [0x18A7B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-636", + direction="l", + linebreak="id", + unicodeslot=0x18A7B, + }, + [0x18A7C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-637", + direction="l", + linebreak="id", + unicodeslot=0x18A7C, + }, + [0x18A7D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-638", + direction="l", + linebreak="id", + unicodeslot=0x18A7D, + }, + [0x18A7E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-639", + direction="l", + linebreak="id", + unicodeslot=0x18A7E, + }, + [0x18A7F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-640", + direction="l", + linebreak="id", + unicodeslot=0x18A7F, + }, + [0x18A80]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-641", + direction="l", + linebreak="id", + unicodeslot=0x18A80, + }, + [0x18A81]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-642", + direction="l", + linebreak="id", + unicodeslot=0x18A81, + }, + [0x18A82]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-643", + direction="l", + linebreak="id", + unicodeslot=0x18A82, + }, + [0x18A83]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-644", + direction="l", + linebreak="id", + unicodeslot=0x18A83, + }, + [0x18A84]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-645", + direction="l", + linebreak="id", + unicodeslot=0x18A84, + }, + [0x18A85]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-646", + direction="l", + linebreak="id", + unicodeslot=0x18A85, + }, + [0x18A86]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-647", + direction="l", + linebreak="id", + unicodeslot=0x18A86, + }, + [0x18A87]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-648", + direction="l", + linebreak="id", + unicodeslot=0x18A87, + }, + [0x18A88]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-649", + direction="l", + linebreak="id", + unicodeslot=0x18A88, + }, + [0x18A89]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-650", + direction="l", + linebreak="id", + unicodeslot=0x18A89, + }, + [0x18A8A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-651", + direction="l", + linebreak="id", + unicodeslot=0x18A8A, + }, + [0x18A8B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-652", + direction="l", + linebreak="id", + unicodeslot=0x18A8B, + }, + [0x18A8C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-653", + direction="l", + linebreak="id", + unicodeslot=0x18A8C, + }, + [0x18A8D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-654", + direction="l", + linebreak="id", + unicodeslot=0x18A8D, + }, + [0x18A8E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-655", + direction="l", + linebreak="id", + unicodeslot=0x18A8E, + }, + [0x18A8F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-656", + direction="l", + linebreak="id", + unicodeslot=0x18A8F, + }, + [0x18A90]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-657", + direction="l", + linebreak="id", + unicodeslot=0x18A90, + }, + [0x18A91]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-658", + direction="l", + linebreak="id", + unicodeslot=0x18A91, + }, + [0x18A92]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-659", + direction="l", + linebreak="id", + unicodeslot=0x18A92, + }, + [0x18A93]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-660", + direction="l", + linebreak="id", + unicodeslot=0x18A93, + }, + [0x18A94]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-661", + direction="l", + linebreak="id", + unicodeslot=0x18A94, + }, + [0x18A95]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-662", + direction="l", + linebreak="id", + unicodeslot=0x18A95, + }, + [0x18A96]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-663", + direction="l", + linebreak="id", + unicodeslot=0x18A96, + }, + [0x18A97]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-664", + direction="l", + linebreak="id", + unicodeslot=0x18A97, + }, + [0x18A98]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-665", + direction="l", + linebreak="id", + unicodeslot=0x18A98, + }, + [0x18A99]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-666", + direction="l", + linebreak="id", + unicodeslot=0x18A99, + }, + [0x18A9A]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-667", + direction="l", + linebreak="id", + unicodeslot=0x18A9A, + }, + [0x18A9B]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-668", + direction="l", + linebreak="id", + unicodeslot=0x18A9B, + }, + [0x18A9C]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-669", + direction="l", + linebreak="id", + unicodeslot=0x18A9C, + }, + [0x18A9D]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-670", + direction="l", + linebreak="id", + unicodeslot=0x18A9D, + }, + [0x18A9E]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-671", + direction="l", + linebreak="id", + unicodeslot=0x18A9E, + }, + [0x18A9F]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-672", + direction="l", + linebreak="id", + unicodeslot=0x18A9F, + }, + [0x18AA0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-673", + direction="l", + linebreak="id", + unicodeslot=0x18AA0, + }, + [0x18AA1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-674", + direction="l", + linebreak="id", + unicodeslot=0x18AA1, + }, + [0x18AA2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-675", + direction="l", + linebreak="id", + unicodeslot=0x18AA2, + }, + [0x18AA3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-676", + direction="l", + linebreak="id", + unicodeslot=0x18AA3, + }, + [0x18AA4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-677", + direction="l", + linebreak="id", + unicodeslot=0x18AA4, + }, + [0x18AA5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-678", + direction="l", + linebreak="id", + unicodeslot=0x18AA5, + }, + [0x18AA6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-679", + direction="l", + linebreak="id", + unicodeslot=0x18AA6, + }, + [0x18AA7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-680", + direction="l", + linebreak="id", + unicodeslot=0x18AA7, + }, + [0x18AA8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-681", + direction="l", + linebreak="id", + unicodeslot=0x18AA8, + }, + [0x18AA9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-682", + direction="l", + linebreak="id", + unicodeslot=0x18AA9, + }, + [0x18AAA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-683", + direction="l", + linebreak="id", + unicodeslot=0x18AAA, + }, + [0x18AAB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-684", + direction="l", + linebreak="id", + unicodeslot=0x18AAB, + }, + [0x18AAC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-685", + direction="l", + linebreak="id", + unicodeslot=0x18AAC, + }, + [0x18AAD]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-686", + direction="l", + linebreak="id", + unicodeslot=0x18AAD, + }, + [0x18AAE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-687", + direction="l", + linebreak="id", + unicodeslot=0x18AAE, + }, + [0x18AAF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-688", + direction="l", + linebreak="id", + unicodeslot=0x18AAF, + }, + [0x18AB0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-689", + direction="l", + linebreak="id", + unicodeslot=0x18AB0, + }, + [0x18AB1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-690", + direction="l", + linebreak="id", + unicodeslot=0x18AB1, + }, + [0x18AB2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-691", + direction="l", + linebreak="id", + unicodeslot=0x18AB2, + }, + [0x18AB3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-692", + direction="l", + linebreak="id", + unicodeslot=0x18AB3, + }, + [0x18AB4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-693", + direction="l", + linebreak="id", + unicodeslot=0x18AB4, + }, + [0x18AB5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-694", + direction="l", + linebreak="id", + unicodeslot=0x18AB5, + }, + [0x18AB6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-695", + direction="l", + linebreak="id", + unicodeslot=0x18AB6, + }, + [0x18AB7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-696", + direction="l", + linebreak="id", + unicodeslot=0x18AB7, + }, + [0x18AB8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-697", + direction="l", + linebreak="id", + unicodeslot=0x18AB8, + }, + [0x18AB9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-698", + direction="l", + linebreak="id", + unicodeslot=0x18AB9, + }, + [0x18ABA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-699", + direction="l", + linebreak="id", + unicodeslot=0x18ABA, + }, + [0x18ABB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-700", + direction="l", + linebreak="id", + unicodeslot=0x18ABB, + }, + [0x18ABC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-701", + direction="l", + linebreak="id", + unicodeslot=0x18ABC, + }, + [0x18ABD]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-702", + direction="l", + linebreak="id", + unicodeslot=0x18ABD, + }, + [0x18ABE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-703", + direction="l", + linebreak="id", + unicodeslot=0x18ABE, + }, + [0x18ABF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-704", + direction="l", + linebreak="id", + unicodeslot=0x18ABF, + }, + [0x18AC0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-705", + direction="l", + linebreak="id", + unicodeslot=0x18AC0, + }, + [0x18AC1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-706", + direction="l", + linebreak="id", + unicodeslot=0x18AC1, + }, + [0x18AC2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-707", + direction="l", + linebreak="id", + unicodeslot=0x18AC2, + }, + [0x18AC3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-708", + direction="l", + linebreak="id", + unicodeslot=0x18AC3, + }, + [0x18AC4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-709", + direction="l", + linebreak="id", + unicodeslot=0x18AC4, + }, + [0x18AC5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-710", + direction="l", + linebreak="id", + unicodeslot=0x18AC5, + }, + [0x18AC6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-711", + direction="l", + linebreak="id", + unicodeslot=0x18AC6, + }, + [0x18AC7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-712", + direction="l", + linebreak="id", + unicodeslot=0x18AC7, + }, + [0x18AC8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-713", + direction="l", + linebreak="id", + unicodeslot=0x18AC8, + }, + [0x18AC9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-714", + direction="l", + linebreak="id", + unicodeslot=0x18AC9, + }, + [0x18ACA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-715", + direction="l", + linebreak="id", + unicodeslot=0x18ACA, + }, + [0x18ACB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-716", + direction="l", + linebreak="id", + unicodeslot=0x18ACB, + }, + [0x18ACC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-717", + direction="l", + linebreak="id", + unicodeslot=0x18ACC, + }, + [0x18ACD]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-718", + direction="l", + linebreak="id", + unicodeslot=0x18ACD, + }, + [0x18ACE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-719", + direction="l", + linebreak="id", + unicodeslot=0x18ACE, + }, + [0x18ACF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-720", + direction="l", + linebreak="id", + unicodeslot=0x18ACF, + }, + [0x18AD0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-721", + direction="l", + linebreak="id", + unicodeslot=0x18AD0, + }, + [0x18AD1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-722", + direction="l", + linebreak="id", + unicodeslot=0x18AD1, + }, + [0x18AD2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-723", + direction="l", + linebreak="id", + unicodeslot=0x18AD2, + }, + [0x18AD3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-724", + direction="l", + linebreak="id", + unicodeslot=0x18AD3, + }, + [0x18AD4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-725", + direction="l", + linebreak="id", + unicodeslot=0x18AD4, + }, + [0x18AD5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-726", + direction="l", + linebreak="id", + unicodeslot=0x18AD5, + }, + [0x18AD6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-727", + direction="l", + linebreak="id", + unicodeslot=0x18AD6, + }, + [0x18AD7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-728", + direction="l", + linebreak="id", + unicodeslot=0x18AD7, + }, + [0x18AD8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-729", + direction="l", + linebreak="id", + unicodeslot=0x18AD8, + }, + [0x18AD9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-730", + direction="l", + linebreak="id", + unicodeslot=0x18AD9, + }, + [0x18ADA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-731", + direction="l", + linebreak="id", + unicodeslot=0x18ADA, + }, + [0x18ADB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-732", + direction="l", + linebreak="id", + unicodeslot=0x18ADB, + }, + [0x18ADC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-733", + direction="l", + linebreak="id", + unicodeslot=0x18ADC, + }, + [0x18ADD]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-734", + direction="l", + linebreak="id", + unicodeslot=0x18ADD, + }, + [0x18ADE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-735", + direction="l", + linebreak="id", + unicodeslot=0x18ADE, + }, + [0x18ADF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-736", + direction="l", + linebreak="id", + unicodeslot=0x18ADF, + }, + [0x18AE0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-737", + direction="l", + linebreak="id", + unicodeslot=0x18AE0, + }, + [0x18AE1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-738", + direction="l", + linebreak="id", + unicodeslot=0x18AE1, + }, + [0x18AE2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-739", + direction="l", + linebreak="id", + unicodeslot=0x18AE2, + }, + [0x18AE3]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-740", + direction="l", + linebreak="id", + unicodeslot=0x18AE3, + }, + [0x18AE4]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-741", + direction="l", + linebreak="id", + unicodeslot=0x18AE4, + }, + [0x18AE5]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-742", + direction="l", + linebreak="id", + unicodeslot=0x18AE5, + }, + [0x18AE6]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-743", + direction="l", + linebreak="id", + unicodeslot=0x18AE6, + }, + [0x18AE7]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-744", + direction="l", + linebreak="id", + unicodeslot=0x18AE7, + }, + [0x18AE8]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-745", + direction="l", + linebreak="id", + unicodeslot=0x18AE8, + }, + [0x18AE9]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-746", + direction="l", + linebreak="id", + unicodeslot=0x18AE9, + }, + [0x18AEA]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-747", + direction="l", + linebreak="id", + unicodeslot=0x18AEA, + }, + [0x18AEB]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-748", + direction="l", + linebreak="id", + unicodeslot=0x18AEB, + }, + [0x18AEC]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-749", + direction="l", + linebreak="id", + unicodeslot=0x18AEC, + }, + [0x18AED]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-750", + direction="l", + linebreak="id", + unicodeslot=0x18AED, + }, + [0x18AEE]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-751", + direction="l", + linebreak="id", + unicodeslot=0x18AEE, + }, + [0x18AEF]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-752", + direction="l", + linebreak="id", + unicodeslot=0x18AEF, + }, + [0x18AF0]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-753", + direction="l", + linebreak="id", + unicodeslot=0x18AF0, + }, + [0x18AF1]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-754", + direction="l", + linebreak="id", + unicodeslot=0x18AF1, + }, + [0x18AF2]={ + category="lo", + cjkwd="w", + description="TANGUT COMPONENT-755", + direction="l", + linebreak="id", + unicodeslot=0x18AF2, + }, [0x1B000]={ category="lo", cjkwd="w", @@ -190000,6 +199327,7 @@ characters.data={ description="MUSICAL SYMBOL WHOLE NOTE", direction="l", linebreak="al", + synonyms={ "semibreve" }, unicodeslot=0x1D15D, }, [0x1D15E]={ @@ -190032,6 +199360,7 @@ characters.data={ direction="l", linebreak="al", specials={ "char", 0x1D15F, 0x1D16F }, + synonyms={ "semiquaver" }, unicodeslot=0x1D161, }, [0x1D162]={ @@ -193711,6 +203040,7 @@ characters.data={ direction="l", linebreak="al", specials={ "font", 0x50 }, + synonyms={ "power set" }, unicodeslot=0x1D4AB, }, [0x1D4AC]={ @@ -194515,6 +203845,7 @@ characters.data={ direction="l", linebreak="al", specials={ "font", 0x4D }, + synonyms={ "new testament majority text" }, unicodeslot=0x1D510, }, [0x1D511]={ @@ -194555,6 +203886,7 @@ characters.data={ direction="l", linebreak="al", specials={ "font", 0x53 }, + synonyms={ "greek old testament", "septuagint" }, unicodeslot=0x1D516, }, [0x1D517]={ @@ -205658,6 +214990,310 @@ characters.data={ linebreak="cm", unicodeslot=0x1DAAF, }, + [0x1E000]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER AZU", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E000, + }, + [0x1E001]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER BUKY", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E001, + }, + [0x1E002]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER VEDE", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E002, + }, + [0x1E003]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER GLAGOLI", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E003, + }, + [0x1E004]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER DOBRO", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E004, + }, + [0x1E005]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER YESTU", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E005, + }, + [0x1E006]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER ZHIVETE", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E006, + }, + [0x1E008]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER ZEMLJA", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E008, + }, + [0x1E009]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER IZHE", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E009, + }, + [0x1E00A]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER INITIAL IZHE", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E00A, + }, + [0x1E00B]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER I", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E00B, + }, + [0x1E00C]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER DJERVI", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E00C, + }, + [0x1E00D]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER KAKO", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E00D, + }, + [0x1E00E]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER LJUDIJE", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E00E, + }, + [0x1E00F]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER MYSLITE", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E00F, + }, + [0x1E010]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER NASHI", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E010, + }, + [0x1E011]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER ONU", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E011, + }, + [0x1E012]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER POKOJI", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E012, + }, + [0x1E013]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER RITSI", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E013, + }, + [0x1E014]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER SLOVO", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E014, + }, + [0x1E015]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER TVRIDO", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E015, + }, + [0x1E016]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER UKU", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E016, + }, + [0x1E017]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER FRITU", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E017, + }, + [0x1E018]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER HERU", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E018, + }, + [0x1E01B]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER SHTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E01B, + }, + [0x1E01C]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER TSI", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E01C, + }, + [0x1E01D]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER CHRIVI", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E01D, + }, + [0x1E01E]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER SHA", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E01E, + }, + [0x1E01F]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER YERU", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E01F, + }, + [0x1E020]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER YERI", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E020, + }, + [0x1E021]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER YATI", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E021, + }, + [0x1E023]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER YU", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E023, + }, + [0x1E024]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER SMALL YUS", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E024, + }, + [0x1E026]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER YO", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E026, + }, + [0x1E027]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER IOTATED SMALL YUS", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E027, + }, + [0x1E028]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER BIG YUS", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E028, + }, + [0x1E029]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER IOTATED BIG YUS", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E029, + }, + [0x1E02A]={ + category="mn", + combining=0xE6, + description="COMBINING GLAGOLITIC LETTER FITA", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E02A, + }, [0x1E800]={ category="lo", description="MENDE KIKAKUI SYLLABLE M001 KI", @@ -207156,6 +216792,690 @@ characters.data={ linebreak="cm", unicodeslot=0x1E8D6, }, + [0x1E900]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER ALIF", + direction="r", + linebreak="al", + unicodeslot=0x1E900, + }, + [0x1E901]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER DAALI", + direction="r", + linebreak="al", + unicodeslot=0x1E901, + }, + [0x1E902]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER LAAM", + direction="r", + linebreak="al", + unicodeslot=0x1E902, + }, + [0x1E903]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER MIIM", + direction="r", + linebreak="al", + unicodeslot=0x1E903, + }, + [0x1E904]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER BA", + direction="r", + linebreak="al", + unicodeslot=0x1E904, + }, + [0x1E905]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER SINNYIIYHE", + direction="r", + linebreak="al", + unicodeslot=0x1E905, + }, + [0x1E906]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER PE", + direction="r", + linebreak="al", + unicodeslot=0x1E906, + }, + [0x1E907]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER BHE", + direction="r", + linebreak="al", + unicodeslot=0x1E907, + }, + [0x1E908]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER RA", + direction="r", + linebreak="al", + unicodeslot=0x1E908, + }, + [0x1E909]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER E", + direction="r", + linebreak="al", + unicodeslot=0x1E909, + }, + [0x1E90A]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER FA", + direction="r", + linebreak="al", + unicodeslot=0x1E90A, + }, + [0x1E90B]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER I", + direction="r", + linebreak="al", + unicodeslot=0x1E90B, + }, + [0x1E90C]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER O", + direction="r", + linebreak="al", + unicodeslot=0x1E90C, + }, + [0x1E90D]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER DHA", + direction="r", + linebreak="al", + unicodeslot=0x1E90D, + }, + [0x1E90E]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER YHE", + direction="r", + linebreak="al", + unicodeslot=0x1E90E, + }, + [0x1E90F]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER WAW", + direction="r", + linebreak="al", + unicodeslot=0x1E90F, + }, + [0x1E910]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER NUN", + direction="r", + linebreak="al", + unicodeslot=0x1E910, + }, + [0x1E911]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER KAF", + direction="r", + linebreak="al", + unicodeslot=0x1E911, + }, + [0x1E912]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER YA", + direction="r", + linebreak="al", + unicodeslot=0x1E912, + }, + [0x1E913]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER U", + direction="r", + linebreak="al", + unicodeslot=0x1E913, + }, + [0x1E914]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER JIIM", + direction="r", + linebreak="al", + unicodeslot=0x1E914, + }, + [0x1E915]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER CHI", + direction="r", + linebreak="al", + unicodeslot=0x1E915, + }, + [0x1E916]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER HA", + direction="r", + linebreak="al", + unicodeslot=0x1E916, + }, + [0x1E917]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER QAAF", + direction="r", + linebreak="al", + unicodeslot=0x1E917, + }, + [0x1E918]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER GA", + direction="r", + linebreak="al", + unicodeslot=0x1E918, + }, + [0x1E919]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER NYA", + direction="r", + linebreak="al", + unicodeslot=0x1E919, + }, + [0x1E91A]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER TU", + direction="r", + linebreak="al", + unicodeslot=0x1E91A, + }, + [0x1E91B]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER NHA", + direction="r", + linebreak="al", + unicodeslot=0x1E91B, + }, + [0x1E91C]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER VA", + direction="r", + linebreak="al", + unicodeslot=0x1E91C, + }, + [0x1E91D]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER KHA", + direction="r", + linebreak="al", + unicodeslot=0x1E91D, + }, + [0x1E91E]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER GBE", + direction="r", + linebreak="al", + unicodeslot=0x1E91E, + }, + [0x1E91F]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER ZAL", + direction="r", + linebreak="al", + unicodeslot=0x1E91F, + }, + [0x1E920]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER KPO", + direction="r", + linebreak="al", + unicodeslot=0x1E920, + }, + [0x1E921]={ + arabic="d", + category="lu", + description="ADLAM CAPITAL LETTER SHA", + direction="r", + linebreak="al", + unicodeslot=0x1E921, + }, + [0x1E922]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER ALIF", + direction="r", + linebreak="al", + unicodeslot=0x1E922, + }, + [0x1E923]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER DAALI", + direction="r", + linebreak="al", + unicodeslot=0x1E923, + }, + [0x1E924]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER LAAM", + direction="r", + linebreak="al", + unicodeslot=0x1E924, + }, + [0x1E925]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER MIIM", + direction="r", + linebreak="al", + unicodeslot=0x1E925, + }, + [0x1E926]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER BA", + direction="r", + linebreak="al", + unicodeslot=0x1E926, + }, + [0x1E927]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER SINNYIIYHE", + direction="r", + linebreak="al", + unicodeslot=0x1E927, + }, + [0x1E928]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER PE", + direction="r", + linebreak="al", + unicodeslot=0x1E928, + }, + [0x1E929]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER BHE", + direction="r", + linebreak="al", + unicodeslot=0x1E929, + }, + [0x1E92A]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER RA", + direction="r", + linebreak="al", + unicodeslot=0x1E92A, + }, + [0x1E92B]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER E", + direction="r", + linebreak="al", + unicodeslot=0x1E92B, + }, + [0x1E92C]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER FA", + direction="r", + linebreak="al", + unicodeslot=0x1E92C, + }, + [0x1E92D]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER I", + direction="r", + linebreak="al", + unicodeslot=0x1E92D, + }, + [0x1E92E]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER O", + direction="r", + linebreak="al", + unicodeslot=0x1E92E, + }, + [0x1E92F]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER DHA", + direction="r", + linebreak="al", + unicodeslot=0x1E92F, + }, + [0x1E930]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER YHE", + direction="r", + linebreak="al", + unicodeslot=0x1E930, + }, + [0x1E931]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER WAW", + direction="r", + linebreak="al", + unicodeslot=0x1E931, + }, + [0x1E932]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER NUN", + direction="r", + linebreak="al", + unicodeslot=0x1E932, + }, + [0x1E933]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER KAF", + direction="r", + linebreak="al", + unicodeslot=0x1E933, + }, + [0x1E934]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER YA", + direction="r", + linebreak="al", + unicodeslot=0x1E934, + }, + [0x1E935]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER U", + direction="r", + linebreak="al", + unicodeslot=0x1E935, + }, + [0x1E936]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER JIIM", + direction="r", + linebreak="al", + unicodeslot=0x1E936, + }, + [0x1E937]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER CHI", + direction="r", + linebreak="al", + unicodeslot=0x1E937, + }, + [0x1E938]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER HA", + direction="r", + linebreak="al", + unicodeslot=0x1E938, + }, + [0x1E939]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER QAAF", + direction="r", + linebreak="al", + unicodeslot=0x1E939, + }, + [0x1E93A]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER GA", + direction="r", + linebreak="al", + unicodeslot=0x1E93A, + }, + [0x1E93B]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER NYA", + direction="r", + linebreak="al", + unicodeslot=0x1E93B, + }, + [0x1E93C]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER TU", + direction="r", + linebreak="al", + unicodeslot=0x1E93C, + }, + [0x1E93D]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER NHA", + direction="r", + linebreak="al", + unicodeslot=0x1E93D, + }, + [0x1E93E]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER VA", + direction="r", + linebreak="al", + unicodeslot=0x1E93E, + }, + [0x1E93F]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER KHA", + direction="r", + linebreak="al", + unicodeslot=0x1E93F, + }, + [0x1E940]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER GBE", + direction="r", + linebreak="al", + unicodeslot=0x1E940, + }, + [0x1E941]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER ZAL", + direction="r", + linebreak="al", + unicodeslot=0x1E941, + }, + [0x1E942]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER KPO", + direction="r", + linebreak="al", + unicodeslot=0x1E942, + }, + [0x1E943]={ + arabic="d", + category="ll", + description="ADLAM SMALL LETTER SHA", + direction="r", + linebreak="al", + unicodeslot=0x1E943, + }, + [0x1E944]={ + category="mn", + combining=0xE6, + description="ADLAM ALIF LENGTHENER", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E944, + }, + [0x1E945]={ + category="mn", + combining=0xE6, + description="ADLAM VOWEL LENGTHENER", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E945, + }, + [0x1E946]={ + category="mn", + combining=0xE6, + description="ADLAM GEMINATION MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E946, + }, + [0x1E947]={ + category="mn", + combining=0xE6, + description="ADLAM HAMZA", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E947, + }, + [0x1E948]={ + category="mn", + combining=0xE6, + description="ADLAM CONSONANT MODIFIER", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E948, + }, + [0x1E949]={ + category="mn", + combining=0xE6, + description="ADLAM GEMINATE CONSONANT MODIFIER", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E949, + }, + [0x1E94A]={ + category="mn", + combining=0x7, + description="ADLAM NUKTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x1E94A, + }, + [0x1E950]={ + category="nd", + description="ADLAM DIGIT ZERO", + direction="r", + linebreak="nu", + unicodeslot=0x1E950, + }, + [0x1E951]={ + category="nd", + description="ADLAM DIGIT ONE", + direction="r", + linebreak="nu", + unicodeslot=0x1E951, + }, + [0x1E952]={ + category="nd", + description="ADLAM DIGIT TWO", + direction="r", + linebreak="nu", + unicodeslot=0x1E952, + }, + [0x1E953]={ + category="nd", + description="ADLAM DIGIT THREE", + direction="r", + linebreak="nu", + unicodeslot=0x1E953, + }, + [0x1E954]={ + category="nd", + description="ADLAM DIGIT FOUR", + direction="r", + linebreak="nu", + unicodeslot=0x1E954, + }, + [0x1E955]={ + category="nd", + description="ADLAM DIGIT FIVE", + direction="r", + linebreak="nu", + unicodeslot=0x1E955, + }, + [0x1E956]={ + category="nd", + description="ADLAM DIGIT SIX", + direction="r", + linebreak="nu", + unicodeslot=0x1E956, + }, + [0x1E957]={ + category="nd", + description="ADLAM DIGIT SEVEN", + direction="r", + linebreak="nu", + unicodeslot=0x1E957, + }, + [0x1E958]={ + category="nd", + description="ADLAM DIGIT EIGHT", + direction="r", + linebreak="nu", + unicodeslot=0x1E958, + }, + [0x1E959]={ + category="nd", + description="ADLAM DIGIT NINE", + direction="r", + linebreak="nu", + unicodeslot=0x1E959, + }, + [0x1E95E]={ + category="po", + description="ADLAM INITIAL EXCLAMATION MARK", + direction="r", + linebreak="op", + unicodeslot=0x1E95E, + }, + [0x1E95F]={ + category="po", + description="ADLAM INITIAL QUESTION MARK", + direction="r", + linebreak="op", + unicodeslot=0x1E95F, + }, [0x1EE00]={ category="lo", comment="check math properties", @@ -208471,14 +218791,12 @@ characters.data={ }, [0x1F004]={ category="so", + cjkwd="w", description="MAHJONG TILE RED DRAGON", direction="on", linebreak="id", unicodeslot=0x1F004, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x1F005]={ category="so", @@ -209763,6 +220081,7 @@ characters.data={ }, [0x1F0CF]={ category="so", + cjkwd="w", description="PLAYING CARD BLACK JOKER", direction="on", linebreak="id", @@ -210920,6 +221239,7 @@ characters.data={ direction="on", linebreak="al", specials={ "super", 0x4D, 0x43 }, + synonyms={ "marque de commerce" }, unicodeslot=0x1F16A, }, [0x1F16B]={ @@ -210928,6 +221248,7 @@ characters.data={ direction="on", linebreak="al", specials={ "super", 0x4D, 0x44 }, + synonyms={ "marque deposee" }, unicodeslot=0x1F16B, }, [0x1F170]={ @@ -210937,10 +221258,7 @@ characters.data={ direction="l", linebreak="ai", unicodeslot=0x1F170, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x1F171]={ category="so", @@ -210949,10 +221267,7 @@ characters.data={ direction="l", linebreak="ai", unicodeslot=0x1F171, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x1F172]={ category="so", @@ -211057,10 +221372,7 @@ characters.data={ direction="l", linebreak="ai", unicodeslot=0x1F17E, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x1F17F]={ category="so", @@ -211069,10 +221381,7 @@ characters.data={ direction="l", linebreak="ai", unicodeslot=0x1F17F, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x1F180]={ category="so", @@ -211188,7 +221497,7 @@ characters.data={ }, [0x1F18E]={ category="so", - cjkwd="a", + cjkwd="w", description="NEGATIVE SQUARED AB", direction="l", linebreak="ai", @@ -211213,7 +221522,7 @@ characters.data={ }, [0x1F191]={ category="so", - cjkwd="a", + cjkwd="w", description="SQUARED CL", direction="l", linebreak="ai", @@ -211221,7 +221530,7 @@ characters.data={ }, [0x1F192]={ category="so", - cjkwd="a", + cjkwd="w", description="SQUARED COOL", direction="l", linebreak="ai", @@ -211229,7 +221538,7 @@ characters.data={ }, [0x1F193]={ category="so", - cjkwd="a", + cjkwd="w", description="SQUARED FREE", direction="l", linebreak="ai", @@ -211237,7 +221546,7 @@ characters.data={ }, [0x1F194]={ category="so", - cjkwd="a", + cjkwd="w", description="SQUARED ID", direction="l", linebreak="ai", @@ -211245,7 +221554,7 @@ characters.data={ }, [0x1F195]={ category="so", - cjkwd="a", + cjkwd="w", description="SQUARED NEW", direction="l", linebreak="ai", @@ -211253,7 +221562,7 @@ characters.data={ }, [0x1F196]={ category="so", - cjkwd="a", + cjkwd="w", description="SQUARED NG", direction="l", linebreak="ai", @@ -211261,7 +221570,7 @@ characters.data={ }, [0x1F197]={ category="so", - cjkwd="a", + cjkwd="w", description="SQUARED OK", direction="l", linebreak="ai", @@ -211269,7 +221578,7 @@ characters.data={ }, [0x1F198]={ category="so", - cjkwd="a", + cjkwd="w", description="SQUARED SOS", direction="l", linebreak="ai", @@ -211277,7 +221586,7 @@ characters.data={ }, [0x1F199]={ category="so", - cjkwd="a", + cjkwd="w", description="SQUARED UP WITH EXCLAMATION MARK", direction="l", linebreak="ai", @@ -211285,12 +221594,156 @@ characters.data={ }, [0x1F19A]={ category="so", - cjkwd="a", + cjkwd="w", description="SQUARED VS", direction="l", linebreak="ai", unicodeslot=0x1F19A, }, + [0x1F19B]={ + category="so", + cjkwd="a", + description="SQUARED THREE D", + direction="l", + linebreak="ai", + unicodeslot=0x1F19B, + }, + [0x1F19C]={ + category="so", + cjkwd="a", + description="SQUARED SECOND SCREEN", + direction="l", + linebreak="ai", + unicodeslot=0x1F19C, + }, + [0x1F19D]={ + category="so", + cjkwd="a", + description="SQUARED TWO K", + direction="l", + linebreak="ai", + unicodeslot=0x1F19D, + }, + [0x1F19E]={ + category="so", + cjkwd="a", + description="SQUARED FOUR K", + direction="l", + linebreak="ai", + unicodeslot=0x1F19E, + }, + [0x1F19F]={ + category="so", + cjkwd="a", + description="SQUARED EIGHT K", + direction="l", + linebreak="ai", + unicodeslot=0x1F19F, + }, + [0x1F1A0]={ + category="so", + cjkwd="a", + description="SQUARED FIVE POINT ONE", + direction="l", + linebreak="ai", + unicodeslot=0x1F1A0, + }, + [0x1F1A1]={ + category="so", + cjkwd="a", + description="SQUARED SEVEN POINT ONE", + direction="l", + linebreak="ai", + unicodeslot=0x1F1A1, + }, + [0x1F1A2]={ + category="so", + cjkwd="a", + description="SQUARED TWENTY-TWO POINT TWO", + direction="l", + linebreak="ai", + unicodeslot=0x1F1A2, + }, + [0x1F1A3]={ + category="so", + cjkwd="a", + description="SQUARED SIXTY P", + direction="l", + linebreak="ai", + unicodeslot=0x1F1A3, + }, + [0x1F1A4]={ + category="so", + cjkwd="a", + description="SQUARED ONE HUNDRED TWENTY P", + direction="l", + linebreak="ai", + unicodeslot=0x1F1A4, + }, + [0x1F1A5]={ + category="so", + cjkwd="a", + description="SQUARED LATIN SMALL LETTER D", + direction="l", + linebreak="ai", + unicodeslot=0x1F1A5, + }, + [0x1F1A6]={ + category="so", + cjkwd="a", + description="SQUARED HC", + direction="l", + linebreak="ai", + unicodeslot=0x1F1A6, + }, + [0x1F1A7]={ + category="so", + cjkwd="a", + description="SQUARED HDR", + direction="l", + linebreak="ai", + unicodeslot=0x1F1A7, + }, + [0x1F1A8]={ + category="so", + cjkwd="a", + description="SQUARED HI-RES", + direction="l", + linebreak="ai", + unicodeslot=0x1F1A8, + }, + [0x1F1A9]={ + category="so", + cjkwd="a", + description="SQUARED LOSSLESS", + direction="l", + linebreak="ai", + unicodeslot=0x1F1A9, + }, + [0x1F1AA]={ + category="so", + cjkwd="a", + description="SQUARED SHV", + direction="l", + linebreak="ai", + unicodeslot=0x1F1AA, + }, + [0x1F1AB]={ + category="so", + cjkwd="a", + description="SQUARED UHD", + direction="l", + linebreak="ai", + unicodeslot=0x1F1AB, + }, + [0x1F1AC]={ + category="so", + cjkwd="a", + description="SQUARED VOD", + direction="l", + linebreak="ai", + unicodeslot=0x1F1AC, + }, [0x1F1E6]={ category="so", description="REGIONAL INDICATOR SYMBOL LETTER A", @@ -211499,10 +221952,7 @@ characters.data={ linebreak="id", specials={ "square", 0x30B5 }, unicodeslot=0x1F202, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x1F210]={ category="so", @@ -211602,10 +222052,7 @@ characters.data={ linebreak="id", specials={ "square", 0x7121 }, unicodeslot=0x1F21A, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x1F21B]={ category="so", @@ -211795,10 +222242,7 @@ characters.data={ linebreak="id", specials={ "square", 0x6307 }, unicodeslot=0x1F22F, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x1F230]={ category="so", @@ -211871,10 +222315,7 @@ characters.data={ linebreak="id", specials={ "square", 0x6708 }, unicodeslot=0x1F237, - variants={ - [0xFE0E]="text style", - [0xFE0F]="emoji style", - }, + variants=variants_emoji, }, [0x1F238]={ category="so", @@ -211903,6 +222344,15 @@ characters.data={ specials={ "square", 0x55B6 }, unicodeslot=0x1F23A, }, + [0x1F23B]={ + category="so", + cjkwd="w", + description="SQUARED CJK UNIFIED IDEOGRAPH-914D", + direction="l", + linebreak="id", + specials={ "square", 0x914D }, + unicodeslot=0x1F23B, + }, [0x1F240]={ category="so", cjkwd="w", @@ -212004,6 +222454,7 @@ characters.data={ }, [0x1F300]={ category="so", + cjkwd="w", description="CYCLONE", direction="on", linebreak="id", @@ -212011,6 +222462,7 @@ characters.data={ }, [0x1F301]={ category="so", + cjkwd="w", description="FOGGY", direction="on", linebreak="id", @@ -212018,6 +222470,7 @@ characters.data={ }, [0x1F302]={ category="so", + cjkwd="w", description="CLOSED UMBRELLA", direction="on", linebreak="id", @@ -212025,6 +222478,7 @@ characters.data={ }, [0x1F303]={ category="so", + cjkwd="w", description="NIGHT WITH STARS", direction="on", linebreak="id", @@ -212032,6 +222486,7 @@ characters.data={ }, [0x1F304]={ category="so", + cjkwd="w", description="SUNRISE OVER MOUNTAINS", direction="on", linebreak="id", @@ -212039,6 +222494,7 @@ characters.data={ }, [0x1F305]={ category="so", + cjkwd="w", description="SUNRISE", direction="on", linebreak="id", @@ -212046,6 +222502,7 @@ characters.data={ }, [0x1F306]={ category="so", + cjkwd="w", description="CITYSCAPE AT DUSK", direction="on", linebreak="id", @@ -212053,6 +222510,7 @@ characters.data={ }, [0x1F307]={ category="so", + cjkwd="w", description="SUNSET OVER BUILDINGS", direction="on", linebreak="id", @@ -212060,6 +222518,7 @@ characters.data={ }, [0x1F308]={ category="so", + cjkwd="w", description="RAINBOW", direction="on", linebreak="id", @@ -212067,6 +222526,7 @@ characters.data={ }, [0x1F309]={ category="so", + cjkwd="w", description="BRIDGE AT NIGHT", direction="on", linebreak="id", @@ -212074,6 +222534,7 @@ characters.data={ }, [0x1F30A]={ category="so", + cjkwd="w", description="WATER WAVE", direction="on", linebreak="id", @@ -212081,6 +222542,7 @@ characters.data={ }, [0x1F30B]={ category="so", + cjkwd="w", description="VOLCANO", direction="on", linebreak="id", @@ -212088,6 +222550,7 @@ characters.data={ }, [0x1F30C]={ category="so", + cjkwd="w", description="MILKY WAY", direction="on", linebreak="id", @@ -212095,6 +222558,7 @@ characters.data={ }, [0x1F30D]={ category="so", + cjkwd="w", description="EARTH GLOBE EUROPE-AFRICA", direction="on", linebreak="id", @@ -212102,6 +222566,7 @@ characters.data={ }, [0x1F30E]={ category="so", + cjkwd="w", description="EARTH GLOBE AMERICAS", direction="on", linebreak="id", @@ -212109,6 +222574,7 @@ characters.data={ }, [0x1F30F]={ category="so", + cjkwd="w", description="EARTH GLOBE ASIA-AUSTRALIA", direction="on", linebreak="id", @@ -212116,6 +222582,7 @@ characters.data={ }, [0x1F310]={ category="so", + cjkwd="w", description="GLOBE WITH MERIDIANS", direction="on", linebreak="id", @@ -212123,6 +222590,7 @@ characters.data={ }, [0x1F311]={ category="so", + cjkwd="w", description="NEW MOON SYMBOL", direction="on", linebreak="id", @@ -212130,6 +222598,7 @@ characters.data={ }, [0x1F312]={ category="so", + cjkwd="w", description="WAXING CRESCENT MOON SYMBOL", direction="on", linebreak="id", @@ -212137,6 +222606,7 @@ characters.data={ }, [0x1F313]={ category="so", + cjkwd="w", description="FIRST QUARTER MOON SYMBOL", direction="on", linebreak="id", @@ -212144,6 +222614,7 @@ characters.data={ }, [0x1F314]={ category="so", + cjkwd="w", description="WAXING GIBBOUS MOON SYMBOL", direction="on", linebreak="id", @@ -212151,6 +222622,7 @@ characters.data={ }, [0x1F315]={ category="so", + cjkwd="w", description="FULL MOON SYMBOL", direction="on", linebreak="id", @@ -212158,6 +222630,7 @@ characters.data={ }, [0x1F316]={ category="so", + cjkwd="w", description="WANING GIBBOUS MOON SYMBOL", direction="on", linebreak="id", @@ -212165,6 +222638,7 @@ characters.data={ }, [0x1F317]={ category="so", + cjkwd="w", description="LAST QUARTER MOON SYMBOL", direction="on", linebreak="id", @@ -212172,6 +222646,7 @@ characters.data={ }, [0x1F318]={ category="so", + cjkwd="w", description="WANING CRESCENT MOON SYMBOL", direction="on", linebreak="id", @@ -212179,6 +222654,7 @@ characters.data={ }, [0x1F319]={ category="so", + cjkwd="w", description="CRESCENT MOON", direction="on", linebreak="id", @@ -212186,6 +222662,7 @@ characters.data={ }, [0x1F31A]={ category="so", + cjkwd="w", description="NEW MOON WITH FACE", direction="on", linebreak="id", @@ -212193,6 +222670,7 @@ characters.data={ }, [0x1F31B]={ category="so", + cjkwd="w", description="FIRST QUARTER MOON WITH FACE", direction="on", linebreak="id", @@ -212200,6 +222678,7 @@ characters.data={ }, [0x1F31C]={ category="so", + cjkwd="w", description="LAST QUARTER MOON WITH FACE", direction="on", linebreak="id", @@ -212207,6 +222686,7 @@ characters.data={ }, [0x1F31D]={ category="so", + cjkwd="w", description="FULL MOON WITH FACE", direction="on", linebreak="id", @@ -212214,6 +222694,7 @@ characters.data={ }, [0x1F31E]={ category="so", + cjkwd="w", description="SUN WITH FACE", direction="on", linebreak="id", @@ -212221,6 +222702,7 @@ characters.data={ }, [0x1F31F]={ category="so", + cjkwd="w", description="GLOWING STAR", direction="on", linebreak="id", @@ -212228,6 +222710,7 @@ characters.data={ }, [0x1F320]={ category="so", + cjkwd="w", description="SHOOTING STAR", direction="on", linebreak="id", @@ -212239,6 +222722,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F321, + variants=variants_emoji, }, [0x1F322]={ category="so", @@ -212260,6 +222744,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F324, + variants=variants_emoji, }, [0x1F325]={ category="so", @@ -212267,6 +222752,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F325, + variants=variants_emoji, }, [0x1F326]={ category="so", @@ -212274,6 +222760,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F326, + variants=variants_emoji, }, [0x1F327]={ category="so", @@ -212281,6 +222768,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F327, + variants=variants_emoji, }, [0x1F328]={ category="so", @@ -212288,6 +222776,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F328, + variants=variants_emoji, }, [0x1F329]={ category="so", @@ -212295,6 +222784,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F329, + variants=variants_emoji, }, [0x1F32A]={ category="so", @@ -212302,6 +222792,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F32A, + variants=variants_emoji, }, [0x1F32B]={ category="so", @@ -212309,6 +222800,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F32B, + variants=variants_emoji, }, [0x1F32C]={ category="so", @@ -212316,9 +222808,11 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F32C, + variants=variants_emoji, }, [0x1F32D]={ category="so", + cjkwd="w", description="HOT DOG", direction="on", linebreak="id", @@ -212326,6 +222820,7 @@ characters.data={ }, [0x1F32E]={ category="so", + cjkwd="w", description="TACO", direction="on", linebreak="id", @@ -212333,6 +222828,7 @@ characters.data={ }, [0x1F32F]={ category="so", + cjkwd="w", description="BURRITO", direction="on", linebreak="id", @@ -212340,6 +222836,7 @@ characters.data={ }, [0x1F330]={ category="so", + cjkwd="w", description="CHESTNUT", direction="on", linebreak="id", @@ -212347,6 +222844,7 @@ characters.data={ }, [0x1F331]={ category="so", + cjkwd="w", description="SEEDLING", direction="on", linebreak="id", @@ -212354,6 +222852,7 @@ characters.data={ }, [0x1F332]={ category="so", + cjkwd="w", description="EVERGREEN TREE", direction="on", linebreak="id", @@ -212361,6 +222860,7 @@ characters.data={ }, [0x1F333]={ category="so", + cjkwd="w", description="DECIDUOUS TREE", direction="on", linebreak="id", @@ -212368,6 +222868,7 @@ characters.data={ }, [0x1F334]={ category="so", + cjkwd="w", description="PALM TREE", direction="on", linebreak="id", @@ -212375,6 +222876,7 @@ characters.data={ }, [0x1F335]={ category="so", + cjkwd="w", description="CACTUS", direction="on", linebreak="id", @@ -212385,10 +222887,13 @@ characters.data={ description="HOT PEPPER", direction="on", linebreak="id", + synonyms={ "spicy" }, unicodeslot=0x1F336, + variants=variants_emoji, }, [0x1F337]={ category="so", + cjkwd="w", description="TULIP", direction="on", linebreak="id", @@ -212396,6 +222901,7 @@ characters.data={ }, [0x1F338]={ category="so", + cjkwd="w", description="CHERRY BLOSSOM", direction="on", linebreak="id", @@ -212403,6 +222909,7 @@ characters.data={ }, [0x1F339]={ category="so", + cjkwd="w", description="ROSE", direction="on", linebreak="id", @@ -212410,6 +222917,7 @@ characters.data={ }, [0x1F33A]={ category="so", + cjkwd="w", description="HIBISCUS", direction="on", linebreak="id", @@ -212417,6 +222925,7 @@ characters.data={ }, [0x1F33B]={ category="so", + cjkwd="w", description="SUNFLOWER", direction="on", linebreak="id", @@ -212424,6 +222933,7 @@ characters.data={ }, [0x1F33C]={ category="so", + cjkwd="w", description="BLOSSOM", direction="on", linebreak="id", @@ -212431,6 +222941,7 @@ characters.data={ }, [0x1F33D]={ category="so", + cjkwd="w", description="EAR OF MAIZE", direction="on", linebreak="id", @@ -212438,6 +222949,7 @@ characters.data={ }, [0x1F33E]={ category="so", + cjkwd="w", description="EAR OF RICE", direction="on", linebreak="id", @@ -212445,6 +222957,7 @@ characters.data={ }, [0x1F33F]={ category="so", + cjkwd="w", description="HERB", direction="on", linebreak="id", @@ -212452,6 +222965,7 @@ characters.data={ }, [0x1F340]={ category="so", + cjkwd="w", description="FOUR LEAF CLOVER", direction="on", linebreak="id", @@ -212459,6 +222973,7 @@ characters.data={ }, [0x1F341]={ category="so", + cjkwd="w", description="MAPLE LEAF", direction="on", linebreak="id", @@ -212466,6 +222981,7 @@ characters.data={ }, [0x1F342]={ category="so", + cjkwd="w", description="FALLEN LEAF", direction="on", linebreak="id", @@ -212473,6 +222989,7 @@ characters.data={ }, [0x1F343]={ category="so", + cjkwd="w", description="LEAF FLUTTERING IN WIND", direction="on", linebreak="id", @@ -212480,6 +222997,7 @@ characters.data={ }, [0x1F344]={ category="so", + cjkwd="w", description="MUSHROOM", direction="on", linebreak="id", @@ -212487,6 +223005,7 @@ characters.data={ }, [0x1F345]={ category="so", + cjkwd="w", description="TOMATO", direction="on", linebreak="id", @@ -212494,6 +223013,7 @@ characters.data={ }, [0x1F346]={ category="so", + cjkwd="w", description="AUBERGINE", direction="on", linebreak="id", @@ -212501,6 +223021,7 @@ characters.data={ }, [0x1F347]={ category="so", + cjkwd="w", description="GRAPES", direction="on", linebreak="id", @@ -212508,6 +223029,7 @@ characters.data={ }, [0x1F348]={ category="so", + cjkwd="w", description="MELON", direction="on", linebreak="id", @@ -212515,6 +223037,7 @@ characters.data={ }, [0x1F349]={ category="so", + cjkwd="w", description="WATERMELON", direction="on", linebreak="id", @@ -212522,6 +223045,7 @@ characters.data={ }, [0x1F34A]={ category="so", + cjkwd="w", description="TANGERINE", direction="on", linebreak="id", @@ -212529,6 +223053,7 @@ characters.data={ }, [0x1F34B]={ category="so", + cjkwd="w", description="LEMON", direction="on", linebreak="id", @@ -212536,6 +223061,7 @@ characters.data={ }, [0x1F34C]={ category="so", + cjkwd="w", description="BANANA", direction="on", linebreak="id", @@ -212543,6 +223069,7 @@ characters.data={ }, [0x1F34D]={ category="so", + cjkwd="w", description="PINEAPPLE", direction="on", linebreak="id", @@ -212550,6 +223077,7 @@ characters.data={ }, [0x1F34E]={ category="so", + cjkwd="w", description="RED APPLE", direction="on", linebreak="id", @@ -212557,6 +223085,7 @@ characters.data={ }, [0x1F34F]={ category="so", + cjkwd="w", description="GREEN APPLE", direction="on", linebreak="id", @@ -212564,6 +223093,7 @@ characters.data={ }, [0x1F350]={ category="so", + cjkwd="w", description="PEAR", direction="on", linebreak="id", @@ -212571,6 +223101,7 @@ characters.data={ }, [0x1F351]={ category="so", + cjkwd="w", description="PEACH", direction="on", linebreak="id", @@ -212578,6 +223109,7 @@ characters.data={ }, [0x1F352]={ category="so", + cjkwd="w", description="CHERRIES", direction="on", linebreak="id", @@ -212585,6 +223117,7 @@ characters.data={ }, [0x1F353]={ category="so", + cjkwd="w", description="STRAWBERRY", direction="on", linebreak="id", @@ -212592,6 +223125,7 @@ characters.data={ }, [0x1F354]={ category="so", + cjkwd="w", description="HAMBURGER", direction="on", linebreak="id", @@ -212599,6 +223133,7 @@ characters.data={ }, [0x1F355]={ category="so", + cjkwd="w", description="SLICE OF PIZZA", direction="on", linebreak="id", @@ -212606,6 +223141,7 @@ characters.data={ }, [0x1F356]={ category="so", + cjkwd="w", description="MEAT ON BONE", direction="on", linebreak="id", @@ -212613,6 +223149,7 @@ characters.data={ }, [0x1F357]={ category="so", + cjkwd="w", description="POULTRY LEG", direction="on", linebreak="id", @@ -212620,6 +223157,7 @@ characters.data={ }, [0x1F358]={ category="so", + cjkwd="w", description="RICE CRACKER", direction="on", linebreak="id", @@ -212627,6 +223165,7 @@ characters.data={ }, [0x1F359]={ category="so", + cjkwd="w", description="RICE BALL", direction="on", linebreak="id", @@ -212634,6 +223173,7 @@ characters.data={ }, [0x1F35A]={ category="so", + cjkwd="w", description="COOKED RICE", direction="on", linebreak="id", @@ -212641,6 +223181,7 @@ characters.data={ }, [0x1F35B]={ category="so", + cjkwd="w", description="CURRY AND RICE", direction="on", linebreak="id", @@ -212648,6 +223189,7 @@ characters.data={ }, [0x1F35C]={ category="so", + cjkwd="w", description="STEAMING BOWL", direction="on", linebreak="id", @@ -212655,6 +223197,7 @@ characters.data={ }, [0x1F35D]={ category="so", + cjkwd="w", description="SPAGHETTI", direction="on", linebreak="id", @@ -212662,6 +223205,7 @@ characters.data={ }, [0x1F35E]={ category="so", + cjkwd="w", description="BREAD", direction="on", linebreak="id", @@ -212669,6 +223213,7 @@ characters.data={ }, [0x1F35F]={ category="so", + cjkwd="w", description="FRENCH FRIES", direction="on", linebreak="id", @@ -212676,6 +223221,7 @@ characters.data={ }, [0x1F360]={ category="so", + cjkwd="w", description="ROASTED SWEET POTATO", direction="on", linebreak="id", @@ -212683,6 +223229,7 @@ characters.data={ }, [0x1F361]={ category="so", + cjkwd="w", description="DANGO", direction="on", linebreak="id", @@ -212690,6 +223237,7 @@ characters.data={ }, [0x1F362]={ category="so", + cjkwd="w", description="ODEN", direction="on", linebreak="id", @@ -212697,6 +223245,7 @@ characters.data={ }, [0x1F363]={ category="so", + cjkwd="w", description="SUSHI", direction="on", linebreak="id", @@ -212704,6 +223253,7 @@ characters.data={ }, [0x1F364]={ category="so", + cjkwd="w", description="FRIED SHRIMP", direction="on", linebreak="id", @@ -212711,6 +223261,7 @@ characters.data={ }, [0x1F365]={ category="so", + cjkwd="w", description="FISH CAKE WITH SWIRL DESIGN", direction="on", linebreak="id", @@ -212718,6 +223269,7 @@ characters.data={ }, [0x1F366]={ category="so", + cjkwd="w", description="SOFT ICE CREAM", direction="on", linebreak="id", @@ -212725,6 +223277,7 @@ characters.data={ }, [0x1F367]={ category="so", + cjkwd="w", description="SHAVED ICE", direction="on", linebreak="id", @@ -212732,6 +223285,7 @@ characters.data={ }, [0x1F368]={ category="so", + cjkwd="w", description="ICE CREAM", direction="on", linebreak="id", @@ -212739,6 +223293,7 @@ characters.data={ }, [0x1F369]={ category="so", + cjkwd="w", description="DOUGHNUT", direction="on", linebreak="id", @@ -212746,6 +223301,7 @@ characters.data={ }, [0x1F36A]={ category="so", + cjkwd="w", description="COOKIE", direction="on", linebreak="id", @@ -212753,6 +223309,7 @@ characters.data={ }, [0x1F36B]={ category="so", + cjkwd="w", description="CHOCOLATE BAR", direction="on", linebreak="id", @@ -212760,6 +223317,7 @@ characters.data={ }, [0x1F36C]={ category="so", + cjkwd="w", description="CANDY", direction="on", linebreak="id", @@ -212767,6 +223325,7 @@ characters.data={ }, [0x1F36D]={ category="so", + cjkwd="w", description="LOLLIPOP", direction="on", linebreak="id", @@ -212774,6 +223333,7 @@ characters.data={ }, [0x1F36E]={ category="so", + cjkwd="w", description="CUSTARD", direction="on", linebreak="id", @@ -212781,6 +223341,7 @@ characters.data={ }, [0x1F36F]={ category="so", + cjkwd="w", description="HONEY POT", direction="on", linebreak="id", @@ -212788,6 +223349,7 @@ characters.data={ }, [0x1F370]={ category="so", + cjkwd="w", description="SHORTCAKE", direction="on", linebreak="id", @@ -212795,6 +223357,7 @@ characters.data={ }, [0x1F371]={ category="so", + cjkwd="w", description="BENTO BOX", direction="on", linebreak="id", @@ -212802,6 +223365,7 @@ characters.data={ }, [0x1F372]={ category="so", + cjkwd="w", description="POT OF FOOD", direction="on", linebreak="id", @@ -212809,6 +223373,7 @@ characters.data={ }, [0x1F373]={ category="so", + cjkwd="w", description="COOKING", direction="on", linebreak="id", @@ -212816,13 +223381,16 @@ characters.data={ }, [0x1F374]={ category="so", + cjkwd="w", description="FORK AND KNIFE", direction="on", linebreak="id", + synonyms={ "meal (glyph may vary) restaurant" }, unicodeslot=0x1F374, }, [0x1F375]={ category="so", + cjkwd="w", description="TEACUP WITHOUT HANDLE", direction="on", linebreak="id", @@ -212830,6 +223398,7 @@ characters.data={ }, [0x1F376]={ category="so", + cjkwd="w", description="SAKE BOTTLE AND CUP", direction="on", linebreak="id", @@ -212837,6 +223406,7 @@ characters.data={ }, [0x1F377]={ category="so", + cjkwd="w", description="WINE GLASS", direction="on", linebreak="id", @@ -212844,6 +223414,7 @@ characters.data={ }, [0x1F378]={ category="so", + cjkwd="w", description="COCKTAIL GLASS", direction="on", linebreak="id", @@ -212851,6 +223422,7 @@ characters.data={ }, [0x1F379]={ category="so", + cjkwd="w", description="TROPICAL DRINK", direction="on", linebreak="id", @@ -212858,6 +223430,7 @@ characters.data={ }, [0x1F37A]={ category="so", + cjkwd="w", description="BEER MUG", direction="on", linebreak="id", @@ -212865,6 +223438,7 @@ characters.data={ }, [0x1F37B]={ category="so", + cjkwd="w", description="CLINKING BEER MUGS", direction="on", linebreak="id", @@ -212872,6 +223446,7 @@ characters.data={ }, [0x1F37C]={ category="so", + cjkwd="w", description="BABY BOTTLE", direction="on", linebreak="id", @@ -212882,10 +223457,13 @@ characters.data={ description="FORK AND KNIFE WITH PLATE", direction="on", linebreak="id", + synonyms={ "dining available symbol", "food available symbol" }, unicodeslot=0x1F37D, + variants=variants_emoji, }, [0x1F37E]={ category="so", + cjkwd="w", description="BOTTLE WITH POPPING CORK", direction="on", linebreak="id", @@ -212893,6 +223471,7 @@ characters.data={ }, [0x1F37F]={ category="so", + cjkwd="w", description="POPCORN", direction="on", linebreak="id", @@ -212900,6 +223479,7 @@ characters.data={ }, [0x1F380]={ category="so", + cjkwd="w", description="RIBBON", direction="on", linebreak="id", @@ -212907,6 +223487,7 @@ characters.data={ }, [0x1F381]={ category="so", + cjkwd="w", description="WRAPPED PRESENT", direction="on", linebreak="id", @@ -212914,6 +223495,7 @@ characters.data={ }, [0x1F382]={ category="so", + cjkwd="w", description="BIRTHDAY CAKE", direction="on", linebreak="id", @@ -212921,6 +223503,7 @@ characters.data={ }, [0x1F383]={ category="so", + cjkwd="w", description="JACK-O-LANTERN", direction="on", linebreak="id", @@ -212928,6 +223511,7 @@ characters.data={ }, [0x1F384]={ category="so", + cjkwd="w", description="CHRISTMAS TREE", direction="on", linebreak="id", @@ -212935,13 +223519,16 @@ characters.data={ }, [0x1F385]={ category="so", + cjkwd="w", description="FATHER CHRISTMAS", direction="on", - linebreak="id", + linebreak="eb", + synonyms={ "santa claus" }, unicodeslot=0x1F385, }, [0x1F386]={ category="so", + cjkwd="w", description="FIREWORKS", direction="on", linebreak="id", @@ -212949,6 +223536,7 @@ characters.data={ }, [0x1F387]={ category="so", + cjkwd="w", description="FIREWORK SPARKLER", direction="on", linebreak="id", @@ -212956,6 +223544,7 @@ characters.data={ }, [0x1F388]={ category="so", + cjkwd="w", description="BALLOON", direction="on", linebreak="id", @@ -212963,6 +223552,7 @@ characters.data={ }, [0x1F389]={ category="so", + cjkwd="w", description="PARTY POPPER", direction="on", linebreak="id", @@ -212970,6 +223560,7 @@ characters.data={ }, [0x1F38A]={ category="so", + cjkwd="w", description="CONFETTI BALL", direction="on", linebreak="id", @@ -212977,6 +223568,7 @@ characters.data={ }, [0x1F38B]={ category="so", + cjkwd="w", description="TANABATA TREE", direction="on", linebreak="id", @@ -212984,6 +223576,7 @@ characters.data={ }, [0x1F38C]={ category="so", + cjkwd="w", description="CROSSED FLAGS", direction="on", linebreak="id", @@ -212991,6 +223584,7 @@ characters.data={ }, [0x1F38D]={ category="so", + cjkwd="w", description="PINE DECORATION", direction="on", linebreak="id", @@ -212998,6 +223592,7 @@ characters.data={ }, [0x1F38E]={ category="so", + cjkwd="w", description="JAPANESE DOLLS", direction="on", linebreak="id", @@ -213005,6 +223600,7 @@ characters.data={ }, [0x1F38F]={ category="so", + cjkwd="w", description="CARP STREAMER", direction="on", linebreak="id", @@ -213012,6 +223608,7 @@ characters.data={ }, [0x1F390]={ category="so", + cjkwd="w", description="WIND CHIME", direction="on", linebreak="id", @@ -213019,6 +223616,7 @@ characters.data={ }, [0x1F391]={ category="so", + cjkwd="w", description="MOON VIEWING CEREMONY", direction="on", linebreak="id", @@ -213026,6 +223624,7 @@ characters.data={ }, [0x1F392]={ category="so", + cjkwd="w", description="SCHOOL SATCHEL", direction="on", linebreak="id", @@ -213033,9 +223632,11 @@ characters.data={ }, [0x1F393]={ category="so", + cjkwd="w", description="GRADUATION CAP", direction="on", linebreak="id", + synonyms={ "mortarboard" }, unicodeslot=0x1F393, }, [0x1F394]={ @@ -213058,6 +223659,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F396, + variants=variants_emoji, }, [0x1F397]={ category="so", @@ -213065,6 +223667,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F397, + variants=variants_emoji, }, [0x1F398]={ category="so", @@ -213079,6 +223682,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F399, + variants=variants_emoji, }, [0x1F39A]={ category="so", @@ -213086,6 +223690,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F39A, + variants=variants_emoji, }, [0x1F39B]={ category="so", @@ -213093,6 +223698,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F39B, + variants=variants_emoji, }, [0x1F39C]={ category="so", @@ -213114,6 +223720,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F39E, + variants=variants_emoji, }, [0x1F39F]={ category="so", @@ -213121,9 +223728,11 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F39F, + variants=variants_emoji, }, [0x1F3A0]={ category="so", + cjkwd="w", description="CAROUSEL HORSE", direction="on", linebreak="id", @@ -213131,6 +223740,7 @@ characters.data={ }, [0x1F3A1]={ category="so", + cjkwd="w", description="FERRIS WHEEL", direction="on", linebreak="id", @@ -213138,6 +223748,7 @@ characters.data={ }, [0x1F3A2]={ category="so", + cjkwd="w", description="ROLLER COASTER", direction="on", linebreak="id", @@ -213145,6 +223756,7 @@ characters.data={ }, [0x1F3A3]={ category="so", + cjkwd="w", description="FISHING POLE AND FISH", direction="on", linebreak="id", @@ -213152,6 +223764,7 @@ characters.data={ }, [0x1F3A4]={ category="so", + cjkwd="w", description="MICROPHONE", direction="on", linebreak="id", @@ -213159,6 +223772,7 @@ characters.data={ }, [0x1F3A5]={ category="so", + cjkwd="w", description="MOVIE CAMERA", direction="on", linebreak="id", @@ -213166,6 +223780,7 @@ characters.data={ }, [0x1F3A6]={ category="so", + cjkwd="w", description="CINEMA", direction="on", linebreak="id", @@ -213173,6 +223788,7 @@ characters.data={ }, [0x1F3A7]={ category="so", + cjkwd="w", description="HEADPHONE", direction="on", linebreak="id", @@ -213180,6 +223796,7 @@ characters.data={ }, [0x1F3A8]={ category="so", + cjkwd="w", description="ARTIST PALETTE", direction="on", linebreak="id", @@ -213187,6 +223804,7 @@ characters.data={ }, [0x1F3A9]={ category="so", + cjkwd="w", description="TOP HAT", direction="on", linebreak="id", @@ -213194,6 +223812,7 @@ characters.data={ }, [0x1F3AA]={ category="so", + cjkwd="w", description="CIRCUS TENT", direction="on", linebreak="id", @@ -213201,6 +223820,7 @@ characters.data={ }, [0x1F3AB]={ category="so", + cjkwd="w", description="TICKET", direction="on", linebreak="id", @@ -213208,6 +223828,7 @@ characters.data={ }, [0x1F3AC]={ category="so", + cjkwd="w", description="CLAPPER BOARD", direction="on", linebreak="id", @@ -213215,13 +223836,16 @@ characters.data={ }, [0x1F3AD]={ category="so", + cjkwd="w", description="PERFORMING ARTS", direction="on", linebreak="id", + synonyms={ "masks of comedy and tragedy", "theater masks" }, unicodeslot=0x1F3AD, }, [0x1F3AE]={ category="so", + cjkwd="w", description="VIDEO GAME", direction="on", linebreak="id", @@ -213229,6 +223853,7 @@ characters.data={ }, [0x1F3AF]={ category="so", + cjkwd="w", description="DIRECT HIT", direction="on", linebreak="id", @@ -213236,6 +223861,7 @@ characters.data={ }, [0x1F3B0]={ category="so", + cjkwd="w", description="SLOT MACHINE", direction="on", linebreak="id", @@ -213243,6 +223869,7 @@ characters.data={ }, [0x1F3B1]={ category="so", + cjkwd="w", description="BILLIARDS", direction="on", linebreak="id", @@ -213250,6 +223877,7 @@ characters.data={ }, [0x1F3B2]={ category="so", + cjkwd="w", description="GAME DIE", direction="on", linebreak="id", @@ -213257,6 +223885,7 @@ characters.data={ }, [0x1F3B3]={ category="so", + cjkwd="w", description="BOWLING", direction="on", linebreak="id", @@ -213264,6 +223893,7 @@ characters.data={ }, [0x1F3B4]={ category="so", + cjkwd="w", description="FLOWER PLAYING CARDS", direction="on", linebreak="id", @@ -213271,6 +223901,7 @@ characters.data={ }, [0x1F3B5]={ category="so", + cjkwd="w", description="MUSICAL NOTE", direction="on", linebreak="al", @@ -213278,6 +223909,7 @@ characters.data={ }, [0x1F3B6]={ category="so", + cjkwd="w", description="MULTIPLE MUSICAL NOTES", direction="on", linebreak="al", @@ -213285,6 +223917,7 @@ characters.data={ }, [0x1F3B7]={ category="so", + cjkwd="w", description="SAXOPHONE", direction="on", linebreak="id", @@ -213292,6 +223925,7 @@ characters.data={ }, [0x1F3B8]={ category="so", + cjkwd="w", description="GUITAR", direction="on", linebreak="id", @@ -213299,6 +223933,7 @@ characters.data={ }, [0x1F3B9]={ category="so", + cjkwd="w", description="MUSICAL KEYBOARD", direction="on", linebreak="id", @@ -213306,6 +223941,7 @@ characters.data={ }, [0x1F3BA]={ category="so", + cjkwd="w", description="TRUMPET", direction="on", linebreak="id", @@ -213313,6 +223949,7 @@ characters.data={ }, [0x1F3BB]={ category="so", + cjkwd="w", description="VIOLIN", direction="on", linebreak="id", @@ -213320,6 +223957,7 @@ characters.data={ }, [0x1F3BC]={ category="so", + cjkwd="w", description="MUSICAL SCORE", direction="on", linebreak="al", @@ -213327,6 +223965,7 @@ characters.data={ }, [0x1F3BD]={ category="so", + cjkwd="w", description="RUNNING SHIRT WITH SASH", direction="on", linebreak="id", @@ -213334,6 +223973,7 @@ characters.data={ }, [0x1F3BE]={ category="so", + cjkwd="w", description="TENNIS RACQUET AND BALL", direction="on", linebreak="id", @@ -213341,6 +223981,7 @@ characters.data={ }, [0x1F3BF]={ category="so", + cjkwd="w", description="SKI AND SKI BOOT", direction="on", linebreak="id", @@ -213348,6 +223989,7 @@ characters.data={ }, [0x1F3C0]={ category="so", + cjkwd="w", description="BASKETBALL AND HOOP", direction="on", linebreak="id", @@ -213355,6 +223997,7 @@ characters.data={ }, [0x1F3C1]={ category="so", + cjkwd="w", description="CHEQUERED FLAG", direction="on", linebreak="id", @@ -213362,6 +224005,7 @@ characters.data={ }, [0x1F3C2]={ category="so", + cjkwd="w", description="SNOWBOARDER", direction="on", linebreak="id", @@ -213369,20 +224013,23 @@ characters.data={ }, [0x1F3C3]={ category="so", + cjkwd="w", description="RUNNER", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F3C3, }, [0x1F3C4]={ category="so", + cjkwd="w", description="SURFER", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F3C4, }, [0x1F3C5]={ category="so", + cjkwd="w", description="SPORTS MEDAL", direction="on", linebreak="id", @@ -213390,6 +224037,7 @@ characters.data={ }, [0x1F3C6]={ category="so", + cjkwd="w", description="TROPHY", direction="on", linebreak="id", @@ -213397,6 +224045,7 @@ characters.data={ }, [0x1F3C7]={ category="so", + cjkwd="w", description="HORSE RACING", direction="on", linebreak="id", @@ -213404,6 +224053,7 @@ characters.data={ }, [0x1F3C8]={ category="so", + cjkwd="w", description="AMERICAN FOOTBALL", direction="on", linebreak="id", @@ -213411,6 +224061,7 @@ characters.data={ }, [0x1F3C9]={ category="so", + cjkwd="w", description="RUGBY FOOTBALL", direction="on", linebreak="id", @@ -213418,17 +224069,19 @@ characters.data={ }, [0x1F3CA]={ category="so", + cjkwd="w", description="SWIMMER", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F3CA, }, [0x1F3CB]={ category="so", description="WEIGHT LIFTER", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F3CB, + variants=variants_emoji, }, [0x1F3CC]={ category="so", @@ -213436,6 +224089,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3CC, + variants=variants_emoji, }, [0x1F3CD]={ category="so", @@ -213443,6 +224097,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3CD, + variants=variants_emoji, }, [0x1F3CE]={ category="so", @@ -213450,9 +224105,11 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3CE, + variants=variants_emoji, }, [0x1F3CF]={ category="so", + cjkwd="w", description="CRICKET BAT AND BALL", direction="on", linebreak="id", @@ -213460,6 +224117,7 @@ characters.data={ }, [0x1F3D0]={ category="so", + cjkwd="w", description="VOLLEYBALL", direction="on", linebreak="id", @@ -213467,6 +224125,7 @@ characters.data={ }, [0x1F3D1]={ category="so", + cjkwd="w", description="FIELD HOCKEY STICK AND BALL", direction="on", linebreak="id", @@ -213474,6 +224133,7 @@ characters.data={ }, [0x1F3D2]={ category="so", + cjkwd="w", description="ICE HOCKEY STICK AND PUCK", direction="on", linebreak="id", @@ -213481,6 +224141,7 @@ characters.data={ }, [0x1F3D3]={ category="so", + cjkwd="w", description="TABLE TENNIS PADDLE AND BALL", direction="on", linebreak="id", @@ -213492,6 +224153,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3D4, + variants=variants_emoji, }, [0x1F3D5]={ category="so", @@ -213499,6 +224161,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3D5, + variants=variants_emoji, }, [0x1F3D6]={ category="so", @@ -213506,6 +224169,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3D6, + variants=variants_emoji, }, [0x1F3D7]={ category="so", @@ -213513,6 +224177,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3D7, + variants=variants_emoji, }, [0x1F3D8]={ category="so", @@ -213520,6 +224185,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3D8, + variants=variants_emoji, }, [0x1F3D9]={ category="so", @@ -213527,6 +224193,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3D9, + variants=variants_emoji, }, [0x1F3DA]={ category="so", @@ -213534,6 +224201,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3DA, + variants=variants_emoji, }, [0x1F3DB]={ category="so", @@ -213541,6 +224209,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3DB, + variants=variants_emoji, }, [0x1F3DC]={ category="so", @@ -213548,6 +224217,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3DC, + variants=variants_emoji, }, [0x1F3DD]={ category="so", @@ -213555,6 +224225,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3DD, + variants=variants_emoji, }, [0x1F3DE]={ category="so", @@ -213562,6 +224233,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3DE, + variants=variants_emoji, }, [0x1F3DF]={ category="so", @@ -213569,9 +224241,11 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3DF, + variants=variants_emoji, }, [0x1F3E0]={ category="so", + cjkwd="w", description="HOUSE BUILDING", direction="on", linebreak="id", @@ -213579,6 +224253,7 @@ characters.data={ }, [0x1F3E1]={ category="so", + cjkwd="w", description="HOUSE WITH GARDEN", direction="on", linebreak="id", @@ -213586,6 +224261,7 @@ characters.data={ }, [0x1F3E2]={ category="so", + cjkwd="w", description="OFFICE BUILDING", direction="on", linebreak="id", @@ -213593,6 +224269,7 @@ characters.data={ }, [0x1F3E3]={ category="so", + cjkwd="w", description="JAPANESE POST OFFICE", direction="on", linebreak="id", @@ -213600,6 +224277,7 @@ characters.data={ }, [0x1F3E4]={ category="so", + cjkwd="w", description="EUROPEAN POST OFFICE", direction="on", linebreak="id", @@ -213607,6 +224285,7 @@ characters.data={ }, [0x1F3E5]={ category="so", + cjkwd="w", description="HOSPITAL", direction="on", linebreak="id", @@ -213614,6 +224293,7 @@ characters.data={ }, [0x1F3E6]={ category="so", + cjkwd="w", description="BANK", direction="on", linebreak="id", @@ -213621,6 +224301,7 @@ characters.data={ }, [0x1F3E7]={ category="so", + cjkwd="w", description="AUTOMATED TELLER MACHINE", direction="on", linebreak="id", @@ -213628,6 +224309,7 @@ characters.data={ }, [0x1F3E8]={ category="so", + cjkwd="w", description="HOTEL", direction="on", linebreak="id", @@ -213635,6 +224317,7 @@ characters.data={ }, [0x1F3E9]={ category="so", + cjkwd="w", description="LOVE HOTEL", direction="on", linebreak="id", @@ -213642,6 +224325,7 @@ characters.data={ }, [0x1F3EA]={ category="so", + cjkwd="w", description="CONVENIENCE STORE", direction="on", linebreak="id", @@ -213649,6 +224333,7 @@ characters.data={ }, [0x1F3EB]={ category="so", + cjkwd="w", description="SCHOOL", direction="on", linebreak="id", @@ -213656,6 +224341,7 @@ characters.data={ }, [0x1F3EC]={ category="so", + cjkwd="w", description="DEPARTMENT STORE", direction="on", linebreak="id", @@ -213663,6 +224349,7 @@ characters.data={ }, [0x1F3ED]={ category="so", + cjkwd="w", description="FACTORY", direction="on", linebreak="id", @@ -213670,6 +224357,7 @@ characters.data={ }, [0x1F3EE]={ category="so", + cjkwd="w", description="IZAKAYA LANTERN", direction="on", linebreak="id", @@ -213677,6 +224365,7 @@ characters.data={ }, [0x1F3EF]={ category="so", + cjkwd="w", description="JAPANESE CASTLE", direction="on", linebreak="id", @@ -213684,6 +224373,7 @@ characters.data={ }, [0x1F3F0]={ category="so", + cjkwd="w", description="EUROPEAN CASTLE", direction="on", linebreak="id", @@ -213709,9 +224399,11 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3F3, + variants=variants_emoji, }, [0x1F3F4]={ category="so", + cjkwd="w", description="WAVING BLACK FLAG", direction="on", linebreak="id", @@ -213723,6 +224415,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3F5, + variants=variants_emoji, }, [0x1F3F6]={ category="so", @@ -213737,9 +224430,11 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F3F7, + variants=variants_emoji, }, [0x1F3F8]={ category="so", + cjkwd="w", description="BADMINTON RACQUET AND SHUTTLECOCK", direction="on", linebreak="id", @@ -213747,6 +224442,7 @@ characters.data={ }, [0x1F3F9]={ category="so", + cjkwd="w", description="BOW AND ARROW", direction="on", linebreak="id", @@ -213754,6 +224450,7 @@ characters.data={ }, [0x1F3FA]={ category="so", + cjkwd="w", description="AMPHORA", direction="on", linebreak="id", @@ -213761,41 +224458,47 @@ characters.data={ }, [0x1F3FB]={ category="sk", + cjkwd="w", description="EMOJI MODIFIER FITZPATRICK TYPE-1-2", direction="on", - linebreak="al", + linebreak="em", unicodeslot=0x1F3FB, }, [0x1F3FC]={ category="sk", + cjkwd="w", description="EMOJI MODIFIER FITZPATRICK TYPE-3", direction="on", - linebreak="al", + linebreak="em", unicodeslot=0x1F3FC, }, [0x1F3FD]={ category="sk", + cjkwd="w", description="EMOJI MODIFIER FITZPATRICK TYPE-4", direction="on", - linebreak="al", + linebreak="em", unicodeslot=0x1F3FD, }, [0x1F3FE]={ category="sk", + cjkwd="w", description="EMOJI MODIFIER FITZPATRICK TYPE-5", direction="on", - linebreak="al", + linebreak="em", unicodeslot=0x1F3FE, }, [0x1F3FF]={ category="sk", + cjkwd="w", description="EMOJI MODIFIER FITZPATRICK TYPE-6", direction="on", - linebreak="al", + linebreak="em", unicodeslot=0x1F3FF, }, [0x1F400]={ category="so", + cjkwd="w", description="RAT", direction="on", linebreak="id", @@ -213803,6 +224506,7 @@ characters.data={ }, [0x1F401]={ category="so", + cjkwd="w", description="MOUSE", direction="on", linebreak="id", @@ -213810,6 +224514,7 @@ characters.data={ }, [0x1F402]={ category="so", + cjkwd="w", description="OX", direction="on", linebreak="id", @@ -213817,6 +224522,7 @@ characters.data={ }, [0x1F403]={ category="so", + cjkwd="w", description="WATER BUFFALO", direction="on", linebreak="id", @@ -213824,13 +224530,16 @@ characters.data={ }, [0x1F404]={ category="so", + cjkwd="w", description="COW", direction="on", linebreak="id", + synonyms={ "beef (on menus)" }, unicodeslot=0x1F404, }, [0x1F405]={ category="so", + cjkwd="w", description="TIGER", direction="on", linebreak="id", @@ -213838,6 +224547,7 @@ characters.data={ }, [0x1F406]={ category="so", + cjkwd="w", description="LEOPARD", direction="on", linebreak="id", @@ -213845,6 +224555,7 @@ characters.data={ }, [0x1F407]={ category="so", + cjkwd="w", description="RABBIT", direction="on", linebreak="id", @@ -213852,6 +224563,7 @@ characters.data={ }, [0x1F408]={ category="so", + cjkwd="w", description="CAT", direction="on", linebreak="id", @@ -213859,6 +224571,7 @@ characters.data={ }, [0x1F409]={ category="so", + cjkwd="w", description="DRAGON", direction="on", linebreak="id", @@ -213866,6 +224579,7 @@ characters.data={ }, [0x1F40A]={ category="so", + cjkwd="w", description="CROCODILE", direction="on", linebreak="id", @@ -213873,6 +224587,7 @@ characters.data={ }, [0x1F40B]={ category="so", + cjkwd="w", description="WHALE", direction="on", linebreak="id", @@ -213880,6 +224595,7 @@ characters.data={ }, [0x1F40C]={ category="so", + cjkwd="w", description="SNAIL", direction="on", linebreak="id", @@ -213887,6 +224603,7 @@ characters.data={ }, [0x1F40D]={ category="so", + cjkwd="w", description="SNAKE", direction="on", linebreak="id", @@ -213894,6 +224611,7 @@ characters.data={ }, [0x1F40E]={ category="so", + cjkwd="w", description="HORSE", direction="on", linebreak="id", @@ -213901,6 +224619,7 @@ characters.data={ }, [0x1F40F]={ category="so", + cjkwd="w", description="RAM", direction="on", linebreak="id", @@ -213908,6 +224627,7 @@ characters.data={ }, [0x1F410]={ category="so", + cjkwd="w", description="GOAT", direction="on", linebreak="id", @@ -213915,6 +224635,7 @@ characters.data={ }, [0x1F411]={ category="so", + cjkwd="w", description="SHEEP", direction="on", linebreak="id", @@ -213922,6 +224643,7 @@ characters.data={ }, [0x1F412]={ category="so", + cjkwd="w", description="MONKEY", direction="on", linebreak="id", @@ -213929,6 +224651,7 @@ characters.data={ }, [0x1F413]={ category="so", + cjkwd="w", description="ROOSTER", direction="on", linebreak="id", @@ -213936,13 +224659,16 @@ characters.data={ }, [0x1F414]={ category="so", + cjkwd="w", description="CHICKEN", direction="on", linebreak="id", + synonyms={ "poultry (on menus)" }, unicodeslot=0x1F414, }, [0x1F415]={ category="so", + cjkwd="w", description="DOG", direction="on", linebreak="id", @@ -213950,13 +224676,16 @@ characters.data={ }, [0x1F416]={ category="so", + cjkwd="w", description="PIG", direction="on", linebreak="id", + synonyms={ "pork (on menus)" }, unicodeslot=0x1F416, }, [0x1F417]={ category="so", + cjkwd="w", description="BOAR", direction="on", linebreak="id", @@ -213964,6 +224693,7 @@ characters.data={ }, [0x1F418]={ category="so", + cjkwd="w", description="ELEPHANT", direction="on", linebreak="id", @@ -213971,6 +224701,7 @@ characters.data={ }, [0x1F419]={ category="so", + cjkwd="w", description="OCTOPUS", direction="on", linebreak="id", @@ -213978,13 +224709,16 @@ characters.data={ }, [0x1F41A]={ category="so", + cjkwd="w", description="SPIRAL SHELL", direction="on", linebreak="id", + synonyms={ "seashell" }, unicodeslot=0x1F41A, }, [0x1F41B]={ category="so", + cjkwd="w", description="BUG", direction="on", linebreak="id", @@ -213992,6 +224726,7 @@ characters.data={ }, [0x1F41C]={ category="so", + cjkwd="w", description="ANT", direction="on", linebreak="id", @@ -213999,6 +224734,7 @@ characters.data={ }, [0x1F41D]={ category="so", + cjkwd="w", description="HONEYBEE", direction="on", linebreak="id", @@ -214006,6 +224742,7 @@ characters.data={ }, [0x1F41E]={ category="so", + cjkwd="w", description="LADY BEETLE", direction="on", linebreak="id", @@ -214013,6 +224750,7 @@ characters.data={ }, [0x1F41F]={ category="so", + cjkwd="w", description="FISH", direction="on", linebreak="id", @@ -214020,6 +224758,7 @@ characters.data={ }, [0x1F420]={ category="so", + cjkwd="w", description="TROPICAL FISH", direction="on", linebreak="id", @@ -214027,6 +224766,7 @@ characters.data={ }, [0x1F421]={ category="so", + cjkwd="w", description="BLOWFISH", direction="on", linebreak="id", @@ -214034,6 +224774,7 @@ characters.data={ }, [0x1F422]={ category="so", + cjkwd="w", description="TURTLE", direction="on", linebreak="id", @@ -214041,6 +224782,7 @@ characters.data={ }, [0x1F423]={ category="so", + cjkwd="w", description="HATCHING CHICK", direction="on", linebreak="id", @@ -214048,6 +224790,7 @@ characters.data={ }, [0x1F424]={ category="so", + cjkwd="w", description="BABY CHICK", direction="on", linebreak="id", @@ -214055,6 +224798,7 @@ characters.data={ }, [0x1F425]={ category="so", + cjkwd="w", description="FRONT-FACING BABY CHICK", direction="on", linebreak="id", @@ -214062,6 +224806,7 @@ characters.data={ }, [0x1F426]={ category="so", + cjkwd="w", description="BIRD", direction="on", linebreak="id", @@ -214069,6 +224814,7 @@ characters.data={ }, [0x1F427]={ category="so", + cjkwd="w", description="PENGUIN", direction="on", linebreak="id", @@ -214076,6 +224822,7 @@ characters.data={ }, [0x1F428]={ category="so", + cjkwd="w", description="KOALA", direction="on", linebreak="id", @@ -214083,6 +224830,7 @@ characters.data={ }, [0x1F429]={ category="so", + cjkwd="w", description="POODLE", direction="on", linebreak="id", @@ -214090,6 +224838,7 @@ characters.data={ }, [0x1F42A]={ category="so", + cjkwd="w", description="DROMEDARY CAMEL", direction="on", linebreak="id", @@ -214097,6 +224846,7 @@ characters.data={ }, [0x1F42B]={ category="so", + cjkwd="w", description="BACTRIAN CAMEL", direction="on", linebreak="id", @@ -214104,6 +224854,7 @@ characters.data={ }, [0x1F42C]={ category="so", + cjkwd="w", description="DOLPHIN", direction="on", linebreak="id", @@ -214111,6 +224862,7 @@ characters.data={ }, [0x1F42D]={ category="so", + cjkwd="w", description="MOUSE FACE", direction="on", linebreak="id", @@ -214118,6 +224870,7 @@ characters.data={ }, [0x1F42E]={ category="so", + cjkwd="w", description="COW FACE", direction="on", linebreak="id", @@ -214125,6 +224878,7 @@ characters.data={ }, [0x1F42F]={ category="so", + cjkwd="w", description="TIGER FACE", direction="on", linebreak="id", @@ -214132,6 +224886,7 @@ characters.data={ }, [0x1F430]={ category="so", + cjkwd="w", description="RABBIT FACE", direction="on", linebreak="id", @@ -214139,6 +224894,7 @@ characters.data={ }, [0x1F431]={ category="so", + cjkwd="w", description="CAT FACE", direction="on", linebreak="id", @@ -214146,6 +224902,7 @@ characters.data={ }, [0x1F432]={ category="so", + cjkwd="w", description="DRAGON FACE", direction="on", linebreak="id", @@ -214153,6 +224910,7 @@ characters.data={ }, [0x1F433]={ category="so", + cjkwd="w", description="SPOUTING WHALE", direction="on", linebreak="id", @@ -214160,6 +224918,7 @@ characters.data={ }, [0x1F434]={ category="so", + cjkwd="w", description="HORSE FACE", direction="on", linebreak="id", @@ -214167,6 +224926,7 @@ characters.data={ }, [0x1F435]={ category="so", + cjkwd="w", description="MONKEY FACE", direction="on", linebreak="id", @@ -214174,6 +224934,7 @@ characters.data={ }, [0x1F436]={ category="so", + cjkwd="w", description="DOG FACE", direction="on", linebreak="id", @@ -214181,6 +224942,7 @@ characters.data={ }, [0x1F437]={ category="so", + cjkwd="w", description="PIG FACE", direction="on", linebreak="id", @@ -214188,6 +224950,7 @@ characters.data={ }, [0x1F438]={ category="so", + cjkwd="w", description="FROG FACE", direction="on", linebreak="id", @@ -214195,6 +224958,7 @@ characters.data={ }, [0x1F439]={ category="so", + cjkwd="w", description="HAMSTER FACE", direction="on", linebreak="id", @@ -214202,6 +224966,7 @@ characters.data={ }, [0x1F43A]={ category="so", + cjkwd="w", description="WOLF FACE", direction="on", linebreak="id", @@ -214209,6 +224974,7 @@ characters.data={ }, [0x1F43B]={ category="so", + cjkwd="w", description="BEAR FACE", direction="on", linebreak="id", @@ -214216,6 +224982,7 @@ characters.data={ }, [0x1F43C]={ category="so", + cjkwd="w", description="PANDA FACE", direction="on", linebreak="id", @@ -214223,6 +224990,7 @@ characters.data={ }, [0x1F43D]={ category="so", + cjkwd="w", description="PIG NOSE", direction="on", linebreak="id", @@ -214230,6 +224998,7 @@ characters.data={ }, [0x1F43E]={ category="so", + cjkwd="w", description="PAW PRINTS", direction="on", linebreak="id", @@ -214241,9 +225010,11 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F43F, + variants=variants_emoji, }, [0x1F440]={ category="so", + cjkwd="w", description="EYES", direction="on", linebreak="id", @@ -214255,23 +225026,27 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F441, + variants=variants_emoji, }, [0x1F442]={ category="so", + cjkwd="w", description="EAR", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F442, }, [0x1F443]={ category="so", + cjkwd="w", description="NOSE", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F443, }, [0x1F444]={ category="so", + cjkwd="w", description="MOUTH", direction="on", linebreak="id", @@ -214279,6 +225054,7 @@ characters.data={ }, [0x1F445]={ category="so", + cjkwd="w", description="TONGUE", direction="on", linebreak="id", @@ -214286,83 +225062,96 @@ characters.data={ }, [0x1F446]={ category="so", + cjkwd="w", description="WHITE UP POINTING BACKHAND INDEX", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F446, }, [0x1F447]={ category="so", + cjkwd="w", description="WHITE DOWN POINTING BACKHAND INDEX", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F447, }, [0x1F448]={ category="so", + cjkwd="w", description="WHITE LEFT POINTING BACKHAND INDEX", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F448, }, [0x1F449]={ category="so", + cjkwd="w", description="WHITE RIGHT POINTING BACKHAND INDEX", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F449, }, [0x1F44A]={ category="so", + cjkwd="w", description="FISTED HAND SIGN", direction="on", - linebreak="id", + linebreak="eb", + synonyms={ "punch" }, unicodeslot=0x1F44A, }, [0x1F44B]={ category="so", + cjkwd="w", description="WAVING HAND SIGN", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F44B, }, [0x1F44C]={ category="so", + cjkwd="w", description="OK HAND SIGN", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F44C, }, [0x1F44D]={ category="so", + cjkwd="w", description="THUMBS UP SIGN", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F44D, }, [0x1F44E]={ category="so", + cjkwd="w", description="THUMBS DOWN SIGN", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F44E, }, [0x1F44F]={ category="so", + cjkwd="w", description="CLAPPING HANDS SIGN", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F44F, }, [0x1F450]={ category="so", + cjkwd="w", description="OPEN HANDS SIGN", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F450, }, [0x1F451]={ category="so", + cjkwd="w", description="CROWN", direction="on", linebreak="id", @@ -214370,6 +225159,7 @@ characters.data={ }, [0x1F452]={ category="so", + cjkwd="w", description="WOMANS HAT", direction="on", linebreak="id", @@ -214377,6 +225167,7 @@ characters.data={ }, [0x1F453]={ category="so", + cjkwd="w", description="EYEGLASSES", direction="on", linebreak="id", @@ -214384,6 +225175,7 @@ characters.data={ }, [0x1F454]={ category="so", + cjkwd="w", description="NECKTIE", direction="on", linebreak="id", @@ -214391,6 +225183,7 @@ characters.data={ }, [0x1F455]={ category="so", + cjkwd="w", description="T-SHIRT", direction="on", linebreak="id", @@ -214398,6 +225191,7 @@ characters.data={ }, [0x1F456]={ category="so", + cjkwd="w", description="JEANS", direction="on", linebreak="id", @@ -214405,6 +225199,7 @@ characters.data={ }, [0x1F457]={ category="so", + cjkwd="w", description="DRESS", direction="on", linebreak="id", @@ -214412,6 +225207,7 @@ characters.data={ }, [0x1F458]={ category="so", + cjkwd="w", description="KIMONO", direction="on", linebreak="id", @@ -214419,6 +225215,7 @@ characters.data={ }, [0x1F459]={ category="so", + cjkwd="w", description="BIKINI", direction="on", linebreak="id", @@ -214426,6 +225223,7 @@ characters.data={ }, [0x1F45A]={ category="so", + cjkwd="w", description="WOMANS CLOTHES", direction="on", linebreak="id", @@ -214433,6 +225231,7 @@ characters.data={ }, [0x1F45B]={ category="so", + cjkwd="w", description="PURSE", direction="on", linebreak="id", @@ -214440,6 +225239,7 @@ characters.data={ }, [0x1F45C]={ category="so", + cjkwd="w", description="HANDBAG", direction="on", linebreak="id", @@ -214447,6 +225247,7 @@ characters.data={ }, [0x1F45D]={ category="so", + cjkwd="w", description="POUCH", direction="on", linebreak="id", @@ -214454,6 +225255,7 @@ characters.data={ }, [0x1F45E]={ category="so", + cjkwd="w", description="MANS SHOE", direction="on", linebreak="id", @@ -214461,6 +225263,7 @@ characters.data={ }, [0x1F45F]={ category="so", + cjkwd="w", description="ATHLETIC SHOE", direction="on", linebreak="id", @@ -214468,6 +225271,7 @@ characters.data={ }, [0x1F460]={ category="so", + cjkwd="w", description="HIGH-HEELED SHOE", direction="on", linebreak="id", @@ -214475,6 +225279,7 @@ characters.data={ }, [0x1F461]={ category="so", + cjkwd="w", description="WOMANS SANDAL", direction="on", linebreak="id", @@ -214482,6 +225287,7 @@ characters.data={ }, [0x1F462]={ category="so", + cjkwd="w", description="WOMANS BOOTS", direction="on", linebreak="id", @@ -214489,6 +225295,7 @@ characters.data={ }, [0x1F463]={ category="so", + cjkwd="w", description="FOOTPRINTS", direction="on", linebreak="id", @@ -214496,48 +225303,57 @@ characters.data={ }, [0x1F464]={ category="so", + cjkwd="w", description="BUST IN SILHOUETTE", direction="on", linebreak="id", + synonyms={ "guest account" }, unicodeslot=0x1F464, }, [0x1F465]={ category="so", + cjkwd="w", description="BUSTS IN SILHOUETTE", direction="on", linebreak="id", + synonyms={ "accounts" }, unicodeslot=0x1F465, }, [0x1F466]={ category="so", + cjkwd="w", description="BOY", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F466, }, [0x1F467]={ category="so", + cjkwd="w", description="GIRL", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F467, }, [0x1F468]={ category="so", + cjkwd="w", description="MAN", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F468, }, [0x1F469]={ category="so", + cjkwd="w", description="WOMAN", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F469, }, [0x1F46A]={ category="so", + cjkwd="w", description="FAMILY", direction="on", linebreak="id", @@ -214545,6 +225361,7 @@ characters.data={ }, [0x1F46B]={ category="so", + cjkwd="w", description="MAN AND WOMAN HOLDING HANDS", direction="on", linebreak="id", @@ -214552,6 +225369,7 @@ characters.data={ }, [0x1F46C]={ category="so", + cjkwd="w", description="TWO MEN HOLDING HANDS", direction="on", linebreak="id", @@ -214559,6 +225377,7 @@ characters.data={ }, [0x1F46D]={ category="so", + cjkwd="w", description="TWO WOMEN HOLDING HANDS", direction="on", linebreak="id", @@ -214566,13 +225385,15 @@ characters.data={ }, [0x1F46E]={ category="so", + cjkwd="w", description="POLICE OFFICER", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F46E, }, [0x1F46F]={ category="so", + cjkwd="w", description="WOMAN WITH BUNNY EARS", direction="on", linebreak="id", @@ -214580,69 +225401,80 @@ characters.data={ }, [0x1F470]={ category="so", + cjkwd="w", description="BRIDE WITH VEIL", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F470, }, [0x1F471]={ category="so", + cjkwd="w", description="PERSON WITH BLOND HAIR", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F471, }, [0x1F472]={ category="so", + cjkwd="w", description="MAN WITH GUA PI MAO", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F472, }, [0x1F473]={ category="so", + cjkwd="w", description="MAN WITH TURBAN", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F473, }, [0x1F474]={ category="so", + cjkwd="w", description="OLDER MAN", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F474, }, [0x1F475]={ category="so", + cjkwd="w", description="OLDER WOMAN", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F475, }, [0x1F476]={ category="so", + cjkwd="w", description="BABY", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F476, }, [0x1F477]={ category="so", + cjkwd="w", description="CONSTRUCTION WORKER", direction="on", - linebreak="id", + linebreak="eb", + synonyms={ "hardhat" }, unicodeslot=0x1F477, }, [0x1F478]={ category="so", + cjkwd="w", description="PRINCESS", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F478, }, [0x1F479]={ category="so", + cjkwd="w", description="JAPANESE OGRE", direction="on", linebreak="id", @@ -214650,6 +225482,7 @@ characters.data={ }, [0x1F47A]={ category="so", + cjkwd="w", description="JAPANESE GOBLIN", direction="on", linebreak="id", @@ -214657,6 +225490,7 @@ characters.data={ }, [0x1F47B]={ category="so", + cjkwd="w", description="GHOST", direction="on", linebreak="id", @@ -214664,13 +225498,15 @@ characters.data={ }, [0x1F47C]={ category="so", + cjkwd="w", description="BABY ANGEL", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F47C, }, [0x1F47D]={ category="so", + cjkwd="w", description="EXTRATERRESTRIAL ALIEN", direction="on", linebreak="id", @@ -214678,6 +225514,7 @@ characters.data={ }, [0x1F47E]={ category="so", + cjkwd="w", description="ALIEN MONSTER", direction="on", linebreak="id", @@ -214685,6 +225522,7 @@ characters.data={ }, [0x1F47F]={ category="so", + cjkwd="w", description="IMP", direction="on", linebreak="id", @@ -214692,6 +225530,7 @@ characters.data={ }, [0x1F480]={ category="so", + cjkwd="w", description="SKULL", direction="on", linebreak="id", @@ -214699,27 +225538,31 @@ characters.data={ }, [0x1F481]={ category="so", + cjkwd="w", description="INFORMATION DESK PERSON", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F481, }, [0x1F482]={ category="so", + cjkwd="w", description="GUARDSMAN", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F482, }, [0x1F483]={ category="so", + cjkwd="w", description="DANCER", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F483, }, [0x1F484]={ category="so", + cjkwd="w", description="LIPSTICK", direction="on", linebreak="id", @@ -214727,27 +225570,31 @@ characters.data={ }, [0x1F485]={ category="so", + cjkwd="w", description="NAIL POLISH", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F485, }, [0x1F486]={ category="so", + cjkwd="w", description="FACE MASSAGE", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F486, }, [0x1F487]={ category="so", + cjkwd="w", description="HAIRCUT", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F487, }, [0x1F488]={ category="so", + cjkwd="w", description="BARBER POLE", direction="on", linebreak="id", @@ -214755,6 +225602,7 @@ characters.data={ }, [0x1F489]={ category="so", + cjkwd="w", description="SYRINGE", direction="on", linebreak="id", @@ -214762,6 +225610,7 @@ characters.data={ }, [0x1F48A]={ category="so", + cjkwd="w", description="PILL", direction="on", linebreak="id", @@ -214769,6 +225618,7 @@ characters.data={ }, [0x1F48B]={ category="so", + cjkwd="w", description="KISS MARK", direction="on", linebreak="id", @@ -214776,6 +225626,7 @@ characters.data={ }, [0x1F48C]={ category="so", + cjkwd="w", description="LOVE LETTER", direction="on", linebreak="id", @@ -214783,6 +225634,7 @@ characters.data={ }, [0x1F48D]={ category="so", + cjkwd="w", description="RING", direction="on", linebreak="id", @@ -214790,6 +225642,7 @@ characters.data={ }, [0x1F48E]={ category="so", + cjkwd="w", description="GEM STONE", direction="on", linebreak="id", @@ -214797,6 +225650,7 @@ characters.data={ }, [0x1F48F]={ category="so", + cjkwd="w", description="KISS", direction="on", linebreak="id", @@ -214804,6 +225658,7 @@ characters.data={ }, [0x1F490]={ category="so", + cjkwd="w", description="BOUQUET", direction="on", linebreak="id", @@ -214811,6 +225666,7 @@ characters.data={ }, [0x1F491]={ category="so", + cjkwd="w", description="COUPLE WITH HEART", direction="on", linebreak="id", @@ -214818,6 +225674,7 @@ characters.data={ }, [0x1F492]={ category="so", + cjkwd="w", description="WEDDING", direction="on", linebreak="id", @@ -214825,6 +225682,7 @@ characters.data={ }, [0x1F493]={ category="so", + cjkwd="w", description="BEATING HEART", direction="on", linebreak="id", @@ -214832,6 +225690,7 @@ characters.data={ }, [0x1F494]={ category="so", + cjkwd="w", description="BROKEN HEART", direction="on", linebreak="id", @@ -214839,6 +225698,7 @@ characters.data={ }, [0x1F495]={ category="so", + cjkwd="w", description="TWO HEARTS", direction="on", linebreak="id", @@ -214846,6 +225706,7 @@ characters.data={ }, [0x1F496]={ category="so", + cjkwd="w", description="SPARKLING HEART", direction="on", linebreak="id", @@ -214853,6 +225714,7 @@ characters.data={ }, [0x1F497]={ category="so", + cjkwd="w", description="GROWING HEART", direction="on", linebreak="id", @@ -214860,6 +225722,7 @@ characters.data={ }, [0x1F498]={ category="so", + cjkwd="w", description="HEART WITH ARROW", direction="on", linebreak="id", @@ -214867,6 +225730,7 @@ characters.data={ }, [0x1F499]={ category="so", + cjkwd="w", description="BLUE HEART", direction="on", linebreak="id", @@ -214874,6 +225738,7 @@ characters.data={ }, [0x1F49A]={ category="so", + cjkwd="w", description="GREEN HEART", direction="on", linebreak="id", @@ -214881,6 +225746,7 @@ characters.data={ }, [0x1F49B]={ category="so", + cjkwd="w", description="YELLOW HEART", direction="on", linebreak="id", @@ -214888,6 +225754,7 @@ characters.data={ }, [0x1F49C]={ category="so", + cjkwd="w", description="PURPLE HEART", direction="on", linebreak="id", @@ -214895,6 +225762,7 @@ characters.data={ }, [0x1F49D]={ category="so", + cjkwd="w", description="HEART WITH RIBBON", direction="on", linebreak="id", @@ -214902,6 +225770,7 @@ characters.data={ }, [0x1F49E]={ category="so", + cjkwd="w", description="REVOLVING HEARTS", direction="on", linebreak="id", @@ -214909,6 +225778,7 @@ characters.data={ }, [0x1F49F]={ category="so", + cjkwd="w", description="HEART DECORATION", direction="on", linebreak="id", @@ -214916,6 +225786,7 @@ characters.data={ }, [0x1F4A0]={ category="so", + cjkwd="w", description="DIAMOND SHAPE WITH A DOT INSIDE", direction="on", linebreak="al", @@ -214923,13 +225794,16 @@ characters.data={ }, [0x1F4A1]={ category="so", + cjkwd="w", description="ELECTRIC LIGHT BULB", direction="on", linebreak="id", + synonyms={ "idea" }, unicodeslot=0x1F4A1, }, [0x1F4A2]={ category="so", + cjkwd="w", description="ANGER SYMBOL", direction="on", linebreak="al", @@ -214937,6 +225811,7 @@ characters.data={ }, [0x1F4A3]={ category="so", + cjkwd="w", description="BOMB", direction="on", linebreak="id", @@ -214944,6 +225819,7 @@ characters.data={ }, [0x1F4A4]={ category="so", + cjkwd="w", description="SLEEPING SYMBOL", direction="on", linebreak="al", @@ -214951,6 +225827,7 @@ characters.data={ }, [0x1F4A5]={ category="so", + cjkwd="w", description="COLLISION SYMBOL", direction="on", linebreak="id", @@ -214958,13 +225835,16 @@ characters.data={ }, [0x1F4A6]={ category="so", + cjkwd="w", description="SPLASHING SWEAT SYMBOL", direction="on", linebreak="id", + synonyms={ "plewds" }, unicodeslot=0x1F4A6, }, [0x1F4A7]={ category="so", + cjkwd="w", description="DROPLET", direction="on", linebreak="id", @@ -214972,13 +225852,16 @@ characters.data={ }, [0x1F4A8]={ category="so", + cjkwd="w", description="DASH SYMBOL", direction="on", linebreak="id", + synonyms={ "briffits" }, unicodeslot=0x1F4A8, }, [0x1F4A9]={ category="so", + cjkwd="w", description="PILE OF POO", direction="on", linebreak="id", @@ -214986,20 +225869,24 @@ characters.data={ }, [0x1F4AA]={ category="so", + cjkwd="w", description="FLEXED BICEPS", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F4AA, }, [0x1F4AB]={ category="so", + cjkwd="w", description="DIZZY SYMBOL", direction="on", linebreak="id", + synonyms={ "squeans" }, unicodeslot=0x1F4AB, }, [0x1F4AC]={ category="so", + cjkwd="w", description="SPEECH BALLOON", direction="on", linebreak="id", @@ -215007,6 +225894,7 @@ characters.data={ }, [0x1F4AD]={ category="so", + cjkwd="w", description="THOUGHT BALLOON", direction="on", linebreak="id", @@ -215014,6 +225902,7 @@ characters.data={ }, [0x1F4AE]={ category="so", + cjkwd="w", description="WHITE FLOWER", direction="on", linebreak="id", @@ -215021,6 +225910,7 @@ characters.data={ }, [0x1F4AF]={ category="so", + cjkwd="w", description="HUNDRED POINTS SYMBOL", direction="on", linebreak="al", @@ -215028,6 +225918,7 @@ characters.data={ }, [0x1F4B0]={ category="so", + cjkwd="w", description="MONEY BAG", direction="on", linebreak="id", @@ -215035,6 +225926,7 @@ characters.data={ }, [0x1F4B1]={ category="so", + cjkwd="w", description="CURRENCY EXCHANGE", direction="on", linebreak="al", @@ -215042,6 +225934,7 @@ characters.data={ }, [0x1F4B2]={ category="so", + cjkwd="w", description="HEAVY DOLLAR SIGN", direction="on", linebreak="al", @@ -215049,6 +225942,7 @@ characters.data={ }, [0x1F4B3]={ category="so", + cjkwd="w", description="CREDIT CARD", direction="on", linebreak="id", @@ -215056,6 +225950,7 @@ characters.data={ }, [0x1F4B4]={ category="so", + cjkwd="w", description="BANKNOTE WITH YEN SIGN", direction="on", linebreak="id", @@ -215063,6 +225958,7 @@ characters.data={ }, [0x1F4B5]={ category="so", + cjkwd="w", description="BANKNOTE WITH DOLLAR SIGN", direction="on", linebreak="id", @@ -215070,6 +225966,7 @@ characters.data={ }, [0x1F4B6]={ category="so", + cjkwd="w", description="BANKNOTE WITH EURO SIGN", direction="on", linebreak="id", @@ -215077,6 +225974,7 @@ characters.data={ }, [0x1F4B7]={ category="so", + cjkwd="w", description="BANKNOTE WITH POUND SIGN", direction="on", linebreak="id", @@ -215084,6 +225982,7 @@ characters.data={ }, [0x1F4B8]={ category="so", + cjkwd="w", description="MONEY WITH WINGS", direction="on", linebreak="id", @@ -215091,6 +225990,7 @@ characters.data={ }, [0x1F4B9]={ category="so", + cjkwd="w", description="CHART WITH UPWARDS TREND AND YEN SIGN", direction="on", linebreak="id", @@ -215098,6 +225998,7 @@ characters.data={ }, [0x1F4BA]={ category="so", + cjkwd="w", description="SEAT", direction="on", linebreak="id", @@ -215105,6 +226006,7 @@ characters.data={ }, [0x1F4BB]={ category="so", + cjkwd="w", description="PERSONAL COMPUTER", direction="on", linebreak="id", @@ -215112,6 +226014,7 @@ characters.data={ }, [0x1F4BC]={ category="so", + cjkwd="w", description="BRIEFCASE", direction="on", linebreak="id", @@ -215119,6 +226022,7 @@ characters.data={ }, [0x1F4BD]={ category="so", + cjkwd="w", description="MINIDISC", direction="on", linebreak="id", @@ -215126,6 +226030,7 @@ characters.data={ }, [0x1F4BE]={ category="so", + cjkwd="w", description="FLOPPY DISK", direction="on", linebreak="id", @@ -215133,13 +226038,16 @@ characters.data={ }, [0x1F4BF]={ category="so", + cjkwd="w", description="OPTICAL DISC", direction="on", linebreak="id", + synonyms={ "cd", "compact disc" }, unicodeslot=0x1F4BF, }, [0x1F4C0]={ category="so", + cjkwd="w", description="DVD", direction="on", linebreak="id", @@ -215147,6 +226055,7 @@ characters.data={ }, [0x1F4C1]={ category="so", + cjkwd="w", description="FILE FOLDER", direction="on", linebreak="id", @@ -215154,6 +226063,7 @@ characters.data={ }, [0x1F4C2]={ category="so", + cjkwd="w", description="OPEN FILE FOLDER", direction="on", linebreak="id", @@ -215161,6 +226071,7 @@ characters.data={ }, [0x1F4C3]={ category="so", + cjkwd="w", description="PAGE WITH CURL", direction="on", linebreak="id", @@ -215168,6 +226079,7 @@ characters.data={ }, [0x1F4C4]={ category="so", + cjkwd="w", description="PAGE FACING UP", direction="on", linebreak="id", @@ -215175,6 +226087,7 @@ characters.data={ }, [0x1F4C5]={ category="so", + cjkwd="w", description="CALENDAR", direction="on", linebreak="id", @@ -215182,6 +226095,7 @@ characters.data={ }, [0x1F4C6]={ category="so", + cjkwd="w", description="TEAR-OFF CALENDAR", direction="on", linebreak="id", @@ -215189,6 +226103,7 @@ characters.data={ }, [0x1F4C7]={ category="so", + cjkwd="w", description="CARD INDEX", direction="on", linebreak="id", @@ -215196,6 +226111,7 @@ characters.data={ }, [0x1F4C8]={ category="so", + cjkwd="w", description="CHART WITH UPWARDS TREND", direction="on", linebreak="id", @@ -215203,6 +226119,7 @@ characters.data={ }, [0x1F4C9]={ category="so", + cjkwd="w", description="CHART WITH DOWNWARDS TREND", direction="on", linebreak="id", @@ -215210,6 +226127,7 @@ characters.data={ }, [0x1F4CA]={ category="so", + cjkwd="w", description="BAR CHART", direction="on", linebreak="id", @@ -215217,6 +226135,7 @@ characters.data={ }, [0x1F4CB]={ category="so", + cjkwd="w", description="CLIPBOARD", direction="on", linebreak="id", @@ -215224,6 +226143,7 @@ characters.data={ }, [0x1F4CC]={ category="so", + cjkwd="w", description="PUSHPIN", direction="on", linebreak="id", @@ -215231,6 +226151,7 @@ characters.data={ }, [0x1F4CD]={ category="so", + cjkwd="w", description="ROUND PUSHPIN", direction="on", linebreak="id", @@ -215238,6 +226159,7 @@ characters.data={ }, [0x1F4CE]={ category="so", + cjkwd="w", description="PAPERCLIP", direction="on", linebreak="id", @@ -215245,6 +226167,7 @@ characters.data={ }, [0x1F4CF]={ category="so", + cjkwd="w", description="STRAIGHT RULER", direction="on", linebreak="id", @@ -215252,6 +226175,7 @@ characters.data={ }, [0x1F4D0]={ category="so", + cjkwd="w", description="TRIANGULAR RULER", direction="on", linebreak="id", @@ -215259,6 +226183,7 @@ characters.data={ }, [0x1F4D1]={ category="so", + cjkwd="w", description="BOOKMARK TABS", direction="on", linebreak="id", @@ -215266,6 +226191,7 @@ characters.data={ }, [0x1F4D2]={ category="so", + cjkwd="w", description="LEDGER", direction="on", linebreak="id", @@ -215273,6 +226199,7 @@ characters.data={ }, [0x1F4D3]={ category="so", + cjkwd="w", description="NOTEBOOK", direction="on", linebreak="id", @@ -215280,6 +226207,7 @@ characters.data={ }, [0x1F4D4]={ category="so", + cjkwd="w", description="NOTEBOOK WITH DECORATIVE COVER", direction="on", linebreak="id", @@ -215287,6 +226215,7 @@ characters.data={ }, [0x1F4D5]={ category="so", + cjkwd="w", description="CLOSED BOOK", direction="on", linebreak="id", @@ -215294,6 +226223,7 @@ characters.data={ }, [0x1F4D6]={ category="so", + cjkwd="w", description="OPEN BOOK", direction="on", linebreak="id", @@ -215301,6 +226231,7 @@ characters.data={ }, [0x1F4D7]={ category="so", + cjkwd="w", description="GREEN BOOK", direction="on", linebreak="id", @@ -215308,6 +226239,7 @@ characters.data={ }, [0x1F4D8]={ category="so", + cjkwd="w", description="BLUE BOOK", direction="on", linebreak="id", @@ -215315,6 +226247,7 @@ characters.data={ }, [0x1F4D9]={ category="so", + cjkwd="w", description="ORANGE BOOK", direction="on", linebreak="id", @@ -215322,6 +226255,7 @@ characters.data={ }, [0x1F4DA]={ category="so", + cjkwd="w", description="BOOKS", direction="on", linebreak="id", @@ -215329,6 +226263,7 @@ characters.data={ }, [0x1F4DB]={ category="so", + cjkwd="w", description="NAME BADGE", direction="on", linebreak="id", @@ -215336,6 +226271,7 @@ characters.data={ }, [0x1F4DC]={ category="so", + cjkwd="w", description="SCROLL", direction="on", linebreak="id", @@ -215343,6 +226279,7 @@ characters.data={ }, [0x1F4DD]={ category="so", + cjkwd="w", description="MEMO", direction="on", linebreak="id", @@ -215350,6 +226287,7 @@ characters.data={ }, [0x1F4DE]={ category="so", + cjkwd="w", description="TELEPHONE RECEIVER", direction="on", linebreak="id", @@ -215357,6 +226295,7 @@ characters.data={ }, [0x1F4DF]={ category="so", + cjkwd="w", description="PAGER", direction="on", linebreak="id", @@ -215364,6 +226303,7 @@ characters.data={ }, [0x1F4E0]={ category="so", + cjkwd="w", description="FAX MACHINE", direction="on", linebreak="id", @@ -215371,6 +226311,7 @@ characters.data={ }, [0x1F4E1]={ category="so", + cjkwd="w", description="SATELLITE ANTENNA", direction="on", linebreak="id", @@ -215378,6 +226319,7 @@ characters.data={ }, [0x1F4E2]={ category="so", + cjkwd="w", description="PUBLIC ADDRESS LOUDSPEAKER", direction="on", linebreak="id", @@ -215385,6 +226327,7 @@ characters.data={ }, [0x1F4E3]={ category="so", + cjkwd="w", description="CHEERING MEGAPHONE", direction="on", linebreak="id", @@ -215392,6 +226335,7 @@ characters.data={ }, [0x1F4E4]={ category="so", + cjkwd="w", description="OUTBOX TRAY", direction="on", linebreak="id", @@ -215399,6 +226343,7 @@ characters.data={ }, [0x1F4E5]={ category="so", + cjkwd="w", description="INBOX TRAY", direction="on", linebreak="id", @@ -215406,6 +226351,7 @@ characters.data={ }, [0x1F4E6]={ category="so", + cjkwd="w", description="PACKAGE", direction="on", linebreak="id", @@ -215413,6 +226359,7 @@ characters.data={ }, [0x1F4E7]={ category="so", + cjkwd="w", description="E-MAIL SYMBOL", direction="on", linebreak="id", @@ -215420,6 +226367,7 @@ characters.data={ }, [0x1F4E8]={ category="so", + cjkwd="w", description="INCOMING ENVELOPE", direction="on", linebreak="id", @@ -215427,6 +226375,7 @@ characters.data={ }, [0x1F4E9]={ category="so", + cjkwd="w", description="ENVELOPE WITH DOWNWARDS ARROW ABOVE", direction="on", linebreak="id", @@ -215434,6 +226383,7 @@ characters.data={ }, [0x1F4EA]={ category="so", + cjkwd="w", description="CLOSED MAILBOX WITH LOWERED FLAG", direction="on", linebreak="id", @@ -215441,6 +226391,7 @@ characters.data={ }, [0x1F4EB]={ category="so", + cjkwd="w", description="CLOSED MAILBOX WITH RAISED FLAG", direction="on", linebreak="id", @@ -215448,6 +226399,7 @@ characters.data={ }, [0x1F4EC]={ category="so", + cjkwd="w", description="OPEN MAILBOX WITH RAISED FLAG", direction="on", linebreak="id", @@ -215455,6 +226407,7 @@ characters.data={ }, [0x1F4ED]={ category="so", + cjkwd="w", description="OPEN MAILBOX WITH LOWERED FLAG", direction="on", linebreak="id", @@ -215462,6 +226415,7 @@ characters.data={ }, [0x1F4EE]={ category="so", + cjkwd="w", description="POSTBOX", direction="on", linebreak="id", @@ -215469,6 +226423,7 @@ characters.data={ }, [0x1F4EF]={ category="so", + cjkwd="w", description="POSTAL HORN", direction="on", linebreak="id", @@ -215476,6 +226431,7 @@ characters.data={ }, [0x1F4F0]={ category="so", + cjkwd="w", description="NEWSPAPER", direction="on", linebreak="id", @@ -215483,6 +226439,7 @@ characters.data={ }, [0x1F4F1]={ category="so", + cjkwd="w", description="MOBILE PHONE", direction="on", linebreak="id", @@ -215490,6 +226447,7 @@ characters.data={ }, [0x1F4F2]={ category="so", + cjkwd="w", description="MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT", direction="on", linebreak="id", @@ -215497,6 +226455,7 @@ characters.data={ }, [0x1F4F3]={ category="so", + cjkwd="w", description="VIBRATION MODE", direction="on", linebreak="id", @@ -215504,6 +226463,7 @@ characters.data={ }, [0x1F4F4]={ category="so", + cjkwd="w", description="MOBILE PHONE OFF", direction="on", linebreak="id", @@ -215511,6 +226471,7 @@ characters.data={ }, [0x1F4F5]={ category="so", + cjkwd="w", description="NO MOBILE PHONES", direction="on", linebreak="id", @@ -215518,6 +226479,7 @@ characters.data={ }, [0x1F4F6]={ category="so", + cjkwd="w", description="ANTENNA WITH BARS", direction="on", linebreak="id", @@ -215525,6 +226487,7 @@ characters.data={ }, [0x1F4F7]={ category="so", + cjkwd="w", description="CAMERA", direction="on", linebreak="id", @@ -215532,6 +226495,7 @@ characters.data={ }, [0x1F4F8]={ category="so", + cjkwd="w", description="CAMERA WITH FLASH", direction="on", linebreak="id", @@ -215539,6 +226503,7 @@ characters.data={ }, [0x1F4F9]={ category="so", + cjkwd="w", description="VIDEO CAMERA", direction="on", linebreak="id", @@ -215546,6 +226511,7 @@ characters.data={ }, [0x1F4FA]={ category="so", + cjkwd="w", description="TELEVISION", direction="on", linebreak="id", @@ -215553,6 +226519,7 @@ characters.data={ }, [0x1F4FB]={ category="so", + cjkwd="w", description="RADIO", direction="on", linebreak="id", @@ -215560,6 +226527,7 @@ characters.data={ }, [0x1F4FC]={ category="so", + cjkwd="w", description="VIDEOCASSETTE", direction="on", linebreak="id", @@ -215571,6 +226539,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F4FD, + variants=variants_emoji, }, [0x1F4FE]={ category="so", @@ -215581,6 +226550,7 @@ characters.data={ }, [0x1F4FF]={ category="so", + cjkwd="w", description="PRAYER BEADS", direction="on", linebreak="id", @@ -215588,6 +226558,7 @@ characters.data={ }, [0x1F500]={ category="so", + cjkwd="w", description="TWISTED RIGHTWARDS ARROWS", direction="on", linebreak="al", @@ -215595,6 +226566,7 @@ characters.data={ }, [0x1F501]={ category="so", + cjkwd="w", description="CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS", direction="on", linebreak="al", @@ -215602,6 +226574,7 @@ characters.data={ }, [0x1F502]={ category="so", + cjkwd="w", description="CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS WITH CIRCLED ONE OVERLAY", direction="on", linebreak="al", @@ -215609,6 +226582,7 @@ characters.data={ }, [0x1F503]={ category="so", + cjkwd="w", description="CLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS", direction="on", linebreak="al", @@ -215616,6 +226590,7 @@ characters.data={ }, [0x1F504]={ category="so", + cjkwd="w", description="ANTICLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS", direction="on", linebreak="al", @@ -215623,6 +226598,7 @@ characters.data={ }, [0x1F505]={ category="so", + cjkwd="w", description="LOW BRIGHTNESS SYMBOL", direction="on", linebreak="al", @@ -215630,6 +226606,7 @@ characters.data={ }, [0x1F506]={ category="so", + cjkwd="w", description="HIGH BRIGHTNESS SYMBOL", direction="on", linebreak="al", @@ -215637,6 +226614,7 @@ characters.data={ }, [0x1F507]={ category="so", + cjkwd="w", description="SPEAKER WITH CANCELLATION STROKE", direction="on", linebreak="id", @@ -215644,6 +226622,7 @@ characters.data={ }, [0x1F508]={ category="so", + cjkwd="w", description="SPEAKER", direction="on", linebreak="id", @@ -215651,6 +226630,7 @@ characters.data={ }, [0x1F509]={ category="so", + cjkwd="w", description="SPEAKER WITH ONE SOUND WAVE", direction="on", linebreak="id", @@ -215658,13 +226638,16 @@ characters.data={ }, [0x1F50A]={ category="so", + cjkwd="w", description="SPEAKER WITH THREE SOUND WAVES", direction="on", linebreak="id", + synonyms={ "sound" }, unicodeslot=0x1F50A, }, [0x1F50B]={ category="so", + cjkwd="w", description="BATTERY", direction="on", linebreak="id", @@ -215672,6 +226655,7 @@ characters.data={ }, [0x1F50C]={ category="so", + cjkwd="w", description="ELECTRIC PLUG", direction="on", linebreak="id", @@ -215679,6 +226663,7 @@ characters.data={ }, [0x1F50D]={ category="so", + cjkwd="w", description="LEFT-POINTING MAGNIFYING GLASS", direction="on", linebreak="id", @@ -215686,6 +226671,7 @@ characters.data={ }, [0x1F50E]={ category="so", + cjkwd="w", description="RIGHT-POINTING MAGNIFYING GLASS", direction="on", linebreak="id", @@ -215693,6 +226679,7 @@ characters.data={ }, [0x1F50F]={ category="so", + cjkwd="w", description="LOCK WITH INK PEN", direction="on", linebreak="id", @@ -215700,6 +226687,7 @@ characters.data={ }, [0x1F510]={ category="so", + cjkwd="w", description="CLOSED LOCK WITH KEY", direction="on", linebreak="id", @@ -215707,6 +226695,7 @@ characters.data={ }, [0x1F511]={ category="so", + cjkwd="w", description="KEY", direction="on", linebreak="id", @@ -215714,6 +226703,7 @@ characters.data={ }, [0x1F512]={ category="so", + cjkwd="w", description="LOCK", direction="on", linebreak="id", @@ -215721,6 +226711,7 @@ characters.data={ }, [0x1F513]={ category="so", + cjkwd="w", description="OPEN LOCK", direction="on", linebreak="id", @@ -215728,6 +226719,7 @@ characters.data={ }, [0x1F514]={ category="so", + cjkwd="w", description="BELL", direction="on", linebreak="id", @@ -215735,6 +226727,7 @@ characters.data={ }, [0x1F515]={ category="so", + cjkwd="w", description="BELL WITH CANCELLATION STROKE", direction="on", linebreak="id", @@ -215742,6 +226735,7 @@ characters.data={ }, [0x1F516]={ category="so", + cjkwd="w", description="BOOKMARK", direction="on", linebreak="id", @@ -215749,6 +226743,7 @@ characters.data={ }, [0x1F517]={ category="so", + cjkwd="w", description="LINK SYMBOL", direction="on", linebreak="al", @@ -215756,6 +226751,7 @@ characters.data={ }, [0x1F518]={ category="so", + cjkwd="w", description="RADIO BUTTON", direction="on", linebreak="al", @@ -215763,6 +226759,7 @@ characters.data={ }, [0x1F519]={ category="so", + cjkwd="w", description="BACK WITH LEFTWARDS ARROW ABOVE", direction="on", linebreak="al", @@ -215770,6 +226767,7 @@ characters.data={ }, [0x1F51A]={ category="so", + cjkwd="w", description="END WITH LEFTWARDS ARROW ABOVE", direction="on", linebreak="al", @@ -215777,6 +226775,7 @@ characters.data={ }, [0x1F51B]={ category="so", + cjkwd="w", description="ON WITH EXCLAMATION MARK WITH LEFT RIGHT ARROW ABOVE", direction="on", linebreak="al", @@ -215784,6 +226783,7 @@ characters.data={ }, [0x1F51C]={ category="so", + cjkwd="w", description="SOON WITH RIGHTWARDS ARROW ABOVE", direction="on", linebreak="al", @@ -215791,6 +226791,7 @@ characters.data={ }, [0x1F51D]={ category="so", + cjkwd="w", description="TOP WITH UPWARDS ARROW ABOVE", direction="on", linebreak="al", @@ -215798,6 +226799,7 @@ characters.data={ }, [0x1F51E]={ category="so", + cjkwd="w", description="NO ONE UNDER EIGHTEEN SYMBOL", direction="on", linebreak="al", @@ -215805,6 +226807,7 @@ characters.data={ }, [0x1F51F]={ category="so", + cjkwd="w", description="KEYCAP TEN", direction="on", linebreak="al", @@ -215812,6 +226815,7 @@ characters.data={ }, [0x1F520]={ category="so", + cjkwd="w", description="INPUT SYMBOL FOR LATIN CAPITAL LETTERS", direction="on", linebreak="al", @@ -215819,6 +226823,7 @@ characters.data={ }, [0x1F521]={ category="so", + cjkwd="w", description="INPUT SYMBOL FOR LATIN SMALL LETTERS", direction="on", linebreak="al", @@ -215826,6 +226831,7 @@ characters.data={ }, [0x1F522]={ category="so", + cjkwd="w", description="INPUT SYMBOL FOR NUMBERS", direction="on", linebreak="al", @@ -215833,6 +226839,7 @@ characters.data={ }, [0x1F523]={ category="so", + cjkwd="w", description="INPUT SYMBOL FOR SYMBOLS", direction="on", linebreak="al", @@ -215840,6 +226847,7 @@ characters.data={ }, [0x1F524]={ category="so", + cjkwd="w", description="INPUT SYMBOL FOR LATIN LETTERS", direction="on", linebreak="al", @@ -215847,6 +226855,7 @@ characters.data={ }, [0x1F525]={ category="so", + cjkwd="w", description="FIRE", direction="on", linebreak="id", @@ -215854,6 +226863,7 @@ characters.data={ }, [0x1F526]={ category="so", + cjkwd="w", description="ELECTRIC TORCH", direction="on", linebreak="id", @@ -215861,6 +226871,7 @@ characters.data={ }, [0x1F527]={ category="so", + cjkwd="w", description="WRENCH", direction="on", linebreak="id", @@ -215868,6 +226879,7 @@ characters.data={ }, [0x1F528]={ category="so", + cjkwd="w", description="HAMMER", direction="on", linebreak="id", @@ -215875,6 +226887,7 @@ characters.data={ }, [0x1F529]={ category="so", + cjkwd="w", description="NUT AND BOLT", direction="on", linebreak="id", @@ -215882,6 +226895,7 @@ characters.data={ }, [0x1F52A]={ category="so", + cjkwd="w", description="HOCHO", direction="on", linebreak="id", @@ -215889,6 +226903,7 @@ characters.data={ }, [0x1F52B]={ category="so", + cjkwd="w", description="PISTOL", direction="on", linebreak="id", @@ -215896,6 +226911,7 @@ characters.data={ }, [0x1F52C]={ category="so", + cjkwd="w", description="MICROSCOPE", direction="on", linebreak="id", @@ -215903,6 +226919,7 @@ characters.data={ }, [0x1F52D]={ category="so", + cjkwd="w", description="TELESCOPE", direction="on", linebreak="id", @@ -215910,6 +226927,7 @@ characters.data={ }, [0x1F52E]={ category="so", + cjkwd="w", description="CRYSTAL BALL", direction="on", linebreak="id", @@ -215917,6 +226935,7 @@ characters.data={ }, [0x1F52F]={ category="so", + cjkwd="w", description="SIX POINTED STAR WITH MIDDLE DOT", direction="on", linebreak="id", @@ -215924,6 +226943,7 @@ characters.data={ }, [0x1F530]={ category="so", + cjkwd="w", description="JAPANESE SYMBOL FOR BEGINNER", direction="on", linebreak="id", @@ -215931,6 +226951,7 @@ characters.data={ }, [0x1F531]={ category="so", + cjkwd="w", description="TRIDENT EMBLEM", direction="on", linebreak="id", @@ -215938,6 +226959,7 @@ characters.data={ }, [0x1F532]={ category="so", + cjkwd="w", description="BLACK SQUARE BUTTON", direction="on", linebreak="al", @@ -215945,6 +226967,7 @@ characters.data={ }, [0x1F533]={ category="so", + cjkwd="w", description="WHITE SQUARE BUTTON", direction="on", linebreak="al", @@ -215952,6 +226975,7 @@ characters.data={ }, [0x1F534]={ category="so", + cjkwd="w", description="LARGE RED CIRCLE", direction="on", linebreak="al", @@ -215959,6 +226983,7 @@ characters.data={ }, [0x1F535]={ category="so", + cjkwd="w", description="LARGE BLUE CIRCLE", direction="on", linebreak="al", @@ -215966,6 +226991,7 @@ characters.data={ }, [0x1F536]={ category="so", + cjkwd="w", description="LARGE ORANGE DIAMOND", direction="on", linebreak="al", @@ -215973,6 +226999,7 @@ characters.data={ }, [0x1F537]={ category="so", + cjkwd="w", description="LARGE BLUE DIAMOND", direction="on", linebreak="al", @@ -215980,6 +227007,7 @@ characters.data={ }, [0x1F538]={ category="so", + cjkwd="w", description="SMALL ORANGE DIAMOND", direction="on", linebreak="al", @@ -215987,6 +227015,7 @@ characters.data={ }, [0x1F539]={ category="so", + cjkwd="w", description="SMALL BLUE DIAMOND", direction="on", linebreak="al", @@ -215994,6 +227023,7 @@ characters.data={ }, [0x1F53A]={ category="so", + cjkwd="w", description="UP-POINTING RED TRIANGLE", direction="on", linebreak="al", @@ -216001,6 +227031,7 @@ characters.data={ }, [0x1F53B]={ category="so", + cjkwd="w", description="DOWN-POINTING RED TRIANGLE", direction="on", linebreak="al", @@ -216008,6 +227039,7 @@ characters.data={ }, [0x1F53C]={ category="so", + cjkwd="w", description="UP-POINTING SMALL RED TRIANGLE", direction="on", linebreak="al", @@ -216015,6 +227047,7 @@ characters.data={ }, [0x1F53D]={ category="so", + cjkwd="w", description="DOWN-POINTING SMALL RED TRIANGLE", direction="on", linebreak="al", @@ -216103,6 +227136,7 @@ characters.data={ direction="on", linebreak="al", unicodeslot=0x1F549, + variants=variants_emoji, }, [0x1F54A]={ category="so", @@ -216110,9 +227144,11 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F54A, + variants=variants_emoji, }, [0x1F54B]={ category="so", + cjkwd="w", description="KAABA", direction="on", linebreak="id", @@ -216120,6 +227156,7 @@ characters.data={ }, [0x1F54C]={ category="so", + cjkwd="w", description="MOSQUE", direction="on", linebreak="id", @@ -216127,6 +227164,7 @@ characters.data={ }, [0x1F54D]={ category="so", + cjkwd="w", description="SYNAGOGUE", direction="on", linebreak="id", @@ -216134,6 +227172,7 @@ characters.data={ }, [0x1F54E]={ category="so", + cjkwd="w", description="MENORAH WITH NINE BRANCHES", direction="on", linebreak="id", @@ -216148,6 +227187,7 @@ characters.data={ }, [0x1F550]={ category="so", + cjkwd="w", description="CLOCK FACE ONE OCLOCK", direction="on", linebreak="id", @@ -216155,6 +227195,7 @@ characters.data={ }, [0x1F551]={ category="so", + cjkwd="w", description="CLOCK FACE TWO OCLOCK", direction="on", linebreak="id", @@ -216162,6 +227203,7 @@ characters.data={ }, [0x1F552]={ category="so", + cjkwd="w", description="CLOCK FACE THREE OCLOCK", direction="on", linebreak="id", @@ -216169,6 +227211,7 @@ characters.data={ }, [0x1F553]={ category="so", + cjkwd="w", description="CLOCK FACE FOUR OCLOCK", direction="on", linebreak="id", @@ -216176,6 +227219,7 @@ characters.data={ }, [0x1F554]={ category="so", + cjkwd="w", description="CLOCK FACE FIVE OCLOCK", direction="on", linebreak="id", @@ -216183,6 +227227,7 @@ characters.data={ }, [0x1F555]={ category="so", + cjkwd="w", description="CLOCK FACE SIX OCLOCK", direction="on", linebreak="id", @@ -216190,6 +227235,7 @@ characters.data={ }, [0x1F556]={ category="so", + cjkwd="w", description="CLOCK FACE SEVEN OCLOCK", direction="on", linebreak="id", @@ -216197,6 +227243,7 @@ characters.data={ }, [0x1F557]={ category="so", + cjkwd="w", description="CLOCK FACE EIGHT OCLOCK", direction="on", linebreak="id", @@ -216204,6 +227251,7 @@ characters.data={ }, [0x1F558]={ category="so", + cjkwd="w", description="CLOCK FACE NINE OCLOCK", direction="on", linebreak="id", @@ -216211,6 +227259,7 @@ characters.data={ }, [0x1F559]={ category="so", + cjkwd="w", description="CLOCK FACE TEN OCLOCK", direction="on", linebreak="id", @@ -216218,6 +227267,7 @@ characters.data={ }, [0x1F55A]={ category="so", + cjkwd="w", description="CLOCK FACE ELEVEN OCLOCK", direction="on", linebreak="id", @@ -216225,6 +227275,7 @@ characters.data={ }, [0x1F55B]={ category="so", + cjkwd="w", description="CLOCK FACE TWELVE OCLOCK", direction="on", linebreak="id", @@ -216232,6 +227283,7 @@ characters.data={ }, [0x1F55C]={ category="so", + cjkwd="w", description="CLOCK FACE ONE-THIRTY", direction="on", linebreak="id", @@ -216239,6 +227291,7 @@ characters.data={ }, [0x1F55D]={ category="so", + cjkwd="w", description="CLOCK FACE TWO-THIRTY", direction="on", linebreak="id", @@ -216246,6 +227299,7 @@ characters.data={ }, [0x1F55E]={ category="so", + cjkwd="w", description="CLOCK FACE THREE-THIRTY", direction="on", linebreak="id", @@ -216253,6 +227307,7 @@ characters.data={ }, [0x1F55F]={ category="so", + cjkwd="w", description="CLOCK FACE FOUR-THIRTY", direction="on", linebreak="id", @@ -216260,6 +227315,7 @@ characters.data={ }, [0x1F560]={ category="so", + cjkwd="w", description="CLOCK FACE FIVE-THIRTY", direction="on", linebreak="id", @@ -216267,6 +227323,7 @@ characters.data={ }, [0x1F561]={ category="so", + cjkwd="w", description="CLOCK FACE SIX-THIRTY", direction="on", linebreak="id", @@ -216274,6 +227331,7 @@ characters.data={ }, [0x1F562]={ category="so", + cjkwd="w", description="CLOCK FACE SEVEN-THIRTY", direction="on", linebreak="id", @@ -216281,6 +227339,7 @@ characters.data={ }, [0x1F563]={ category="so", + cjkwd="w", description="CLOCK FACE EIGHT-THIRTY", direction="on", linebreak="id", @@ -216288,6 +227347,7 @@ characters.data={ }, [0x1F564]={ category="so", + cjkwd="w", description="CLOCK FACE NINE-THIRTY", direction="on", linebreak="id", @@ -216295,6 +227355,7 @@ characters.data={ }, [0x1F565]={ category="so", + cjkwd="w", description="CLOCK FACE TEN-THIRTY", direction="on", linebreak="id", @@ -216302,6 +227363,7 @@ characters.data={ }, [0x1F566]={ category="so", + cjkwd="w", description="CLOCK FACE ELEVEN-THIRTY", direction="on", linebreak="id", @@ -216309,6 +227371,7 @@ characters.data={ }, [0x1F567]={ category="so", + cjkwd="w", description="CLOCK FACE TWELVE-THIRTY", direction="on", linebreak="id", @@ -216369,6 +227432,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F56F, + variants=variants_emoji, }, [0x1F570]={ category="so", @@ -216376,6 +227440,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F570, + variants=variants_emoji, }, [0x1F571]={ category="so", @@ -216397,6 +227462,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F573, + variants=variants_emoji, }, [0x1F574]={ category="so", @@ -216404,13 +227470,15 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F574, + variants=variants_emoji, }, [0x1F575]={ category="so", description="SLEUTH OR SPY", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F575, + variants=variants_emoji, }, [0x1F576]={ category="so", @@ -216418,6 +227486,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F576, + variants=variants_emoji, }, [0x1F577]={ category="so", @@ -216425,6 +227494,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F577, + variants=variants_emoji, }, [0x1F578]={ category="so", @@ -216432,6 +227502,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F578, + variants=variants_emoji, }, [0x1F579]={ category="so", @@ -216439,6 +227510,15 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F579, + variants=variants_emoji, + }, + [0x1F57A]={ + category="so", + cjkwd="w", + description="MAN DANCING", + direction="on", + linebreak="eb", + unicodeslot=0x1F57A, }, [0x1F57B]={ category="so", @@ -216459,6 +227539,7 @@ characters.data={ description="RIGHT HAND TELEPHONE RECEIVER", direction="on", linebreak="id", + synonyms={ "telephone handset" }, unicodeslot=0x1F57D, }, [0x1F57E]={ @@ -216530,6 +227611,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F587, + variants=variants_emoji, }, [0x1F588]={ category="so", @@ -216551,6 +227633,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F58A, + variants=variants_emoji, }, [0x1F58B]={ category="so", @@ -216558,6 +227641,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F58B, + variants=variants_emoji, }, [0x1F58C]={ category="so", @@ -216565,6 +227649,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F58C, + variants=variants_emoji, }, [0x1F58D]={ category="so", @@ -216572,6 +227657,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F58D, + variants=variants_emoji, }, [0x1F58E]={ category="so", @@ -216591,8 +227677,9 @@ characters.data={ category="so", description="RAISED HAND WITH FINGERS SPLAYED", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F590, + variants=variants_emoji, }, [0x1F591]={ category="so", @@ -216624,16 +227711,18 @@ characters.data={ }, [0x1F595]={ category="so", + cjkwd="w", description="REVERSED HAND WITH MIDDLE FINGER EXTENDED", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F595, }, [0x1F596]={ category="so", + cjkwd="w", description="RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F596, }, [0x1F597]={ @@ -216727,12 +227816,21 @@ characters.data={ linebreak="id", unicodeslot=0x1F5A3, }, + [0x1F5A4]={ + category="so", + cjkwd="w", + description="BLACK HEART", + direction="on", + linebreak="id", + unicodeslot=0x1F5A4, + }, [0x1F5A5]={ category="so", description="DESKTOP COMPUTER", direction="on", linebreak="id", unicodeslot=0x1F5A5, + variants=variants_emoji, }, [0x1F5A6]={ category="so", @@ -216754,6 +227852,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5A8, + variants=variants_emoji, }, [0x1F5A9]={ category="so", @@ -216817,6 +227916,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5B1, + variants=variants_emoji, }, [0x1F5B2]={ category="so", @@ -216824,6 +227924,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5B2, + variants=variants_emoji, }, [0x1F5B3]={ category="so", @@ -216894,6 +227995,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5BC, + variants=variants_emoji, }, [0x1F5BD]={ category="so", @@ -216936,6 +228038,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5C2, + variants=variants_emoji, }, [0x1F5C3]={ category="so", @@ -216943,6 +228046,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5C3, + variants=variants_emoji, }, [0x1F5C4]={ category="so", @@ -216950,6 +228054,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5C4, + variants=variants_emoji, }, [0x1F5C5]={ category="so", @@ -217040,7 +228145,9 @@ characters.data={ description="WASTEBASKET", direction="on", linebreak="id", + synonyms={ "trashcan" }, unicodeslot=0x1F5D1, + variants=variants_emoji, }, [0x1F5D2]={ category="so", @@ -217048,6 +228155,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5D2, + variants=variants_emoji, }, [0x1F5D3]={ category="so", @@ -217055,6 +228163,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5D3, + variants=variants_emoji, }, [0x1F5D4]={ category="so", @@ -217118,6 +228227,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5DC, + variants=variants_emoji, }, [0x1F5DD]={ category="so", @@ -217125,6 +228235,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5DD, + variants=variants_emoji, }, [0x1F5DE]={ category="so", @@ -217132,6 +228243,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5DE, + variants=variants_emoji, }, [0x1F5DF]={ category="so", @@ -217153,6 +228265,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5E1, + variants=variants_emoji, }, [0x1F5E2]={ category="so", @@ -217167,6 +228280,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5E3, + variants=variants_emoji, }, [0x1F5E4]={ category="so", @@ -217202,6 +228316,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5E8, + variants=variants_emoji, }, [0x1F5E9]={ category="so", @@ -217251,6 +228366,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5EF, + variants=variants_emoji, }, [0x1F5F0]={ category="so", @@ -217271,6 +228387,7 @@ characters.data={ description="LIGHTNING MOOD", direction="on", linebreak="id", + synonyms={ "lightning bolt" }, unicodeslot=0x1F5F2, }, [0x1F5F3]={ @@ -217279,6 +228396,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5F3, + variants=variants_emoji, }, [0x1F5F4]={ category="so", @@ -217328,9 +228446,11 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F5FA, + variants=variants_emoji, }, [0x1F5FB]={ category="so", + cjkwd="w", description="MOUNT FUJI", direction="on", linebreak="id", @@ -217338,6 +228458,7 @@ characters.data={ }, [0x1F5FC]={ category="so", + cjkwd="w", description="TOKYO TOWER", direction="on", linebreak="id", @@ -217345,6 +228466,7 @@ characters.data={ }, [0x1F5FD]={ category="so", + cjkwd="w", description="STATUE OF LIBERTY", direction="on", linebreak="id", @@ -217352,6 +228474,7 @@ characters.data={ }, [0x1F5FE]={ category="so", + cjkwd="w", description="SILHOUETTE OF JAPAN", direction="on", linebreak="id", @@ -217359,6 +228482,7 @@ characters.data={ }, [0x1F5FF]={ category="so", + cjkwd="w", description="MOYAI", direction="on", linebreak="id", @@ -217366,6 +228490,7 @@ characters.data={ }, [0x1F600]={ category="so", + cjkwd="w", description="GRINNING FACE", direction="on", linebreak="id", @@ -217373,6 +228498,7 @@ characters.data={ }, [0x1F601]={ category="so", + cjkwd="w", description="GRINNING FACE WITH SMILING EYES", direction="on", linebreak="id", @@ -217380,6 +228506,7 @@ characters.data={ }, [0x1F602]={ category="so", + cjkwd="w", description="FACE WITH TEARS OF JOY", direction="on", linebreak="id", @@ -217387,6 +228514,7 @@ characters.data={ }, [0x1F603]={ category="so", + cjkwd="w", description="SMILING FACE WITH OPEN MOUTH", direction="on", linebreak="id", @@ -217394,6 +228522,7 @@ characters.data={ }, [0x1F604]={ category="so", + cjkwd="w", description="SMILING FACE WITH OPEN MOUTH AND SMILING EYES", direction="on", linebreak="id", @@ -217401,6 +228530,7 @@ characters.data={ }, [0x1F605]={ category="so", + cjkwd="w", description="SMILING FACE WITH OPEN MOUTH AND COLD SWEAT", direction="on", linebreak="id", @@ -217408,6 +228538,7 @@ characters.data={ }, [0x1F606]={ category="so", + cjkwd="w", description="SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES", direction="on", linebreak="id", @@ -217415,6 +228546,7 @@ characters.data={ }, [0x1F607]={ category="so", + cjkwd="w", description="SMILING FACE WITH HALO", direction="on", linebreak="id", @@ -217422,6 +228554,7 @@ characters.data={ }, [0x1F608]={ category="so", + cjkwd="w", description="SMILING FACE WITH HORNS", direction="on", linebreak="id", @@ -217429,6 +228562,7 @@ characters.data={ }, [0x1F609]={ category="so", + cjkwd="w", description="WINKING FACE", direction="on", linebreak="id", @@ -217436,6 +228570,7 @@ characters.data={ }, [0x1F60A]={ category="so", + cjkwd="w", description="SMILING FACE WITH SMILING EYES", direction="on", linebreak="id", @@ -217443,6 +228578,7 @@ characters.data={ }, [0x1F60B]={ category="so", + cjkwd="w", description="FACE SAVOURING DELICIOUS FOOD", direction="on", linebreak="id", @@ -217450,6 +228586,7 @@ characters.data={ }, [0x1F60C]={ category="so", + cjkwd="w", description="RELIEVED FACE", direction="on", linebreak="id", @@ -217457,6 +228594,7 @@ characters.data={ }, [0x1F60D]={ category="so", + cjkwd="w", description="SMILING FACE WITH HEART-SHAPED EYES", direction="on", linebreak="id", @@ -217464,6 +228602,7 @@ characters.data={ }, [0x1F60E]={ category="so", + cjkwd="w", description="SMILING FACE WITH SUNGLASSES", direction="on", linebreak="id", @@ -217471,6 +228610,7 @@ characters.data={ }, [0x1F60F]={ category="so", + cjkwd="w", description="SMIRKING FACE", direction="on", linebreak="id", @@ -217478,6 +228618,7 @@ characters.data={ }, [0x1F610]={ category="so", + cjkwd="w", description="NEUTRAL FACE", direction="on", linebreak="id", @@ -217485,6 +228626,7 @@ characters.data={ }, [0x1F611]={ category="so", + cjkwd="w", description="EXPRESSIONLESS FACE", direction="on", linebreak="id", @@ -217492,6 +228634,7 @@ characters.data={ }, [0x1F612]={ category="so", + cjkwd="w", description="UNAMUSED FACE", direction="on", linebreak="id", @@ -217499,6 +228642,7 @@ characters.data={ }, [0x1F613]={ category="so", + cjkwd="w", description="FACE WITH COLD SWEAT", direction="on", linebreak="id", @@ -217506,6 +228650,7 @@ characters.data={ }, [0x1F614]={ category="so", + cjkwd="w", description="PENSIVE FACE", direction="on", linebreak="id", @@ -217513,6 +228658,7 @@ characters.data={ }, [0x1F615]={ category="so", + cjkwd="w", description="CONFUSED FACE", direction="on", linebreak="id", @@ -217520,6 +228666,7 @@ characters.data={ }, [0x1F616]={ category="so", + cjkwd="w", description="CONFOUNDED FACE", direction="on", linebreak="id", @@ -217527,6 +228674,7 @@ characters.data={ }, [0x1F617]={ category="so", + cjkwd="w", description="KISSING FACE", direction="on", linebreak="id", @@ -217534,6 +228682,7 @@ characters.data={ }, [0x1F618]={ category="so", + cjkwd="w", description="FACE THROWING A KISS", direction="on", linebreak="id", @@ -217541,6 +228690,7 @@ characters.data={ }, [0x1F619]={ category="so", + cjkwd="w", description="KISSING FACE WITH SMILING EYES", direction="on", linebreak="id", @@ -217548,6 +228698,7 @@ characters.data={ }, [0x1F61A]={ category="so", + cjkwd="w", description="KISSING FACE WITH CLOSED EYES", direction="on", linebreak="id", @@ -217555,6 +228706,7 @@ characters.data={ }, [0x1F61B]={ category="so", + cjkwd="w", description="FACE WITH STUCK-OUT TONGUE", direction="on", linebreak="id", @@ -217562,6 +228714,7 @@ characters.data={ }, [0x1F61C]={ category="so", + cjkwd="w", description="FACE WITH STUCK-OUT TONGUE AND WINKING EYE", direction="on", linebreak="id", @@ -217569,6 +228722,7 @@ characters.data={ }, [0x1F61D]={ category="so", + cjkwd="w", description="FACE WITH STUCK-OUT TONGUE AND TIGHTLY-CLOSED EYES", direction="on", linebreak="id", @@ -217576,6 +228730,7 @@ characters.data={ }, [0x1F61E]={ category="so", + cjkwd="w", description="DISAPPOINTED FACE", direction="on", linebreak="id", @@ -217583,6 +228738,7 @@ characters.data={ }, [0x1F61F]={ category="so", + cjkwd="w", description="WORRIED FACE", direction="on", linebreak="id", @@ -217590,6 +228746,7 @@ characters.data={ }, [0x1F620]={ category="so", + cjkwd="w", description="ANGRY FACE", direction="on", linebreak="id", @@ -217597,6 +228754,7 @@ characters.data={ }, [0x1F621]={ category="so", + cjkwd="w", description="POUTING FACE", direction="on", linebreak="id", @@ -217604,6 +228762,7 @@ characters.data={ }, [0x1F622]={ category="so", + cjkwd="w", description="CRYING FACE", direction="on", linebreak="id", @@ -217611,6 +228770,7 @@ characters.data={ }, [0x1F623]={ category="so", + cjkwd="w", description="PERSEVERING FACE", direction="on", linebreak="id", @@ -217618,6 +228778,7 @@ characters.data={ }, [0x1F624]={ category="so", + cjkwd="w", description="FACE WITH LOOK OF TRIUMPH", direction="on", linebreak="id", @@ -217625,6 +228786,7 @@ characters.data={ }, [0x1F625]={ category="so", + cjkwd="w", description="DISAPPOINTED BUT RELIEVED FACE", direction="on", linebreak="id", @@ -217632,6 +228794,7 @@ characters.data={ }, [0x1F626]={ category="so", + cjkwd="w", description="FROWNING FACE WITH OPEN MOUTH", direction="on", linebreak="id", @@ -217639,6 +228802,7 @@ characters.data={ }, [0x1F627]={ category="so", + cjkwd="w", description="ANGUISHED FACE", direction="on", linebreak="id", @@ -217646,6 +228810,7 @@ characters.data={ }, [0x1F628]={ category="so", + cjkwd="w", description="FEARFUL FACE", direction="on", linebreak="id", @@ -217653,6 +228818,7 @@ characters.data={ }, [0x1F629]={ category="so", + cjkwd="w", description="WEARY FACE", direction="on", linebreak="id", @@ -217660,6 +228826,7 @@ characters.data={ }, [0x1F62A]={ category="so", + cjkwd="w", description="SLEEPY FACE", direction="on", linebreak="id", @@ -217667,6 +228834,7 @@ characters.data={ }, [0x1F62B]={ category="so", + cjkwd="w", description="TIRED FACE", direction="on", linebreak="id", @@ -217674,6 +228842,7 @@ characters.data={ }, [0x1F62C]={ category="so", + cjkwd="w", description="GRIMACING FACE", direction="on", linebreak="id", @@ -217681,6 +228850,7 @@ characters.data={ }, [0x1F62D]={ category="so", + cjkwd="w", description="LOUDLY CRYING FACE", direction="on", linebreak="id", @@ -217688,6 +228858,7 @@ characters.data={ }, [0x1F62E]={ category="so", + cjkwd="w", description="FACE WITH OPEN MOUTH", direction="on", linebreak="id", @@ -217695,6 +228866,7 @@ characters.data={ }, [0x1F62F]={ category="so", + cjkwd="w", description="HUSHED FACE", direction="on", linebreak="id", @@ -217702,6 +228874,7 @@ characters.data={ }, [0x1F630]={ category="so", + cjkwd="w", description="FACE WITH OPEN MOUTH AND COLD SWEAT", direction="on", linebreak="id", @@ -217709,6 +228882,7 @@ characters.data={ }, [0x1F631]={ category="so", + cjkwd="w", description="FACE SCREAMING IN FEAR", direction="on", linebreak="id", @@ -217716,6 +228890,7 @@ characters.data={ }, [0x1F632]={ category="so", + cjkwd="w", description="ASTONISHED FACE", direction="on", linebreak="id", @@ -217723,6 +228898,7 @@ characters.data={ }, [0x1F633]={ category="so", + cjkwd="w", description="FLUSHED FACE", direction="on", linebreak="id", @@ -217730,6 +228906,7 @@ characters.data={ }, [0x1F634]={ category="so", + cjkwd="w", description="SLEEPING FACE", direction="on", linebreak="id", @@ -217737,6 +228914,7 @@ characters.data={ }, [0x1F635]={ category="so", + cjkwd="w", description="DIZZY FACE", direction="on", linebreak="id", @@ -217744,6 +228922,7 @@ characters.data={ }, [0x1F636]={ category="so", + cjkwd="w", description="FACE WITHOUT MOUTH", direction="on", linebreak="id", @@ -217751,6 +228930,7 @@ characters.data={ }, [0x1F637]={ category="so", + cjkwd="w", description="FACE WITH MEDICAL MASK", direction="on", linebreak="id", @@ -217758,6 +228938,7 @@ characters.data={ }, [0x1F638]={ category="so", + cjkwd="w", description="GRINNING CAT FACE WITH SMILING EYES", direction="on", linebreak="id", @@ -217765,6 +228946,7 @@ characters.data={ }, [0x1F639]={ category="so", + cjkwd="w", description="CAT FACE WITH TEARS OF JOY", direction="on", linebreak="id", @@ -217772,6 +228954,7 @@ characters.data={ }, [0x1F63A]={ category="so", + cjkwd="w", description="SMILING CAT FACE WITH OPEN MOUTH", direction="on", linebreak="id", @@ -217779,6 +228962,7 @@ characters.data={ }, [0x1F63B]={ category="so", + cjkwd="w", description="SMILING CAT FACE WITH HEART-SHAPED EYES", direction="on", linebreak="id", @@ -217786,6 +228970,7 @@ characters.data={ }, [0x1F63C]={ category="so", + cjkwd="w", description="CAT FACE WITH WRY SMILE", direction="on", linebreak="id", @@ -217793,6 +228978,7 @@ characters.data={ }, [0x1F63D]={ category="so", + cjkwd="w", description="KISSING CAT FACE WITH CLOSED EYES", direction="on", linebreak="id", @@ -217800,6 +228986,7 @@ characters.data={ }, [0x1F63E]={ category="so", + cjkwd="w", description="POUTING CAT FACE", direction="on", linebreak="id", @@ -217807,6 +228994,7 @@ characters.data={ }, [0x1F63F]={ category="so", + cjkwd="w", description="CRYING CAT FACE", direction="on", linebreak="id", @@ -217814,6 +229002,7 @@ characters.data={ }, [0x1F640]={ category="so", + cjkwd="w", description="WEARY CAT FACE", direction="on", linebreak="id", @@ -217821,6 +229010,7 @@ characters.data={ }, [0x1F641]={ category="so", + cjkwd="w", description="SLIGHTLY FROWNING FACE", direction="on", linebreak="id", @@ -217828,6 +229018,7 @@ characters.data={ }, [0x1F642]={ category="so", + cjkwd="w", description="SLIGHTLY SMILING FACE", direction="on", linebreak="id", @@ -217835,6 +229026,7 @@ characters.data={ }, [0x1F643]={ category="so", + cjkwd="w", description="UPSIDE-DOWN FACE", direction="on", linebreak="id", @@ -217842,6 +229034,7 @@ characters.data={ }, [0x1F644]={ category="so", + cjkwd="w", description="FACE WITH ROLLING EYES", direction="on", linebreak="id", @@ -217849,27 +229042,31 @@ characters.data={ }, [0x1F645]={ category="so", + cjkwd="w", description="FACE WITH NO GOOD GESTURE", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F645, }, [0x1F646]={ category="so", + cjkwd="w", description="FACE WITH OK GESTURE", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F646, }, [0x1F647]={ category="so", + cjkwd="w", description="PERSON BOWING DEEPLY", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F647, }, [0x1F648]={ category="so", + cjkwd="w", description="SEE-NO-EVIL MONKEY", direction="on", linebreak="id", @@ -217877,6 +229074,7 @@ characters.data={ }, [0x1F649]={ category="so", + cjkwd="w", description="HEAR-NO-EVIL MONKEY", direction="on", linebreak="id", @@ -217884,6 +229082,7 @@ characters.data={ }, [0x1F64A]={ category="so", + cjkwd="w", description="SPEAK-NO-EVIL MONKEY", direction="on", linebreak="id", @@ -217891,37 +229090,42 @@ characters.data={ }, [0x1F64B]={ category="so", + cjkwd="w", description="HAPPY PERSON RAISING ONE HAND", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F64B, }, [0x1F64C]={ category="so", + cjkwd="w", description="PERSON RAISING BOTH HANDS IN CELEBRATION", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F64C, }, [0x1F64D]={ category="so", + cjkwd="w", description="PERSON FROWNING", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F64D, }, [0x1F64E]={ category="so", + cjkwd="w", description="PERSON WITH POUTING FACE", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F64E, }, [0x1F64F]={ category="so", + cjkwd="w", description="PERSON WITH FOLDED HANDS", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F64F, }, [0x1F650]={ @@ -218262,6 +229466,7 @@ characters.data={ }, [0x1F680]={ category="so", + cjkwd="w", description="ROCKET", direction="on", linebreak="id", @@ -218269,6 +229474,7 @@ characters.data={ }, [0x1F681]={ category="so", + cjkwd="w", description="HELICOPTER", direction="on", linebreak="id", @@ -218276,6 +229482,7 @@ characters.data={ }, [0x1F682]={ category="so", + cjkwd="w", description="STEAM LOCOMOTIVE", direction="on", linebreak="id", @@ -218283,6 +229490,7 @@ characters.data={ }, [0x1F683]={ category="so", + cjkwd="w", description="RAILWAY CAR", direction="on", linebreak="id", @@ -218290,6 +229498,7 @@ characters.data={ }, [0x1F684]={ category="so", + cjkwd="w", description="HIGH-SPEED TRAIN", direction="on", linebreak="id", @@ -218297,6 +229506,7 @@ characters.data={ }, [0x1F685]={ category="so", + cjkwd="w", description="HIGH-SPEED TRAIN WITH BULLET NOSE", direction="on", linebreak="id", @@ -218304,6 +229514,7 @@ characters.data={ }, [0x1F686]={ category="so", + cjkwd="w", description="TRAIN", direction="on", linebreak="id", @@ -218311,6 +229522,7 @@ characters.data={ }, [0x1F687]={ category="so", + cjkwd="w", description="METRO", direction="on", linebreak="id", @@ -218318,6 +229530,7 @@ characters.data={ }, [0x1F688]={ category="so", + cjkwd="w", description="LIGHT RAIL", direction="on", linebreak="id", @@ -218325,6 +229538,7 @@ characters.data={ }, [0x1F689]={ category="so", + cjkwd="w", description="STATION", direction="on", linebreak="id", @@ -218332,6 +229546,7 @@ characters.data={ }, [0x1F68A]={ category="so", + cjkwd="w", description="TRAM", direction="on", linebreak="id", @@ -218339,6 +229554,7 @@ characters.data={ }, [0x1F68B]={ category="so", + cjkwd="w", description="TRAM CAR", direction="on", linebreak="id", @@ -218346,6 +229562,7 @@ characters.data={ }, [0x1F68C]={ category="so", + cjkwd="w", description="BUS", direction="on", linebreak="id", @@ -218353,6 +229570,7 @@ characters.data={ }, [0x1F68D]={ category="so", + cjkwd="w", description="ONCOMING BUS", direction="on", linebreak="id", @@ -218360,6 +229578,7 @@ characters.data={ }, [0x1F68E]={ category="so", + cjkwd="w", description="TROLLEYBUS", direction="on", linebreak="id", @@ -218367,6 +229586,7 @@ characters.data={ }, [0x1F68F]={ category="so", + cjkwd="w", description="BUS STOP", direction="on", linebreak="id", @@ -218374,6 +229594,7 @@ characters.data={ }, [0x1F690]={ category="so", + cjkwd="w", description="MINIBUS", direction="on", linebreak="id", @@ -218381,6 +229602,7 @@ characters.data={ }, [0x1F691]={ category="so", + cjkwd="w", description="AMBULANCE", direction="on", linebreak="id", @@ -218388,6 +229610,7 @@ characters.data={ }, [0x1F692]={ category="so", + cjkwd="w", description="FIRE ENGINE", direction="on", linebreak="id", @@ -218395,6 +229618,7 @@ characters.data={ }, [0x1F693]={ category="so", + cjkwd="w", description="POLICE CAR", direction="on", linebreak="id", @@ -218402,6 +229626,7 @@ characters.data={ }, [0x1F694]={ category="so", + cjkwd="w", description="ONCOMING POLICE CAR", direction="on", linebreak="id", @@ -218409,6 +229634,7 @@ characters.data={ }, [0x1F695]={ category="so", + cjkwd="w", description="TAXI", direction="on", linebreak="id", @@ -218416,6 +229642,7 @@ characters.data={ }, [0x1F696]={ category="so", + cjkwd="w", description="ONCOMING TAXI", direction="on", linebreak="id", @@ -218423,6 +229650,7 @@ characters.data={ }, [0x1F697]={ category="so", + cjkwd="w", description="AUTOMOBILE", direction="on", linebreak="id", @@ -218430,6 +229658,7 @@ characters.data={ }, [0x1F698]={ category="so", + cjkwd="w", description="ONCOMING AUTOMOBILE", direction="on", linebreak="id", @@ -218437,6 +229666,7 @@ characters.data={ }, [0x1F699]={ category="so", + cjkwd="w", description="RECREATIONAL VEHICLE", direction="on", linebreak="id", @@ -218444,6 +229674,7 @@ characters.data={ }, [0x1F69A]={ category="so", + cjkwd="w", description="DELIVERY TRUCK", direction="on", linebreak="id", @@ -218451,6 +229682,7 @@ characters.data={ }, [0x1F69B]={ category="so", + cjkwd="w", description="ARTICULATED LORRY", direction="on", linebreak="id", @@ -218458,6 +229690,7 @@ characters.data={ }, [0x1F69C]={ category="so", + cjkwd="w", description="TRACTOR", direction="on", linebreak="id", @@ -218465,6 +229698,7 @@ characters.data={ }, [0x1F69D]={ category="so", + cjkwd="w", description="MONORAIL", direction="on", linebreak="id", @@ -218472,6 +229706,7 @@ characters.data={ }, [0x1F69E]={ category="so", + cjkwd="w", description="MOUNTAIN RAILWAY", direction="on", linebreak="id", @@ -218479,6 +229714,7 @@ characters.data={ }, [0x1F69F]={ category="so", + cjkwd="w", description="SUSPENSION RAILWAY", direction="on", linebreak="id", @@ -218486,6 +229722,7 @@ characters.data={ }, [0x1F6A0]={ category="so", + cjkwd="w", description="MOUNTAIN CABLEWAY", direction="on", linebreak="id", @@ -218493,6 +229730,7 @@ characters.data={ }, [0x1F6A1]={ category="so", + cjkwd="w", description="AERIAL TRAMWAY", direction="on", linebreak="id", @@ -218500,6 +229738,7 @@ characters.data={ }, [0x1F6A2]={ category="so", + cjkwd="w", description="SHIP", direction="on", linebreak="id", @@ -218507,13 +229746,15 @@ characters.data={ }, [0x1F6A3]={ category="so", + cjkwd="w", description="ROWBOAT", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F6A3, }, [0x1F6A4]={ category="so", + cjkwd="w", description="SPEEDBOAT", direction="on", linebreak="id", @@ -218521,6 +229762,7 @@ characters.data={ }, [0x1F6A5]={ category="so", + cjkwd="w", description="HORIZONTAL TRAFFIC LIGHT", direction="on", linebreak="id", @@ -218528,6 +229770,7 @@ characters.data={ }, [0x1F6A6]={ category="so", + cjkwd="w", description="VERTICAL TRAFFIC LIGHT", direction="on", linebreak="id", @@ -218535,6 +229778,7 @@ characters.data={ }, [0x1F6A7]={ category="so", + cjkwd="w", description="CONSTRUCTION SIGN", direction="on", linebreak="id", @@ -218542,6 +229786,7 @@ characters.data={ }, [0x1F6A8]={ category="so", + cjkwd="w", description="POLICE CARS REVOLVING LIGHT", direction="on", linebreak="id", @@ -218549,6 +229794,7 @@ characters.data={ }, [0x1F6A9]={ category="so", + cjkwd="w", description="TRIANGULAR FLAG ON POST", direction="on", linebreak="id", @@ -218556,6 +229802,7 @@ characters.data={ }, [0x1F6AA]={ category="so", + cjkwd="w", description="DOOR", direction="on", linebreak="id", @@ -218563,6 +229810,7 @@ characters.data={ }, [0x1F6AB]={ category="so", + cjkwd="w", description="NO ENTRY SIGN", direction="on", linebreak="id", @@ -218570,6 +229818,7 @@ characters.data={ }, [0x1F6AC]={ category="so", + cjkwd="w", description="SMOKING SYMBOL", direction="on", linebreak="id", @@ -218577,6 +229826,7 @@ characters.data={ }, [0x1F6AD]={ category="so", + cjkwd="w", description="NO SMOKING SYMBOL", direction="on", linebreak="id", @@ -218584,6 +229834,7 @@ characters.data={ }, [0x1F6AE]={ category="so", + cjkwd="w", description="PUT LITTER IN ITS PLACE SYMBOL", direction="on", linebreak="id", @@ -218591,6 +229842,7 @@ characters.data={ }, [0x1F6AF]={ category="so", + cjkwd="w", description="DO NOT LITTER SYMBOL", direction="on", linebreak="id", @@ -218598,6 +229850,7 @@ characters.data={ }, [0x1F6B0]={ category="so", + cjkwd="w", description="POTABLE WATER SYMBOL", direction="on", linebreak="id", @@ -218605,6 +229858,7 @@ characters.data={ }, [0x1F6B1]={ category="so", + cjkwd="w", description="NON-POTABLE WATER SYMBOL", direction="on", linebreak="id", @@ -218612,6 +229866,7 @@ characters.data={ }, [0x1F6B2]={ category="so", + cjkwd="w", description="BICYCLE", direction="on", linebreak="id", @@ -218619,6 +229874,7 @@ characters.data={ }, [0x1F6B3]={ category="so", + cjkwd="w", description="NO BICYCLES", direction="on", linebreak="id", @@ -218626,27 +229882,31 @@ characters.data={ }, [0x1F6B4]={ category="so", + cjkwd="w", description="BICYCLIST", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F6B4, }, [0x1F6B5]={ category="so", + cjkwd="w", description="MOUNTAIN BICYCLIST", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F6B5, }, [0x1F6B6]={ category="so", + cjkwd="w", description="PEDESTRIAN", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F6B6, }, [0x1F6B7]={ category="so", + cjkwd="w", description="NO PEDESTRIANS", direction="on", linebreak="id", @@ -218654,6 +229914,7 @@ characters.data={ }, [0x1F6B8]={ category="so", + cjkwd="w", description="CHILDREN CROSSING", direction="on", linebreak="id", @@ -218661,6 +229922,7 @@ characters.data={ }, [0x1F6B9]={ category="so", + cjkwd="w", description="MENS SYMBOL", direction="on", linebreak="id", @@ -218668,6 +229930,7 @@ characters.data={ }, [0x1F6BA]={ category="so", + cjkwd="w", description="WOMENS SYMBOL", direction="on", linebreak="id", @@ -218675,6 +229938,7 @@ characters.data={ }, [0x1F6BB]={ category="so", + cjkwd="w", description="RESTROOM", direction="on", linebreak="id", @@ -218682,6 +229946,7 @@ characters.data={ }, [0x1F6BC]={ category="so", + cjkwd="w", description="BABY SYMBOL", direction="on", linebreak="id", @@ -218689,6 +229954,7 @@ characters.data={ }, [0x1F6BD]={ category="so", + cjkwd="w", description="TOILET", direction="on", linebreak="id", @@ -218696,6 +229962,7 @@ characters.data={ }, [0x1F6BE]={ category="so", + cjkwd="w", description="WATER CLOSET", direction="on", linebreak="id", @@ -218703,6 +229970,7 @@ characters.data={ }, [0x1F6BF]={ category="so", + cjkwd="w", description="SHOWER", direction="on", linebreak="id", @@ -218710,13 +229978,15 @@ characters.data={ }, [0x1F6C0]={ category="so", + cjkwd="w", description="BATH", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F6C0, }, [0x1F6C1]={ category="so", + cjkwd="w", description="BATHTUB", direction="on", linebreak="id", @@ -218724,6 +229994,7 @@ characters.data={ }, [0x1F6C2]={ category="so", + cjkwd="w", description="PASSPORT CONTROL", direction="on", linebreak="id", @@ -218731,6 +230002,7 @@ characters.data={ }, [0x1F6C3]={ category="so", + cjkwd="w", description="CUSTOMS", direction="on", linebreak="id", @@ -218738,6 +230010,7 @@ characters.data={ }, [0x1F6C4]={ category="so", + cjkwd="w", description="BAGGAGE CLAIM", direction="on", linebreak="id", @@ -218745,6 +230018,7 @@ characters.data={ }, [0x1F6C5]={ category="so", + cjkwd="w", description="LEFT LUGGAGE", direction="on", linebreak="id", @@ -218755,6 +230029,7 @@ characters.data={ description="TRIANGLE WITH ROUNDED CORNERS", direction="on", linebreak="id", + synonyms={ "caution" }, unicodeslot=0x1F6C6, }, [0x1F6C7]={ @@ -218769,6 +230044,7 @@ characters.data={ description="CIRCLED INFORMATION SOURCE", direction="on", linebreak="id", + synonyms={ "information" }, unicodeslot=0x1F6C8, }, [0x1F6C9]={ @@ -218791,9 +230067,11 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F6CB, + variants=variants_emoji, }, [0x1F6CC]={ category="so", + cjkwd="w", description="SLEEPING ACCOMMODATION", direction="on", linebreak="id", @@ -218805,6 +230083,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F6CD, + variants=variants_emoji, }, [0x1F6CE]={ category="so", @@ -218812,6 +230091,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F6CE, + variants=variants_emoji, }, [0x1F6CF]={ category="so", @@ -218819,20 +230099,41 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F6CF, + variants=variants_emoji, }, [0x1F6D0]={ category="so", + cjkwd="w", description="PLACE OF WORSHIP", direction="on", linebreak="id", unicodeslot=0x1F6D0, }, + [0x1F6D1]={ + category="so", + cjkwd="w", + description="OCTAGONAL SIGN", + direction="on", + linebreak="id", + synonyms={ "stop sign" }, + unicodeslot=0x1F6D1, + }, + [0x1F6D2]={ + category="so", + cjkwd="w", + description="SHOPPING TROLLEY", + direction="on", + linebreak="id", + synonyms={ "shopping cart" }, + unicodeslot=0x1F6D2, + }, [0x1F6E0]={ category="so", description="HAMMER AND WRENCH", direction="on", linebreak="id", unicodeslot=0x1F6E0, + variants=variants_emoji, }, [0x1F6E1]={ category="so", @@ -218840,6 +230141,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F6E1, + variants=variants_emoji, }, [0x1F6E2]={ category="so", @@ -218847,6 +230149,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F6E2, + variants=variants_emoji, }, [0x1F6E3]={ category="so", @@ -218854,6 +230157,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F6E3, + variants=variants_emoji, }, [0x1F6E4]={ category="so", @@ -218861,6 +230165,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F6E4, + variants=variants_emoji, }, [0x1F6E5]={ category="so", @@ -218868,6 +230173,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F6E5, + variants=variants_emoji, }, [0x1F6E6]={ category="so", @@ -218896,6 +230202,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F6E9, + variants=variants_emoji, }, [0x1F6EA]={ category="so", @@ -218906,6 +230213,7 @@ characters.data={ }, [0x1F6EB]={ category="so", + cjkwd="w", description="AIRPLANE DEPARTURE", direction="on", linebreak="id", @@ -218913,6 +230221,7 @@ characters.data={ }, [0x1F6EC]={ category="so", + cjkwd="w", description="AIRPLANE ARRIVING", direction="on", linebreak="id", @@ -218924,6 +230233,7 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F6F0, + variants=variants_emoji, }, [0x1F6F1]={ category="so", @@ -218945,6 +230255,31 @@ characters.data={ direction="on", linebreak="id", unicodeslot=0x1F6F3, + variants=variants_emoji, + }, + [0x1F6F4]={ + category="so", + cjkwd="w", + description="SCOOTER", + direction="on", + linebreak="id", + unicodeslot=0x1F6F4, + }, + [0x1F6F5]={ + category="so", + cjkwd="w", + description="MOTOR SCOOTER", + direction="on", + linebreak="id", + unicodeslot=0x1F6F5, + }, + [0x1F6F6]={ + category="so", + cjkwd="w", + description="CANOE", + direction="on", + linebreak="id", + unicodeslot=0x1F6F6, }, [0x1F700]={ category="so", @@ -219840,6 +231175,7 @@ characters.data={ description="ROUND TARGET", direction="on", linebreak="al", + synonyms={ "bullseye" }, unicodeslot=0x1F78B, }, [0x1F78C]={ @@ -221391,6 +232727,7 @@ characters.data={ }, [0x1F910]={ category="so", + cjkwd="w", description="ZIPPER-MOUTH FACE", direction="on", linebreak="id", @@ -221398,6 +232735,7 @@ characters.data={ }, [0x1F911]={ category="so", + cjkwd="w", description="MONEY-MOUTH FACE", direction="on", linebreak="id", @@ -221405,6 +232743,7 @@ characters.data={ }, [0x1F912]={ category="so", + cjkwd="w", description="FACE WITH THERMOMETER", direction="on", linebreak="id", @@ -221412,6 +232751,7 @@ characters.data={ }, [0x1F913]={ category="so", + cjkwd="w", description="NERD FACE", direction="on", linebreak="id", @@ -221419,6 +232759,7 @@ characters.data={ }, [0x1F914]={ category="so", + cjkwd="w", description="THINKING FACE", direction="on", linebreak="id", @@ -221426,6 +232767,7 @@ characters.data={ }, [0x1F915]={ category="so", + cjkwd="w", description="FACE WITH HEAD-BANDAGE", direction="on", linebreak="id", @@ -221433,6 +232775,7 @@ characters.data={ }, [0x1F916]={ category="so", + cjkwd="w", description="ROBOT FACE", direction="on", linebreak="id", @@ -221440,6 +232783,7 @@ characters.data={ }, [0x1F917]={ category="so", + cjkwd="w", description="HUGGING FACE", direction="on", linebreak="id", @@ -221447,13 +232791,453 @@ characters.data={ }, [0x1F918]={ category="so", + cjkwd="w", description="SIGN OF THE HORNS", direction="on", - linebreak="id", + linebreak="eb", unicodeslot=0x1F918, }, + [0x1F919]={ + category="so", + cjkwd="w", + description="CALL ME HAND", + direction="on", + linebreak="eb", + unicodeslot=0x1F919, + }, + [0x1F91A]={ + category="so", + cjkwd="w", + description="RAISED BACK OF HAND", + direction="on", + linebreak="eb", + unicodeslot=0x1F91A, + }, + [0x1F91B]={ + category="so", + cjkwd="w", + description="LEFT-FACING FIST", + direction="on", + linebreak="eb", + unicodeslot=0x1F91B, + }, + [0x1F91C]={ + category="so", + cjkwd="w", + description="RIGHT-FACING FIST", + direction="on", + linebreak="eb", + unicodeslot=0x1F91C, + }, + [0x1F91D]={ + category="so", + cjkwd="w", + description="HANDSHAKE", + direction="on", + linebreak="eb", + unicodeslot=0x1F91D, + }, + [0x1F91E]={ + category="so", + cjkwd="w", + description="HAND WITH INDEX AND MIDDLE FINGERS CROSSED", + direction="on", + linebreak="eb", + synonyms={ "crossed fingers", "fingers crossed" }, + unicodeslot=0x1F91E, + }, + [0x1F920]={ + category="so", + cjkwd="w", + description="FACE WITH COWBOY HAT", + direction="on", + linebreak="id", + unicodeslot=0x1F920, + }, + [0x1F921]={ + category="so", + cjkwd="w", + description="CLOWN FACE", + direction="on", + linebreak="id", + unicodeslot=0x1F921, + }, + [0x1F922]={ + category="so", + cjkwd="w", + description="NAUSEATED FACE", + direction="on", + linebreak="id", + unicodeslot=0x1F922, + }, + [0x1F923]={ + category="so", + cjkwd="w", + description="ROLLING ON THE FLOOR LAUGHING", + direction="on", + linebreak="id", + synonyms={ "rofl" }, + unicodeslot=0x1F923, + }, + [0x1F924]={ + category="so", + cjkwd="w", + description="DROOLING FACE", + direction="on", + linebreak="id", + unicodeslot=0x1F924, + }, + [0x1F925]={ + category="so", + cjkwd="w", + description="LYING FACE", + direction="on", + linebreak="id", + unicodeslot=0x1F925, + }, + [0x1F926]={ + category="so", + cjkwd="w", + description="FACE PALM", + direction="on", + linebreak="eb", + unicodeslot=0x1F926, + }, + [0x1F927]={ + category="so", + cjkwd="w", + description="SNEEZING FACE", + direction="on", + linebreak="id", + unicodeslot=0x1F927, + }, + [0x1F930]={ + category="so", + cjkwd="w", + description="PREGNANT WOMAN", + direction="on", + linebreak="eb", + unicodeslot=0x1F930, + }, + [0x1F933]={ + category="so", + cjkwd="w", + description="SELFIE", + direction="on", + linebreak="eb", + unicodeslot=0x1F933, + }, + [0x1F934]={ + category="so", + cjkwd="w", + description="PRINCE", + direction="on", + linebreak="eb", + unicodeslot=0x1F934, + }, + [0x1F935]={ + category="so", + cjkwd="w", + description="MAN IN TUXEDO", + direction="on", + linebreak="eb", + unicodeslot=0x1F935, + }, + [0x1F936]={ + category="so", + cjkwd="w", + description="MOTHER CHRISTMAS", + direction="on", + linebreak="eb", + unicodeslot=0x1F936, + }, + [0x1F937]={ + category="so", + cjkwd="w", + description="SHRUG", + direction="on", + linebreak="eb", + unicodeslot=0x1F937, + }, + [0x1F938]={ + category="so", + cjkwd="w", + description="PERSON DOING CARTWHEEL", + direction="on", + linebreak="eb", + unicodeslot=0x1F938, + }, + [0x1F939]={ + category="so", + cjkwd="w", + description="JUGGLING", + direction="on", + linebreak="eb", + unicodeslot=0x1F939, + }, + [0x1F93A]={ + category="so", + cjkwd="w", + description="FENCER", + direction="on", + linebreak="id", + unicodeslot=0x1F93A, + }, + [0x1F93B]={ + category="so", + cjkwd="w", + description="MODERN PENTATHLON", + direction="on", + linebreak="id", + unicodeslot=0x1F93B, + }, + [0x1F93C]={ + category="so", + cjkwd="w", + description="WRESTLERS", + direction="on", + linebreak="eb", + unicodeslot=0x1F93C, + }, + [0x1F93D]={ + category="so", + cjkwd="w", + description="WATER POLO", + direction="on", + linebreak="eb", + unicodeslot=0x1F93D, + }, + [0x1F93E]={ + category="so", + cjkwd="w", + description="HANDBALL", + direction="on", + linebreak="eb", + unicodeslot=0x1F93E, + }, + [0x1F940]={ + category="so", + cjkwd="w", + description="WILTED FLOWER", + direction="on", + linebreak="id", + unicodeslot=0x1F940, + }, + [0x1F941]={ + category="so", + cjkwd="w", + description="DRUM WITH DRUMSTICKS", + direction="on", + linebreak="id", + unicodeslot=0x1F941, + }, + [0x1F942]={ + category="so", + cjkwd="w", + description="CLINKING GLASSES", + direction="on", + linebreak="id", + unicodeslot=0x1F942, + }, + [0x1F943]={ + category="so", + cjkwd="w", + description="TUMBLER GLASS", + direction="on", + linebreak="id", + unicodeslot=0x1F943, + }, + [0x1F944]={ + category="so", + cjkwd="w", + description="SPOON", + direction="on", + linebreak="id", + unicodeslot=0x1F944, + }, + [0x1F945]={ + category="so", + cjkwd="w", + description="GOAL NET", + direction="on", + linebreak="id", + unicodeslot=0x1F945, + }, + [0x1F946]={ + category="so", + cjkwd="w", + description="RIFLE", + direction="on", + linebreak="id", + unicodeslot=0x1F946, + }, + [0x1F947]={ + category="so", + cjkwd="w", + description="FIRST PLACE MEDAL", + direction="on", + linebreak="id", + synonyms={ "gold medal" }, + unicodeslot=0x1F947, + }, + [0x1F948]={ + category="so", + cjkwd="w", + description="SECOND PLACE MEDAL", + direction="on", + linebreak="id", + synonyms={ "silver medal" }, + unicodeslot=0x1F948, + }, + [0x1F949]={ + category="so", + cjkwd="w", + description="THIRD PLACE MEDAL", + direction="on", + linebreak="id", + synonyms={ "bronze medal" }, + unicodeslot=0x1F949, + }, + [0x1F94A]={ + category="so", + cjkwd="w", + description="BOXING GLOVE", + direction="on", + linebreak="id", + unicodeslot=0x1F94A, + }, + [0x1F94B]={ + category="so", + cjkwd="w", + description="MARTIAL ARTS UNIFORM", + direction="on", + linebreak="id", + unicodeslot=0x1F94B, + }, + [0x1F950]={ + category="so", + cjkwd="w", + description="CROISSANT", + direction="on", + linebreak="id", + unicodeslot=0x1F950, + }, + [0x1F951]={ + category="so", + cjkwd="w", + description="AVOCADO", + direction="on", + linebreak="id", + unicodeslot=0x1F951, + }, + [0x1F952]={ + category="so", + cjkwd="w", + description="CUCUMBER", + direction="on", + linebreak="id", + unicodeslot=0x1F952, + }, + [0x1F953]={ + category="so", + cjkwd="w", + description="BACON", + direction="on", + linebreak="id", + unicodeslot=0x1F953, + }, + [0x1F954]={ + category="so", + cjkwd="w", + description="POTATO", + direction="on", + linebreak="id", + unicodeslot=0x1F954, + }, + [0x1F955]={ + category="so", + cjkwd="w", + description="CARROT", + direction="on", + linebreak="id", + unicodeslot=0x1F955, + }, + [0x1F956]={ + category="so", + cjkwd="w", + description="BAGUETTE BREAD", + direction="on", + linebreak="id", + unicodeslot=0x1F956, + }, + [0x1F957]={ + category="so", + cjkwd="w", + description="GREEN SALAD", + direction="on", + linebreak="id", + unicodeslot=0x1F957, + }, + [0x1F958]={ + category="so", + cjkwd="w", + description="SHALLOW PAN OF FOOD", + direction="on", + linebreak="id", + synonyms={ "paella" }, + unicodeslot=0x1F958, + }, + [0x1F959]={ + category="so", + cjkwd="w", + description="STUFFED FLATBREAD", + direction="on", + linebreak="id", + unicodeslot=0x1F959, + }, + [0x1F95A]={ + category="so", + cjkwd="w", + description="EGG", + direction="on", + linebreak="id", + unicodeslot=0x1F95A, + }, + [0x1F95B]={ + category="so", + cjkwd="w", + description="GLASS OF MILK", + direction="on", + linebreak="id", + unicodeslot=0x1F95B, + }, + [0x1F95C]={ + category="so", + cjkwd="w", + description="PEANUTS", + direction="on", + linebreak="id", + unicodeslot=0x1F95C, + }, + [0x1F95D]={ + category="so", + cjkwd="w", + description="KIWIFRUIT", + direction="on", + linebreak="id", + unicodeslot=0x1F95D, + }, + [0x1F95E]={ + category="so", + cjkwd="w", + description="PANCAKES", + direction="on", + linebreak="id", + unicodeslot=0x1F95E, + }, [0x1F980]={ category="so", + cjkwd="w", description="CRAB", direction="on", linebreak="id", @@ -221461,6 +233245,7 @@ characters.data={ }, [0x1F981]={ category="so", + cjkwd="w", description="LION FACE", direction="on", linebreak="id", @@ -221468,6 +233253,7 @@ characters.data={ }, [0x1F982]={ category="so", + cjkwd="w", description="SCORPION", direction="on", linebreak="id", @@ -221475,6 +233261,7 @@ characters.data={ }, [0x1F983]={ category="so", + cjkwd="w", description="TURKEY", direction="on", linebreak="id", @@ -221482,13 +233269,119 @@ characters.data={ }, [0x1F984]={ category="so", + cjkwd="w", description="UNICORN FACE", direction="on", linebreak="id", unicodeslot=0x1F984, }, + [0x1F985]={ + category="so", + cjkwd="w", + description="EAGLE", + direction="on", + linebreak="id", + unicodeslot=0x1F985, + }, + [0x1F986]={ + category="so", + cjkwd="w", + description="DUCK", + direction="on", + linebreak="id", + unicodeslot=0x1F986, + }, + [0x1F987]={ + category="so", + cjkwd="w", + description="BAT", + direction="on", + linebreak="id", + unicodeslot=0x1F987, + }, + [0x1F988]={ + category="so", + cjkwd="w", + description="SHARK", + direction="on", + linebreak="id", + unicodeslot=0x1F988, + }, + [0x1F989]={ + category="so", + cjkwd="w", + description="OWL", + direction="on", + linebreak="id", + unicodeslot=0x1F989, + }, + [0x1F98A]={ + category="so", + cjkwd="w", + description="FOX FACE", + direction="on", + linebreak="id", + unicodeslot=0x1F98A, + }, + [0x1F98B]={ + category="so", + cjkwd="w", + description="BUTTERFLY", + direction="on", + linebreak="id", + unicodeslot=0x1F98B, + }, + [0x1F98C]={ + category="so", + cjkwd="w", + description="DEER", + direction="on", + linebreak="id", + unicodeslot=0x1F98C, + }, + [0x1F98D]={ + category="so", + cjkwd="w", + description="GORILLA", + direction="on", + linebreak="id", + unicodeslot=0x1F98D, + }, + [0x1F98E]={ + category="so", + cjkwd="w", + description="LIZARD", + direction="on", + linebreak="id", + unicodeslot=0x1F98E, + }, + [0x1F98F]={ + category="so", + cjkwd="w", + description="RHINOCEROS", + direction="on", + linebreak="id", + unicodeslot=0x1F98F, + }, + [0x1F990]={ + category="so", + cjkwd="w", + description="SHRIMP", + direction="on", + linebreak="id", + unicodeslot=0x1F990, + }, + [0x1F991]={ + category="so", + cjkwd="w", + description="SQUID", + direction="on", + linebreak="id", + unicodeslot=0x1F991, + }, [0x1F9C0]={ category="so", + cjkwd="w", description="CHEESE WEDGE", direction="on", linebreak="id", @@ -227051,4 +238944,9 @@ characters.data={ linebreak="cm", unicodeslot=0xE007F, }, -}
\ No newline at end of file + [0xE0100]={ + description="VARIATION SELECTOR-0x0011", + synonyms={ "vs17" }, + unicodeslot=0xE0100, + }, +} diff --git a/tex/context/base/mkiv/char-emj.lua b/tex/context/base/mkiv/char-emj.lua new file mode 100644 index 000000000..718d3bc6e --- /dev/null +++ b/tex/context/base/mkiv/char-emj.lua @@ -0,0 +1,2633 @@ +if not modules then modules = { } end modules ['char-emj'] = { + version = 1.001, + comment = "companion to char-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", + dataonly = true, +} + +-- This table is generated. + +return { + ["1st place medal"]={ 0x1F947 }, + ["2nd place medal"]={ 0x1F948 }, + ["3rd place medal"]={ 0x1F949 }, + ["a button (blood type)"]={ 0x1F170 }, + ["ab button (blood type)"]={ 0x1F18E }, + ["admission tickets"]={ 0x1F39F }, + ["adult"]={ 0x1F9D1 }, + ["adult: dark skin tone"]={ 0x1F9D1, 0x1F3FF }, + ["adult: light skin tone"]={ 0x1F9D1, 0x1F3FB }, + ["adult: medium skin tone"]={ 0x1F9D1, 0x1F3FD }, + ["adult: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE }, + ["adult: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC }, + ["aerial tramway"]={ 0x1F6A1 }, + ["afghanistan"]={ 0x1F1E6, 0x1F1EB }, + ["airplane"]={ 0x2708 }, + ["airplane arrival"]={ 0x1F6EC }, + ["airplane departure"]={ 0x1F6EB }, + ["alarm clock"]={ 0x23F0 }, + ["albania"]={ 0x1F1E6, 0x1F1F1 }, + ["alembic"]={ 0x2697 }, + ["algeria"]={ 0x1F1E9, 0x1F1FF }, + ["alien"]={ 0x1F47D }, + ["alien monster"]={ 0x1F47E }, + ["ambulance"]={ 0x1F691 }, + ["american football"]={ 0x1F3C8 }, + ["american samoa"]={ 0x1F1E6, 0x1F1F8 }, + ["amphora"]={ 0x1F3FA }, + ["anchor"]={ 0x2693 }, + ["andorra"]={ 0x1F1E6, 0x1F1E9 }, + ["anger symbol"]={ 0x1F4A2 }, + ["angola"]={ 0x1F1E6, 0x1F1F4 }, + ["angry face"]={ 0x1F620 }, + ["angry face with horns"]={ 0x1F47F }, + ["anguilla"]={ 0x1F1E6, 0x1F1EE }, + ["anguished face"]={ 0x1F627 }, + ["ant"]={ 0x1F41C }, + ["antarctica"]={ 0x1F1E6, 0x1F1F6 }, + ["antenna bars"]={ 0x1F4F6 }, + ["anticlockwise arrows button"]={ 0x1F504 }, + ["antigua & barbuda"]={ 0x1F1E6, 0x1F1EC }, + ["aquarius"]={ 0x2652 }, + ["argentina"]={ 0x1F1E6, 0x1F1F7 }, + ["aries"]={ 0x2648 }, + ["armenia"]={ 0x1F1E6, 0x1F1F2 }, + ["articulated lorry"]={ 0x1F69B }, + ["artist palette"]={ 0x1F3A8 }, + ["aruba"]={ 0x1F1E6, 0x1F1FC }, + ["ascension island"]={ 0x1F1E6, 0x1F1E8 }, + ["astonished face"]={ 0x1F632 }, + ["atm sign"]={ 0x1F3E7 }, + ["atom symbol"]={ 0x269B }, + ["australia"]={ 0x1F1E6, 0x1F1FA }, + ["austria"]={ 0x1F1E6, 0x1F1F9 }, + ["automobile"]={ 0x1F697 }, + ["avocado"]={ 0x1F951 }, + ["azerbaijan"]={ 0x1F1E6, 0x1F1FF }, + ["b button (blood type)"]={ 0x1F171 }, + ["baby"]={ 0x1F476 }, + ["baby angel"]={ 0x1F47C }, + ["baby angel: dark skin tone"]={ 0x1F47C, 0x1F3FF }, + ["baby angel: light skin tone"]={ 0x1F47C, 0x1F3FB }, + ["baby angel: medium skin tone"]={ 0x1F47C, 0x1F3FD }, + ["baby angel: medium-dark skin tone"]={ 0x1F47C, 0x1F3FE }, + ["baby angel: medium-light skin tone"]={ 0x1F47C, 0x1F3FC }, + ["baby bottle"]={ 0x1F37C }, + ["baby chick"]={ 0x1F424 }, + ["baby symbol"]={ 0x1F6BC }, + ["baby: dark skin tone"]={ 0x1F476, 0x1F3FF }, + ["baby: light skin tone"]={ 0x1F476, 0x1F3FB }, + ["baby: medium skin tone"]={ 0x1F476, 0x1F3FD }, + ["baby: medium-dark skin tone"]={ 0x1F476, 0x1F3FE }, + ["baby: medium-light skin tone"]={ 0x1F476, 0x1F3FC }, + ["back arrow"]={ 0x1F519 }, + ["backhand index pointing down"]={ 0x1F447 }, + ["backhand index pointing down: dark skin tone"]={ 0x1F447, 0x1F3FF }, + ["backhand index pointing down: light skin tone"]={ 0x1F447, 0x1F3FB }, + ["backhand index pointing down: medium skin tone"]={ 0x1F447, 0x1F3FD }, + ["backhand index pointing down: medium-dark skin tone"]={ 0x1F447, 0x1F3FE }, + ["backhand index pointing down: medium-light skin tone"]={ 0x1F447, 0x1F3FC }, + ["backhand index pointing left"]={ 0x1F448 }, + ["backhand index pointing left: dark skin tone"]={ 0x1F448, 0x1F3FF }, + ["backhand index pointing left: light skin tone"]={ 0x1F448, 0x1F3FB }, + ["backhand index pointing left: medium skin tone"]={ 0x1F448, 0x1F3FD }, + ["backhand index pointing left: medium-dark skin tone"]={ 0x1F448, 0x1F3FE }, + ["backhand index pointing left: medium-light skin tone"]={ 0x1F448, 0x1F3FC }, + ["backhand index pointing right"]={ 0x1F449 }, + ["backhand index pointing right: dark skin tone"]={ 0x1F449, 0x1F3FF }, + ["backhand index pointing right: light skin tone"]={ 0x1F449, 0x1F3FB }, + ["backhand index pointing right: medium skin tone"]={ 0x1F449, 0x1F3FD }, + ["backhand index pointing right: medium-dark skin tone"]={ 0x1F449, 0x1F3FE }, + ["backhand index pointing right: medium-light skin tone"]={ 0x1F449, 0x1F3FC }, + ["backhand index pointing up"]={ 0x1F446 }, + ["backhand index pointing up: dark skin tone"]={ 0x1F446, 0x1F3FF }, + ["backhand index pointing up: light skin tone"]={ 0x1F446, 0x1F3FB }, + ["backhand index pointing up: medium skin tone"]={ 0x1F446, 0x1F3FD }, + ["backhand index pointing up: medium-dark skin tone"]={ 0x1F446, 0x1F3FE }, + ["backhand index pointing up: medium-light skin tone"]={ 0x1F446, 0x1F3FC }, + ["bacon"]={ 0x1F953 }, + ["badminton"]={ 0x1F3F8 }, + ["baggage claim"]={ 0x1F6C4 }, + ["baguette bread"]={ 0x1F956 }, + ["bahamas"]={ 0x1F1E7, 0x1F1F8 }, + ["bahrain"]={ 0x1F1E7, 0x1F1ED }, + ["balance scale"]={ 0x2696 }, + ["balloon"]={ 0x1F388 }, + ["ballot box with ballot"]={ 0x1F5F3 }, + ["ballot box with check"]={ 0x2611 }, + ["banana"]={ 0x1F34C }, + ["bangladesh"]={ 0x1F1E7, 0x1F1E9 }, + ["bank"]={ 0x1F3E6 }, + ["bar chart"]={ 0x1F4CA }, + ["barbados"]={ 0x1F1E7, 0x1F1E7 }, + ["barber pole"]={ 0x1F488 }, + ["baseball"]={ 0x26BE }, + ["basketball"]={ 0x1F3C0 }, + ["bat"]={ 0x1F987 }, + ["bathtub"]={ 0x1F6C1 }, + ["battery"]={ 0x1F50B }, + ["beach with umbrella"]={ 0x1F3D6 }, + ["bear face"]={ 0x1F43B }, + ["bearded person"]={ 0x1F9D4 }, + ["bearded person: dark skin tone"]={ 0x1F9D4, 0x1F3FF }, + ["bearded person: light skin tone"]={ 0x1F9D4, 0x1F3FB }, + ["bearded person: medium skin tone"]={ 0x1F9D4, 0x1F3FD }, + ["bearded person: medium-dark skin tone"]={ 0x1F9D4, 0x1F3FE }, + ["bearded person: medium-light skin tone"]={ 0x1F9D4, 0x1F3FC }, + ["beating heart"]={ 0x1F493 }, + ["bed"]={ 0x1F6CF }, + ["beer mug"]={ 0x1F37A }, + ["belarus"]={ 0x1F1E7, 0x1F1FE }, + ["belgium"]={ 0x1F1E7, 0x1F1EA }, + ["belize"]={ 0x1F1E7, 0x1F1FF }, + ["bell"]={ 0x1F514 }, + ["bell with slash"]={ 0x1F515 }, + ["bellhop bell"]={ 0x1F6CE }, + ["benin"]={ 0x1F1E7, 0x1F1EF }, + ["bento box"]={ 0x1F371 }, + ["bermuda"]={ 0x1F1E7, 0x1F1F2 }, + ["bhutan"]={ 0x1F1E7, 0x1F1F9 }, + ["bicycle"]={ 0x1F6B2 }, + ["bikini"]={ 0x1F459 }, + ["billed cap"]={ 0x1F9E2 }, + ["biohazard"]={ 0x2623 }, + ["bird"]={ 0x1F426 }, + ["birthday cake"]={ 0x1F382 }, + ["black circle"]={ 0x26AB }, + ["black flag"]={ 0x1F3F4 }, + ["black heart"]={ 0x1F5A4 }, + ["black large square"]={ 0x2B1B }, + ["black medium square"]={ 0x25FC }, + ["black medium-small square"]={ 0x25FE }, + ["black nib"]={ 0x2712 }, + ["black small square"]={ 0x25AA }, + ["black square button"]={ 0x1F532 }, + ["blond-haired man"]={ 0x1F471, 0x200D, 0x2642 }, + ["blond-haired man: dark skin tone"]={ 0x1F471, 0x1F3FF, 0x200D, 0x2642 }, + ["blond-haired man: light skin tone"]={ 0x1F471, 0x1F3FB, 0x200D, 0x2642 }, + ["blond-haired man: medium skin tone"]={ 0x1F471, 0x1F3FD, 0x200D, 0x2642 }, + ["blond-haired man: medium-dark skin tone"]={ 0x1F471, 0x1F3FE, 0x200D, 0x2642 }, + ["blond-haired man: medium-light skin tone"]={ 0x1F471, 0x1F3FC, 0x200D, 0x2642 }, + ["blond-haired person"]={ 0x1F471 }, + ["blond-haired person: dark skin tone"]={ 0x1F471, 0x1F3FF }, + ["blond-haired person: light skin tone"]={ 0x1F471, 0x1F3FB }, + ["blond-haired person: medium skin tone"]={ 0x1F471, 0x1F3FD }, + ["blond-haired person: medium-dark skin tone"]={ 0x1F471, 0x1F3FE }, + ["blond-haired person: medium-light skin tone"]={ 0x1F471, 0x1F3FC }, + ["blond-haired woman"]={ 0x1F471, 0x200D, 0x2640 }, + ["blond-haired woman: dark skin tone"]={ 0x1F471, 0x1F3FF, 0x200D, 0x2640 }, + ["blond-haired woman: light skin tone"]={ 0x1F471, 0x1F3FB, 0x200D, 0x2640 }, + ["blond-haired woman: medium skin tone"]={ 0x1F471, 0x1F3FD, 0x200D, 0x2640 }, + ["blond-haired woman: medium-dark skin tone"]={ 0x1F471, 0x1F3FE, 0x200D, 0x2640 }, + ["blond-haired woman: medium-light skin tone"]={ 0x1F471, 0x1F3FC, 0x200D, 0x2640 }, + ["blossom"]={ 0x1F33C }, + ["blowfish"]={ 0x1F421 }, + ["blue book"]={ 0x1F4D8 }, + ["blue circle"]={ 0x1F535 }, + ["blue heart"]={ 0x1F499 }, + ["boar"]={ 0x1F417 }, + ["bolivia"]={ 0x1F1E7, 0x1F1F4 }, + ["bomb"]={ 0x1F4A3 }, + ["bookmark"]={ 0x1F516 }, + ["bookmark tabs"]={ 0x1F4D1 }, + ["books"]={ 0x1F4DA }, + ["bosnia & herzegovina"]={ 0x1F1E7, 0x1F1E6 }, + ["botswana"]={ 0x1F1E7, 0x1F1FC }, + ["bottle with popping cork"]={ 0x1F37E }, + ["bouquet"]={ 0x1F490 }, + ["bouvet island"]={ 0x1F1E7, 0x1F1FB }, + ["bow and arrow"]={ 0x1F3F9 }, + ["bowl with spoon"]={ 0x1F963 }, + ["bowling"]={ 0x1F3B3 }, + ["boxing glove"]={ 0x1F94A }, + ["boy"]={ 0x1F466 }, + ["boy: dark skin tone"]={ 0x1F466, 0x1F3FF }, + ["boy: light skin tone"]={ 0x1F466, 0x1F3FB }, + ["boy: medium skin tone"]={ 0x1F466, 0x1F3FD }, + ["boy: medium-dark skin tone"]={ 0x1F466, 0x1F3FE }, + ["boy: medium-light skin tone"]={ 0x1F466, 0x1F3FC }, + ["brain"]={ 0x1F9E0 }, + ["brazil"]={ 0x1F1E7, 0x1F1F7 }, + ["bread"]={ 0x1F35E }, + ["breast-feeding"]={ 0x1F931 }, + ["breast-feeding: dark skin tone"]={ 0x1F931, 0x1F3FF }, + ["breast-feeding: light skin tone"]={ 0x1F931, 0x1F3FB }, + ["breast-feeding: medium skin tone"]={ 0x1F931, 0x1F3FD }, + ["breast-feeding: medium-dark skin tone"]={ 0x1F931, 0x1F3FE }, + ["breast-feeding: medium-light skin tone"]={ 0x1F931, 0x1F3FC }, + ["bride with veil"]={ 0x1F470 }, + ["bride with veil: dark skin tone"]={ 0x1F470, 0x1F3FF }, + ["bride with veil: light skin tone"]={ 0x1F470, 0x1F3FB }, + ["bride with veil: medium skin tone"]={ 0x1F470, 0x1F3FD }, + ["bride with veil: medium-dark skin tone"]={ 0x1F470, 0x1F3FE }, + ["bride with veil: medium-light skin tone"]={ 0x1F470, 0x1F3FC }, + ["bridge at night"]={ 0x1F309 }, + ["briefcase"]={ 0x1F4BC }, + ["bright button"]={ 0x1F506 }, + ["british indian ocean territory"]={ 0x1F1EE, 0x1F1F4 }, + ["british virgin islands"]={ 0x1F1FB, 0x1F1EC }, + ["broccoli"]={ 0x1F966 }, + ["broken heart"]={ 0x1F494 }, + ["brunei"]={ 0x1F1E7, 0x1F1F3 }, + ["bug"]={ 0x1F41B }, + ["building construction"]={ 0x1F3D7 }, + ["bulgaria"]={ 0x1F1E7, 0x1F1EC }, + ["burkina faso"]={ 0x1F1E7, 0x1F1EB }, + ["burrito"]={ 0x1F32F }, + ["burundi"]={ 0x1F1E7, 0x1F1EE }, + ["bus"]={ 0x1F68C }, + ["bus stop"]={ 0x1F68F }, + ["bust in silhouette"]={ 0x1F464 }, + ["busts in silhouette"]={ 0x1F465 }, + ["butterfly"]={ 0x1F98B }, + ["cactus"]={ 0x1F335 }, + ["calendar"]={ 0x1F4C5 }, + ["call me hand"]={ 0x1F919 }, + ["call me hand: dark skin tone"]={ 0x1F919, 0x1F3FF }, + ["call me hand: light skin tone"]={ 0x1F919, 0x1F3FB }, + ["call me hand: medium skin tone"]={ 0x1F919, 0x1F3FD }, + ["call me hand: medium-dark skin tone"]={ 0x1F919, 0x1F3FE }, + ["call me hand: medium-light skin tone"]={ 0x1F919, 0x1F3FC }, + ["cambodia"]={ 0x1F1F0, 0x1F1ED }, + ["camel"]={ 0x1F42A }, + ["camera"]={ 0x1F4F7 }, + ["camera with flash"]={ 0x1F4F8 }, + ["cameroon"]={ 0x1F1E8, 0x1F1F2 }, + ["camping"]={ 0x1F3D5 }, + ["canada"]={ 0x1F1E8, 0x1F1E6 }, + ["canary islands"]={ 0x1F1EE, 0x1F1E8 }, + ["cancer"]={ 0x264B }, + ["candle"]={ 0x1F56F }, + ["candy"]={ 0x1F36C }, + ["canned food"]={ 0x1F96B }, + ["canoe"]={ 0x1F6F6 }, + ["cape verde"]={ 0x1F1E8, 0x1F1FB }, + ["capricorn"]={ 0x2651 }, + ["card file box"]={ 0x1F5C3 }, + ["card index"]={ 0x1F4C7 }, + ["card index dividers"]={ 0x1F5C2 }, + ["caribbean netherlands"]={ 0x1F1E7, 0x1F1F6 }, + ["carousel horse"]={ 0x1F3A0 }, + ["carp streamer"]={ 0x1F38F }, + ["carrot"]={ 0x1F955 }, + ["castle"]={ 0x1F3F0 }, + ["cat"]={ 0x1F408 }, + ["cat face"]={ 0x1F431 }, + ["cat face with tears of joy"]={ 0x1F639 }, + ["cat face with wry smile"]={ 0x1F63C }, + ["cayman islands"]={ 0x1F1F0, 0x1F1FE }, + ["central african republic"]={ 0x1F1E8, 0x1F1EB }, + ["ceuta & melilla"]={ 0x1F1EA, 0x1F1E6 }, + ["chad"]={ 0x1F1F9, 0x1F1E9 }, + ["chains"]={ 0x26D3 }, + ["chart decreasing"]={ 0x1F4C9 }, + ["chart increasing"]={ 0x1F4C8 }, + ["chart increasing with yen"]={ 0x1F4B9 }, + ["cheese wedge"]={ 0x1F9C0 }, + ["chequered flag"]={ 0x1F3C1 }, + ["cherries"]={ 0x1F352 }, + ["cherry blossom"]={ 0x1F338 }, + ["chestnut"]={ 0x1F330 }, + ["chicken"]={ 0x1F414 }, + ["child"]={ 0x1F9D2 }, + ["child: dark skin tone"]={ 0x1F9D2, 0x1F3FF }, + ["child: light skin tone"]={ 0x1F9D2, 0x1F3FB }, + ["child: medium skin tone"]={ 0x1F9D2, 0x1F3FD }, + ["child: medium-dark skin tone"]={ 0x1F9D2, 0x1F3FE }, + ["child: medium-light skin tone"]={ 0x1F9D2, 0x1F3FC }, + ["children crossing"]={ 0x1F6B8 }, + ["chile"]={ 0x1F1E8, 0x1F1F1 }, + ["china"]={ 0x1F1E8, 0x1F1F3 }, + ["chipmunk"]={ 0x1F43F }, + ["chocolate bar"]={ 0x1F36B }, + ["chopsticks"]={ 0x1F962 }, + ["christmas island"]={ 0x1F1E8, 0x1F1FD }, + ["christmas tree"]={ 0x1F384 }, + ["church"]={ 0x26EA }, + ["cigarette"]={ 0x1F6AC }, + ["cinema"]={ 0x1F3A6 }, + ["circled m"]={ 0x24C2 }, + ["circus tent"]={ 0x1F3AA }, + ["cityscape"]={ 0x1F3D9 }, + ["cityscape at dusk"]={ 0x1F306 }, + ["cl button"]={ 0x1F191 }, + ["clamp"]={ 0x1F5DC }, + ["clapper board"]={ 0x1F3AC }, + ["clapping hands"]={ 0x1F44F }, + ["clapping hands: dark skin tone"]={ 0x1F44F, 0x1F3FF }, + ["clapping hands: light skin tone"]={ 0x1F44F, 0x1F3FB }, + ["clapping hands: medium skin tone"]={ 0x1F44F, 0x1F3FD }, + ["clapping hands: medium-dark skin tone"]={ 0x1F44F, 0x1F3FE }, + ["clapping hands: medium-light skin tone"]={ 0x1F44F, 0x1F3FC }, + ["classical building"]={ 0x1F3DB }, + ["clinking beer mugs"]={ 0x1F37B }, + ["clinking glasses"]={ 0x1F942 }, + ["clipboard"]={ 0x1F4CB }, + ["clipperton island"]={ 0x1F1E8, 0x1F1F5 }, + ["clockwise vertical arrows"]={ 0x1F503 }, + ["closed book"]={ 0x1F4D5 }, + ["closed mailbox with lowered flag"]={ 0x1F4EA }, + ["closed mailbox with raised flag"]={ 0x1F4EB }, + ["closed umbrella"]={ 0x1F302 }, + ["cloud"]={ 0x2601 }, + ["cloud with lightning"]={ 0x1F329 }, + ["cloud with lightning and rain"]={ 0x26C8 }, + ["cloud with rain"]={ 0x1F327 }, + ["cloud with snow"]={ 0x1F328 }, + ["clown face"]={ 0x1F921 }, + ["club suit"]={ 0x2663 }, + ["clutch bag"]={ 0x1F45D }, + ["coat"]={ 0x1F9E5 }, + ["cocktail glass"]={ 0x1F378 }, + ["coconut"]={ 0x1F965 }, + ["cocos (keeling) islands"]={ 0x1F1E8, 0x1F1E8 }, + ["coffin"]={ 0x26B0 }, + ["collision"]={ 0x1F4A5 }, + ["colombia"]={ 0x1F1E8, 0x1F1F4 }, + ["comet"]={ 0x2604 }, + ["comoros"]={ 0x1F1F0, 0x1F1F2 }, + ["computer disk"]={ 0x1F4BD }, + ["computer mouse"]={ 0x1F5B1 }, + ["confetti ball"]={ 0x1F38A }, + ["confounded face"]={ 0x1F616 }, + ["confused face"]={ 0x1F615 }, + ["congo - brazzaville"]={ 0x1F1E8, 0x1F1EC }, + ["congo - kinshasa"]={ 0x1F1E8, 0x1F1E9 }, + ["construction"]={ 0x1F6A7 }, + ["construction worker"]={ 0x1F477 }, + ["construction worker: dark skin tone"]={ 0x1F477, 0x1F3FF }, + ["construction worker: light skin tone"]={ 0x1F477, 0x1F3FB }, + ["construction worker: medium skin tone"]={ 0x1F477, 0x1F3FD }, + ["construction worker: medium-dark skin tone"]={ 0x1F477, 0x1F3FE }, + ["construction worker: medium-light skin tone"]={ 0x1F477, 0x1F3FC }, + ["control knobs"]={ 0x1F39B }, + ["convenience store"]={ 0x1F3EA }, + ["cook islands"]={ 0x1F1E8, 0x1F1F0 }, + ["cooked rice"]={ 0x1F35A }, + ["cookie"]={ 0x1F36A }, + ["cooking"]={ 0x1F373 }, + ["cool button"]={ 0x1F192 }, + ["copyright"]={ 0xA9 }, + ["costa rica"]={ 0x1F1E8, 0x1F1F7 }, + ["couch and lamp"]={ 0x1F6CB }, + ["couple with heart"]={ 0x1F491 }, + ["couple with heart: man, man"]={ 0x1F468, 0x200D, 0x2764, 0x200D, 0x1F468 }, + ["couple with heart: woman, man"]={ 0x1F469, 0x200D, 0x2764, 0x200D, 0x1F468 }, + ["couple with heart: woman, woman"]={ 0x1F469, 0x200D, 0x2764, 0x200D, 0x1F469 }, + ["cow"]={ 0x1F404 }, + ["cow face"]={ 0x1F42E }, + ["cowboy hat face"]={ 0x1F920 }, + ["crab"]={ 0x1F980 }, + ["crayon"]={ 0x1F58D }, + ["crazy face"]={ 0x1F92A }, + ["credit card"]={ 0x1F4B3 }, + ["crescent moon"]={ 0x1F319 }, + ["cricket"]={ 0x1F3CF }, + ["croatia"]={ 0x1F1ED, 0x1F1F7 }, + ["crocodile"]={ 0x1F40A }, + ["croissant"]={ 0x1F950 }, + ["cross mark"]={ 0x274C }, + ["cross mark button"]={ 0x274E }, + ["crossed fingers"]={ 0x1F91E }, + ["crossed fingers: dark skin tone"]={ 0x1F91E, 0x1F3FF }, + ["crossed fingers: light skin tone"]={ 0x1F91E, 0x1F3FB }, + ["crossed fingers: medium skin tone"]={ 0x1F91E, 0x1F3FD }, + ["crossed fingers: medium-dark skin tone"]={ 0x1F91E, 0x1F3FE }, + ["crossed fingers: medium-light skin tone"]={ 0x1F91E, 0x1F3FC }, + ["crossed flags"]={ 0x1F38C }, + ["crossed swords"]={ 0x2694 }, + ["crown"]={ 0x1F451 }, + ["crying cat face"]={ 0x1F63F }, + ["crying face"]={ 0x1F622 }, + ["crystal ball"]={ 0x1F52E }, + ["cuba"]={ 0x1F1E8, 0x1F1FA }, + ["cucumber"]={ 0x1F952 }, + ["cup with straw"]={ 0x1F964 }, + ["curaçao"]={ 0x1F1E8, 0x1F1FC }, + ["curling stone"]={ 0x1F94C }, + ["curly loop"]={ 0x27B0 }, + ["currency exchange"]={ 0x1F4B1 }, + ["curry rice"]={ 0x1F35B }, + ["custard"]={ 0x1F36E }, + ["customs"]={ 0x1F6C3 }, + ["cut of meat"]={ 0x1F969 }, + ["cyclone"]={ 0x1F300 }, + ["cyprus"]={ 0x1F1E8, 0x1F1FE }, + ["czechia"]={ 0x1F1E8, 0x1F1FF }, + ["côte d’ivoire"]={ 0x1F1E8, 0x1F1EE }, + ["dagger"]={ 0x1F5E1 }, + ["dango"]={ 0x1F361 }, + ["dashing away"]={ 0x1F4A8 }, + ["deciduous tree"]={ 0x1F333 }, + ["deer"]={ 0x1F98C }, + ["delivery truck"]={ 0x1F69A }, + ["denmark"]={ 0x1F1E9, 0x1F1F0 }, + ["department store"]={ 0x1F3EC }, + ["derelict house"]={ 0x1F3DA }, + ["desert"]={ 0x1F3DC }, + ["desert island"]={ 0x1F3DD }, + ["desktop computer"]={ 0x1F5A5 }, + ["detective"]={ 0x1F575 }, + ["detective: dark skin tone"]={ 0x1F575, 0x1F3FF }, + ["detective: light skin tone"]={ 0x1F575, 0x1F3FB }, + ["detective: medium skin tone"]={ 0x1F575, 0x1F3FD }, + ["detective: medium-dark skin tone"]={ 0x1F575, 0x1F3FE }, + ["detective: medium-light skin tone"]={ 0x1F575, 0x1F3FC }, + ["diamond suit"]={ 0x2666 }, + ["diamond with a dot"]={ 0x1F4A0 }, + ["diego garcia"]={ 0x1F1E9, 0x1F1EC }, + ["dim button"]={ 0x1F505 }, + ["direct hit"]={ 0x1F3AF }, + ["disappointed but relieved face"]={ 0x1F625 }, + ["disappointed face"]={ 0x1F61E }, + ["dizzy"]={ 0x1F4AB }, + ["dizzy face"]={ 0x1F635 }, + ["djibouti"]={ 0x1F1E9, 0x1F1EF }, + ["dog"]={ 0x1F415 }, + ["dog face"]={ 0x1F436 }, + ["dollar banknote"]={ 0x1F4B5 }, + ["dolphin"]={ 0x1F42C }, + ["dominica"]={ 0x1F1E9, 0x1F1F2 }, + ["dominican republic"]={ 0x1F1E9, 0x1F1F4 }, + ["door"]={ 0x1F6AA }, + ["dotted six-pointed star"]={ 0x1F52F }, + ["double curly loop"]={ 0x27BF }, + ["double exclamation mark"]={ 0x203C }, + ["doughnut"]={ 0x1F369 }, + ["dove"]={ 0x1F54A }, + ["down arrow"]={ 0x2B07 }, + ["down button"]={ 0x1F53D }, + ["down-left arrow"]={ 0x2199 }, + ["down-right arrow"]={ 0x2198 }, + ["dragon"]={ 0x1F409 }, + ["dragon face"]={ 0x1F432 }, + ["dress"]={ 0x1F457 }, + ["drooling face"]={ 0x1F924 }, + ["droplet"]={ 0x1F4A7 }, + ["drum"]={ 0x1F941 }, + ["duck"]={ 0x1F986 }, + ["dumpling"]={ 0x1F95F }, + ["dvd"]={ 0x1F4C0 }, + ["e-mail"]={ 0x1F4E7 }, + ["eagle"]={ 0x1F985 }, + ["ear"]={ 0x1F442 }, + ["ear of corn"]={ 0x1F33D }, + ["ear: dark skin tone"]={ 0x1F442, 0x1F3FF }, + ["ear: light skin tone"]={ 0x1F442, 0x1F3FB }, + ["ear: medium skin tone"]={ 0x1F442, 0x1F3FD }, + ["ear: medium-dark skin tone"]={ 0x1F442, 0x1F3FE }, + ["ear: medium-light skin tone"]={ 0x1F442, 0x1F3FC }, + ["ecuador"]={ 0x1F1EA, 0x1F1E8 }, + ["egg"]={ 0x1F95A }, + ["eggplant"]={ 0x1F346 }, + ["egypt"]={ 0x1F1EA, 0x1F1EC }, + ["eight o’clock"]={ 0x1F557 }, + ["eight-pointed star"]={ 0x2734 }, + ["eight-spoked asterisk"]={ 0x2733 }, + ["eight-thirty"]={ 0x1F563 }, + ["eject button"]={ 0x23CF }, + ["el salvador"]={ 0x1F1F8, 0x1F1FB }, + ["electric plug"]={ 0x1F50C }, + ["elephant"]={ 0x1F418 }, + ["eleven o’clock"]={ 0x1F55A }, + ["eleven-thirty"]={ 0x1F566 }, + ["elf"]={ 0x1F9DD }, + ["elf: dark skin tone"]={ 0x1F9DD, 0x1F3FF }, + ["elf: light skin tone"]={ 0x1F9DD, 0x1F3FB }, + ["elf: medium skin tone"]={ 0x1F9DD, 0x1F3FD }, + ["elf: medium-dark skin tone"]={ 0x1F9DD, 0x1F3FE }, + ["elf: medium-light skin tone"]={ 0x1F9DD, 0x1F3FC }, + ["end arrow"]={ 0x1F51A }, + ["england"]={ 0x1F3F4, 0xE0067, 0xE0062, 0xE0065, 0xE006E, 0xE0067, 0xE007F }, + ["envelope"]={ 0x2709 }, + ["envelope with arrow"]={ 0x1F4E9 }, + ["equatorial guinea"]={ 0x1F1EC, 0x1F1F6 }, + ["eritrea"]={ 0x1F1EA, 0x1F1F7 }, + ["estonia"]={ 0x1F1EA, 0x1F1EA }, + ["ethiopia"]={ 0x1F1EA, 0x1F1F9 }, + ["euro banknote"]={ 0x1F4B6 }, + ["european union"]={ 0x1F1EA, 0x1F1FA }, + ["evergreen tree"]={ 0x1F332 }, + ["ewe"]={ 0x1F411 }, + ["exclamation mark"]={ 0x2757 }, + ["exclamation question mark"]={ 0x2049 }, + ["exploding head"]={ 0x1F92F }, + ["expressionless face"]={ 0x1F611 }, + ["eye"]={ 0x1F441 }, + ["eye in speech bubble"]={ 0x1F441, 0x200D, 0x1F5E8 }, + ["eyes"]={ 0x1F440 }, + ["face blowing a kiss"]={ 0x1F618 }, + ["face savouring delicious food"]={ 0x1F60B }, + ["face screaming in fear"]={ 0x1F631 }, + ["face vomiting"]={ 0x1F92E }, + ["face with cold sweat"]={ 0x1F613 }, + ["face with hand over mouth"]={ 0x1F92D }, + ["face with head-bandage"]={ 0x1F915 }, + ["face with medical mask"]={ 0x1F637 }, + ["face with monocle"]={ 0x1F9D0 }, + ["face with open mouth"]={ 0x1F62E }, + ["face with open mouth & cold sweat"]={ 0x1F630 }, + ["face with raised eyebrow"]={ 0x1F928 }, + ["face with rolling eyes"]={ 0x1F644 }, + ["face with steam from nose"]={ 0x1F624 }, + ["face with stuck-out tongue"]={ 0x1F61B }, + ["face with stuck-out tongue & closed eyes"]={ 0x1F61D }, + ["face with stuck-out tongue & winking eye"]={ 0x1F61C }, + ["face with symbols over mouth"]={ 0x1F92C }, + ["face with tears of joy"]={ 0x1F602 }, + ["face with thermometer"]={ 0x1F912 }, + ["face without mouth"]={ 0x1F636 }, + ["factory"]={ 0x1F3ED }, + ["fairy"]={ 0x1F9DA }, + ["fairy: dark skin tone"]={ 0x1F9DA, 0x1F3FF }, + ["fairy: light skin tone"]={ 0x1F9DA, 0x1F3FB }, + ["fairy: medium skin tone"]={ 0x1F9DA, 0x1F3FD }, + ["fairy: medium-dark skin tone"]={ 0x1F9DA, 0x1F3FE }, + ["fairy: medium-light skin tone"]={ 0x1F9DA, 0x1F3FC }, + ["falkland islands"]={ 0x1F1EB, 0x1F1F0 }, + ["fallen leaf"]={ 0x1F342 }, + ["family"]={ 0x1F46A }, + ["family: man, boy"]={ 0x1F468, 0x200D, 0x1F466 }, + ["family: man, boy, boy"]={ 0x1F468, 0x200D, 0x1F466, 0x200D, 0x1F466 }, + ["family: man, girl"]={ 0x1F468, 0x200D, 0x1F467 }, + ["family: man, girl, boy"]={ 0x1F468, 0x200D, 0x1F467, 0x200D, 0x1F466 }, + ["family: man, girl, girl"]={ 0x1F468, 0x200D, 0x1F467, 0x200D, 0x1F467 }, + ["family: man, man, boy"]={ 0x1F468, 0x200D, 0x1F468, 0x200D, 0x1F466 }, + ["family: man, man, boy, boy"]={ 0x1F468, 0x200D, 0x1F468, 0x200D, 0x1F466, 0x200D, 0x1F466 }, + ["family: man, man, girl"]={ 0x1F468, 0x200D, 0x1F468, 0x200D, 0x1F467 }, + ["family: man, man, girl, boy"]={ 0x1F468, 0x200D, 0x1F468, 0x200D, 0x1F467, 0x200D, 0x1F466 }, + ["family: man, man, girl, girl"]={ 0x1F468, 0x200D, 0x1F468, 0x200D, 0x1F467, 0x200D, 0x1F467 }, + ["family: man, woman, boy"]={ 0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F466 }, + ["family: man, woman, boy, boy"]={ 0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F466, 0x200D, 0x1F466 }, + ["family: man, woman, girl"]={ 0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F467 }, + ["family: man, woman, girl, boy"]={ 0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F466 }, + ["family: man, woman, girl, girl"]={ 0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F467 }, + ["family: woman, boy"]={ 0x1F469, 0x200D, 0x1F466 }, + ["family: woman, boy, boy"]={ 0x1F469, 0x200D, 0x1F466, 0x200D, 0x1F466 }, + ["family: woman, girl"]={ 0x1F469, 0x200D, 0x1F467 }, + ["family: woman, girl, boy"]={ 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F466 }, + ["family: woman, girl, girl"]={ 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F467 }, + ["family: woman, woman, boy"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F466 }, + ["family: woman, woman, boy, boy"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F466, 0x200D, 0x1F466 }, + ["family: woman, woman, girl"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F467 }, + ["family: woman, woman, girl, boy"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F466 }, + ["family: woman, woman, girl, girl"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F467 }, + ["faroe islands"]={ 0x1F1EB, 0x1F1F4 }, + ["fast down button"]={ 0x23EC }, + ["fast reverse button"]={ 0x23EA }, + ["fast up button"]={ 0x23EB }, + ["fast-forward button"]={ 0x23E9 }, + ["fax machine"]={ 0x1F4E0 }, + ["fearful face"]={ 0x1F628 }, + ["female sign"]={ 0x2640 }, + ["ferris wheel"]={ 0x1F3A1 }, + ["ferry"]={ 0x26F4 }, + ["field hockey"]={ 0x1F3D1 }, + ["fiji"]={ 0x1F1EB, 0x1F1EF }, + ["file cabinet"]={ 0x1F5C4 }, + ["file folder"]={ 0x1F4C1 }, + ["film frames"]={ 0x1F39E }, + ["film projector"]={ 0x1F4FD }, + ["finland"]={ 0x1F1EB, 0x1F1EE }, + ["fire"]={ 0x1F525 }, + ["fire engine"]={ 0x1F692 }, + ["fireworks"]={ 0x1F386 }, + ["first quarter moon"]={ 0x1F313 }, + ["first quarter moon with face"]={ 0x1F31B }, + ["fish"]={ 0x1F41F }, + ["fish cake with swirl"]={ 0x1F365 }, + ["fishing pole"]={ 0x1F3A3 }, + ["five o’clock"]={ 0x1F554 }, + ["five-thirty"]={ 0x1F560 }, + ["flag in hole"]={ 0x26F3 }, + ["flashlight"]={ 0x1F526 }, + ["fleur-de-lis"]={ 0x269C }, + ["flexed biceps"]={ 0x1F4AA }, + ["flexed biceps: dark skin tone"]={ 0x1F4AA, 0x1F3FF }, + ["flexed biceps: light skin tone"]={ 0x1F4AA, 0x1F3FB }, + ["flexed biceps: medium skin tone"]={ 0x1F4AA, 0x1F3FD }, + ["flexed biceps: medium-dark skin tone"]={ 0x1F4AA, 0x1F3FE }, + ["flexed biceps: medium-light skin tone"]={ 0x1F4AA, 0x1F3FC }, + ["floppy disk"]={ 0x1F4BE }, + ["flower playing cards"]={ 0x1F3B4 }, + ["flushed face"]={ 0x1F633 }, + ["flying saucer"]={ 0x1F6F8 }, + ["fog"]={ 0x1F32B }, + ["foggy"]={ 0x1F301 }, + ["folded hands"]={ 0x1F64F }, + ["folded hands: dark skin tone"]={ 0x1F64F, 0x1F3FF }, + ["folded hands: light skin tone"]={ 0x1F64F, 0x1F3FB }, + ["folded hands: medium skin tone"]={ 0x1F64F, 0x1F3FD }, + ["folded hands: medium-dark skin tone"]={ 0x1F64F, 0x1F3FE }, + ["folded hands: medium-light skin tone"]={ 0x1F64F, 0x1F3FC }, + ["footprints"]={ 0x1F463 }, + ["fork and knife"]={ 0x1F374 }, + ["fork and knife with plate"]={ 0x1F37D }, + ["fortune cookie"]={ 0x1F960 }, + ["fountain"]={ 0x26F2 }, + ["fountain pen"]={ 0x1F58B }, + ["four leaf clover"]={ 0x1F340 }, + ["four o’clock"]={ 0x1F553 }, + ["four-thirty"]={ 0x1F55F }, + ["fox face"]={ 0x1F98A }, + ["framed picture"]={ 0x1F5BC }, + ["france"]={ 0x1F1EB, 0x1F1F7 }, + ["free button"]={ 0x1F193 }, + ["french fries"]={ 0x1F35F }, + ["french guiana"]={ 0x1F1EC, 0x1F1EB }, + ["french polynesia"]={ 0x1F1F5, 0x1F1EB }, + ["french southern territories"]={ 0x1F1F9, 0x1F1EB }, + ["fried shrimp"]={ 0x1F364 }, + ["frog face"]={ 0x1F438 }, + ["front-facing baby chick"]={ 0x1F425 }, + ["frowning face"]={ 0x2639 }, + ["frowning face with open mouth"]={ 0x1F626 }, + ["fuel pump"]={ 0x26FD }, + ["full moon"]={ 0x1F315 }, + ["full moon with face"]={ 0x1F31D }, + ["funeral urn"]={ 0x26B1 }, + ["gabon"]={ 0x1F1EC, 0x1F1E6 }, + ["gambia"]={ 0x1F1EC, 0x1F1F2 }, + ["game die"]={ 0x1F3B2 }, + ["gear"]={ 0x2699 }, + ["gem stone"]={ 0x1F48E }, + ["gemini"]={ 0x264A }, + ["genie"]={ 0x1F9DE }, + ["georgia"]={ 0x1F1EC, 0x1F1EA }, + ["germany"]={ 0x1F1E9, 0x1F1EA }, + ["ghana"]={ 0x1F1EC, 0x1F1ED }, + ["ghost"]={ 0x1F47B }, + ["gibraltar"]={ 0x1F1EC, 0x1F1EE }, + ["giraffe"]={ 0x1F992 }, + ["girl"]={ 0x1F467 }, + ["girl: dark skin tone"]={ 0x1F467, 0x1F3FF }, + ["girl: light skin tone"]={ 0x1F467, 0x1F3FB }, + ["girl: medium skin tone"]={ 0x1F467, 0x1F3FD }, + ["girl: medium-dark skin tone"]={ 0x1F467, 0x1F3FE }, + ["girl: medium-light skin tone"]={ 0x1F467, 0x1F3FC }, + ["glass of milk"]={ 0x1F95B }, + ["glasses"]={ 0x1F453 }, + ["globe showing americas"]={ 0x1F30E }, + ["globe showing asia-australia"]={ 0x1F30F }, + ["globe showing europe-africa"]={ 0x1F30D }, + ["globe with meridians"]={ 0x1F310 }, + ["gloves"]={ 0x1F9E4 }, + ["glowing star"]={ 0x1F31F }, + ["goal net"]={ 0x1F945 }, + ["goat"]={ 0x1F410 }, + ["goblin"]={ 0x1F47A }, + ["gorilla"]={ 0x1F98D }, + ["graduation cap"]={ 0x1F393 }, + ["grapes"]={ 0x1F347 }, + ["greece"]={ 0x1F1EC, 0x1F1F7 }, + ["green apple"]={ 0x1F34F }, + ["green book"]={ 0x1F4D7 }, + ["green heart"]={ 0x1F49A }, + ["green salad"]={ 0x1F957 }, + ["greenland"]={ 0x1F1EC, 0x1F1F1 }, + ["grenada"]={ 0x1F1EC, 0x1F1E9 }, + ["grimacing face"]={ 0x1F62C }, + ["grinning cat face with smiling eyes"]={ 0x1F638 }, + ["grinning face"]={ 0x1F600 }, + ["grinning face with smiling eyes"]={ 0x1F601 }, + ["growing heart"]={ 0x1F497 }, + ["guadeloupe"]={ 0x1F1EC, 0x1F1F5 }, + ["guam"]={ 0x1F1EC, 0x1F1FA }, + ["guard"]={ 0x1F482 }, + ["guard: dark skin tone"]={ 0x1F482, 0x1F3FF }, + ["guard: light skin tone"]={ 0x1F482, 0x1F3FB }, + ["guard: medium skin tone"]={ 0x1F482, 0x1F3FD }, + ["guard: medium-dark skin tone"]={ 0x1F482, 0x1F3FE }, + ["guard: medium-light skin tone"]={ 0x1F482, 0x1F3FC }, + ["guatemala"]={ 0x1F1EC, 0x1F1F9 }, + ["guernsey"]={ 0x1F1EC, 0x1F1EC }, + ["guinea"]={ 0x1F1EC, 0x1F1F3 }, + ["guinea-bissau"]={ 0x1F1EC, 0x1F1FC }, + ["guitar"]={ 0x1F3B8 }, + ["guyana"]={ 0x1F1EC, 0x1F1FE }, + ["haiti"]={ 0x1F1ED, 0x1F1F9 }, + ["hamburger"]={ 0x1F354 }, + ["hammer"]={ 0x1F528 }, + ["hammer and pick"]={ 0x2692 }, + ["hammer and wrench"]={ 0x1F6E0 }, + ["hamster face"]={ 0x1F439 }, + ["handbag"]={ 0x1F45C }, + ["handshake"]={ 0x1F91D }, + ["hatching chick"]={ 0x1F423 }, + ["headphone"]={ 0x1F3A7 }, + ["hear-no-evil monkey"]={ 0x1F649 }, + ["heard & mcdonald islands"]={ 0x1F1ED, 0x1F1F2 }, + ["heart decoration"]={ 0x1F49F }, + ["heart suit"]={ 0x2665 }, + ["heart with arrow"]={ 0x1F498 }, + ["heart with ribbon"]={ 0x1F49D }, + ["heavy check mark"]={ 0x2714 }, + ["heavy division sign"]={ 0x2797 }, + ["heavy dollar sign"]={ 0x1F4B2 }, + ["heavy heart exclamation"]={ 0x2763 }, + ["heavy large circle"]={ 0x2B55 }, + ["heavy minus sign"]={ 0x2796 }, + ["heavy multiplication x"]={ 0x2716 }, + ["heavy plus sign"]={ 0x2795 }, + ["hedgehog"]={ 0x1F994 }, + ["helicopter"]={ 0x1F681 }, + ["herb"]={ 0x1F33F }, + ["hibiscus"]={ 0x1F33A }, + ["high voltage"]={ 0x26A1 }, + ["high-heeled shoe"]={ 0x1F460 }, + ["high-speed train"]={ 0x1F684 }, + ["high-speed train with bullet nose"]={ 0x1F685 }, + ["hole"]={ 0x1F573 }, + ["honduras"]={ 0x1F1ED, 0x1F1F3 }, + ["honey pot"]={ 0x1F36F }, + ["honeybee"]={ 0x1F41D }, + ["hong kong sar china"]={ 0x1F1ED, 0x1F1F0 }, + ["horizontal traffic light"]={ 0x1F6A5 }, + ["horse"]={ 0x1F40E }, + ["horse face"]={ 0x1F434 }, + ["horse racing"]={ 0x1F3C7 }, + ["horse racing: dark skin tone"]={ 0x1F3C7, 0x1F3FF }, + ["horse racing: light skin tone"]={ 0x1F3C7, 0x1F3FB }, + ["horse racing: medium skin tone"]={ 0x1F3C7, 0x1F3FD }, + ["horse racing: medium-dark skin tone"]={ 0x1F3C7, 0x1F3FE }, + ["horse racing: medium-light skin tone"]={ 0x1F3C7, 0x1F3FC }, + ["hospital"]={ 0x1F3E5 }, + ["hot beverage"]={ 0x2615 }, + ["hot dog"]={ 0x1F32D }, + ["hot pepper"]={ 0x1F336 }, + ["hot springs"]={ 0x2668 }, + ["hotel"]={ 0x1F3E8 }, + ["hourglass"]={ 0x231B }, + ["hourglass with flowing sand"]={ 0x23F3 }, + ["house"]={ 0x1F3E0 }, + ["house with garden"]={ 0x1F3E1 }, + ["hugging face"]={ 0x1F917 }, + ["hundred points"]={ 0x1F4AF }, + ["hungary"]={ 0x1F1ED, 0x1F1FA }, + ["hushed face"]={ 0x1F62F }, + ["ice cream"]={ 0x1F368 }, + ["ice hockey"]={ 0x1F3D2 }, + ["ice skate"]={ 0x26F8 }, + ["iceland"]={ 0x1F1EE, 0x1F1F8 }, + ["id button"]={ 0x1F194 }, + ["inbox tray"]={ 0x1F4E5 }, + ["incoming envelope"]={ 0x1F4E8 }, + ["index pointing up"]={ 0x261D }, + ["index pointing up: dark skin tone"]={ 0x261D, 0x1F3FF }, + ["index pointing up: light skin tone"]={ 0x261D, 0x1F3FB }, + ["index pointing up: medium skin tone"]={ 0x261D, 0x1F3FD }, + ["index pointing up: medium-dark skin tone"]={ 0x261D, 0x1F3FE }, + ["index pointing up: medium-light skin tone"]={ 0x261D, 0x1F3FC }, + ["india"]={ 0x1F1EE, 0x1F1F3 }, + ["indonesia"]={ 0x1F1EE, 0x1F1E9 }, + ["information"]={ 0x2139 }, + ["input latin letters"]={ 0x1F524 }, + ["input latin lowercase"]={ 0x1F521 }, + ["input latin uppercase"]={ 0x1F520 }, + ["input numbers"]={ 0x1F522 }, + ["input symbols"]={ 0x1F523 }, + ["iran"]={ 0x1F1EE, 0x1F1F7 }, + ["iraq"]={ 0x1F1EE, 0x1F1F6 }, + ["ireland"]={ 0x1F1EE, 0x1F1EA }, + ["isle of man"]={ 0x1F1EE, 0x1F1F2 }, + ["israel"]={ 0x1F1EE, 0x1F1F1 }, + ["italy"]={ 0x1F1EE, 0x1F1F9 }, + ["jack-o-lantern"]={ 0x1F383 }, + ["jamaica"]={ 0x1F1EF, 0x1F1F2 }, + ["japan"]={ 0x1F1EF, 0x1F1F5 }, + ["japanese castle"]={ 0x1F3EF }, + ["japanese dolls"]={ 0x1F38E }, + ["japanese post office"]={ 0x1F3E3 }, + ["japanese symbol for beginner"]={ 0x1F530 }, + ["japanese “acceptable” button"]={ 0x1F251 }, + ["japanese “application” button"]={ 0x1F238 }, + ["japanese “bargain” button"]={ 0x1F250 }, + ["japanese “congratulations” button"]={ 0x3297 }, + ["japanese “discount” button"]={ 0x1F239 }, + ["japanese “free of charge” button"]={ 0x1F21A }, + ["japanese “here” button"]={ 0x1F201 }, + ["japanese “monthly amount” button"]={ 0x1F237 }, + ["japanese “no vacancy” button"]={ 0x1F235 }, + ["japanese “not free of charge” button"]={ 0x1F236 }, + ["japanese “open for business” button"]={ 0x1F23A }, + ["japanese “passing grade” button"]={ 0x1F234 }, + ["japanese “prohibited” button"]={ 0x1F232 }, + ["japanese “reserved” button"]={ 0x1F22F }, + ["japanese “secret” button"]={ 0x3299 }, + ["japanese “service charge” button"]={ 0x1F202 }, + ["japanese “vacancy” button"]={ 0x1F233 }, + ["jeans"]={ 0x1F456 }, + ["jersey"]={ 0x1F1EF, 0x1F1EA }, + ["joker"]={ 0x1F0CF }, + ["jordan"]={ 0x1F1EF, 0x1F1F4 }, + ["joystick"]={ 0x1F579 }, + ["kaaba"]={ 0x1F54B }, + ["kazakhstan"]={ 0x1F1F0, 0x1F1FF }, + ["kenya"]={ 0x1F1F0, 0x1F1EA }, + ["key"]={ 0x1F511 }, + ["keyboard"]={ 0x2328 }, + ["keycap 10"]={ 0x1F51F }, + ["keycap: 0"]={ 0x30, 0x20E3 }, + ["keycap: 1"]={ 0x31, 0x20E3 }, + ["keycap: 2"]={ 0x32, 0x20E3 }, + ["keycap: 3"]={ 0x33, 0x20E3 }, + ["keycap: 4"]={ 0x34, 0x20E3 }, + ["keycap: 5"]={ 0x35, 0x20E3 }, + ["keycap: 6"]={ 0x36, 0x20E3 }, + ["keycap: 7"]={ 0x37, 0x20E3 }, + ["keycap: 8"]={ 0x38, 0x20E3 }, + ["keycap: 9"]={ 0x39, 0x20E3 }, + ["keycap: asterisk"]={ 0x2A, 0x20E3 }, + ["keycap: hash"]={ 0x23, 0x20E3 }, + ["kick scooter"]={ 0x1F6F4 }, + ["kimono"]={ 0x1F458 }, + ["kiribati"]={ 0x1F1F0, 0x1F1EE }, + ["kiss"]={ 0x1F48F }, + ["kiss mark"]={ 0x1F48B }, + ["kiss: man, man"]={ 0x1F468, 0x200D, 0x2764, 0x200D, 0x1F48B, 0x200D, 0x1F468 }, + ["kiss: woman, man"]={ 0x1F469, 0x200D, 0x2764, 0x200D, 0x1F48B, 0x200D, 0x1F468 }, + ["kiss: woman, woman"]={ 0x1F469, 0x200D, 0x2764, 0x200D, 0x1F48B, 0x200D, 0x1F469 }, + ["kissing cat face with closed eyes"]={ 0x1F63D }, + ["kissing face"]={ 0x1F617 }, + ["kissing face with closed eyes"]={ 0x1F61A }, + ["kissing face with smiling eyes"]={ 0x1F619 }, + ["kitchen knife"]={ 0x1F52A }, + ["kiwi fruit"]={ 0x1F95D }, + ["koala"]={ 0x1F428 }, + ["kosovo"]={ 0x1F1FD, 0x1F1F0 }, + ["kuwait"]={ 0x1F1F0, 0x1F1FC }, + ["kyrgyzstan"]={ 0x1F1F0, 0x1F1EC }, + ["label"]={ 0x1F3F7 }, + ["lady beetle"]={ 0x1F41E }, + ["laos"]={ 0x1F1F1, 0x1F1E6 }, + ["laptop computer"]={ 0x1F4BB }, + ["large blue diamond"]={ 0x1F537 }, + ["large orange diamond"]={ 0x1F536 }, + ["last quarter moon"]={ 0x1F317 }, + ["last quarter moon with face"]={ 0x1F31C }, + ["last track button"]={ 0x23EE }, + ["latin cross"]={ 0x271D }, + ["latvia"]={ 0x1F1F1, 0x1F1FB }, + ["leaf fluttering in wind"]={ 0x1F343 }, + ["lebanon"]={ 0x1F1F1, 0x1F1E7 }, + ["ledger"]={ 0x1F4D2 }, + ["left arrow"]={ 0x2B05 }, + ["left arrow curving right"]={ 0x21AA }, + ["left luggage"]={ 0x1F6C5 }, + ["left speech bubble"]={ 0x1F5E8 }, + ["left-facing fist"]={ 0x1F91B }, + ["left-facing fist: dark skin tone"]={ 0x1F91B, 0x1F3FF }, + ["left-facing fist: light skin tone"]={ 0x1F91B, 0x1F3FB }, + ["left-facing fist: medium skin tone"]={ 0x1F91B, 0x1F3FD }, + ["left-facing fist: medium-dark skin tone"]={ 0x1F91B, 0x1F3FE }, + ["left-facing fist: medium-light skin tone"]={ 0x1F91B, 0x1F3FC }, + ["left-pointing magnifying glass"]={ 0x1F50D }, + ["left-right arrow"]={ 0x2194 }, + ["lemon"]={ 0x1F34B }, + ["leo"]={ 0x264C }, + ["leopard"]={ 0x1F406 }, + ["lesotho"]={ 0x1F1F1, 0x1F1F8 }, + ["level slider"]={ 0x1F39A }, + ["liberia"]={ 0x1F1F1, 0x1F1F7 }, + ["libra"]={ 0x264E }, + ["libya"]={ 0x1F1F1, 0x1F1FE }, + ["liechtenstein"]={ 0x1F1F1, 0x1F1EE }, + ["light bulb"]={ 0x1F4A1 }, + ["light rail"]={ 0x1F688 }, + ["link"]={ 0x1F517 }, + ["linked paperclips"]={ 0x1F587 }, + ["lion face"]={ 0x1F981 }, + ["lipstick"]={ 0x1F484 }, + ["lithuania"]={ 0x1F1F1, 0x1F1F9 }, + ["litter in bin sign"]={ 0x1F6AE }, + ["lizard"]={ 0x1F98E }, + ["locked"]={ 0x1F512 }, + ["locked with key"]={ 0x1F510 }, + ["locked with pen"]={ 0x1F50F }, + ["locomotive"]={ 0x1F682 }, + ["lollipop"]={ 0x1F36D }, + ["loudly crying face"]={ 0x1F62D }, + ["loudspeaker"]={ 0x1F4E2 }, + ["love hotel"]={ 0x1F3E9 }, + ["love letter"]={ 0x1F48C }, + ["love-you gesture"]={ 0x1F91F }, + ["love-you gesture: dark skin tone"]={ 0x1F91F, 0x1F3FF }, + ["love-you gesture: light skin tone"]={ 0x1F91F, 0x1F3FB }, + ["love-you gesture: medium skin tone"]={ 0x1F91F, 0x1F3FD }, + ["love-you gesture: medium-dark skin tone"]={ 0x1F91F, 0x1F3FE }, + ["love-you gesture: medium-light skin tone"]={ 0x1F91F, 0x1F3FC }, + ["luxembourg"]={ 0x1F1F1, 0x1F1FA }, + ["lying face"]={ 0x1F925 }, + ["macau sar china"]={ 0x1F1F2, 0x1F1F4 }, + ["macedonia"]={ 0x1F1F2, 0x1F1F0 }, + ["madagascar"]={ 0x1F1F2, 0x1F1EC }, + ["mage"]={ 0x1F9D9 }, + ["mage: dark skin tone"]={ 0x1F9D9, 0x1F3FF }, + ["mage: light skin tone"]={ 0x1F9D9, 0x1F3FB }, + ["mage: medium skin tone"]={ 0x1F9D9, 0x1F3FD }, + ["mage: medium-dark skin tone"]={ 0x1F9D9, 0x1F3FE }, + ["mage: medium-light skin tone"]={ 0x1F9D9, 0x1F3FC }, + ["mahjong red dragon"]={ 0x1F004 }, + ["malawi"]={ 0x1F1F2, 0x1F1FC }, + ["malaysia"]={ 0x1F1F2, 0x1F1FE }, + ["maldives"]={ 0x1F1F2, 0x1F1FB }, + ["male sign"]={ 0x2642 }, + ["mali"]={ 0x1F1F2, 0x1F1F1 }, + ["malta"]={ 0x1F1F2, 0x1F1F9 }, + ["man"]={ 0x1F468 }, + ["man and woman holding hands"]={ 0x1F46B }, + ["man artist"]={ 0x1F468, 0x200D, 0x1F3A8 }, + ["man artist: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F3A8 }, + ["man artist: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F3A8 }, + ["man artist: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F3A8 }, + ["man artist: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F3A8 }, + ["man artist: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F3A8 }, + ["man astronaut"]={ 0x1F468, 0x200D, 0x1F680 }, + ["man astronaut: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F680 }, + ["man astronaut: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F680 }, + ["man astronaut: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F680 }, + ["man astronaut: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F680 }, + ["man astronaut: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F680 }, + ["man biking"]={ 0x1F6B4, 0x200D, 0x2642 }, + ["man biking: dark skin tone"]={ 0x1F6B4, 0x1F3FF, 0x200D, 0x2642 }, + ["man biking: light skin tone"]={ 0x1F6B4, 0x1F3FB, 0x200D, 0x2642 }, + ["man biking: medium skin tone"]={ 0x1F6B4, 0x1F3FD, 0x200D, 0x2642 }, + ["man biking: medium-dark skin tone"]={ 0x1F6B4, 0x1F3FE, 0x200D, 0x2642 }, + ["man biking: medium-light skin tone"]={ 0x1F6B4, 0x1F3FC, 0x200D, 0x2642 }, + ["man bouncing ball"]={ 0x26F9, 0x200D, 0x2642 }, + ["man bouncing ball: dark skin tone"]={ 0x26F9, 0x1F3FF, 0x200D, 0x2642 }, + ["man bouncing ball: light skin tone"]={ 0x26F9, 0x1F3FB, 0x200D, 0x2642 }, + ["man bouncing ball: medium skin tone"]={ 0x26F9, 0x1F3FD, 0x200D, 0x2642 }, + ["man bouncing ball: medium-dark skin tone"]={ 0x26F9, 0x1F3FE, 0x200D, 0x2642 }, + ["man bouncing ball: medium-light skin tone"]={ 0x26F9, 0x1F3FC, 0x200D, 0x2642 }, + ["man bowing"]={ 0x1F647, 0x200D, 0x2642 }, + ["man bowing: dark skin tone"]={ 0x1F647, 0x1F3FF, 0x200D, 0x2642 }, + ["man bowing: light skin tone"]={ 0x1F647, 0x1F3FB, 0x200D, 0x2642 }, + ["man bowing: medium skin tone"]={ 0x1F647, 0x1F3FD, 0x200D, 0x2642 }, + ["man bowing: medium-dark skin tone"]={ 0x1F647, 0x1F3FE, 0x200D, 0x2642 }, + ["man bowing: medium-light skin tone"]={ 0x1F647, 0x1F3FC, 0x200D, 0x2642 }, + ["man cartwheeling"]={ 0x1F938, 0x200D, 0x2642 }, + ["man cartwheeling: dark skin tone"]={ 0x1F938, 0x1F3FF, 0x200D, 0x2642 }, + ["man cartwheeling: light skin tone"]={ 0x1F938, 0x1F3FB, 0x200D, 0x2642 }, + ["man cartwheeling: medium skin tone"]={ 0x1F938, 0x1F3FD, 0x200D, 0x2642 }, + ["man cartwheeling: medium-dark skin tone"]={ 0x1F938, 0x1F3FE, 0x200D, 0x2642 }, + ["man cartwheeling: medium-light skin tone"]={ 0x1F938, 0x1F3FC, 0x200D, 0x2642 }, + ["man climbing"]={ 0x1F9D7, 0x200D, 0x2642 }, + ["man climbing: dark skin tone"]={ 0x1F9D7, 0x1F3FF, 0x200D, 0x2642 }, + ["man climbing: light skin tone"]={ 0x1F9D7, 0x1F3FB, 0x200D, 0x2642 }, + ["man climbing: medium skin tone"]={ 0x1F9D7, 0x1F3FD, 0x200D, 0x2642 }, + ["man climbing: medium-dark skin tone"]={ 0x1F9D7, 0x1F3FE, 0x200D, 0x2642 }, + ["man climbing: medium-light skin tone"]={ 0x1F9D7, 0x1F3FC, 0x200D, 0x2642 }, + ["man construction worker"]={ 0x1F477, 0x200D, 0x2642 }, + ["man construction worker: dark skin tone"]={ 0x1F477, 0x1F3FF, 0x200D, 0x2642 }, + ["man construction worker: light skin tone"]={ 0x1F477, 0x1F3FB, 0x200D, 0x2642 }, + ["man construction worker: medium skin tone"]={ 0x1F477, 0x1F3FD, 0x200D, 0x2642 }, + ["man construction worker: medium-dark skin tone"]={ 0x1F477, 0x1F3FE, 0x200D, 0x2642 }, + ["man construction worker: medium-light skin tone"]={ 0x1F477, 0x1F3FC, 0x200D, 0x2642 }, + ["man cook"]={ 0x1F468, 0x200D, 0x1F373 }, + ["man cook: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F373 }, + ["man cook: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F373 }, + ["man cook: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F373 }, + ["man cook: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F373 }, + ["man cook: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F373 }, + ["man dancing"]={ 0x1F57A }, + ["man dancing: dark skin tone"]={ 0x1F57A, 0x1F3FF }, + ["man dancing: light skin tone"]={ 0x1F57A, 0x1F3FB }, + ["man dancing: medium skin tone"]={ 0x1F57A, 0x1F3FD }, + ["man dancing: medium-dark skin tone"]={ 0x1F57A, 0x1F3FE }, + ["man dancing: medium-light skin tone"]={ 0x1F57A, 0x1F3FC }, + ["man detective"]={ 0x1F575, 0x200D, 0x2642 }, + ["man detective: dark skin tone"]={ 0x1F575, 0x1F3FF, 0x200D, 0x2642 }, + ["man detective: light skin tone"]={ 0x1F575, 0x1F3FB, 0x200D, 0x2642 }, + ["man detective: medium skin tone"]={ 0x1F575, 0x1F3FD, 0x200D, 0x2642 }, + ["man detective: medium-dark skin tone"]={ 0x1F575, 0x1F3FE, 0x200D, 0x2642 }, + ["man detective: medium-light skin tone"]={ 0x1F575, 0x1F3FC, 0x200D, 0x2642 }, + ["man elf"]={ 0x1F9DD, 0x200D, 0x2642 }, + ["man elf: dark skin tone"]={ 0x1F9DD, 0x1F3FF, 0x200D, 0x2642 }, + ["man elf: light skin tone"]={ 0x1F9DD, 0x1F3FB, 0x200D, 0x2642 }, + ["man elf: medium skin tone"]={ 0x1F9DD, 0x1F3FD, 0x200D, 0x2642 }, + ["man elf: medium-dark skin tone"]={ 0x1F9DD, 0x1F3FE, 0x200D, 0x2642 }, + ["man elf: medium-light skin tone"]={ 0x1F9DD, 0x1F3FC, 0x200D, 0x2642 }, + ["man facepalming"]={ 0x1F926, 0x200D, 0x2642 }, + ["man facepalming: dark skin tone"]={ 0x1F926, 0x1F3FF, 0x200D, 0x2642 }, + ["man facepalming: light skin tone"]={ 0x1F926, 0x1F3FB, 0x200D, 0x2642 }, + ["man facepalming: medium skin tone"]={ 0x1F926, 0x1F3FD, 0x200D, 0x2642 }, + ["man facepalming: medium-dark skin tone"]={ 0x1F926, 0x1F3FE, 0x200D, 0x2642 }, + ["man facepalming: medium-light skin tone"]={ 0x1F926, 0x1F3FC, 0x200D, 0x2642 }, + ["man factory worker"]={ 0x1F468, 0x200D, 0x1F3ED }, + ["man factory worker: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F3ED }, + ["man factory worker: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F3ED }, + ["man factory worker: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F3ED }, + ["man factory worker: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F3ED }, + ["man factory worker: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F3ED }, + ["man fairy"]={ 0x1F9DA, 0x200D, 0x2642 }, + ["man fairy: dark skin tone"]={ 0x1F9DA, 0x1F3FF, 0x200D, 0x2642 }, + ["man fairy: light skin tone"]={ 0x1F9DA, 0x1F3FB, 0x200D, 0x2642 }, + ["man fairy: medium skin tone"]={ 0x1F9DA, 0x1F3FD, 0x200D, 0x2642 }, + ["man fairy: medium-dark skin tone"]={ 0x1F9DA, 0x1F3FE, 0x200D, 0x2642 }, + ["man fairy: medium-light skin tone"]={ 0x1F9DA, 0x1F3FC, 0x200D, 0x2642 }, + ["man farmer"]={ 0x1F468, 0x200D, 0x1F33E }, + ["man farmer: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F33E }, + ["man farmer: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F33E }, + ["man farmer: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F33E }, + ["man farmer: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F33E }, + ["man farmer: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F33E }, + ["man firefighter"]={ 0x1F468, 0x200D, 0x1F692 }, + ["man firefighter: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F692 }, + ["man firefighter: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F692 }, + ["man firefighter: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F692 }, + ["man firefighter: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F692 }, + ["man firefighter: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F692 }, + ["man frowning"]={ 0x1F64D, 0x200D, 0x2642 }, + ["man frowning: dark skin tone"]={ 0x1F64D, 0x1F3FF, 0x200D, 0x2642 }, + ["man frowning: light skin tone"]={ 0x1F64D, 0x1F3FB, 0x200D, 0x2642 }, + ["man frowning: medium skin tone"]={ 0x1F64D, 0x1F3FD, 0x200D, 0x2642 }, + ["man frowning: medium-dark skin tone"]={ 0x1F64D, 0x1F3FE, 0x200D, 0x2642 }, + ["man frowning: medium-light skin tone"]={ 0x1F64D, 0x1F3FC, 0x200D, 0x2642 }, + ["man genie"]={ 0x1F9DE, 0x200D, 0x2642 }, + ["man gesturing no"]={ 0x1F645, 0x200D, 0x2642 }, + ["man gesturing no: dark skin tone"]={ 0x1F645, 0x1F3FF, 0x200D, 0x2642 }, + ["man gesturing no: light skin tone"]={ 0x1F645, 0x1F3FB, 0x200D, 0x2642 }, + ["man gesturing no: medium skin tone"]={ 0x1F645, 0x1F3FD, 0x200D, 0x2642 }, + ["man gesturing no: medium-dark skin tone"]={ 0x1F645, 0x1F3FE, 0x200D, 0x2642 }, + ["man gesturing no: medium-light skin tone"]={ 0x1F645, 0x1F3FC, 0x200D, 0x2642 }, + ["man gesturing ok"]={ 0x1F646, 0x200D, 0x2642 }, + ["man gesturing ok: dark skin tone"]={ 0x1F646, 0x1F3FF, 0x200D, 0x2642 }, + ["man gesturing ok: light skin tone"]={ 0x1F646, 0x1F3FB, 0x200D, 0x2642 }, + ["man gesturing ok: medium skin tone"]={ 0x1F646, 0x1F3FD, 0x200D, 0x2642 }, + ["man gesturing ok: medium-dark skin tone"]={ 0x1F646, 0x1F3FE, 0x200D, 0x2642 }, + ["man gesturing ok: medium-light skin tone"]={ 0x1F646, 0x1F3FC, 0x200D, 0x2642 }, + ["man getting haircut"]={ 0x1F487, 0x200D, 0x2642 }, + ["man getting haircut: dark skin tone"]={ 0x1F487, 0x1F3FF, 0x200D, 0x2642 }, + ["man getting haircut: light skin tone"]={ 0x1F487, 0x1F3FB, 0x200D, 0x2642 }, + ["man getting haircut: medium skin tone"]={ 0x1F487, 0x1F3FD, 0x200D, 0x2642 }, + ["man getting haircut: medium-dark skin tone"]={ 0x1F487, 0x1F3FE, 0x200D, 0x2642 }, + ["man getting haircut: medium-light skin tone"]={ 0x1F487, 0x1F3FC, 0x200D, 0x2642 }, + ["man getting massage"]={ 0x1F486, 0x200D, 0x2642 }, + ["man getting massage: dark skin tone"]={ 0x1F486, 0x1F3FF, 0x200D, 0x2642 }, + ["man getting massage: light skin tone"]={ 0x1F486, 0x1F3FB, 0x200D, 0x2642 }, + ["man getting massage: medium skin tone"]={ 0x1F486, 0x1F3FD, 0x200D, 0x2642 }, + ["man getting massage: medium-dark skin tone"]={ 0x1F486, 0x1F3FE, 0x200D, 0x2642 }, + ["man getting massage: medium-light skin tone"]={ 0x1F486, 0x1F3FC, 0x200D, 0x2642 }, + ["man golfing"]={ 0x1F3CC, 0x200D, 0x2642 }, + ["man golfing: dark skin tone"]={ 0x1F3CC, 0x1F3FF, 0x200D, 0x2642 }, + ["man golfing: light skin tone"]={ 0x1F3CC, 0x1F3FB, 0x200D, 0x2642 }, + ["man golfing: medium skin tone"]={ 0x1F3CC, 0x1F3FD, 0x200D, 0x2642 }, + ["man golfing: medium-dark skin tone"]={ 0x1F3CC, 0x1F3FE, 0x200D, 0x2642 }, + ["man golfing: medium-light skin tone"]={ 0x1F3CC, 0x1F3FC, 0x200D, 0x2642 }, + ["man guard"]={ 0x1F482, 0x200D, 0x2642 }, + ["man guard: dark skin tone"]={ 0x1F482, 0x1F3FF, 0x200D, 0x2642 }, + ["man guard: light skin tone"]={ 0x1F482, 0x1F3FB, 0x200D, 0x2642 }, + ["man guard: medium skin tone"]={ 0x1F482, 0x1F3FD, 0x200D, 0x2642 }, + ["man guard: medium-dark skin tone"]={ 0x1F482, 0x1F3FE, 0x200D, 0x2642 }, + ["man guard: medium-light skin tone"]={ 0x1F482, 0x1F3FC, 0x200D, 0x2642 }, + ["man health worker"]={ 0x1F468, 0x200D, 0x2695 }, + ["man health worker: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x2695 }, + ["man health worker: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x2695 }, + ["man health worker: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x2695 }, + ["man health worker: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x2695 }, + ["man health worker: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x2695 }, + ["man in business suit levitating"]={ 0x1F574 }, + ["man in business suit levitating: dark skin tone"]={ 0x1F574, 0x1F3FF }, + ["man in business suit levitating: light skin tone"]={ 0x1F574, 0x1F3FB }, + ["man in business suit levitating: medium skin tone"]={ 0x1F574, 0x1F3FD }, + ["man in business suit levitating: medium-dark skin tone"]={ 0x1F574, 0x1F3FE }, + ["man in business suit levitating: medium-light skin tone"]={ 0x1F574, 0x1F3FC }, + ["man in lotus position"]={ 0x1F9D8, 0x200D, 0x2642 }, + ["man in lotus position: dark skin tone"]={ 0x1F9D8, 0x1F3FF, 0x200D, 0x2642 }, + ["man in lotus position: light skin tone"]={ 0x1F9D8, 0x1F3FB, 0x200D, 0x2642 }, + ["man in lotus position: medium skin tone"]={ 0x1F9D8, 0x1F3FD, 0x200D, 0x2642 }, + ["man in lotus position: medium-dark skin tone"]={ 0x1F9D8, 0x1F3FE, 0x200D, 0x2642 }, + ["man in lotus position: medium-light skin tone"]={ 0x1F9D8, 0x1F3FC, 0x200D, 0x2642 }, + ["man in steamy room"]={ 0x1F9D6, 0x200D, 0x2642 }, + ["man in steamy room: dark skin tone"]={ 0x1F9D6, 0x1F3FF, 0x200D, 0x2642 }, + ["man in steamy room: light skin tone"]={ 0x1F9D6, 0x1F3FB, 0x200D, 0x2642 }, + ["man in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD, 0x200D, 0x2642 }, + ["man in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE, 0x200D, 0x2642 }, + ["man in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC, 0x200D, 0x2642 }, + ["man in tuxedo"]={ 0x1F935 }, + ["man in tuxedo: dark skin tone"]={ 0x1F935, 0x1F3FF }, + ["man in tuxedo: light skin tone"]={ 0x1F935, 0x1F3FB }, + ["man in tuxedo: medium skin tone"]={ 0x1F935, 0x1F3FD }, + ["man in tuxedo: medium-dark skin tone"]={ 0x1F935, 0x1F3FE }, + ["man in tuxedo: medium-light skin tone"]={ 0x1F935, 0x1F3FC }, + ["man judge"]={ 0x1F468, 0x200D, 0x2696 }, + ["man judge: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x2696 }, + ["man judge: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x2696 }, + ["man judge: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x2696 }, + ["man judge: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x2696 }, + ["man judge: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x2696 }, + ["man juggling"]={ 0x1F939, 0x200D, 0x2642 }, + ["man juggling: dark skin tone"]={ 0x1F939, 0x1F3FF, 0x200D, 0x2642 }, + ["man juggling: light skin tone"]={ 0x1F939, 0x1F3FB, 0x200D, 0x2642 }, + ["man juggling: medium skin tone"]={ 0x1F939, 0x1F3FD, 0x200D, 0x2642 }, + ["man juggling: medium-dark skin tone"]={ 0x1F939, 0x1F3FE, 0x200D, 0x2642 }, + ["man juggling: medium-light skin tone"]={ 0x1F939, 0x1F3FC, 0x200D, 0x2642 }, + ["man lifting weights"]={ 0x1F3CB, 0x200D, 0x2642 }, + ["man lifting weights: dark skin tone"]={ 0x1F3CB, 0x1F3FF, 0x200D, 0x2642 }, + ["man lifting weights: light skin tone"]={ 0x1F3CB, 0x1F3FB, 0x200D, 0x2642 }, + ["man lifting weights: medium skin tone"]={ 0x1F3CB, 0x1F3FD, 0x200D, 0x2642 }, + ["man lifting weights: medium-dark skin tone"]={ 0x1F3CB, 0x1F3FE, 0x200D, 0x2642 }, + ["man lifting weights: medium-light skin tone"]={ 0x1F3CB, 0x1F3FC, 0x200D, 0x2642 }, + ["man mage"]={ 0x1F9D9, 0x200D, 0x2642 }, + ["man mage: dark skin tone"]={ 0x1F9D9, 0x1F3FF, 0x200D, 0x2642 }, + ["man mage: light skin tone"]={ 0x1F9D9, 0x1F3FB, 0x200D, 0x2642 }, + ["man mage: medium skin tone"]={ 0x1F9D9, 0x1F3FD, 0x200D, 0x2642 }, + ["man mage: medium-dark skin tone"]={ 0x1F9D9, 0x1F3FE, 0x200D, 0x2642 }, + ["man mage: medium-light skin tone"]={ 0x1F9D9, 0x1F3FC, 0x200D, 0x2642 }, + ["man mechanic"]={ 0x1F468, 0x200D, 0x1F527 }, + ["man mechanic: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F527 }, + ["man mechanic: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F527 }, + ["man mechanic: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F527 }, + ["man mechanic: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F527 }, + ["man mechanic: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F527 }, + ["man mountain biking"]={ 0x1F6B5, 0x200D, 0x2642 }, + ["man mountain biking: dark skin tone"]={ 0x1F6B5, 0x1F3FF, 0x200D, 0x2642 }, + ["man mountain biking: light skin tone"]={ 0x1F6B5, 0x1F3FB, 0x200D, 0x2642 }, + ["man mountain biking: medium skin tone"]={ 0x1F6B5, 0x1F3FD, 0x200D, 0x2642 }, + ["man mountain biking: medium-dark skin tone"]={ 0x1F6B5, 0x1F3FE, 0x200D, 0x2642 }, + ["man mountain biking: medium-light skin tone"]={ 0x1F6B5, 0x1F3FC, 0x200D, 0x2642 }, + ["man office worker"]={ 0x1F468, 0x200D, 0x1F4BC }, + ["man office worker: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F4BC }, + ["man office worker: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F4BC }, + ["man office worker: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F4BC }, + ["man office worker: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F4BC }, + ["man office worker: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F4BC }, + ["man pilot"]={ 0x1F468, 0x200D, 0x2708 }, + ["man pilot: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x2708 }, + ["man pilot: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x2708 }, + ["man pilot: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x2708 }, + ["man pilot: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x2708 }, + ["man pilot: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x2708 }, + ["man playing handball"]={ 0x1F93E, 0x200D, 0x2642 }, + ["man playing handball: dark skin tone"]={ 0x1F93E, 0x1F3FF, 0x200D, 0x2642 }, + ["man playing handball: light skin tone"]={ 0x1F93E, 0x1F3FB, 0x200D, 0x2642 }, + ["man playing handball: medium skin tone"]={ 0x1F93E, 0x1F3FD, 0x200D, 0x2642 }, + ["man playing handball: medium-dark skin tone"]={ 0x1F93E, 0x1F3FE, 0x200D, 0x2642 }, + ["man playing handball: medium-light skin tone"]={ 0x1F93E, 0x1F3FC, 0x200D, 0x2642 }, + ["man playing water polo"]={ 0x1F93D, 0x200D, 0x2642 }, + ["man playing water polo: dark skin tone"]={ 0x1F93D, 0x1F3FF, 0x200D, 0x2642 }, + ["man playing water polo: light skin tone"]={ 0x1F93D, 0x1F3FB, 0x200D, 0x2642 }, + ["man playing water polo: medium skin tone"]={ 0x1F93D, 0x1F3FD, 0x200D, 0x2642 }, + ["man playing water polo: medium-dark skin tone"]={ 0x1F93D, 0x1F3FE, 0x200D, 0x2642 }, + ["man playing water polo: medium-light skin tone"]={ 0x1F93D, 0x1F3FC, 0x200D, 0x2642 }, + ["man police officer"]={ 0x1F46E, 0x200D, 0x2642 }, + ["man police officer: dark skin tone"]={ 0x1F46E, 0x1F3FF, 0x200D, 0x2642 }, + ["man police officer: light skin tone"]={ 0x1F46E, 0x1F3FB, 0x200D, 0x2642 }, + ["man police officer: medium skin tone"]={ 0x1F46E, 0x1F3FD, 0x200D, 0x2642 }, + ["man police officer: medium-dark skin tone"]={ 0x1F46E, 0x1F3FE, 0x200D, 0x2642 }, + ["man police officer: medium-light skin tone"]={ 0x1F46E, 0x1F3FC, 0x200D, 0x2642 }, + ["man pouting"]={ 0x1F64E, 0x200D, 0x2642 }, + ["man pouting: dark skin tone"]={ 0x1F64E, 0x1F3FF, 0x200D, 0x2642 }, + ["man pouting: light skin tone"]={ 0x1F64E, 0x1F3FB, 0x200D, 0x2642 }, + ["man pouting: medium skin tone"]={ 0x1F64E, 0x1F3FD, 0x200D, 0x2642 }, + ["man pouting: medium-dark skin tone"]={ 0x1F64E, 0x1F3FE, 0x200D, 0x2642 }, + ["man pouting: medium-light skin tone"]={ 0x1F64E, 0x1F3FC, 0x200D, 0x2642 }, + ["man raising hand"]={ 0x1F64B, 0x200D, 0x2642 }, + ["man raising hand: dark skin tone"]={ 0x1F64B, 0x1F3FF, 0x200D, 0x2642 }, + ["man raising hand: light skin tone"]={ 0x1F64B, 0x1F3FB, 0x200D, 0x2642 }, + ["man raising hand: medium skin tone"]={ 0x1F64B, 0x1F3FD, 0x200D, 0x2642 }, + ["man raising hand: medium-dark skin tone"]={ 0x1F64B, 0x1F3FE, 0x200D, 0x2642 }, + ["man raising hand: medium-light skin tone"]={ 0x1F64B, 0x1F3FC, 0x200D, 0x2642 }, + ["man rowing boat"]={ 0x1F6A3, 0x200D, 0x2642 }, + ["man rowing boat: dark skin tone"]={ 0x1F6A3, 0x1F3FF, 0x200D, 0x2642 }, + ["man rowing boat: light skin tone"]={ 0x1F6A3, 0x1F3FB, 0x200D, 0x2642 }, + ["man rowing boat: medium skin tone"]={ 0x1F6A3, 0x1F3FD, 0x200D, 0x2642 }, + ["man rowing boat: medium-dark skin tone"]={ 0x1F6A3, 0x1F3FE, 0x200D, 0x2642 }, + ["man rowing boat: medium-light skin tone"]={ 0x1F6A3, 0x1F3FC, 0x200D, 0x2642 }, + ["man running"]={ 0x1F3C3, 0x200D, 0x2642 }, + ["man running: dark skin tone"]={ 0x1F3C3, 0x1F3FF, 0x200D, 0x2642 }, + ["man running: light skin tone"]={ 0x1F3C3, 0x1F3FB, 0x200D, 0x2642 }, + ["man running: medium skin tone"]={ 0x1F3C3, 0x1F3FD, 0x200D, 0x2642 }, + ["man running: medium-dark skin tone"]={ 0x1F3C3, 0x1F3FE, 0x200D, 0x2642 }, + ["man running: medium-light skin tone"]={ 0x1F3C3, 0x1F3FC, 0x200D, 0x2642 }, + ["man scientist"]={ 0x1F468, 0x200D, 0x1F52C }, + ["man scientist: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F52C }, + ["man scientist: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F52C }, + ["man scientist: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F52C }, + ["man scientist: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F52C }, + ["man scientist: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F52C }, + ["man shrugging"]={ 0x1F937, 0x200D, 0x2642 }, + ["man shrugging: dark skin tone"]={ 0x1F937, 0x1F3FF, 0x200D, 0x2642 }, + ["man shrugging: light skin tone"]={ 0x1F937, 0x1F3FB, 0x200D, 0x2642 }, + ["man shrugging: medium skin tone"]={ 0x1F937, 0x1F3FD, 0x200D, 0x2642 }, + ["man shrugging: medium-dark skin tone"]={ 0x1F937, 0x1F3FE, 0x200D, 0x2642 }, + ["man shrugging: medium-light skin tone"]={ 0x1F937, 0x1F3FC, 0x200D, 0x2642 }, + ["man singer"]={ 0x1F468, 0x200D, 0x1F3A4 }, + ["man singer: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F3A4 }, + ["man singer: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F3A4 }, + ["man singer: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F3A4 }, + ["man singer: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F3A4 }, + ["man singer: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F3A4 }, + ["man student"]={ 0x1F468, 0x200D, 0x1F393 }, + ["man student: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F393 }, + ["man student: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F393 }, + ["man student: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F393 }, + ["man student: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F393 }, + ["man student: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F393 }, + ["man surfing"]={ 0x1F3C4, 0x200D, 0x2642 }, + ["man surfing: dark skin tone"]={ 0x1F3C4, 0x1F3FF, 0x200D, 0x2642 }, + ["man surfing: light skin tone"]={ 0x1F3C4, 0x1F3FB, 0x200D, 0x2642 }, + ["man surfing: medium skin tone"]={ 0x1F3C4, 0x1F3FD, 0x200D, 0x2642 }, + ["man surfing: medium-dark skin tone"]={ 0x1F3C4, 0x1F3FE, 0x200D, 0x2642 }, + ["man surfing: medium-light skin tone"]={ 0x1F3C4, 0x1F3FC, 0x200D, 0x2642 }, + ["man swimming"]={ 0x1F3CA, 0x200D, 0x2642 }, + ["man swimming: dark skin tone"]={ 0x1F3CA, 0x1F3FF, 0x200D, 0x2642 }, + ["man swimming: light skin tone"]={ 0x1F3CA, 0x1F3FB, 0x200D, 0x2642 }, + ["man swimming: medium skin tone"]={ 0x1F3CA, 0x1F3FD, 0x200D, 0x2642 }, + ["man swimming: medium-dark skin tone"]={ 0x1F3CA, 0x1F3FE, 0x200D, 0x2642 }, + ["man swimming: medium-light skin tone"]={ 0x1F3CA, 0x1F3FC, 0x200D, 0x2642 }, + ["man teacher"]={ 0x1F468, 0x200D, 0x1F3EB }, + ["man teacher: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F3EB }, + ["man teacher: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F3EB }, + ["man teacher: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F3EB }, + ["man teacher: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F3EB }, + ["man teacher: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F3EB }, + ["man technologist"]={ 0x1F468, 0x200D, 0x1F4BB }, + ["man technologist: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F4BB }, + ["man technologist: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F4BB }, + ["man technologist: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F4BB }, + ["man technologist: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F4BB }, + ["man technologist: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F4BB }, + ["man tipping hand"]={ 0x1F481, 0x200D, 0x2642 }, + ["man tipping hand: dark skin tone"]={ 0x1F481, 0x1F3FF, 0x200D, 0x2642 }, + ["man tipping hand: light skin tone"]={ 0x1F481, 0x1F3FB, 0x200D, 0x2642 }, + ["man tipping hand: medium skin tone"]={ 0x1F481, 0x1F3FD, 0x200D, 0x2642 }, + ["man tipping hand: medium-dark skin tone"]={ 0x1F481, 0x1F3FE, 0x200D, 0x2642 }, + ["man tipping hand: medium-light skin tone"]={ 0x1F481, 0x1F3FC, 0x200D, 0x2642 }, + ["man vampire"]={ 0x1F9DB, 0x200D, 0x2642 }, + ["man vampire: dark skin tone"]={ 0x1F9DB, 0x1F3FF, 0x200D, 0x2642 }, + ["man vampire: light skin tone"]={ 0x1F9DB, 0x1F3FB, 0x200D, 0x2642 }, + ["man vampire: medium skin tone"]={ 0x1F9DB, 0x1F3FD, 0x200D, 0x2642 }, + ["man vampire: medium-dark skin tone"]={ 0x1F9DB, 0x1F3FE, 0x200D, 0x2642 }, + ["man vampire: medium-light skin tone"]={ 0x1F9DB, 0x1F3FC, 0x200D, 0x2642 }, + ["man walking"]={ 0x1F6B6, 0x200D, 0x2642 }, + ["man walking: dark skin tone"]={ 0x1F6B6, 0x1F3FF, 0x200D, 0x2642 }, + ["man walking: light skin tone"]={ 0x1F6B6, 0x1F3FB, 0x200D, 0x2642 }, + ["man walking: medium skin tone"]={ 0x1F6B6, 0x1F3FD, 0x200D, 0x2642 }, + ["man walking: medium-dark skin tone"]={ 0x1F6B6, 0x1F3FE, 0x200D, 0x2642 }, + ["man walking: medium-light skin tone"]={ 0x1F6B6, 0x1F3FC, 0x200D, 0x2642 }, + ["man wearing turban"]={ 0x1F473, 0x200D, 0x2642 }, + ["man wearing turban: dark skin tone"]={ 0x1F473, 0x1F3FF, 0x200D, 0x2642 }, + ["man wearing turban: light skin tone"]={ 0x1F473, 0x1F3FB, 0x200D, 0x2642 }, + ["man wearing turban: medium skin tone"]={ 0x1F473, 0x1F3FD, 0x200D, 0x2642 }, + ["man wearing turban: medium-dark skin tone"]={ 0x1F473, 0x1F3FE, 0x200D, 0x2642 }, + ["man wearing turban: medium-light skin tone"]={ 0x1F473, 0x1F3FC, 0x200D, 0x2642 }, + ["man with chinese cap"]={ 0x1F472 }, + ["man with chinese cap: dark skin tone"]={ 0x1F472, 0x1F3FF }, + ["man with chinese cap: light skin tone"]={ 0x1F472, 0x1F3FB }, + ["man with chinese cap: medium skin tone"]={ 0x1F472, 0x1F3FD }, + ["man with chinese cap: medium-dark skin tone"]={ 0x1F472, 0x1F3FE }, + ["man with chinese cap: medium-light skin tone"]={ 0x1F472, 0x1F3FC }, + ["man zombie"]={ 0x1F9DF, 0x200D, 0x2642 }, + ["man: dark skin tone"]={ 0x1F468, 0x1F3FF }, + ["man: light skin tone"]={ 0x1F468, 0x1F3FB }, + ["man: medium skin tone"]={ 0x1F468, 0x1F3FD }, + ["man: medium-dark skin tone"]={ 0x1F468, 0x1F3FE }, + ["man: medium-light skin tone"]={ 0x1F468, 0x1F3FC }, + ["mantelpiece clock"]={ 0x1F570 }, + ["man’s shoe"]={ 0x1F45E }, + ["map of japan"]={ 0x1F5FE }, + ["maple leaf"]={ 0x1F341 }, + ["marshall islands"]={ 0x1F1F2, 0x1F1ED }, + ["martial arts uniform"]={ 0x1F94B }, + ["martinique"]={ 0x1F1F2, 0x1F1F6 }, + ["mauritania"]={ 0x1F1F2, 0x1F1F7 }, + ["mauritius"]={ 0x1F1F2, 0x1F1FA }, + ["mayotte"]={ 0x1F1FE, 0x1F1F9 }, + ["meat on bone"]={ 0x1F356 }, + ["medical symbol"]={ 0x2695 }, + ["megaphone"]={ 0x1F4E3 }, + ["melon"]={ 0x1F348 }, + ["memo"]={ 0x1F4DD }, + ["men with bunny ears partying"]={ 0x1F46F, 0x200D, 0x2642 }, + ["men wrestling"]={ 0x1F93C, 0x200D, 0x2642 }, + ["menorah"]={ 0x1F54E }, + ["men’s room"]={ 0x1F6B9 }, + ["mermaid"]={ 0x1F9DC, 0x200D, 0x2640 }, + ["mermaid: dark skin tone"]={ 0x1F9DC, 0x1F3FF, 0x200D, 0x2640 }, + ["mermaid: light skin tone"]={ 0x1F9DC, 0x1F3FB, 0x200D, 0x2640 }, + ["mermaid: medium skin tone"]={ 0x1F9DC, 0x1F3FD, 0x200D, 0x2640 }, + ["mermaid: medium-dark skin tone"]={ 0x1F9DC, 0x1F3FE, 0x200D, 0x2640 }, + ["mermaid: medium-light skin tone"]={ 0x1F9DC, 0x1F3FC, 0x200D, 0x2640 }, + ["merman"]={ 0x1F9DC, 0x200D, 0x2642 }, + ["merman: dark skin tone"]={ 0x1F9DC, 0x1F3FF, 0x200D, 0x2642 }, + ["merman: light skin tone"]={ 0x1F9DC, 0x1F3FB, 0x200D, 0x2642 }, + ["merman: medium skin tone"]={ 0x1F9DC, 0x1F3FD, 0x200D, 0x2642 }, + ["merman: medium-dark skin tone"]={ 0x1F9DC, 0x1F3FE, 0x200D, 0x2642 }, + ["merman: medium-light skin tone"]={ 0x1F9DC, 0x1F3FC, 0x200D, 0x2642 }, + ["merperson"]={ 0x1F9DC }, + ["merperson: dark skin tone"]={ 0x1F9DC, 0x1F3FF }, + ["merperson: light skin tone"]={ 0x1F9DC, 0x1F3FB }, + ["merperson: medium skin tone"]={ 0x1F9DC, 0x1F3FD }, + ["merperson: medium-dark skin tone"]={ 0x1F9DC, 0x1F3FE }, + ["merperson: medium-light skin tone"]={ 0x1F9DC, 0x1F3FC }, + ["metro"]={ 0x1F687 }, + ["mexico"]={ 0x1F1F2, 0x1F1FD }, + ["micronesia"]={ 0x1F1EB, 0x1F1F2 }, + ["microphone"]={ 0x1F3A4 }, + ["microscope"]={ 0x1F52C }, + ["middle finger"]={ 0x1F595 }, + ["middle finger: dark skin tone"]={ 0x1F595, 0x1F3FF }, + ["middle finger: light skin tone"]={ 0x1F595, 0x1F3FB }, + ["middle finger: medium skin tone"]={ 0x1F595, 0x1F3FD }, + ["middle finger: medium-dark skin tone"]={ 0x1F595, 0x1F3FE }, + ["middle finger: medium-light skin tone"]={ 0x1F595, 0x1F3FC }, + ["military medal"]={ 0x1F396 }, + ["milky way"]={ 0x1F30C }, + ["minibus"]={ 0x1F690 }, + ["moai"]={ 0x1F5FF }, + ["mobile phone"]={ 0x1F4F1 }, + ["mobile phone off"]={ 0x1F4F4 }, + ["mobile phone with arrow"]={ 0x1F4F2 }, + ["moldova"]={ 0x1F1F2, 0x1F1E9 }, + ["monaco"]={ 0x1F1F2, 0x1F1E8 }, + ["money bag"]={ 0x1F4B0 }, + ["money with wings"]={ 0x1F4B8 }, + ["money-mouth face"]={ 0x1F911 }, + ["mongolia"]={ 0x1F1F2, 0x1F1F3 }, + ["monkey"]={ 0x1F412 }, + ["monkey face"]={ 0x1F435 }, + ["monorail"]={ 0x1F69D }, + ["montenegro"]={ 0x1F1F2, 0x1F1EA }, + ["montserrat"]={ 0x1F1F2, 0x1F1F8 }, + ["moon viewing ceremony"]={ 0x1F391 }, + ["morocco"]={ 0x1F1F2, 0x1F1E6 }, + ["mosque"]={ 0x1F54C }, + ["motor boat"]={ 0x1F6E5 }, + ["motor scooter"]={ 0x1F6F5 }, + ["motorcycle"]={ 0x1F3CD }, + ["motorway"]={ 0x1F6E3 }, + ["mount fuji"]={ 0x1F5FB }, + ["mountain"]={ 0x26F0 }, + ["mountain cableway"]={ 0x1F6A0 }, + ["mountain railway"]={ 0x1F69E }, + ["mouse"]={ 0x1F401 }, + ["mouse face"]={ 0x1F42D }, + ["mouth"]={ 0x1F444 }, + ["movie camera"]={ 0x1F3A5 }, + ["mozambique"]={ 0x1F1F2, 0x1F1FF }, + ["mrs. claus"]={ 0x1F936 }, + ["mrs. claus: dark skin tone"]={ 0x1F936, 0x1F3FF }, + ["mrs. claus: light skin tone"]={ 0x1F936, 0x1F3FB }, + ["mrs. claus: medium skin tone"]={ 0x1F936, 0x1F3FD }, + ["mrs. claus: medium-dark skin tone"]={ 0x1F936, 0x1F3FE }, + ["mrs. claus: medium-light skin tone"]={ 0x1F936, 0x1F3FC }, + ["mushroom"]={ 0x1F344 }, + ["musical keyboard"]={ 0x1F3B9 }, + ["musical note"]={ 0x1F3B5 }, + ["musical notes"]={ 0x1F3B6 }, + ["musical score"]={ 0x1F3BC }, + ["muted speaker"]={ 0x1F507 }, + ["myanmar (burma)"]={ 0x1F1F2, 0x1F1F2 }, + ["nail polish"]={ 0x1F485 }, + ["nail polish: dark skin tone"]={ 0x1F485, 0x1F3FF }, + ["nail polish: light skin tone"]={ 0x1F485, 0x1F3FB }, + ["nail polish: medium skin tone"]={ 0x1F485, 0x1F3FD }, + ["nail polish: medium-dark skin tone"]={ 0x1F485, 0x1F3FE }, + ["nail polish: medium-light skin tone"]={ 0x1F485, 0x1F3FC }, + ["name badge"]={ 0x1F4DB }, + ["namibia"]={ 0x1F1F3, 0x1F1E6 }, + ["national park"]={ 0x1F3DE }, + ["nauru"]={ 0x1F1F3, 0x1F1F7 }, + ["nauseated face"]={ 0x1F922 }, + ["necktie"]={ 0x1F454 }, + ["nepal"]={ 0x1F1F3, 0x1F1F5 }, + ["nerd face"]={ 0x1F913 }, + ["netherlands"]={ 0x1F1F3, 0x1F1F1 }, + ["neutral face"]={ 0x1F610 }, + ["new button"]={ 0x1F195 }, + ["new caledonia"]={ 0x1F1F3, 0x1F1E8 }, + ["new moon"]={ 0x1F311 }, + ["new moon face"]={ 0x1F31A }, + ["new zealand"]={ 0x1F1F3, 0x1F1FF }, + ["newspaper"]={ 0x1F4F0 }, + ["next track button"]={ 0x23ED }, + ["ng button"]={ 0x1F196 }, + ["nicaragua"]={ 0x1F1F3, 0x1F1EE }, + ["niger"]={ 0x1F1F3, 0x1F1EA }, + ["nigeria"]={ 0x1F1F3, 0x1F1EC }, + ["night with stars"]={ 0x1F303 }, + ["nine o’clock"]={ 0x1F558 }, + ["nine-thirty"]={ 0x1F564 }, + ["niue"]={ 0x1F1F3, 0x1F1FA }, + ["no bicycles"]={ 0x1F6B3 }, + ["no entry"]={ 0x26D4 }, + ["no littering"]={ 0x1F6AF }, + ["no mobile phones"]={ 0x1F4F5 }, + ["no one under eighteen"]={ 0x1F51E }, + ["no pedestrians"]={ 0x1F6B7 }, + ["no smoking"]={ 0x1F6AD }, + ["non-potable water"]={ 0x1F6B1 }, + ["norfolk island"]={ 0x1F1F3, 0x1F1EB }, + ["north korea"]={ 0x1F1F0, 0x1F1F5 }, + ["northern mariana islands"]={ 0x1F1F2, 0x1F1F5 }, + ["norway"]={ 0x1F1F3, 0x1F1F4 }, + ["nose"]={ 0x1F443 }, + ["nose: dark skin tone"]={ 0x1F443, 0x1F3FF }, + ["nose: light skin tone"]={ 0x1F443, 0x1F3FB }, + ["nose: medium skin tone"]={ 0x1F443, 0x1F3FD }, + ["nose: medium-dark skin tone"]={ 0x1F443, 0x1F3FE }, + ["nose: medium-light skin tone"]={ 0x1F443, 0x1F3FC }, + ["notebook"]={ 0x1F4D3 }, + ["notebook with decorative cover"]={ 0x1F4D4 }, + ["nut and bolt"]={ 0x1F529 }, + ["o button (blood type)"]={ 0x1F17E }, + ["octopus"]={ 0x1F419 }, + ["oden"]={ 0x1F362 }, + ["office building"]={ 0x1F3E2 }, + ["ogre"]={ 0x1F479 }, + ["oil drum"]={ 0x1F6E2 }, + ["ok button"]={ 0x1F197 }, + ["ok hand"]={ 0x1F44C }, + ["ok hand: dark skin tone"]={ 0x1F44C, 0x1F3FF }, + ["ok hand: light skin tone"]={ 0x1F44C, 0x1F3FB }, + ["ok hand: medium skin tone"]={ 0x1F44C, 0x1F3FD }, + ["ok hand: medium-dark skin tone"]={ 0x1F44C, 0x1F3FE }, + ["ok hand: medium-light skin tone"]={ 0x1F44C, 0x1F3FC }, + ["old key"]={ 0x1F5DD }, + ["old man"]={ 0x1F474 }, + ["old man: dark skin tone"]={ 0x1F474, 0x1F3FF }, + ["old man: light skin tone"]={ 0x1F474, 0x1F3FB }, + ["old man: medium skin tone"]={ 0x1F474, 0x1F3FD }, + ["old man: medium-dark skin tone"]={ 0x1F474, 0x1F3FE }, + ["old man: medium-light skin tone"]={ 0x1F474, 0x1F3FC }, + ["old woman"]={ 0x1F475 }, + ["old woman: dark skin tone"]={ 0x1F475, 0x1F3FF }, + ["old woman: light skin tone"]={ 0x1F475, 0x1F3FB }, + ["old woman: medium skin tone"]={ 0x1F475, 0x1F3FD }, + ["old woman: medium-dark skin tone"]={ 0x1F475, 0x1F3FE }, + ["old woman: medium-light skin tone"]={ 0x1F475, 0x1F3FC }, + ["older adult"]={ 0x1F9D3 }, + ["older adult: dark skin tone"]={ 0x1F9D3, 0x1F3FF }, + ["older adult: light skin tone"]={ 0x1F9D3, 0x1F3FB }, + ["older adult: medium skin tone"]={ 0x1F9D3, 0x1F3FD }, + ["older adult: medium-dark skin tone"]={ 0x1F9D3, 0x1F3FE }, + ["older adult: medium-light skin tone"]={ 0x1F9D3, 0x1F3FC }, + ["om"]={ 0x1F549 }, + ["oman"]={ 0x1F1F4, 0x1F1F2 }, + ["on! arrow"]={ 0x1F51B }, + ["oncoming automobile"]={ 0x1F698 }, + ["oncoming bus"]={ 0x1F68D }, + ["oncoming fist"]={ 0x1F44A }, + ["oncoming fist: dark skin tone"]={ 0x1F44A, 0x1F3FF }, + ["oncoming fist: light skin tone"]={ 0x1F44A, 0x1F3FB }, + ["oncoming fist: medium skin tone"]={ 0x1F44A, 0x1F3FD }, + ["oncoming fist: medium-dark skin tone"]={ 0x1F44A, 0x1F3FE }, + ["oncoming fist: medium-light skin tone"]={ 0x1F44A, 0x1F3FC }, + ["oncoming police car"]={ 0x1F694 }, + ["oncoming taxi"]={ 0x1F696 }, + ["one o’clock"]={ 0x1F550 }, + ["one-thirty"]={ 0x1F55C }, + ["open book"]={ 0x1F4D6 }, + ["open file folder"]={ 0x1F4C2 }, + ["open hands"]={ 0x1F450 }, + ["open hands: dark skin tone"]={ 0x1F450, 0x1F3FF }, + ["open hands: light skin tone"]={ 0x1F450, 0x1F3FB }, + ["open hands: medium skin tone"]={ 0x1F450, 0x1F3FD }, + ["open hands: medium-dark skin tone"]={ 0x1F450, 0x1F3FE }, + ["open hands: medium-light skin tone"]={ 0x1F450, 0x1F3FC }, + ["open mailbox with lowered flag"]={ 0x1F4ED }, + ["open mailbox with raised flag"]={ 0x1F4EC }, + ["ophiuchus"]={ 0x26CE }, + ["optical disk"]={ 0x1F4BF }, + ["orange book"]={ 0x1F4D9 }, + ["orange heart"]={ 0x1F9E1 }, + ["orthodox cross"]={ 0x2626 }, + ["outbox tray"]={ 0x1F4E4 }, + ["owl"]={ 0x1F989 }, + ["ox"]={ 0x1F402 }, + ["p button"]={ 0x1F17F }, + ["package"]={ 0x1F4E6 }, + ["page facing up"]={ 0x1F4C4 }, + ["page with curl"]={ 0x1F4C3 }, + ["pager"]={ 0x1F4DF }, + ["paintbrush"]={ 0x1F58C }, + ["pakistan"]={ 0x1F1F5, 0x1F1F0 }, + ["palau"]={ 0x1F1F5, 0x1F1FC }, + ["palestinian territories"]={ 0x1F1F5, 0x1F1F8 }, + ["palm tree"]={ 0x1F334 }, + ["palms up together"]={ 0x1F932 }, + ["palms up together: dark skin tone"]={ 0x1F932, 0x1F3FF }, + ["palms up together: light skin tone"]={ 0x1F932, 0x1F3FB }, + ["palms up together: medium skin tone"]={ 0x1F932, 0x1F3FD }, + ["palms up together: medium-dark skin tone"]={ 0x1F932, 0x1F3FE }, + ["palms up together: medium-light skin tone"]={ 0x1F932, 0x1F3FC }, + ["panama"]={ 0x1F1F5, 0x1F1E6 }, + ["pancakes"]={ 0x1F95E }, + ["panda face"]={ 0x1F43C }, + ["paperclip"]={ 0x1F4CE }, + ["papua new guinea"]={ 0x1F1F5, 0x1F1EC }, + ["paraguay"]={ 0x1F1F5, 0x1F1FE }, + ["part alternation mark"]={ 0x303D }, + ["party popper"]={ 0x1F389 }, + ["passenger ship"]={ 0x1F6F3 }, + ["passport control"]={ 0x1F6C2 }, + ["pause button"]={ 0x23F8 }, + ["paw prints"]={ 0x1F43E }, + ["peace symbol"]={ 0x262E }, + ["peach"]={ 0x1F351 }, + ["peanuts"]={ 0x1F95C }, + ["pear"]={ 0x1F350 }, + ["pen"]={ 0x1F58A }, + ["pencil"]={ 0x270F }, + ["penguin"]={ 0x1F427 }, + ["pensive face"]={ 0x1F614 }, + ["people with bunny ears partying"]={ 0x1F46F }, + ["people wrestling"]={ 0x1F93C }, + ["performing arts"]={ 0x1F3AD }, + ["persevering face"]={ 0x1F623 }, + ["person biking"]={ 0x1F6B4 }, + ["person biking: dark skin tone"]={ 0x1F6B4, 0x1F3FF }, + ["person biking: light skin tone"]={ 0x1F6B4, 0x1F3FB }, + ["person biking: medium skin tone"]={ 0x1F6B4, 0x1F3FD }, + ["person biking: medium-dark skin tone"]={ 0x1F6B4, 0x1F3FE }, + ["person biking: medium-light skin tone"]={ 0x1F6B4, 0x1F3FC }, + ["person bouncing ball"]={ 0x26F9 }, + ["person bouncing ball: dark skin tone"]={ 0x26F9, 0x1F3FF }, + ["person bouncing ball: light skin tone"]={ 0x26F9, 0x1F3FB }, + ["person bouncing ball: medium skin tone"]={ 0x26F9, 0x1F3FD }, + ["person bouncing ball: medium-dark skin tone"]={ 0x26F9, 0x1F3FE }, + ["person bouncing ball: medium-light skin tone"]={ 0x26F9, 0x1F3FC }, + ["person bowing"]={ 0x1F647 }, + ["person bowing: dark skin tone"]={ 0x1F647, 0x1F3FF }, + ["person bowing: light skin tone"]={ 0x1F647, 0x1F3FB }, + ["person bowing: medium skin tone"]={ 0x1F647, 0x1F3FD }, + ["person bowing: medium-dark skin tone"]={ 0x1F647, 0x1F3FE }, + ["person bowing: medium-light skin tone"]={ 0x1F647, 0x1F3FC }, + ["person cartwheeling"]={ 0x1F938 }, + ["person cartwheeling: dark skin tone"]={ 0x1F938, 0x1F3FF }, + ["person cartwheeling: light skin tone"]={ 0x1F938, 0x1F3FB }, + ["person cartwheeling: medium skin tone"]={ 0x1F938, 0x1F3FD }, + ["person cartwheeling: medium-dark skin tone"]={ 0x1F938, 0x1F3FE }, + ["person cartwheeling: medium-light skin tone"]={ 0x1F938, 0x1F3FC }, + ["person climbing"]={ 0x1F9D7 }, + ["person climbing: dark skin tone"]={ 0x1F9D7, 0x1F3FF }, + ["person climbing: light skin tone"]={ 0x1F9D7, 0x1F3FB }, + ["person climbing: medium skin tone"]={ 0x1F9D7, 0x1F3FD }, + ["person climbing: medium-dark skin tone"]={ 0x1F9D7, 0x1F3FE }, + ["person climbing: medium-light skin tone"]={ 0x1F9D7, 0x1F3FC }, + ["person facepalming"]={ 0x1F926 }, + ["person facepalming: dark skin tone"]={ 0x1F926, 0x1F3FF }, + ["person facepalming: light skin tone"]={ 0x1F926, 0x1F3FB }, + ["person facepalming: medium skin tone"]={ 0x1F926, 0x1F3FD }, + ["person facepalming: medium-dark skin tone"]={ 0x1F926, 0x1F3FE }, + ["person facepalming: medium-light skin tone"]={ 0x1F926, 0x1F3FC }, + ["person fencing"]={ 0x1F93A }, + ["person frowning"]={ 0x1F64D }, + ["person frowning: dark skin tone"]={ 0x1F64D, 0x1F3FF }, + ["person frowning: light skin tone"]={ 0x1F64D, 0x1F3FB }, + ["person frowning: medium skin tone"]={ 0x1F64D, 0x1F3FD }, + ["person frowning: medium-dark skin tone"]={ 0x1F64D, 0x1F3FE }, + ["person frowning: medium-light skin tone"]={ 0x1F64D, 0x1F3FC }, + ["person gesturing no"]={ 0x1F645 }, + ["person gesturing no: dark skin tone"]={ 0x1F645, 0x1F3FF }, + ["person gesturing no: light skin tone"]={ 0x1F645, 0x1F3FB }, + ["person gesturing no: medium skin tone"]={ 0x1F645, 0x1F3FD }, + ["person gesturing no: medium-dark skin tone"]={ 0x1F645, 0x1F3FE }, + ["person gesturing no: medium-light skin tone"]={ 0x1F645, 0x1F3FC }, + ["person gesturing ok"]={ 0x1F646 }, + ["person gesturing ok: dark skin tone"]={ 0x1F646, 0x1F3FF }, + ["person gesturing ok: light skin tone"]={ 0x1F646, 0x1F3FB }, + ["person gesturing ok: medium skin tone"]={ 0x1F646, 0x1F3FD }, + ["person gesturing ok: medium-dark skin tone"]={ 0x1F646, 0x1F3FE }, + ["person gesturing ok: medium-light skin tone"]={ 0x1F646, 0x1F3FC }, + ["person getting haircut"]={ 0x1F487 }, + ["person getting haircut: dark skin tone"]={ 0x1F487, 0x1F3FF }, + ["person getting haircut: light skin tone"]={ 0x1F487, 0x1F3FB }, + ["person getting haircut: medium skin tone"]={ 0x1F487, 0x1F3FD }, + ["person getting haircut: medium-dark skin tone"]={ 0x1F487, 0x1F3FE }, + ["person getting haircut: medium-light skin tone"]={ 0x1F487, 0x1F3FC }, + ["person getting massage"]={ 0x1F486 }, + ["person getting massage: dark skin tone"]={ 0x1F486, 0x1F3FF }, + ["person getting massage: light skin tone"]={ 0x1F486, 0x1F3FB }, + ["person getting massage: medium skin tone"]={ 0x1F486, 0x1F3FD }, + ["person getting massage: medium-dark skin tone"]={ 0x1F486, 0x1F3FE }, + ["person getting massage: medium-light skin tone"]={ 0x1F486, 0x1F3FC }, + ["person golfing"]={ 0x1F3CC }, + ["person golfing: dark skin tone"]={ 0x1F3CC, 0x1F3FF }, + ["person golfing: light skin tone"]={ 0x1F3CC, 0x1F3FB }, + ["person golfing: medium skin tone"]={ 0x1F3CC, 0x1F3FD }, + ["person golfing: medium-dark skin tone"]={ 0x1F3CC, 0x1F3FE }, + ["person golfing: medium-light skin tone"]={ 0x1F3CC, 0x1F3FC }, + ["person in bed"]={ 0x1F6CC }, + ["person in bed: dark skin tone"]={ 0x1F6CC, 0x1F3FF }, + ["person in bed: light skin tone"]={ 0x1F6CC, 0x1F3FB }, + ["person in bed: medium skin tone"]={ 0x1F6CC, 0x1F3FD }, + ["person in bed: medium-dark skin tone"]={ 0x1F6CC, 0x1F3FE }, + ["person in bed: medium-light skin tone"]={ 0x1F6CC, 0x1F3FC }, + ["person in lotus position"]={ 0x1F9D8 }, + ["person in lotus position: dark skin tone"]={ 0x1F9D8, 0x1F3FF }, + ["person in lotus position: light skin tone"]={ 0x1F9D8, 0x1F3FB }, + ["person in lotus position: medium skin tone"]={ 0x1F9D8, 0x1F3FD }, + ["person in lotus position: medium-dark skin tone"]={ 0x1F9D8, 0x1F3FE }, + ["person in lotus position: medium-light skin tone"]={ 0x1F9D8, 0x1F3FC }, + ["person in steamy room"]={ 0x1F9D6 }, + ["person in steamy room: dark skin tone"]={ 0x1F9D6, 0x1F3FF }, + ["person in steamy room: light skin tone"]={ 0x1F9D6, 0x1F3FB }, + ["person in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD }, + ["person in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE }, + ["person in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC }, + ["person juggling"]={ 0x1F939 }, + ["person juggling: dark skin tone"]={ 0x1F939, 0x1F3FF }, + ["person juggling: light skin tone"]={ 0x1F939, 0x1F3FB }, + ["person juggling: medium skin tone"]={ 0x1F939, 0x1F3FD }, + ["person juggling: medium-dark skin tone"]={ 0x1F939, 0x1F3FE }, + ["person juggling: medium-light skin tone"]={ 0x1F939, 0x1F3FC }, + ["person lifting weights"]={ 0x1F3CB }, + ["person lifting weights: dark skin tone"]={ 0x1F3CB, 0x1F3FF }, + ["person lifting weights: light skin tone"]={ 0x1F3CB, 0x1F3FB }, + ["person lifting weights: medium skin tone"]={ 0x1F3CB, 0x1F3FD }, + ["person lifting weights: medium-dark skin tone"]={ 0x1F3CB, 0x1F3FE }, + ["person lifting weights: medium-light skin tone"]={ 0x1F3CB, 0x1F3FC }, + ["person mountain biking"]={ 0x1F6B5 }, + ["person mountain biking: dark skin tone"]={ 0x1F6B5, 0x1F3FF }, + ["person mountain biking: light skin tone"]={ 0x1F6B5, 0x1F3FB }, + ["person mountain biking: medium skin tone"]={ 0x1F6B5, 0x1F3FD }, + ["person mountain biking: medium-dark skin tone"]={ 0x1F6B5, 0x1F3FE }, + ["person mountain biking: medium-light skin tone"]={ 0x1F6B5, 0x1F3FC }, + ["person playing handball"]={ 0x1F93E }, + ["person playing handball: dark skin tone"]={ 0x1F93E, 0x1F3FF }, + ["person playing handball: light skin tone"]={ 0x1F93E, 0x1F3FB }, + ["person playing handball: medium skin tone"]={ 0x1F93E, 0x1F3FD }, + ["person playing handball: medium-dark skin tone"]={ 0x1F93E, 0x1F3FE }, + ["person playing handball: medium-light skin tone"]={ 0x1F93E, 0x1F3FC }, + ["person playing water polo"]={ 0x1F93D }, + ["person playing water polo: dark skin tone"]={ 0x1F93D, 0x1F3FF }, + ["person playing water polo: light skin tone"]={ 0x1F93D, 0x1F3FB }, + ["person playing water polo: medium skin tone"]={ 0x1F93D, 0x1F3FD }, + ["person playing water polo: medium-dark skin tone"]={ 0x1F93D, 0x1F3FE }, + ["person playing water polo: medium-light skin tone"]={ 0x1F93D, 0x1F3FC }, + ["person pouting"]={ 0x1F64E }, + ["person pouting: dark skin tone"]={ 0x1F64E, 0x1F3FF }, + ["person pouting: light skin tone"]={ 0x1F64E, 0x1F3FB }, + ["person pouting: medium skin tone"]={ 0x1F64E, 0x1F3FD }, + ["person pouting: medium-dark skin tone"]={ 0x1F64E, 0x1F3FE }, + ["person pouting: medium-light skin tone"]={ 0x1F64E, 0x1F3FC }, + ["person raising hand"]={ 0x1F64B }, + ["person raising hand: dark skin tone"]={ 0x1F64B, 0x1F3FF }, + ["person raising hand: light skin tone"]={ 0x1F64B, 0x1F3FB }, + ["person raising hand: medium skin tone"]={ 0x1F64B, 0x1F3FD }, + ["person raising hand: medium-dark skin tone"]={ 0x1F64B, 0x1F3FE }, + ["person raising hand: medium-light skin tone"]={ 0x1F64B, 0x1F3FC }, + ["person rowing boat"]={ 0x1F6A3 }, + ["person rowing boat: dark skin tone"]={ 0x1F6A3, 0x1F3FF }, + ["person rowing boat: light skin tone"]={ 0x1F6A3, 0x1F3FB }, + ["person rowing boat: medium skin tone"]={ 0x1F6A3, 0x1F3FD }, + ["person rowing boat: medium-dark skin tone"]={ 0x1F6A3, 0x1F3FE }, + ["person rowing boat: medium-light skin tone"]={ 0x1F6A3, 0x1F3FC }, + ["person running"]={ 0x1F3C3 }, + ["person running: dark skin tone"]={ 0x1F3C3, 0x1F3FF }, + ["person running: light skin tone"]={ 0x1F3C3, 0x1F3FB }, + ["person running: medium skin tone"]={ 0x1F3C3, 0x1F3FD }, + ["person running: medium-dark skin tone"]={ 0x1F3C3, 0x1F3FE }, + ["person running: medium-light skin tone"]={ 0x1F3C3, 0x1F3FC }, + ["person shrugging"]={ 0x1F937 }, + ["person shrugging: dark skin tone"]={ 0x1F937, 0x1F3FF }, + ["person shrugging: light skin tone"]={ 0x1F937, 0x1F3FB }, + ["person shrugging: medium skin tone"]={ 0x1F937, 0x1F3FD }, + ["person shrugging: medium-dark skin tone"]={ 0x1F937, 0x1F3FE }, + ["person shrugging: medium-light skin tone"]={ 0x1F937, 0x1F3FC }, + ["person surfing"]={ 0x1F3C4 }, + ["person surfing: dark skin tone"]={ 0x1F3C4, 0x1F3FF }, + ["person surfing: light skin tone"]={ 0x1F3C4, 0x1F3FB }, + ["person surfing: medium skin tone"]={ 0x1F3C4, 0x1F3FD }, + ["person surfing: medium-dark skin tone"]={ 0x1F3C4, 0x1F3FE }, + ["person surfing: medium-light skin tone"]={ 0x1F3C4, 0x1F3FC }, + ["person swimming"]={ 0x1F3CA }, + ["person swimming: dark skin tone"]={ 0x1F3CA, 0x1F3FF }, + ["person swimming: light skin tone"]={ 0x1F3CA, 0x1F3FB }, + ["person swimming: medium skin tone"]={ 0x1F3CA, 0x1F3FD }, + ["person swimming: medium-dark skin tone"]={ 0x1F3CA, 0x1F3FE }, + ["person swimming: medium-light skin tone"]={ 0x1F3CA, 0x1F3FC }, + ["person taking bath"]={ 0x1F6C0 }, + ["person taking bath: dark skin tone"]={ 0x1F6C0, 0x1F3FF }, + ["person taking bath: light skin tone"]={ 0x1F6C0, 0x1F3FB }, + ["person taking bath: medium skin tone"]={ 0x1F6C0, 0x1F3FD }, + ["person taking bath: medium-dark skin tone"]={ 0x1F6C0, 0x1F3FE }, + ["person taking bath: medium-light skin tone"]={ 0x1F6C0, 0x1F3FC }, + ["person tipping hand"]={ 0x1F481 }, + ["person tipping hand: dark skin tone"]={ 0x1F481, 0x1F3FF }, + ["person tipping hand: light skin tone"]={ 0x1F481, 0x1F3FB }, + ["person tipping hand: medium skin tone"]={ 0x1F481, 0x1F3FD }, + ["person tipping hand: medium-dark skin tone"]={ 0x1F481, 0x1F3FE }, + ["person tipping hand: medium-light skin tone"]={ 0x1F481, 0x1F3FC }, + ["person walking"]={ 0x1F6B6 }, + ["person walking: dark skin tone"]={ 0x1F6B6, 0x1F3FF }, + ["person walking: light skin tone"]={ 0x1F6B6, 0x1F3FB }, + ["person walking: medium skin tone"]={ 0x1F6B6, 0x1F3FD }, + ["person walking: medium-dark skin tone"]={ 0x1F6B6, 0x1F3FE }, + ["person walking: medium-light skin tone"]={ 0x1F6B6, 0x1F3FC }, + ["person wearing turban"]={ 0x1F473 }, + ["person wearing turban: dark skin tone"]={ 0x1F473, 0x1F3FF }, + ["person wearing turban: light skin tone"]={ 0x1F473, 0x1F3FB }, + ["person wearing turban: medium skin tone"]={ 0x1F473, 0x1F3FD }, + ["person wearing turban: medium-dark skin tone"]={ 0x1F473, 0x1F3FE }, + ["person wearing turban: medium-light skin tone"]={ 0x1F473, 0x1F3FC }, + ["peru"]={ 0x1F1F5, 0x1F1EA }, + ["philippines"]={ 0x1F1F5, 0x1F1ED }, + ["pick"]={ 0x26CF }, + ["pie"]={ 0x1F967 }, + ["pig"]={ 0x1F416 }, + ["pig face"]={ 0x1F437 }, + ["pig nose"]={ 0x1F43D }, + ["pile of poo"]={ 0x1F4A9 }, + ["pill"]={ 0x1F48A }, + ["pine decoration"]={ 0x1F38D }, + ["pineapple"]={ 0x1F34D }, + ["ping pong"]={ 0x1F3D3 }, + ["pisces"]={ 0x2653 }, + ["pistol"]={ 0x1F52B }, + ["pitcairn islands"]={ 0x1F1F5, 0x1F1F3 }, + ["pizza"]={ 0x1F355 }, + ["place of worship"]={ 0x1F6D0 }, + ["play button"]={ 0x25B6 }, + ["play or pause button"]={ 0x23EF }, + ["poland"]={ 0x1F1F5, 0x1F1F1 }, + ["police car"]={ 0x1F693 }, + ["police car light"]={ 0x1F6A8 }, + ["police officer"]={ 0x1F46E }, + ["police officer: dark skin tone"]={ 0x1F46E, 0x1F3FF }, + ["police officer: light skin tone"]={ 0x1F46E, 0x1F3FB }, + ["police officer: medium skin tone"]={ 0x1F46E, 0x1F3FD }, + ["police officer: medium-dark skin tone"]={ 0x1F46E, 0x1F3FE }, + ["police officer: medium-light skin tone"]={ 0x1F46E, 0x1F3FC }, + ["poodle"]={ 0x1F429 }, + ["pool 8 ball"]={ 0x1F3B1 }, + ["popcorn"]={ 0x1F37F }, + ["portugal"]={ 0x1F1F5, 0x1F1F9 }, + ["post office"]={ 0x1F3E4 }, + ["postal horn"]={ 0x1F4EF }, + ["postbox"]={ 0x1F4EE }, + ["pot of food"]={ 0x1F372 }, + ["potable water"]={ 0x1F6B0 }, + ["potato"]={ 0x1F954 }, + ["poultry leg"]={ 0x1F357 }, + ["pound banknote"]={ 0x1F4B7 }, + ["pouting cat face"]={ 0x1F63E }, + ["pouting face"]={ 0x1F621 }, + ["prayer beads"]={ 0x1F4FF }, + ["pregnant woman"]={ 0x1F930 }, + ["pregnant woman: dark skin tone"]={ 0x1F930, 0x1F3FF }, + ["pregnant woman: light skin tone"]={ 0x1F930, 0x1F3FB }, + ["pregnant woman: medium skin tone"]={ 0x1F930, 0x1F3FD }, + ["pregnant woman: medium-dark skin tone"]={ 0x1F930, 0x1F3FE }, + ["pregnant woman: medium-light skin tone"]={ 0x1F930, 0x1F3FC }, + ["pretzel"]={ 0x1F968 }, + ["prince"]={ 0x1F934 }, + ["prince: dark skin tone"]={ 0x1F934, 0x1F3FF }, + ["prince: light skin tone"]={ 0x1F934, 0x1F3FB }, + ["prince: medium skin tone"]={ 0x1F934, 0x1F3FD }, + ["prince: medium-dark skin tone"]={ 0x1F934, 0x1F3FE }, + ["prince: medium-light skin tone"]={ 0x1F934, 0x1F3FC }, + ["princess"]={ 0x1F478 }, + ["princess: dark skin tone"]={ 0x1F478, 0x1F3FF }, + ["princess: light skin tone"]={ 0x1F478, 0x1F3FB }, + ["princess: medium skin tone"]={ 0x1F478, 0x1F3FD }, + ["princess: medium-dark skin tone"]={ 0x1F478, 0x1F3FE }, + ["princess: medium-light skin tone"]={ 0x1F478, 0x1F3FC }, + ["printer"]={ 0x1F5A8 }, + ["prohibited"]={ 0x1F6AB }, + ["puerto rico"]={ 0x1F1F5, 0x1F1F7 }, + ["purple heart"]={ 0x1F49C }, + ["purse"]={ 0x1F45B }, + ["pushpin"]={ 0x1F4CC }, + ["qatar"]={ 0x1F1F6, 0x1F1E6 }, + ["question mark"]={ 0x2753 }, + ["rabbit"]={ 0x1F407 }, + ["rabbit face"]={ 0x1F430 }, + ["racing car"]={ 0x1F3CE }, + ["radio"]={ 0x1F4FB }, + ["radio button"]={ 0x1F518 }, + ["radioactive"]={ 0x2622 }, + ["railway car"]={ 0x1F683 }, + ["railway track"]={ 0x1F6E4 }, + ["rainbow"]={ 0x1F308 }, + ["rainbow flag"]={ 0x1F3F3, 0x200D, 0x1F308 }, + ["raised back of hand"]={ 0x1F91A }, + ["raised back of hand: dark skin tone"]={ 0x1F91A, 0x1F3FF }, + ["raised back of hand: light skin tone"]={ 0x1F91A, 0x1F3FB }, + ["raised back of hand: medium skin tone"]={ 0x1F91A, 0x1F3FD }, + ["raised back of hand: medium-dark skin tone"]={ 0x1F91A, 0x1F3FE }, + ["raised back of hand: medium-light skin tone"]={ 0x1F91A, 0x1F3FC }, + ["raised fist"]={ 0x270A }, + ["raised fist: dark skin tone"]={ 0x270A, 0x1F3FF }, + ["raised fist: light skin tone"]={ 0x270A, 0x1F3FB }, + ["raised fist: medium skin tone"]={ 0x270A, 0x1F3FD }, + ["raised fist: medium-dark skin tone"]={ 0x270A, 0x1F3FE }, + ["raised fist: medium-light skin tone"]={ 0x270A, 0x1F3FC }, + ["raised hand"]={ 0x270B }, + ["raised hand with fingers splayed"]={ 0x1F590 }, + ["raised hand with fingers splayed: dark skin tone"]={ 0x1F590, 0x1F3FF }, + ["raised hand with fingers splayed: light skin tone"]={ 0x1F590, 0x1F3FB }, + ["raised hand with fingers splayed: medium skin tone"]={ 0x1F590, 0x1F3FD }, + ["raised hand with fingers splayed: medium-dark skin tone"]={ 0x1F590, 0x1F3FE }, + ["raised hand with fingers splayed: medium-light skin tone"]={ 0x1F590, 0x1F3FC }, + ["raised hand: dark skin tone"]={ 0x270B, 0x1F3FF }, + ["raised hand: light skin tone"]={ 0x270B, 0x1F3FB }, + ["raised hand: medium skin tone"]={ 0x270B, 0x1F3FD }, + ["raised hand: medium-dark skin tone"]={ 0x270B, 0x1F3FE }, + ["raised hand: medium-light skin tone"]={ 0x270B, 0x1F3FC }, + ["raising hands"]={ 0x1F64C }, + ["raising hands: dark skin tone"]={ 0x1F64C, 0x1F3FF }, + ["raising hands: light skin tone"]={ 0x1F64C, 0x1F3FB }, + ["raising hands: medium skin tone"]={ 0x1F64C, 0x1F3FD }, + ["raising hands: medium-dark skin tone"]={ 0x1F64C, 0x1F3FE }, + ["raising hands: medium-light skin tone"]={ 0x1F64C, 0x1F3FC }, + ["ram"]={ 0x1F40F }, + ["rat"]={ 0x1F400 }, + ["record button"]={ 0x23FA }, + ["recycling symbol"]={ 0x267B }, + ["red apple"]={ 0x1F34E }, + ["red circle"]={ 0x1F534 }, + ["red heart"]={ 0x2764 }, + ["red paper lantern"]={ 0x1F3EE }, + ["red triangle pointed down"]={ 0x1F53B }, + ["red triangle pointed up"]={ 0x1F53A }, + ["registered"]={ 0xAE }, + ["relieved face"]={ 0x1F60C }, + ["reminder ribbon"]={ 0x1F397 }, + ["repeat button"]={ 0x1F501 }, + ["repeat single button"]={ 0x1F502 }, + ["rescue worker’s helmet"]={ 0x26D1 }, + ["restroom"]={ 0x1F6BB }, + ["reverse button"]={ 0x25C0 }, + ["revolving hearts"]={ 0x1F49E }, + ["rhinoceros"]={ 0x1F98F }, + ["ribbon"]={ 0x1F380 }, + ["rice ball"]={ 0x1F359 }, + ["rice cracker"]={ 0x1F358 }, + ["right anger bubble"]={ 0x1F5EF }, + ["right arrow"]={ 0x27A1 }, + ["right arrow curving down"]={ 0x2935 }, + ["right arrow curving left"]={ 0x21A9 }, + ["right arrow curving up"]={ 0x2934 }, + ["right-facing fist"]={ 0x1F91C }, + ["right-facing fist: dark skin tone"]={ 0x1F91C, 0x1F3FF }, + ["right-facing fist: light skin tone"]={ 0x1F91C, 0x1F3FB }, + ["right-facing fist: medium skin tone"]={ 0x1F91C, 0x1F3FD }, + ["right-facing fist: medium-dark skin tone"]={ 0x1F91C, 0x1F3FE }, + ["right-facing fist: medium-light skin tone"]={ 0x1F91C, 0x1F3FC }, + ["right-pointing magnifying glass"]={ 0x1F50E }, + ["ring"]={ 0x1F48D }, + ["roasted sweet potato"]={ 0x1F360 }, + ["robot face"]={ 0x1F916 }, + ["rocket"]={ 0x1F680 }, + ["rolled-up newspaper"]={ 0x1F5DE }, + ["roller coaster"]={ 0x1F3A2 }, + ["rolling on the floor laughing"]={ 0x1F923 }, + ["romania"]={ 0x1F1F7, 0x1F1F4 }, + ["rooster"]={ 0x1F413 }, + ["rose"]={ 0x1F339 }, + ["rosette"]={ 0x1F3F5 }, + ["round pushpin"]={ 0x1F4CD }, + ["rugby football"]={ 0x1F3C9 }, + ["running shirt"]={ 0x1F3BD }, + ["running shoe"]={ 0x1F45F }, + ["russia"]={ 0x1F1F7, 0x1F1FA }, + ["rwanda"]={ 0x1F1F7, 0x1F1FC }, + ["réunion"]={ 0x1F1F7, 0x1F1EA }, + ["sagittarius"]={ 0x2650 }, + ["sailboat"]={ 0x26F5 }, + ["sake"]={ 0x1F376 }, + ["samoa"]={ 0x1F1FC, 0x1F1F8 }, + ["san marino"]={ 0x1F1F8, 0x1F1F2 }, + ["sandwich"]={ 0x1F96A }, + ["santa claus"]={ 0x1F385 }, + ["santa claus: dark skin tone"]={ 0x1F385, 0x1F3FF }, + ["santa claus: light skin tone"]={ 0x1F385, 0x1F3FB }, + ["santa claus: medium skin tone"]={ 0x1F385, 0x1F3FD }, + ["santa claus: medium-dark skin tone"]={ 0x1F385, 0x1F3FE }, + ["santa claus: medium-light skin tone"]={ 0x1F385, 0x1F3FC }, + ["satellite"]={ 0x1F6F0 }, + ["satellite antenna"]={ 0x1F4E1 }, + ["saudi arabia"]={ 0x1F1F8, 0x1F1E6 }, + ["sauropod"]={ 0x1F995 }, + ["saxophone"]={ 0x1F3B7 }, + ["scarf"]={ 0x1F9E3 }, + ["school"]={ 0x1F3EB }, + ["school backpack"]={ 0x1F392 }, + ["scissors"]={ 0x2702 }, + ["scorpion"]={ 0x1F982 }, + ["scorpius"]={ 0x264F }, + ["scotland"]={ 0x1F3F4, 0xE0067, 0xE0062, 0xE0073, 0xE0063, 0xE0074, 0xE007F }, + ["scroll"]={ 0x1F4DC }, + ["seat"]={ 0x1F4BA }, + ["see-no-evil monkey"]={ 0x1F648 }, + ["seedling"]={ 0x1F331 }, + ["selfie"]={ 0x1F933 }, + ["selfie: dark skin tone"]={ 0x1F933, 0x1F3FF }, + ["selfie: light skin tone"]={ 0x1F933, 0x1F3FB }, + ["selfie: medium skin tone"]={ 0x1F933, 0x1F3FD }, + ["selfie: medium-dark skin tone"]={ 0x1F933, 0x1F3FE }, + ["selfie: medium-light skin tone"]={ 0x1F933, 0x1F3FC }, + ["senegal"]={ 0x1F1F8, 0x1F1F3 }, + ["serbia"]={ 0x1F1F7, 0x1F1F8 }, + ["seven o’clock"]={ 0x1F556 }, + ["seven-thirty"]={ 0x1F562 }, + ["seychelles"]={ 0x1F1F8, 0x1F1E8 }, + ["shallow pan of food"]={ 0x1F958 }, + ["shamrock"]={ 0x2618 }, + ["shark"]={ 0x1F988 }, + ["shaved ice"]={ 0x1F367 }, + ["sheaf of rice"]={ 0x1F33E }, + ["shield"]={ 0x1F6E1 }, + ["shinto shrine"]={ 0x26E9 }, + ["ship"]={ 0x1F6A2 }, + ["shooting star"]={ 0x1F320 }, + ["shopping bags"]={ 0x1F6CD }, + ["shopping cart"]={ 0x1F6D2 }, + ["shortcake"]={ 0x1F370 }, + ["shower"]={ 0x1F6BF }, + ["shrimp"]={ 0x1F990 }, + ["shuffle tracks button"]={ 0x1F500 }, + ["shushing face"]={ 0x1F92B }, + ["sierra leone"]={ 0x1F1F8, 0x1F1F1 }, + ["sign of the horns"]={ 0x1F918 }, + ["sign of the horns: dark skin tone"]={ 0x1F918, 0x1F3FF }, + ["sign of the horns: light skin tone"]={ 0x1F918, 0x1F3FB }, + ["sign of the horns: medium skin tone"]={ 0x1F918, 0x1F3FD }, + ["sign of the horns: medium-dark skin tone"]={ 0x1F918, 0x1F3FE }, + ["sign of the horns: medium-light skin tone"]={ 0x1F918, 0x1F3FC }, + ["singapore"]={ 0x1F1F8, 0x1F1EC }, + ["sint maarten"]={ 0x1F1F8, 0x1F1FD }, + ["six o’clock"]={ 0x1F555 }, + ["six-thirty"]={ 0x1F561 }, + ["skier"]={ 0x26F7 }, + ["skis"]={ 0x1F3BF }, + ["skull"]={ 0x1F480 }, + ["skull and crossbones"]={ 0x2620 }, + ["sled"]={ 0x1F6F7 }, + ["sleeping face"]={ 0x1F634 }, + ["sleepy face"]={ 0x1F62A }, + ["slightly frowning face"]={ 0x1F641 }, + ["slightly smiling face"]={ 0x1F642 }, + ["slot machine"]={ 0x1F3B0 }, + ["slovakia"]={ 0x1F1F8, 0x1F1F0 }, + ["slovenia"]={ 0x1F1F8, 0x1F1EE }, + ["small airplane"]={ 0x1F6E9 }, + ["small blue diamond"]={ 0x1F539 }, + ["small orange diamond"]={ 0x1F538 }, + ["smiling cat face with heart-eyes"]={ 0x1F63B }, + ["smiling cat face with open mouth"]={ 0x1F63A }, + ["smiling face"]={ 0x263A }, + ["smiling face with halo"]={ 0x1F607 }, + ["smiling face with heart-eyes"]={ 0x1F60D }, + ["smiling face with horns"]={ 0x1F608 }, + ["smiling face with open mouth"]={ 0x1F603 }, + ["smiling face with open mouth & closed eyes"]={ 0x1F606 }, + ["smiling face with open mouth & cold sweat"]={ 0x1F605 }, + ["smiling face with open mouth & smiling eyes"]={ 0x1F604 }, + ["smiling face with smiling eyes"]={ 0x1F60A }, + ["smiling face with sunglasses"]={ 0x1F60E }, + ["smirking face"]={ 0x1F60F }, + ["snail"]={ 0x1F40C }, + ["snake"]={ 0x1F40D }, + ["sneezing face"]={ 0x1F927 }, + ["snow-capped mountain"]={ 0x1F3D4 }, + ["snowboarder"]={ 0x1F3C2 }, + ["snowboarder: dark skin tone"]={ 0x1F3C2, 0x1F3FF }, + ["snowboarder: light skin tone"]={ 0x1F3C2, 0x1F3FB }, + ["snowboarder: medium skin tone"]={ 0x1F3C2, 0x1F3FD }, + ["snowboarder: medium-dark skin tone"]={ 0x1F3C2, 0x1F3FE }, + ["snowboarder: medium-light skin tone"]={ 0x1F3C2, 0x1F3FC }, + ["snowflake"]={ 0x2744 }, + ["snowman"]={ 0x2603 }, + ["snowman without snow"]={ 0x26C4 }, + ["soccer ball"]={ 0x26BD }, + ["socks"]={ 0x1F9E6 }, + ["soft ice cream"]={ 0x1F366 }, + ["solomon islands"]={ 0x1F1F8, 0x1F1E7 }, + ["somalia"]={ 0x1F1F8, 0x1F1F4 }, + ["soon arrow"]={ 0x1F51C }, + ["sos button"]={ 0x1F198 }, + ["south africa"]={ 0x1F1FF, 0x1F1E6 }, + ["south georgia & south sandwich islands"]={ 0x1F1EC, 0x1F1F8 }, + ["south korea"]={ 0x1F1F0, 0x1F1F7 }, + ["south sudan"]={ 0x1F1F8, 0x1F1F8 }, + ["spade suit"]={ 0x2660 }, + ["spaghetti"]={ 0x1F35D }, + ["spain"]={ 0x1F1EA, 0x1F1F8 }, + ["sparkle"]={ 0x2747 }, + ["sparkler"]={ 0x1F387 }, + ["sparkles"]={ 0x2728 }, + ["sparkling heart"]={ 0x1F496 }, + ["speak-no-evil monkey"]={ 0x1F64A }, + ["speaker high volume"]={ 0x1F50A }, + ["speaker low volume"]={ 0x1F508 }, + ["speaker medium volume"]={ 0x1F509 }, + ["speaking head"]={ 0x1F5E3 }, + ["speech balloon"]={ 0x1F4AC }, + ["speedboat"]={ 0x1F6A4 }, + ["spider"]={ 0x1F577 }, + ["spider web"]={ 0x1F578 }, + ["spiral calendar"]={ 0x1F5D3 }, + ["spiral notepad"]={ 0x1F5D2 }, + ["spiral shell"]={ 0x1F41A }, + ["spoon"]={ 0x1F944 }, + ["sport utility vehicle"]={ 0x1F699 }, + ["sports medal"]={ 0x1F3C5 }, + ["spouting whale"]={ 0x1F433 }, + ["squid"]={ 0x1F991 }, + ["sri lanka"]={ 0x1F1F1, 0x1F1F0 }, + ["st. barthélemy"]={ 0x1F1E7, 0x1F1F1 }, + ["st. helena"]={ 0x1F1F8, 0x1F1ED }, + ["st. kitts & nevis"]={ 0x1F1F0, 0x1F1F3 }, + ["st. lucia"]={ 0x1F1F1, 0x1F1E8 }, + ["st. martin"]={ 0x1F1F2, 0x1F1EB }, + ["st. pierre & miquelon"]={ 0x1F1F5, 0x1F1F2 }, + ["st. vincent & grenadines"]={ 0x1F1FB, 0x1F1E8 }, + ["stadium"]={ 0x1F3DF }, + ["star and crescent"]={ 0x262A }, + ["star of david"]={ 0x2721 }, + ["star-struck"]={ 0x1F929 }, + ["station"]={ 0x1F689 }, + ["statue of liberty"]={ 0x1F5FD }, + ["steaming bowl"]={ 0x1F35C }, + ["stop button"]={ 0x23F9 }, + ["stop sign"]={ 0x1F6D1 }, + ["stopwatch"]={ 0x23F1 }, + ["straight ruler"]={ 0x1F4CF }, + ["strawberry"]={ 0x1F353 }, + ["studio microphone"]={ 0x1F399 }, + ["stuffed flatbread"]={ 0x1F959 }, + ["sudan"]={ 0x1F1F8, 0x1F1E9 }, + ["sun"]={ 0x2600 }, + ["sun behind cloud"]={ 0x26C5 }, + ["sun behind large cloud"]={ 0x1F325 }, + ["sun behind rain cloud"]={ 0x1F326 }, + ["sun behind small cloud"]={ 0x1F324 }, + ["sun with face"]={ 0x1F31E }, + ["sunflower"]={ 0x1F33B }, + ["sunglasses"]={ 0x1F576 }, + ["sunrise"]={ 0x1F305 }, + ["sunrise over mountains"]={ 0x1F304 }, + ["sunset"]={ 0x1F307 }, + ["suriname"]={ 0x1F1F8, 0x1F1F7 }, + ["sushi"]={ 0x1F363 }, + ["suspension railway"]={ 0x1F69F }, + ["svalbard & jan mayen"]={ 0x1F1F8, 0x1F1EF }, + ["swaziland"]={ 0x1F1F8, 0x1F1FF }, + ["sweat droplets"]={ 0x1F4A6 }, + ["sweden"]={ 0x1F1F8, 0x1F1EA }, + ["switzerland"]={ 0x1F1E8, 0x1F1ED }, + ["synagogue"]={ 0x1F54D }, + ["syria"]={ 0x1F1F8, 0x1F1FE }, + ["syringe"]={ 0x1F489 }, + ["são tomé & príncipe"]={ 0x1F1F8, 0x1F1F9 }, + ["t-rex"]={ 0x1F996 }, + ["t-shirt"]={ 0x1F455 }, + ["taco"]={ 0x1F32E }, + ["taiwan"]={ 0x1F1F9, 0x1F1FC }, + ["tajikistan"]={ 0x1F1F9, 0x1F1EF }, + ["takeout box"]={ 0x1F961 }, + ["tanabata tree"]={ 0x1F38B }, + ["tangerine"]={ 0x1F34A }, + ["tanzania"]={ 0x1F1F9, 0x1F1FF }, + ["taurus"]={ 0x2649 }, + ["taxi"]={ 0x1F695 }, + ["teacup without handle"]={ 0x1F375 }, + ["tear-off calendar"]={ 0x1F4C6 }, + ["telephone"]={ 0x260E }, + ["telephone receiver"]={ 0x1F4DE }, + ["telescope"]={ 0x1F52D }, + ["television"]={ 0x1F4FA }, + ["ten o’clock"]={ 0x1F559 }, + ["ten-thirty"]={ 0x1F565 }, + ["tennis"]={ 0x1F3BE }, + ["tent"]={ 0x26FA }, + ["thailand"]={ 0x1F1F9, 0x1F1ED }, + ["thermometer"]={ 0x1F321 }, + ["thinking face"]={ 0x1F914 }, + ["thought balloon"]={ 0x1F4AD }, + ["three o’clock"]={ 0x1F552 }, + ["three-thirty"]={ 0x1F55E }, + ["thumbs down"]={ 0x1F44E }, + ["thumbs down: dark skin tone"]={ 0x1F44E, 0x1F3FF }, + ["thumbs down: light skin tone"]={ 0x1F44E, 0x1F3FB }, + ["thumbs down: medium skin tone"]={ 0x1F44E, 0x1F3FD }, + ["thumbs down: medium-dark skin tone"]={ 0x1F44E, 0x1F3FE }, + ["thumbs down: medium-light skin tone"]={ 0x1F44E, 0x1F3FC }, + ["thumbs up"]={ 0x1F44D }, + ["thumbs up: dark skin tone"]={ 0x1F44D, 0x1F3FF }, + ["thumbs up: light skin tone"]={ 0x1F44D, 0x1F3FB }, + ["thumbs up: medium skin tone"]={ 0x1F44D, 0x1F3FD }, + ["thumbs up: medium-dark skin tone"]={ 0x1F44D, 0x1F3FE }, + ["thumbs up: medium-light skin tone"]={ 0x1F44D, 0x1F3FC }, + ["ticket"]={ 0x1F3AB }, + ["tiger"]={ 0x1F405 }, + ["tiger face"]={ 0x1F42F }, + ["timer clock"]={ 0x23F2 }, + ["timor-leste"]={ 0x1F1F9, 0x1F1F1 }, + ["tired face"]={ 0x1F62B }, + ["togo"]={ 0x1F1F9, 0x1F1EC }, + ["toilet"]={ 0x1F6BD }, + ["tokelau"]={ 0x1F1F9, 0x1F1F0 }, + ["tokyo tower"]={ 0x1F5FC }, + ["tomato"]={ 0x1F345 }, + ["tonga"]={ 0x1F1F9, 0x1F1F4 }, + ["tongue"]={ 0x1F445 }, + ["top arrow"]={ 0x1F51D }, + ["top hat"]={ 0x1F3A9 }, + ["tornado"]={ 0x1F32A }, + ["trackball"]={ 0x1F5B2 }, + ["tractor"]={ 0x1F69C }, + ["trade mark"]={ 0x2122 }, + ["train"]={ 0x1F686 }, + ["tram"]={ 0x1F68A }, + ["tram car"]={ 0x1F68B }, + ["triangular flag"]={ 0x1F6A9 }, + ["triangular ruler"]={ 0x1F4D0 }, + ["trident emblem"]={ 0x1F531 }, + ["trinidad & tobago"]={ 0x1F1F9, 0x1F1F9 }, + ["tristan da cunha"]={ 0x1F1F9, 0x1F1E6 }, + ["trolleybus"]={ 0x1F68E }, + ["trophy"]={ 0x1F3C6 }, + ["tropical drink"]={ 0x1F379 }, + ["tropical fish"]={ 0x1F420 }, + ["trumpet"]={ 0x1F3BA }, + ["tulip"]={ 0x1F337 }, + ["tumbler glass"]={ 0x1F943 }, + ["tunisia"]={ 0x1F1F9, 0x1F1F3 }, + ["turkey"]={ 0x1F1F9, 0x1F1F7 }, + ["turkmenistan"]={ 0x1F1F9, 0x1F1F2 }, + ["turks & caicos islands"]={ 0x1F1F9, 0x1F1E8 }, + ["turtle"]={ 0x1F422 }, + ["tuvalu"]={ 0x1F1F9, 0x1F1FB }, + ["twelve o’clock"]={ 0x1F55B }, + ["twelve-thirty"]={ 0x1F567 }, + ["two hearts"]={ 0x1F495 }, + ["two men holding hands"]={ 0x1F46C }, + ["two o’clock"]={ 0x1F551 }, + ["two women holding hands"]={ 0x1F46D }, + ["two-hump camel"]={ 0x1F42B }, + ["two-thirty"]={ 0x1F55D }, + ["u.s. outlying islands"]={ 0x1F1FA, 0x1F1F2 }, + ["u.s. virgin islands"]={ 0x1F1FB, 0x1F1EE }, + ["uganda"]={ 0x1F1FA, 0x1F1EC }, + ["ukraine"]={ 0x1F1FA, 0x1F1E6 }, + ["umbrella"]={ 0x2602 }, + ["umbrella on ground"]={ 0x26F1 }, + ["umbrella with rain drops"]={ 0x2614 }, + ["unamused face"]={ 0x1F612 }, + ["unicorn face"]={ 0x1F984 }, + ["united arab emirates"]={ 0x1F1E6, 0x1F1EA }, + ["united kingdom"]={ 0x1F1EC, 0x1F1E7 }, + ["united nations"]={ 0x1F1FA, 0x1F1F3 }, + ["united states"]={ 0x1F1FA, 0x1F1F8 }, + ["unlocked"]={ 0x1F513 }, + ["up arrow"]={ 0x2B06 }, + ["up button"]={ 0x1F53C }, + ["up! button"]={ 0x1F199 }, + ["up-down arrow"]={ 0x2195 }, + ["up-left arrow"]={ 0x2196 }, + ["up-right arrow"]={ 0x2197 }, + ["upside-down face"]={ 0x1F643 }, + ["uruguay"]={ 0x1F1FA, 0x1F1FE }, + ["uzbekistan"]={ 0x1F1FA, 0x1F1FF }, + ["vampire"]={ 0x1F9DB }, + ["vampire: dark skin tone"]={ 0x1F9DB, 0x1F3FF }, + ["vampire: light skin tone"]={ 0x1F9DB, 0x1F3FB }, + ["vampire: medium skin tone"]={ 0x1F9DB, 0x1F3FD }, + ["vampire: medium-dark skin tone"]={ 0x1F9DB, 0x1F3FE }, + ["vampire: medium-light skin tone"]={ 0x1F9DB, 0x1F3FC }, + ["vanuatu"]={ 0x1F1FB, 0x1F1FA }, + ["vatican city"]={ 0x1F1FB, 0x1F1E6 }, + ["venezuela"]={ 0x1F1FB, 0x1F1EA }, + ["vertical traffic light"]={ 0x1F6A6 }, + ["vibration mode"]={ 0x1F4F3 }, + ["victory hand"]={ 0x270C }, + ["victory hand: dark skin tone"]={ 0x270C, 0x1F3FF }, + ["victory hand: light skin tone"]={ 0x270C, 0x1F3FB }, + ["victory hand: medium skin tone"]={ 0x270C, 0x1F3FD }, + ["victory hand: medium-dark skin tone"]={ 0x270C, 0x1F3FE }, + ["victory hand: medium-light skin tone"]={ 0x270C, 0x1F3FC }, + ["video camera"]={ 0x1F4F9 }, + ["video game"]={ 0x1F3AE }, + ["videocassette"]={ 0x1F4FC }, + ["vietnam"]={ 0x1F1FB, 0x1F1F3 }, + ["violin"]={ 0x1F3BB }, + ["virgo"]={ 0x264D }, + ["volcano"]={ 0x1F30B }, + ["volleyball"]={ 0x1F3D0 }, + ["vs button"]={ 0x1F19A }, + ["vulcan salute"]={ 0x1F596 }, + ["vulcan salute: dark skin tone"]={ 0x1F596, 0x1F3FF }, + ["vulcan salute: light skin tone"]={ 0x1F596, 0x1F3FB }, + ["vulcan salute: medium skin tone"]={ 0x1F596, 0x1F3FD }, + ["vulcan salute: medium-dark skin tone"]={ 0x1F596, 0x1F3FE }, + ["vulcan salute: medium-light skin tone"]={ 0x1F596, 0x1F3FC }, + ["wales"]={ 0x1F3F4, 0xE0067, 0xE0062, 0xE0077, 0xE006C, 0xE0073, 0xE007F }, + ["wallis & futuna"]={ 0x1F1FC, 0x1F1EB }, + ["waning crescent moon"]={ 0x1F318 }, + ["waning gibbous moon"]={ 0x1F316 }, + ["warning"]={ 0x26A0 }, + ["wastebasket"]={ 0x1F5D1 }, + ["watch"]={ 0x231A }, + ["water buffalo"]={ 0x1F403 }, + ["water closet"]={ 0x1F6BE }, + ["water wave"]={ 0x1F30A }, + ["watermelon"]={ 0x1F349 }, + ["waving hand"]={ 0x1F44B }, + ["waving hand: dark skin tone"]={ 0x1F44B, 0x1F3FF }, + ["waving hand: light skin tone"]={ 0x1F44B, 0x1F3FB }, + ["waving hand: medium skin tone"]={ 0x1F44B, 0x1F3FD }, + ["waving hand: medium-dark skin tone"]={ 0x1F44B, 0x1F3FE }, + ["waving hand: medium-light skin tone"]={ 0x1F44B, 0x1F3FC }, + ["wavy dash"]={ 0x3030 }, + ["waxing crescent moon"]={ 0x1F312 }, + ["waxing gibbous moon"]={ 0x1F314 }, + ["weary cat face"]={ 0x1F640 }, + ["weary face"]={ 0x1F629 }, + ["wedding"]={ 0x1F492 }, + ["western sahara"]={ 0x1F1EA, 0x1F1ED }, + ["whale"]={ 0x1F40B }, + ["wheel of dharma"]={ 0x2638 }, + ["wheelchair symbol"]={ 0x267F }, + ["white circle"]={ 0x26AA }, + ["white exclamation mark"]={ 0x2755 }, + ["white flag"]={ 0x1F3F3 }, + ["white flower"]={ 0x1F4AE }, + ["white heavy check mark"]={ 0x2705 }, + ["white large square"]={ 0x2B1C }, + ["white medium square"]={ 0x25FB }, + ["white medium star"]={ 0x2B50 }, + ["white medium-small square"]={ 0x25FD }, + ["white question mark"]={ 0x2754 }, + ["white small square"]={ 0x25AB }, + ["white square button"]={ 0x1F533 }, + ["wilted flower"]={ 0x1F940 }, + ["wind chime"]={ 0x1F390 }, + ["wind face"]={ 0x1F32C }, + ["wine glass"]={ 0x1F377 }, + ["winking face"]={ 0x1F609 }, + ["wolf face"]={ 0x1F43A }, + ["woman"]={ 0x1F469 }, + ["woman artist"]={ 0x1F469, 0x200D, 0x1F3A8 }, + ["woman artist: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F3A8 }, + ["woman artist: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F3A8 }, + ["woman artist: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F3A8 }, + ["woman artist: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F3A8 }, + ["woman artist: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F3A8 }, + ["woman astronaut"]={ 0x1F469, 0x200D, 0x1F680 }, + ["woman astronaut: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F680 }, + ["woman astronaut: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F680 }, + ["woman astronaut: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F680 }, + ["woman astronaut: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F680 }, + ["woman astronaut: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F680 }, + ["woman biking"]={ 0x1F6B4, 0x200D, 0x2640 }, + ["woman biking: dark skin tone"]={ 0x1F6B4, 0x1F3FF, 0x200D, 0x2640 }, + ["woman biking: light skin tone"]={ 0x1F6B4, 0x1F3FB, 0x200D, 0x2640 }, + ["woman biking: medium skin tone"]={ 0x1F6B4, 0x1F3FD, 0x200D, 0x2640 }, + ["woman biking: medium-dark skin tone"]={ 0x1F6B4, 0x1F3FE, 0x200D, 0x2640 }, + ["woman biking: medium-light skin tone"]={ 0x1F6B4, 0x1F3FC, 0x200D, 0x2640 }, + ["woman bouncing ball"]={ 0x26F9, 0x200D, 0x2640 }, + ["woman bouncing ball: dark skin tone"]={ 0x26F9, 0x1F3FF, 0x200D, 0x2640 }, + ["woman bouncing ball: light skin tone"]={ 0x26F9, 0x1F3FB, 0x200D, 0x2640 }, + ["woman bouncing ball: medium skin tone"]={ 0x26F9, 0x1F3FD, 0x200D, 0x2640 }, + ["woman bouncing ball: medium-dark skin tone"]={ 0x26F9, 0x1F3FE, 0x200D, 0x2640 }, + ["woman bouncing ball: medium-light skin tone"]={ 0x26F9, 0x1F3FC, 0x200D, 0x2640 }, + ["woman bowing"]={ 0x1F647, 0x200D, 0x2640 }, + ["woman bowing: dark skin tone"]={ 0x1F647, 0x1F3FF, 0x200D, 0x2640 }, + ["woman bowing: light skin tone"]={ 0x1F647, 0x1F3FB, 0x200D, 0x2640 }, + ["woman bowing: medium skin tone"]={ 0x1F647, 0x1F3FD, 0x200D, 0x2640 }, + ["woman bowing: medium-dark skin tone"]={ 0x1F647, 0x1F3FE, 0x200D, 0x2640 }, + ["woman bowing: medium-light skin tone"]={ 0x1F647, 0x1F3FC, 0x200D, 0x2640 }, + ["woman cartwheeling"]={ 0x1F938, 0x200D, 0x2640 }, + ["woman cartwheeling: dark skin tone"]={ 0x1F938, 0x1F3FF, 0x200D, 0x2640 }, + ["woman cartwheeling: light skin tone"]={ 0x1F938, 0x1F3FB, 0x200D, 0x2640 }, + ["woman cartwheeling: medium skin tone"]={ 0x1F938, 0x1F3FD, 0x200D, 0x2640 }, + ["woman cartwheeling: medium-dark skin tone"]={ 0x1F938, 0x1F3FE, 0x200D, 0x2640 }, + ["woman cartwheeling: medium-light skin tone"]={ 0x1F938, 0x1F3FC, 0x200D, 0x2640 }, + ["woman climbing"]={ 0x1F9D7, 0x200D, 0x2640 }, + ["woman climbing: dark skin tone"]={ 0x1F9D7, 0x1F3FF, 0x200D, 0x2640 }, + ["woman climbing: light skin tone"]={ 0x1F9D7, 0x1F3FB, 0x200D, 0x2640 }, + ["woman climbing: medium skin tone"]={ 0x1F9D7, 0x1F3FD, 0x200D, 0x2640 }, + ["woman climbing: medium-dark skin tone"]={ 0x1F9D7, 0x1F3FE, 0x200D, 0x2640 }, + ["woman climbing: medium-light skin tone"]={ 0x1F9D7, 0x1F3FC, 0x200D, 0x2640 }, + ["woman construction worker"]={ 0x1F477, 0x200D, 0x2640 }, + ["woman construction worker: dark skin tone"]={ 0x1F477, 0x1F3FF, 0x200D, 0x2640 }, + ["woman construction worker: light skin tone"]={ 0x1F477, 0x1F3FB, 0x200D, 0x2640 }, + ["woman construction worker: medium skin tone"]={ 0x1F477, 0x1F3FD, 0x200D, 0x2640 }, + ["woman construction worker: medium-dark skin tone"]={ 0x1F477, 0x1F3FE, 0x200D, 0x2640 }, + ["woman construction worker: medium-light skin tone"]={ 0x1F477, 0x1F3FC, 0x200D, 0x2640 }, + ["woman cook"]={ 0x1F469, 0x200D, 0x1F373 }, + ["woman cook: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F373 }, + ["woman cook: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F373 }, + ["woman cook: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F373 }, + ["woman cook: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F373 }, + ["woman cook: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F373 }, + ["woman dancing"]={ 0x1F483 }, + ["woman dancing: dark skin tone"]={ 0x1F483, 0x1F3FF }, + ["woman dancing: light skin tone"]={ 0x1F483, 0x1F3FB }, + ["woman dancing: medium skin tone"]={ 0x1F483, 0x1F3FD }, + ["woman dancing: medium-dark skin tone"]={ 0x1F483, 0x1F3FE }, + ["woman dancing: medium-light skin tone"]={ 0x1F483, 0x1F3FC }, + ["woman detective"]={ 0x1F575, 0x200D, 0x2640 }, + ["woman detective: dark skin tone"]={ 0x1F575, 0x1F3FF, 0x200D, 0x2640 }, + ["woman detective: light skin tone"]={ 0x1F575, 0x1F3FB, 0x200D, 0x2640 }, + ["woman detective: medium skin tone"]={ 0x1F575, 0x1F3FD, 0x200D, 0x2640 }, + ["woman detective: medium-dark skin tone"]={ 0x1F575, 0x1F3FE, 0x200D, 0x2640 }, + ["woman detective: medium-light skin tone"]={ 0x1F575, 0x1F3FC, 0x200D, 0x2640 }, + ["woman elf"]={ 0x1F9DD, 0x200D, 0x2640 }, + ["woman elf: dark skin tone"]={ 0x1F9DD, 0x1F3FF, 0x200D, 0x2640 }, + ["woman elf: light skin tone"]={ 0x1F9DD, 0x1F3FB, 0x200D, 0x2640 }, + ["woman elf: medium skin tone"]={ 0x1F9DD, 0x1F3FD, 0x200D, 0x2640 }, + ["woman elf: medium-dark skin tone"]={ 0x1F9DD, 0x1F3FE, 0x200D, 0x2640 }, + ["woman elf: medium-light skin tone"]={ 0x1F9DD, 0x1F3FC, 0x200D, 0x2640 }, + ["woman facepalming"]={ 0x1F926, 0x200D, 0x2640 }, + ["woman facepalming: dark skin tone"]={ 0x1F926, 0x1F3FF, 0x200D, 0x2640 }, + ["woman facepalming: light skin tone"]={ 0x1F926, 0x1F3FB, 0x200D, 0x2640 }, + ["woman facepalming: medium skin tone"]={ 0x1F926, 0x1F3FD, 0x200D, 0x2640 }, + ["woman facepalming: medium-dark skin tone"]={ 0x1F926, 0x1F3FE, 0x200D, 0x2640 }, + ["woman facepalming: medium-light skin tone"]={ 0x1F926, 0x1F3FC, 0x200D, 0x2640 }, + ["woman factory worker"]={ 0x1F469, 0x200D, 0x1F3ED }, + ["woman factory worker: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F3ED }, + ["woman factory worker: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F3ED }, + ["woman factory worker: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F3ED }, + ["woman factory worker: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F3ED }, + ["woman factory worker: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F3ED }, + ["woman fairy"]={ 0x1F9DA, 0x200D, 0x2640 }, + ["woman fairy: dark skin tone"]={ 0x1F9DA, 0x1F3FF, 0x200D, 0x2640 }, + ["woman fairy: light skin tone"]={ 0x1F9DA, 0x1F3FB, 0x200D, 0x2640 }, + ["woman fairy: medium skin tone"]={ 0x1F9DA, 0x1F3FD, 0x200D, 0x2640 }, + ["woman fairy: medium-dark skin tone"]={ 0x1F9DA, 0x1F3FE, 0x200D, 0x2640 }, + ["woman fairy: medium-light skin tone"]={ 0x1F9DA, 0x1F3FC, 0x200D, 0x2640 }, + ["woman farmer"]={ 0x1F469, 0x200D, 0x1F33E }, + ["woman farmer: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F33E }, + ["woman farmer: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F33E }, + ["woman farmer: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F33E }, + ["woman farmer: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F33E }, + ["woman farmer: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F33E }, + ["woman firefighter"]={ 0x1F469, 0x200D, 0x1F692 }, + ["woman firefighter: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F692 }, + ["woman firefighter: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F692 }, + ["woman firefighter: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F692 }, + ["woman firefighter: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F692 }, + ["woman firefighter: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F692 }, + ["woman frowning"]={ 0x1F64D, 0x200D, 0x2640 }, + ["woman frowning: dark skin tone"]={ 0x1F64D, 0x1F3FF, 0x200D, 0x2640 }, + ["woman frowning: light skin tone"]={ 0x1F64D, 0x1F3FB, 0x200D, 0x2640 }, + ["woman frowning: medium skin tone"]={ 0x1F64D, 0x1F3FD, 0x200D, 0x2640 }, + ["woman frowning: medium-dark skin tone"]={ 0x1F64D, 0x1F3FE, 0x200D, 0x2640 }, + ["woman frowning: medium-light skin tone"]={ 0x1F64D, 0x1F3FC, 0x200D, 0x2640 }, + ["woman genie"]={ 0x1F9DE, 0x200D, 0x2640 }, + ["woman gesturing no"]={ 0x1F645, 0x200D, 0x2640 }, + ["woman gesturing no: dark skin tone"]={ 0x1F645, 0x1F3FF, 0x200D, 0x2640 }, + ["woman gesturing no: light skin tone"]={ 0x1F645, 0x1F3FB, 0x200D, 0x2640 }, + ["woman gesturing no: medium skin tone"]={ 0x1F645, 0x1F3FD, 0x200D, 0x2640 }, + ["woman gesturing no: medium-dark skin tone"]={ 0x1F645, 0x1F3FE, 0x200D, 0x2640 }, + ["woman gesturing no: medium-light skin tone"]={ 0x1F645, 0x1F3FC, 0x200D, 0x2640 }, + ["woman gesturing ok"]={ 0x1F646, 0x200D, 0x2640 }, + ["woman gesturing ok: dark skin tone"]={ 0x1F646, 0x1F3FF, 0x200D, 0x2640 }, + ["woman gesturing ok: light skin tone"]={ 0x1F646, 0x1F3FB, 0x200D, 0x2640 }, + ["woman gesturing ok: medium skin tone"]={ 0x1F646, 0x1F3FD, 0x200D, 0x2640 }, + ["woman gesturing ok: medium-dark skin tone"]={ 0x1F646, 0x1F3FE, 0x200D, 0x2640 }, + ["woman gesturing ok: medium-light skin tone"]={ 0x1F646, 0x1F3FC, 0x200D, 0x2640 }, + ["woman getting haircut"]={ 0x1F487, 0x200D, 0x2640 }, + ["woman getting haircut: dark skin tone"]={ 0x1F487, 0x1F3FF, 0x200D, 0x2640 }, + ["woman getting haircut: light skin tone"]={ 0x1F487, 0x1F3FB, 0x200D, 0x2640 }, + ["woman getting haircut: medium skin tone"]={ 0x1F487, 0x1F3FD, 0x200D, 0x2640 }, + ["woman getting haircut: medium-dark skin tone"]={ 0x1F487, 0x1F3FE, 0x200D, 0x2640 }, + ["woman getting haircut: medium-light skin tone"]={ 0x1F487, 0x1F3FC, 0x200D, 0x2640 }, + ["woman getting massage"]={ 0x1F486, 0x200D, 0x2640 }, + ["woman getting massage: dark skin tone"]={ 0x1F486, 0x1F3FF, 0x200D, 0x2640 }, + ["woman getting massage: light skin tone"]={ 0x1F486, 0x1F3FB, 0x200D, 0x2640 }, + ["woman getting massage: medium skin tone"]={ 0x1F486, 0x1F3FD, 0x200D, 0x2640 }, + ["woman getting massage: medium-dark skin tone"]={ 0x1F486, 0x1F3FE, 0x200D, 0x2640 }, + ["woman getting massage: medium-light skin tone"]={ 0x1F486, 0x1F3FC, 0x200D, 0x2640 }, + ["woman golfing"]={ 0x1F3CC, 0x200D, 0x2640 }, + ["woman golfing: dark skin tone"]={ 0x1F3CC, 0x1F3FF, 0x200D, 0x2640 }, + ["woman golfing: light skin tone"]={ 0x1F3CC, 0x1F3FB, 0x200D, 0x2640 }, + ["woman golfing: medium skin tone"]={ 0x1F3CC, 0x1F3FD, 0x200D, 0x2640 }, + ["woman golfing: medium-dark skin tone"]={ 0x1F3CC, 0x1F3FE, 0x200D, 0x2640 }, + ["woman golfing: medium-light skin tone"]={ 0x1F3CC, 0x1F3FC, 0x200D, 0x2640 }, + ["woman guard"]={ 0x1F482, 0x200D, 0x2640 }, + ["woman guard: dark skin tone"]={ 0x1F482, 0x1F3FF, 0x200D, 0x2640 }, + ["woman guard: light skin tone"]={ 0x1F482, 0x1F3FB, 0x200D, 0x2640 }, + ["woman guard: medium skin tone"]={ 0x1F482, 0x1F3FD, 0x200D, 0x2640 }, + ["woman guard: medium-dark skin tone"]={ 0x1F482, 0x1F3FE, 0x200D, 0x2640 }, + ["woman guard: medium-light skin tone"]={ 0x1F482, 0x1F3FC, 0x200D, 0x2640 }, + ["woman health worker"]={ 0x1F469, 0x200D, 0x2695 }, + ["woman health worker: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x2695 }, + ["woman health worker: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x2695 }, + ["woman health worker: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x2695 }, + ["woman health worker: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x2695 }, + ["woman health worker: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x2695 }, + ["woman in lotus position"]={ 0x1F9D8, 0x200D, 0x2640 }, + ["woman in lotus position: dark skin tone"]={ 0x1F9D8, 0x1F3FF, 0x200D, 0x2640 }, + ["woman in lotus position: light skin tone"]={ 0x1F9D8, 0x1F3FB, 0x200D, 0x2640 }, + ["woman in lotus position: medium skin tone"]={ 0x1F9D8, 0x1F3FD, 0x200D, 0x2640 }, + ["woman in lotus position: medium-dark skin tone"]={ 0x1F9D8, 0x1F3FE, 0x200D, 0x2640 }, + ["woman in lotus position: medium-light skin tone"]={ 0x1F9D8, 0x1F3FC, 0x200D, 0x2640 }, + ["woman in steamy room"]={ 0x1F9D6, 0x200D, 0x2640 }, + ["woman in steamy room: dark skin tone"]={ 0x1F9D6, 0x1F3FF, 0x200D, 0x2640 }, + ["woman in steamy room: light skin tone"]={ 0x1F9D6, 0x1F3FB, 0x200D, 0x2640 }, + ["woman in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD, 0x200D, 0x2640 }, + ["woman in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE, 0x200D, 0x2640 }, + ["woman in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC, 0x200D, 0x2640 }, + ["woman judge"]={ 0x1F469, 0x200D, 0x2696 }, + ["woman judge: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x2696 }, + ["woman judge: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x2696 }, + ["woman judge: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x2696 }, + ["woman judge: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x2696 }, + ["woman judge: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x2696 }, + ["woman juggling"]={ 0x1F939, 0x200D, 0x2640 }, + ["woman juggling: dark skin tone"]={ 0x1F939, 0x1F3FF, 0x200D, 0x2640 }, + ["woman juggling: light skin tone"]={ 0x1F939, 0x1F3FB, 0x200D, 0x2640 }, + ["woman juggling: medium skin tone"]={ 0x1F939, 0x1F3FD, 0x200D, 0x2640 }, + ["woman juggling: medium-dark skin tone"]={ 0x1F939, 0x1F3FE, 0x200D, 0x2640 }, + ["woman juggling: medium-light skin tone"]={ 0x1F939, 0x1F3FC, 0x200D, 0x2640 }, + ["woman lifting weights"]={ 0x1F3CB, 0x200D, 0x2640 }, + ["woman lifting weights: dark skin tone"]={ 0x1F3CB, 0x1F3FF, 0x200D, 0x2640 }, + ["woman lifting weights: light skin tone"]={ 0x1F3CB, 0x1F3FB, 0x200D, 0x2640 }, + ["woman lifting weights: medium skin tone"]={ 0x1F3CB, 0x1F3FD, 0x200D, 0x2640 }, + ["woman lifting weights: medium-dark skin tone"]={ 0x1F3CB, 0x1F3FE, 0x200D, 0x2640 }, + ["woman lifting weights: medium-light skin tone"]={ 0x1F3CB, 0x1F3FC, 0x200D, 0x2640 }, + ["woman mage"]={ 0x1F9D9, 0x200D, 0x2640 }, + ["woman mage: dark skin tone"]={ 0x1F9D9, 0x1F3FF, 0x200D, 0x2640 }, + ["woman mage: light skin tone"]={ 0x1F9D9, 0x1F3FB, 0x200D, 0x2640 }, + ["woman mage: medium skin tone"]={ 0x1F9D9, 0x1F3FD, 0x200D, 0x2640 }, + ["woman mage: medium-dark skin tone"]={ 0x1F9D9, 0x1F3FE, 0x200D, 0x2640 }, + ["woman mage: medium-light skin tone"]={ 0x1F9D9, 0x1F3FC, 0x200D, 0x2640 }, + ["woman mechanic"]={ 0x1F469, 0x200D, 0x1F527 }, + ["woman mechanic: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F527 }, + ["woman mechanic: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F527 }, + ["woman mechanic: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F527 }, + ["woman mechanic: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F527 }, + ["woman mechanic: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F527 }, + ["woman mountain biking"]={ 0x1F6B5, 0x200D, 0x2640 }, + ["woman mountain biking: dark skin tone"]={ 0x1F6B5, 0x1F3FF, 0x200D, 0x2640 }, + ["woman mountain biking: light skin tone"]={ 0x1F6B5, 0x1F3FB, 0x200D, 0x2640 }, + ["woman mountain biking: medium skin tone"]={ 0x1F6B5, 0x1F3FD, 0x200D, 0x2640 }, + ["woman mountain biking: medium-dark skin tone"]={ 0x1F6B5, 0x1F3FE, 0x200D, 0x2640 }, + ["woman mountain biking: medium-light skin tone"]={ 0x1F6B5, 0x1F3FC, 0x200D, 0x2640 }, + ["woman office worker"]={ 0x1F469, 0x200D, 0x1F4BC }, + ["woman office worker: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F4BC }, + ["woman office worker: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F4BC }, + ["woman office worker: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F4BC }, + ["woman office worker: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F4BC }, + ["woman office worker: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F4BC }, + ["woman pilot"]={ 0x1F469, 0x200D, 0x2708 }, + ["woman pilot: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x2708 }, + ["woman pilot: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x2708 }, + ["woman pilot: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x2708 }, + ["woman pilot: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x2708 }, + ["woman pilot: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x2708 }, + ["woman playing handball"]={ 0x1F93E, 0x200D, 0x2640 }, + ["woman playing handball: dark skin tone"]={ 0x1F93E, 0x1F3FF, 0x200D, 0x2640 }, + ["woman playing handball: light skin tone"]={ 0x1F93E, 0x1F3FB, 0x200D, 0x2640 }, + ["woman playing handball: medium skin tone"]={ 0x1F93E, 0x1F3FD, 0x200D, 0x2640 }, + ["woman playing handball: medium-dark skin tone"]={ 0x1F93E, 0x1F3FE, 0x200D, 0x2640 }, + ["woman playing handball: medium-light skin tone"]={ 0x1F93E, 0x1F3FC, 0x200D, 0x2640 }, + ["woman playing water polo"]={ 0x1F93D, 0x200D, 0x2640 }, + ["woman playing water polo: dark skin tone"]={ 0x1F93D, 0x1F3FF, 0x200D, 0x2640 }, + ["woman playing water polo: light skin tone"]={ 0x1F93D, 0x1F3FB, 0x200D, 0x2640 }, + ["woman playing water polo: medium skin tone"]={ 0x1F93D, 0x1F3FD, 0x200D, 0x2640 }, + ["woman playing water polo: medium-dark skin tone"]={ 0x1F93D, 0x1F3FE, 0x200D, 0x2640 }, + ["woman playing water polo: medium-light skin tone"]={ 0x1F93D, 0x1F3FC, 0x200D, 0x2640 }, + ["woman police officer"]={ 0x1F46E, 0x200D, 0x2640 }, + ["woman police officer: dark skin tone"]={ 0x1F46E, 0x1F3FF, 0x200D, 0x2640 }, + ["woman police officer: light skin tone"]={ 0x1F46E, 0x1F3FB, 0x200D, 0x2640 }, + ["woman police officer: medium skin tone"]={ 0x1F46E, 0x1F3FD, 0x200D, 0x2640 }, + ["woman police officer: medium-dark skin tone"]={ 0x1F46E, 0x1F3FE, 0x200D, 0x2640 }, + ["woman police officer: medium-light skin tone"]={ 0x1F46E, 0x1F3FC, 0x200D, 0x2640 }, + ["woman pouting"]={ 0x1F64E, 0x200D, 0x2640 }, + ["woman pouting: dark skin tone"]={ 0x1F64E, 0x1F3FF, 0x200D, 0x2640 }, + ["woman pouting: light skin tone"]={ 0x1F64E, 0x1F3FB, 0x200D, 0x2640 }, + ["woman pouting: medium skin tone"]={ 0x1F64E, 0x1F3FD, 0x200D, 0x2640 }, + ["woman pouting: medium-dark skin tone"]={ 0x1F64E, 0x1F3FE, 0x200D, 0x2640 }, + ["woman pouting: medium-light skin tone"]={ 0x1F64E, 0x1F3FC, 0x200D, 0x2640 }, + ["woman raising hand"]={ 0x1F64B, 0x200D, 0x2640 }, + ["woman raising hand: dark skin tone"]={ 0x1F64B, 0x1F3FF, 0x200D, 0x2640 }, + ["woman raising hand: light skin tone"]={ 0x1F64B, 0x1F3FB, 0x200D, 0x2640 }, + ["woman raising hand: medium skin tone"]={ 0x1F64B, 0x1F3FD, 0x200D, 0x2640 }, + ["woman raising hand: medium-dark skin tone"]={ 0x1F64B, 0x1F3FE, 0x200D, 0x2640 }, + ["woman raising hand: medium-light skin tone"]={ 0x1F64B, 0x1F3FC, 0x200D, 0x2640 }, + ["woman rowing boat"]={ 0x1F6A3, 0x200D, 0x2640 }, + ["woman rowing boat: dark skin tone"]={ 0x1F6A3, 0x1F3FF, 0x200D, 0x2640 }, + ["woman rowing boat: light skin tone"]={ 0x1F6A3, 0x1F3FB, 0x200D, 0x2640 }, + ["woman rowing boat: medium skin tone"]={ 0x1F6A3, 0x1F3FD, 0x200D, 0x2640 }, + ["woman rowing boat: medium-dark skin tone"]={ 0x1F6A3, 0x1F3FE, 0x200D, 0x2640 }, + ["woman rowing boat: medium-light skin tone"]={ 0x1F6A3, 0x1F3FC, 0x200D, 0x2640 }, + ["woman running"]={ 0x1F3C3, 0x200D, 0x2640 }, + ["woman running: dark skin tone"]={ 0x1F3C3, 0x1F3FF, 0x200D, 0x2640 }, + ["woman running: light skin tone"]={ 0x1F3C3, 0x1F3FB, 0x200D, 0x2640 }, + ["woman running: medium skin tone"]={ 0x1F3C3, 0x1F3FD, 0x200D, 0x2640 }, + ["woman running: medium-dark skin tone"]={ 0x1F3C3, 0x1F3FE, 0x200D, 0x2640 }, + ["woman running: medium-light skin tone"]={ 0x1F3C3, 0x1F3FC, 0x200D, 0x2640 }, + ["woman scientist"]={ 0x1F469, 0x200D, 0x1F52C }, + ["woman scientist: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F52C }, + ["woman scientist: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F52C }, + ["woman scientist: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F52C }, + ["woman scientist: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F52C }, + ["woman scientist: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F52C }, + ["woman shrugging"]={ 0x1F937, 0x200D, 0x2640 }, + ["woman shrugging: dark skin tone"]={ 0x1F937, 0x1F3FF, 0x200D, 0x2640 }, + ["woman shrugging: light skin tone"]={ 0x1F937, 0x1F3FB, 0x200D, 0x2640 }, + ["woman shrugging: medium skin tone"]={ 0x1F937, 0x1F3FD, 0x200D, 0x2640 }, + ["woman shrugging: medium-dark skin tone"]={ 0x1F937, 0x1F3FE, 0x200D, 0x2640 }, + ["woman shrugging: medium-light skin tone"]={ 0x1F937, 0x1F3FC, 0x200D, 0x2640 }, + ["woman singer"]={ 0x1F469, 0x200D, 0x1F3A4 }, + ["woman singer: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F3A4 }, + ["woman singer: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F3A4 }, + ["woman singer: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F3A4 }, + ["woman singer: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F3A4 }, + ["woman singer: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F3A4 }, + ["woman student"]={ 0x1F469, 0x200D, 0x1F393 }, + ["woman student: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F393 }, + ["woman student: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F393 }, + ["woman student: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F393 }, + ["woman student: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F393 }, + ["woman student: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F393 }, + ["woman surfing"]={ 0x1F3C4, 0x200D, 0x2640 }, + ["woman surfing: dark skin tone"]={ 0x1F3C4, 0x1F3FF, 0x200D, 0x2640 }, + ["woman surfing: light skin tone"]={ 0x1F3C4, 0x1F3FB, 0x200D, 0x2640 }, + ["woman surfing: medium skin tone"]={ 0x1F3C4, 0x1F3FD, 0x200D, 0x2640 }, + ["woman surfing: medium-dark skin tone"]={ 0x1F3C4, 0x1F3FE, 0x200D, 0x2640 }, + ["woman surfing: medium-light skin tone"]={ 0x1F3C4, 0x1F3FC, 0x200D, 0x2640 }, + ["woman swimming"]={ 0x1F3CA, 0x200D, 0x2640 }, + ["woman swimming: dark skin tone"]={ 0x1F3CA, 0x1F3FF, 0x200D, 0x2640 }, + ["woman swimming: light skin tone"]={ 0x1F3CA, 0x1F3FB, 0x200D, 0x2640 }, + ["woman swimming: medium skin tone"]={ 0x1F3CA, 0x1F3FD, 0x200D, 0x2640 }, + ["woman swimming: medium-dark skin tone"]={ 0x1F3CA, 0x1F3FE, 0x200D, 0x2640 }, + ["woman swimming: medium-light skin tone"]={ 0x1F3CA, 0x1F3FC, 0x200D, 0x2640 }, + ["woman teacher"]={ 0x1F469, 0x200D, 0x1F3EB }, + ["woman teacher: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F3EB }, + ["woman teacher: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F3EB }, + ["woman teacher: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F3EB }, + ["woman teacher: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F3EB }, + ["woman teacher: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F3EB }, + ["woman technologist"]={ 0x1F469, 0x200D, 0x1F4BB }, + ["woman technologist: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F4BB }, + ["woman technologist: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F4BB }, + ["woman technologist: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F4BB }, + ["woman technologist: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F4BB }, + ["woman technologist: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F4BB }, + ["woman tipping hand"]={ 0x1F481, 0x200D, 0x2640 }, + ["woman tipping hand: dark skin tone"]={ 0x1F481, 0x1F3FF, 0x200D, 0x2640 }, + ["woman tipping hand: light skin tone"]={ 0x1F481, 0x1F3FB, 0x200D, 0x2640 }, + ["woman tipping hand: medium skin tone"]={ 0x1F481, 0x1F3FD, 0x200D, 0x2640 }, + ["woman tipping hand: medium-dark skin tone"]={ 0x1F481, 0x1F3FE, 0x200D, 0x2640 }, + ["woman tipping hand: medium-light skin tone"]={ 0x1F481, 0x1F3FC, 0x200D, 0x2640 }, + ["woman vampire"]={ 0x1F9DB, 0x200D, 0x2640 }, + ["woman vampire: dark skin tone"]={ 0x1F9DB, 0x1F3FF, 0x200D, 0x2640 }, + ["woman vampire: light skin tone"]={ 0x1F9DB, 0x1F3FB, 0x200D, 0x2640 }, + ["woman vampire: medium skin tone"]={ 0x1F9DB, 0x1F3FD, 0x200D, 0x2640 }, + ["woman vampire: medium-dark skin tone"]={ 0x1F9DB, 0x1F3FE, 0x200D, 0x2640 }, + ["woman vampire: medium-light skin tone"]={ 0x1F9DB, 0x1F3FC, 0x200D, 0x2640 }, + ["woman walking"]={ 0x1F6B6, 0x200D, 0x2640 }, + ["woman walking: dark skin tone"]={ 0x1F6B6, 0x1F3FF, 0x200D, 0x2640 }, + ["woman walking: light skin tone"]={ 0x1F6B6, 0x1F3FB, 0x200D, 0x2640 }, + ["woman walking: medium skin tone"]={ 0x1F6B6, 0x1F3FD, 0x200D, 0x2640 }, + ["woman walking: medium-dark skin tone"]={ 0x1F6B6, 0x1F3FE, 0x200D, 0x2640 }, + ["woman walking: medium-light skin tone"]={ 0x1F6B6, 0x1F3FC, 0x200D, 0x2640 }, + ["woman wearing turban"]={ 0x1F473, 0x200D, 0x2640 }, + ["woman wearing turban: dark skin tone"]={ 0x1F473, 0x1F3FF, 0x200D, 0x2640 }, + ["woman wearing turban: light skin tone"]={ 0x1F473, 0x1F3FB, 0x200D, 0x2640 }, + ["woman wearing turban: medium skin tone"]={ 0x1F473, 0x1F3FD, 0x200D, 0x2640 }, + ["woman wearing turban: medium-dark skin tone"]={ 0x1F473, 0x1F3FE, 0x200D, 0x2640 }, + ["woman wearing turban: medium-light skin tone"]={ 0x1F473, 0x1F3FC, 0x200D, 0x2640 }, + ["woman with headscarf"]={ 0x1F9D5 }, + ["woman with headscarf: dark skin tone"]={ 0x1F9D5, 0x1F3FF }, + ["woman with headscarf: light skin tone"]={ 0x1F9D5, 0x1F3FB }, + ["woman with headscarf: medium skin tone"]={ 0x1F9D5, 0x1F3FD }, + ["woman with headscarf: medium-dark skin tone"]={ 0x1F9D5, 0x1F3FE }, + ["woman with headscarf: medium-light skin tone"]={ 0x1F9D5, 0x1F3FC }, + ["woman zombie"]={ 0x1F9DF, 0x200D, 0x2640 }, + ["woman: dark skin tone"]={ 0x1F469, 0x1F3FF }, + ["woman: light skin tone"]={ 0x1F469, 0x1F3FB }, + ["woman: medium skin tone"]={ 0x1F469, 0x1F3FD }, + ["woman: medium-dark skin tone"]={ 0x1F469, 0x1F3FE }, + ["woman: medium-light skin tone"]={ 0x1F469, 0x1F3FC }, + ["woman’s boot"]={ 0x1F462 }, + ["woman’s clothes"]={ 0x1F45A }, + ["woman’s hat"]={ 0x1F452 }, + ["woman’s sandal"]={ 0x1F461 }, + ["women with bunny ears partying"]={ 0x1F46F, 0x200D, 0x2640 }, + ["women wrestling"]={ 0x1F93C, 0x200D, 0x2640 }, + ["women’s room"]={ 0x1F6BA }, + ["world map"]={ 0x1F5FA }, + ["worried face"]={ 0x1F61F }, + ["wrapped gift"]={ 0x1F381 }, + ["wrench"]={ 0x1F527 }, + ["writing hand"]={ 0x270D }, + ["writing hand: dark skin tone"]={ 0x270D, 0x1F3FF }, + ["writing hand: light skin tone"]={ 0x270D, 0x1F3FB }, + ["writing hand: medium skin tone"]={ 0x270D, 0x1F3FD }, + ["writing hand: medium-dark skin tone"]={ 0x270D, 0x1F3FE }, + ["writing hand: medium-light skin tone"]={ 0x270D, 0x1F3FC }, + ["yellow heart"]={ 0x1F49B }, + ["yemen"]={ 0x1F1FE, 0x1F1EA }, + ["yen banknote"]={ 0x1F4B4 }, + ["yin yang"]={ 0x262F }, + ["zambia"]={ 0x1F1FF, 0x1F1F2 }, + ["zebra"]={ 0x1F993 }, + ["zimbabwe"]={ 0x1F1FF, 0x1F1FC }, + ["zipper-mouth face"]={ 0x1F910 }, + ["zombie"]={ 0x1F9DF }, + ["zzz"]={ 0x1F4A4 }, + ["Åland islands"]={ 0x1F1E6, 0x1F1FD }, +} diff --git a/tex/context/base/mkiv/char-enc.lua b/tex/context/base/mkiv/char-enc.lua index c2061891a..f4f9fb95a 100644 --- a/tex/context/base/mkiv/char-enc.lua +++ b/tex/context/base/mkiv/char-enc.lua @@ -162,7 +162,6 @@ characters.synonyms = allocate { -- afm mess -- if not enccodes[name] then enccodes[name] = unicode end -- end -- --- -- end -- -- storage.register("characters.enccodes", characters.enccodes, "characters.enccodes") diff --git a/tex/context/base/mkiv/char-fio.lua b/tex/context/base/mkiv/char-fio.lua index ab2555935..fa69d9356 100644 --- a/tex/context/base/mkiv/char-fio.lua +++ b/tex/context/base/mkiv/char-fio.lua @@ -42,18 +42,19 @@ local reporting = "no" -- per line by default local enforced = { - ["characters.filters.utf.reorder"] = true, ["characters.filters.utf.collapse"] = true, ["characters.filters.utf.decompose"] = true, + ["characters.filters.utf.reorder"] = false, } function utffilters.enable() + -- only used one time (normally) for k, v in next, enforced do if v then if reporting == "yes" then report("%a enabled",k) end - enableaction(textfileactions,v) + enableaction(textfileactions,k) else if reporting == "yes" then report("%a not enabled",k) diff --git a/tex/context/base/mkiv/char-ini.lua b/tex/context/base/mkiv/char-ini.lua index 63328a177..8fe852b58 100644 --- a/tex/context/base/mkiv/char-ini.lua +++ b/tex/context/base/mkiv/char-ini.lua @@ -14,8 +14,9 @@ if not modules then modules = { } end modules ['char-ini'] = { local utfchar, utfbyte, utfvalues, ustring, utotable = utf.char, utf.byte, utf.values, utf.ustring, utf.totable local concat, unpack, tohash, insert = table.concat, table.unpack, table.tohash, table.insert local next, tonumber, type, rawget, rawset = next, tonumber, type, rawget, rawset -local format, lower, gsub = string.format, string.lower, string.gsub -local P, R, S, Cs = lpeg.P, lpeg.R, lpeg.S, lpeg.Cs +local format, lower, gsub, find, match = string.format, string.lower, string.gsub, string.find, string.match +local P, R, S, C, Cs, Ct, Cc, V = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.Cc, lpeg.V +local formatters = string.formatters if not characters then require("char-def") end @@ -178,6 +179,7 @@ insert(characters.ranges,{ }) local blocks = allocate { + ["adlam"] = { first = 0x1E900, last = 0x1E95F, description = "Adlam" }, ["aegeannumbers"] = { first = 0x10100, last = 0x1013F, description = "Aegean Numbers" }, ["ahom"] = { first = 0x11700, last = 0x1173F, description = "Ahom" }, ["alchemicalsymbols"] = { first = 0x1F700, last = 0x1F77F, description = "Alchemical Symbols" }, @@ -202,6 +204,7 @@ local blocks = allocate { ["bassavah"] = { first = 0x16AD0, last = 0x16AFF, description = "Bassa Vah" }, ["batak"] = { first = 0x01BC0, last = 0x01BFF, description = "Batak" }, ["bengali"] = { first = 0x00980, last = 0x009FF, otf="beng", description = "Bengali" }, + ["bhaiksuki"] = { first = 0x11C00, last = 0x11C6F, description = "Bhaiksuki" }, ["blockelements"] = { first = 0x02580, last = 0x0259F, otf="bopo", description = "Block Elements" }, ["bopomofo"] = { first = 0x03100, last = 0x0312F, otf="bopo", description = "Bopomofo" }, ["bopomofoextended"] = { first = 0x031A0, last = 0x031BF, otf="bopo", description = "Bopomofo Extended" }, @@ -247,6 +250,7 @@ local blocks = allocate { ["cyrillic"] = { first = 0x00400, last = 0x004FF, otf="cyrl", description = "Cyrillic" }, ["cyrillicextendeda"] = { first = 0x02DE0, last = 0x02DFF, otf="cyrl", description = "Cyrillic Extended-A" }, ["cyrillicextendedb"] = { first = 0x0A640, last = 0x0A69F, otf="cyrl", description = "Cyrillic Extended-B" }, + ["cyrillicextendedc"] = { first = 0x01C80, last = 0x01C8F, description = "Cyrillic Extended-C" }, ["cyrillicsupplement"] = { first = 0x00500, last = 0x0052F, otf="cyrl", description = "Cyrillic Supplement" }, ["deseret"] = { first = 0x10400, last = 0x1044F, otf="dsrt", description = "Deseret" }, ["devanagari"] = { first = 0x00900, last = 0x0097F, otf="deva", description = "Devanagari" }, @@ -297,6 +301,7 @@ local blocks = allocate { ["georgian"] = { first = 0x010A0, last = 0x010FF, otf="geor", description = "Georgian" }, ["georgiansupplement"] = { first = 0x02D00, last = 0x02D2F, otf="geor", description = "Georgian Supplement" }, ["glagolitic"] = { first = 0x02C00, last = 0x02C5F, otf="glag", description = "Glagolitic" }, + ["glagoliticsupplement"] = { first = 0x1E000, last = 0x1E02F, description = "Glagolitic Supplement" }, ["gothic"] = { first = 0x10330, last = 0x1034F, otf="goth", description = "Gothic" }, ["grantha"] = { first = 0x11300, last = 0x1137F, description = "Grantha" }, ["greekandcoptic"] = { first = 0x00370, last = 0x003FF, otf="grek", description = "Greek and Coptic" }, @@ -316,6 +321,7 @@ local blocks = allocate { ["highsurrogates"] = { first = 0x0D800, last = 0x0DB7F, description = "High Surrogates" }, ["hiragana"] = { first = 0x03040, last = 0x0309F, otf="kana", description = "Hiragana" }, ["ideographicdescriptioncharacters"] = { first = 0x02FF0, last = 0x02FFF, description = "Ideographic Description Characters" }, + ["ideographicsymbolsandpunctuation"] = { first = 0x16FE0, last = 0x16FFF, description = "Ideographic Symbols and Punctuation" }, ["imperialaramaic"] = { first = 0x10840, last = 0x1085F, description = "Imperial Aramaic" }, ["inscriptionalpahlavi"] = { first = 0x10B60, last = 0x10B7F, description = "Inscriptional Pahlavi" }, ["inscriptionalparthian"] = { first = 0x10B40, last = 0x10B5F, description = "Inscriptional Parthian" }, @@ -377,6 +383,7 @@ local blocks = allocate { ["malayalam"] = { first = 0x00D00, last = 0x00D7F, otf="mlym", description = "Malayalam" }, ["mandaic"] = { first = 0x00840, last = 0x0085F, otf="mand", description = "Mandaic" }, ["manichaean"] = { first = 0x10AC0, last = 0x10AFF, description = "Manichaean" }, + ["marchen"] = { first = 0x11C70, last = 0x11CBF, description = "Marchen" }, ["mathematicalalphanumericsymbols"] = { first = 0x1D400, last = 0x1D7FF, math = true, description = "Mathematical Alphanumeric Symbols" }, ["mathematicaloperators"] = { first = 0x02200, last = 0x022FF, math = true, description = "Mathematical Operators" }, ["meeteimayek"] = { first = 0x0ABC0, last = 0x0ABFF, description = "Meetei Mayek" }, @@ -394,6 +401,7 @@ local blocks = allocate { ["modi"] = { first = 0x11600, last = 0x1165F, description = "Modi" }, ["modifiertoneletters"] = { first = 0x0A700, last = 0x0A71F, description = "Modifier Tone Letters" }, ["mongolian"] = { first = 0x01800, last = 0x018AF, otf="mong", description = "Mongolian" }, + ["mongoliansupplement"] = { first = 0x11660, last = 0x1167F, description = "Mongolian Supplement" }, ["mro"] = { first = 0x16A40, last = 0x16A6F, description = "Mro" }, ["multani"] = { first = 0x11280, last = 0x112AF, description = "Multani" }, ["musicalsymbols"] = { first = 0x1D100, last = 0x1D1FF, otf="musc", description = "Musical Symbols" }, @@ -401,6 +409,7 @@ local blocks = allocate { ["myanmarextendeda"] = { first = 0x0AA60, last = 0x0AA7F, description = "Myanmar Extended-A" }, ["myanmarextendedb"] = { first = 0x0A9E0, last = 0x0A9FF, description = "Myanmar Extended-B" }, ["nabataean"] = { first = 0x10880, last = 0x108AF, description = "Nabataean" }, + ["newa"] = { first = 0x11400, last = 0x1147F, description = "Newa" }, ["newtailue"] = { first = 0x01980, last = 0x019DF, description = "New Tai Lue" }, ["nko"] = { first = 0x007C0, last = 0x007FF, otf="nko", description = "NKo" }, ["numberforms"] = { first = 0x02150, last = 0x0218F, description = "Number Forms" }, @@ -416,6 +425,7 @@ local blocks = allocate { ["opticalcharacterrecognition"] = { first = 0x02440, last = 0x0245F, description = "Optical Character Recognition" }, ["oriya"] = { first = 0x00B00, last = 0x00B7F, otf="orya", description = "Oriya" }, ["ornamentaldingbats"] = { first = 0x1F650, last = 0x1F67F, description = "Ornamental Dingbats" }, + ["osage"] = { first = 0x104B0, last = 0x104FF, description = "Osage" }, ["osmanya"] = { first = 0x10480, last = 0x104AF, otf="osma", description = "Osmanya" }, ["pahawhhmong"] = { first = 0x16B00, last = 0x16B8F, description = "Pahawh Hmong" }, ["palmyrene"] = { first = 0x10860, last = 0x1087F, description = "Palmyrene" }, @@ -466,6 +476,8 @@ local blocks = allocate { ["taixuanjingsymbols"] = { first = 0x1D300, last = 0x1D35F, description = "Tai Xuan Jing Symbols" }, ["takri"] = { first = 0x11680, last = 0x116CF, description = "Takri" }, ["tamil"] = { first = 0x00B80, last = 0x00BFF, otf="taml", description = "Tamil" }, + ["tangut"] = { first = 0x17000, last = 0x187FF, description = "Tangut" }, + ["tangutcomponents"] = { first = 0x18800, last = 0x18AFF, description = "Tangut Components" }, ["telugu"] = { first = 0x00C00, last = 0x00C7F, otf="telu", description = "Telugu" }, ["thaana"] = { first = 0x00780, last = 0x007BF, otf="thaa", description = "Thaana" }, ["thai"] = { first = 0x00E00, last = 0x00E7F, otf="thai", description = "Thai" }, @@ -541,15 +553,34 @@ setmetatableindex(otfscripts,function(t,unicode) return "dflt" end) -local splitter = lpeg.splitat(S(":-")) +local splitter1 = lpeg.splitat(S(":-")) +local splitter2 = lpeg.splitat(S(" +-"),true) -function characters.getrange(name) -- used in font fallback definitions (name or range) - local range = blocks[name] +function characters.getrange(name,expression) -- used in font fallback definitions (name or range) + local range = rawget(blocks,lower(gsub(name,"[^a-zA-Z0-9]",""))) if range then return range.first, range.last, range.description, range.gaps end name = gsub(name,'"',"0x") -- goodie: tex hex notation - local start, stop = lpegmatch(splitter,name) + local start, stop + if expression then + local first, rest = lpegmatch(splitter2,name) + local range = rawget(blocks,lower(gsub(first,"[^a-zA-Z0-9]",""))) + if range then + start = range.first + stop = range.last + local s = loadstring("return 0 " .. rest) + if type(s) == "function" then + local d = s() + if type(d) == "number" then + start = start + d + stop = stop + d + return start, stop, nil + end + end + end + end + start, stop = lpegmatch(splitter1,name) if start and stop then start, stop = tonumber(start,16) or tonumber(start), tonumber(stop,16) or tonumber(stop) if start and stop then @@ -560,6 +591,9 @@ function characters.getrange(name) -- used in font fallback definitions (name or return slot, slot, nil end +-- print(characters.getrange("lowercaseitalic + 123",true)) +-- print(characters.getrange("lowercaseitalic + 124",true)) + local categorytags = allocate { lu = "Letter Uppercase", ll = "Letter Lowercase", @@ -674,16 +708,17 @@ characters.linebreaks = { -- non-tailorable line breaking classes - ["bk"] = "mandatory break", -- nl, ps : cause a line break (after) - ["cr"] = "carriage return", -- cr : cause a line break (after), except between cr and lf - ["lf"] = "line feed", -- lf : cause a line break (after) - ["cm"] = "combining mark", -- combining marks, control codes : prohibit a line break between the character and the preceding character - ["nl"] = "next line", -- nel : cause a line break (after) - ["sg"] = "surrogate", -- surrogates :do not occur in well-formed text - ["wj"] = "word joiner", -- wj : prohibit line breaks before and after - ["zw"] = "zero width space", -- zwsp : provide a break opportunity - ["gl"] = "non-breaking (glue)", -- cgj, nbsp, zwnbsp : prohibit line breaks before and after - ["sp"] = "space", -- space : enable indirect line breaks + ["bk"] = "mandatory break", -- nl, ps : cause a line break (after) + ["cr"] = "carriage return", -- cr : cause a line break (after), except between cr and lf + ["lf"] = "line feed", -- lf : cause a line break (after) + ["cm"] = "combining mark", -- combining marks, control codes : prohibit a line break between the character and the preceding character + ["nl"] = "next line", -- nel : cause a line break (after) + ["sg"] = "surrogate", -- surrogates :do not occur in well-formed text + ["wj"] = "word joiner", -- wj : prohibit line breaks before and after + ["zw"] = "zero width space", -- zwsp : provide a break opportunity + ["gl"] = "non-breaking (glue)", -- cgj, nbsp, zwnbsp : prohibit line breaks before and after + ["sp"] = "space", -- space : enable indirect line breaks + ["zwj"] = "zero width joiner", -- prohibit line breaks within joiner sequences -- break opportunities @@ -716,6 +751,8 @@ characters.linebreaks = { ["ai"] = "ambiguous (alphabetic or ideographic)", -- characters with ambiguous east asian width : act like al when the resolved eaw is n; otherwise, act as id ["al"] = "alphabetic", -- alphabets and regular symbols : are alphabetic characters or symbols that are used with alphabetic characters ["cj"] = "conditional japanese starter", -- small kana : treat as ns or id for strict or normal breaking. + ["eb"] = "emoji base", -- all emoji allowing modifiers, do not break from following emoji modifier + ["em"] = "emoji modifier", -- skin tone modifiers, do not break from preceding emoji base ["h2"] = "hangul lv syllable", -- hangul : form korean syllable blocks ["h3"] = "hangul lvt syllable", -- hangul : form korean syllable blocks ["hl"] = "hebrew letter", -- hebrew : do not break around a following hyphen; otherwise act as alphabetic @@ -802,7 +839,7 @@ setmetatableindex(characters.directions,function(t,k) end end t[k] = false -- maybe 'l' - return v + return false end) characters.mirrors = { } @@ -817,7 +854,7 @@ setmetatableindex(characters.mirrors,function(t,k) end end t[k] = false - return v + return false end) characters.textclasses = { } @@ -832,7 +869,7 @@ setmetatableindex(characters.textclasses,function(t,k) end end t[k] = false - return v + return false end) --[[ldx-- @@ -928,6 +965,7 @@ end) local specialchars = allocate() characters.specialchars = specialchars -- lazy table local descriptions = allocate() characters.descriptions = descriptions -- lazy table +local synonyms = allocate() characters.synonyms = synonyms -- lazy table setmetatableindex(specialchars, function(t,u) if u then @@ -961,7 +999,9 @@ setmetatableindex(descriptions, function(t,k) for u, c in next, data do local d = c.description if d then - d = gsub(d," ","") + if find(d," ") then + d = gsub(d," ","") + end d = lower(d) t[d] = u end @@ -973,6 +1013,24 @@ setmetatableindex(descriptions, function(t,k) return d end) +setmetatableindex(synonyms, function(t,k) + for u, c in next, data do + local s = c.synonyms + if s then + if find(s," ") then + s = gsub(s," ","") + end + -- s = lower(s) -- is already lowercase + t[s] = u + end + end + local s = rawget(t,k) + if not s then + t[s] = s + end + return s +end) + function characters.unicodechar(asked) local n = tonumber(asked) if n then @@ -1352,6 +1410,184 @@ function characters.showstring(str) end end +do + + -- There is no need to preload this table. + + local any = P(1) + local special = S([['".,:;-+()]]) + + P('“') + P('”') + local apostrofe = P("’") + P("'") + + local pattern = Cs ( ( + (P("medium light") / "medium-light" + P("medium dark") / "medium-dark") * P(" skin tone") + + (apostrofe * P("s"))/"" + + special/"" + + any + )^1) + + local function load() + local name = resolvers.find_file("char-emj.lua") + local data = name and name ~= "" and dofile(name) or { } + local hash = { } + for d, c in next, data do + local k = lpegmatch(pattern,d) or d + local u = { } + for i=1,#c do + u[i] = utfchar(c[i]) + end + u = concat(u) + hash[k] = u + end + return data, hash + end + + local data, hash = nil, nil + + function characters.emojized(name) + local t = lpegmatch(pattern,name) + if t then + return t + else + return { name } + end + end + + local start = P(" ") + local finish = P(-1) + P(" ") + local skintone = P("medium ")^0 * (P("light ") + P("dark "))^0 * P("skin tone") + local gender = P("woman") + P("man") + local expanded = ( + P("m-l-")/"medium-light" + + P("m-d-")/"medium-dark" + + P("l-") /"light" + + P("m-") /"medium" + + P("d-") /"dark" + ) + * (P("s-t")/" skin tone") + local compacted = ( + (P("medium-")/"m-" * (P("light")/"l" + P("dark")/"d")) + + (P("medium")/"m" + P("light")/"l" + P("dark")/"d") + ) + * (P(" skin tone")/"-s-t") + + local pattern_0 = Cs((expanded + any)^1) + local pattern_1 = Cs(((start * skintone + skintone * finish)/"" + any)^1) + local pattern_2 = Cs(((start * gender + gender * finish)/"" + any)^1) + local pattern_4 = Cs((compacted + any)^1) + + -- print(lpegmatch(pattern_0,"kiss woman l-s-t man d-s-t")) + -- print(lpegmatch(pattern_0,"something m-l-s-t")) + -- print(lpegmatch(pattern_0,"something m-s-t")) + -- print(lpegmatch(pattern_4,"something medium-light skin tone")) + -- print(lpegmatch(pattern_4,"something medium skin tone")) + + local skin = + P("light skin tone") / utfchar(0x1F3FB) + + P("medium-light skin tone") / utfchar(0x1F3FC) + + P("medium skin tone") / utfchar(0x1F3FD) + + P("medium-dark skin tone") / utfchar(0x1F3FE) + + P("dark skin tone") / utfchar(0x1F3FF) + + local parent = + P("man") / utfchar(0x1F468) + + P("woman") / utfchar(0x1F469) + + local child = + P("baby") / utfchar(0x1F476) + + P("boy") / utfchar(0x1F466) + + P("girl") / utfchar(0x1F467) + + local zwj = utfchar(0x200D) + local heart = utfchar(0x2764) .. utfchar(0xFE0F) .. zwj + local kiss = utfchar(0x2764) .. utfchar(0xFE0F) .. utfchar(0x200D) .. utfchar(0x1F48B) .. zwj + + ----- member = parent + child + + local space = P(" ") + local final = P(-1) + + local p_done = (space^1/zwj) + P(-1) + local p_rest = space/"" * (skin * p_done) + p_done + local p_parent = parent * p_rest + local p_child = child * p_rest + + local p_family = Cs ( (P("family") * space^1)/"" * p_parent^-2 * p_child^-2 ) + local p_couple = Cs ( (P("couple with heart") * space^1)/"" * p_parent * Cc(heart) * p_parent ) + local p_kiss = Cs ( (P("kiss") * space^1)/"" * p_parent * Cc(kiss) * p_parent ) + + local p_special = p_family + p_couple + p_kiss + + -- print(lpeg.match(p_special,"family man woman girl")) + -- print(lpeg.match(p_special,"family man dark skin tone woman girl girl")) + + -- local p_special = P { "all", + -- all = Cs (V("family") + V("couple") + V("kiss")), + -- family = C("family") * space^1 * V("parent")^-2 * V("child")^-2, + -- couple = P("couple with heart") * space^1 * V("parent") * Cc(heart) * V("parent"), + -- kiss = P("kiss") * space^1 * V("parent") * Cc(kiss) * V("parent"), + -- parent = parent * V("rest"), + -- child = child * V("rest"), + -- rest = (space * skin)^0/"" * ((space^1/zwj) + P(-1)), + -- } + + local emoji = { } + characters.emoji = emoji + +local cache = setmetatable({ }, { __mode = "k" } ) + + function emoji.resolve(name) + if not hash then + data, hash = load() + end + local h = hash[name] + if h then + return h + end +local h = cache[name] +if h then + return h +elseif h == false then + return +end + -- expand shortcuts + local name = lpegmatch(pattern_0,name) or name + -- expand some 25K variants + local h = lpegmatch(p_special,name) + if h then +cache[name] = h + return h + end + -- simplify + local s = lpegmatch(pattern_1,name) + local h = hash[s] + if h then +cache[name] = h + return h + end + -- simplify + local s = lpegmatch(pattern_2,name) + local h = hash[s] + if h then +cache[name] = h + return h + end +cache[name] = false + end + + function emoji.known() + if not hash then + data, hash = load() + end + return hash, data + end + + function emoji.compact(name) + return lpegmatch(pattern_4,name) or name + end + +end + -- code moved to char-tex.lua return characters diff --git a/tex/context/base/mkiv/char-obs.lua b/tex/context/base/mkiv/char-obs.lua new file mode 100644 index 000000000..0f0e43d3c --- /dev/null +++ b/tex/context/base/mkiv/char-obs.lua @@ -0,0 +1,269 @@ +------------------------ +----- char-ini.lua ----- +------------------------ + +-- local template_a = "\\startextendcatcodetable{%s}\\chardef\\l=11\\chardef\\a=13\\let\\c\\catcode%s\\let\\a\\undefined\\let\\l\\undefined\\let\\c\\undefined\\stopextendcatcodetable" +-- local template_b = "\\chardef\\l=11\\chardef\\a=13\\let\\c\\catcode%s\\let\\a\\undefined\\let\\l\\undefined\\let\\c\\undefined" +-- +-- function characters.define(tobelettered, tobeactivated) -- catcodetables +-- local lettered, activated, l, a = { }, { }, 0, 0 +-- for u, chr in next, data do +-- -- we can use a macro instead of direct settings +-- local fallback = chr.fallback +-- if fallback then +-- -- texprint(format("{\\catcode %s=13\\unexpanded\\gdef %s{\\checkedchar{%s}{%s}}}",u,utfchar(u),u,fallback)) +-- texsprint("{\\catcode",u,"=13\\unexpanded\\gdef ",utfchar(u),"{\\checkedchar{",u,"}{",fallback,"}}}") -- no texprint +-- a = a + 1 +-- activated[a] = "\\c"..u.."\\a" +-- else +-- local contextname = chr.contextname +-- local category = chr.category +-- if contextname then +-- if is_character[category] then +-- -- by this time, we're still in normal catcode mode +-- -- subtle: not "\\",contextname but "\\"..contextname +-- if chr.unicodeslot < 128 then +-- texprint(ctxcatcodes,format("\\chardef\\%s=%s",contextname,u)) +-- else +-- texprint(ctxcatcodes,format("\\let\\%s=%s",contextname,utfchar(u))) +-- if is_letter[category] then +-- l = l + 1 +-- lettered[l] = "\\c"..u.."\\l" +-- end +-- end +-- elseif is_command[category] then +-- -- this might change: contextcommand ipv contextname +-- -- texprint(format("{\\catcode %s=13\\unexpanded\\gdef %s{\\%s}}",u,utfchar(u),contextname)) +-- texsprint("{\\catcode",u,"=13\\unexpanded\\gdef ",utfchar(u),"{\\"..contextname,"}}") -- no texprint +-- a = a + 1 +-- activated[a] = "\\c"..u.."\\a" +-- end +-- elseif is_letter[category] then +-- if u >= 128 and u <= 65536 then -- catch private mess +-- l = l + 1 +-- lettered[l] = "\\c"..u.."\\l" +-- end +-- end +-- end +-- local range = chr.range +-- if range then +-- l = l + 1 +-- lettered[l] = format('\\dofastrecurse{"%05X}{"%05X}{1}{\\c\\fastrecursecounter\\l}',range.first,range.last) +-- end +-- end +-- -- if false then +-- l = l + 1 +-- lettered[l] = "\\c"..0x200C.."\\l" -- non-joiner +-- l = l + 1 +-- lettered[l] = "\\c"..0x200D.."\\l" -- joiner +-- -- fi +-- if tobelettered then +-- lettered = concat(lettered) +-- if true then +-- texsprint(ctxcatcodes,format(template_b,lettered)) -- global +-- else +-- for l=1,#tobelettered do +-- texsprint(ctxcatcodes,format(template_a,tobelettered[l],lettered)) +-- end +-- end +-- end +-- if tobeactivated then +-- activated = concat(activated) +-- for a=1,#tobeactivated do +-- texsprint(ctxcatcodes,format(template_a,tobeactivated[a],activated)) +-- end +-- end +-- end +-- +-- function characters.setcodes() +-- for code, chr in next, data do +-- local cc = chr.category +-- if cc == 'll' or cc == 'lu' or cc == 'lt' then +-- local lc, uc = chr.lccode, chr.uccode +-- if not lc then chr.lccode, lc = code, code end +-- if not uc then chr.uccode, uc = code, code end +-- texsprint(ctxcatcodes,format("\\setcclcuc{%i}{%i}{%i}",code,lc,uc)) +-- end +-- if cc == "lu" then +-- texprint(ctxcatcodes,"\\sfcode ",code,"999 ") +-- end +-- if cc == "lo" then +-- local range = chr.range +-- if range then +-- texsprint(ctxcatcodes,format('\\dofastrecurse{"%05X}{"%05X}{1}{\\setcclcucself\\fastrecursecounter}',range.first,range.last)) +-- end +-- end +-- end +-- end + +-- --[[ldx-- +-- <p>The next variant has lazy token collecting, on a 140 page mk.tex this saves +-- about .25 seconds, which is understandable because we have no graphemes and +-- not collecting tokens is not only faster but also saves garbage collecting. +-- </p> +-- --ldx]]-- +-- +-- function utffilters.collapse(str,filename) -- we can make high a seperate pass (never needed with collapse) +-- if skippable[filesuffix(filename)] then +-- return str +-- -- elseif find(filename,"^virtual://") then +-- -- return str +-- -- else +-- -- -- print("\n"..filename) +-- end +-- if str and str ~= "" then +-- local nstr = #str +-- if nstr > 1 then +-- if initialize then -- saves a call +-- initialize() +-- end +-- local tokens, t, first, done, n = { }, 0, false, false, 0 +-- for second in utfcharacters(str) do +-- if done then +-- if first then +-- if second == " " then +-- t = t + 1 +-- tokens[t] = first +-- first = second +-- else +-- -- local crs = high[second] +-- -- if crs then +-- -- t = t + 1 +-- -- tokens[t] = first +-- -- first = crs +-- -- else +-- local cgf = graphemes[first] +-- if cgf and cgf[second] then +-- first = cgf[second] +-- else +-- t = t + 1 +-- tokens[t] = first +-- first = second +-- end +-- -- end +-- end +-- elseif second == " " then +-- first = second +-- else +-- -- local crs = high[second] +-- -- if crs then +-- -- first = crs +-- -- else +-- first = second +-- -- end +-- end +-- elseif second == " " then +-- first = nil +-- n = n + 1 +-- else +-- -- local crs = high[second] +-- -- if crs then +-- -- for s in utfcharacters(str) do +-- -- if n == 1 then +-- -- break +-- -- else +-- -- t = t + 1 +-- -- tokens[t] = s +-- -- n = n - 1 +-- -- end +-- -- end +-- -- if first then +-- -- t = t + 1 +-- -- tokens[t] = first +-- -- end +-- -- first = crs +-- -- done = true +-- -- else +-- local cgf = graphemes[first] +-- if cgf and cgf[second] then +-- for s in utfcharacters(str) do +-- if n == 1 then +-- break +-- else +-- t = t + 1 +-- tokens[t] = s +-- n = n - 1 +-- end +-- end +-- first = cgf[second] +-- done = true +-- else +-- first = second +-- n = n + 1 +-- end +-- -- end +-- end +-- end +-- if done then +-- if first then +-- t = t + 1 +-- tokens[t] = first +-- end +-- return concat(tokens) -- seldom called +-- end +-- elseif nstr > 0 then +-- return high[str] or str -- this will go from here +-- end +-- end +-- return str +-- end + +-- function utffilters.decompose(str) +-- if str and str ~= "" then +-- local nstr = #str +-- if nstr > 1 then +-- -- if initialize then -- saves a call +-- -- initialize() +-- -- end +-- local tokens, t, done, n = { }, 0, false, 0 +-- for s in utfcharacters(str) do +-- local dec = decomposed[s] +-- if dec then +-- if not done then +-- if n > 0 then +-- for s in utfcharacters(str) do +-- if n == 0 then +-- break +-- else +-- t = t + 1 +-- tokens[t] = s +-- n = n - 1 +-- end +-- end +-- end +-- done = true +-- end +-- t = t + 1 +-- tokens[t] = dec +-- elseif done then +-- t = t + 1 +-- tokens[t] = s +-- else +-- n = n + 1 +-- end +-- end +-- if done then +-- return concat(tokens) -- seldom called +-- end +-- end +-- end +-- return str +-- end + +-- local replacer = nil +-- local finder = nil +-- +-- function utffilters.decompose(str) -- 3 to 4 times faster than the above +-- if not replacer then +-- if initialize then +-- initialize() +-- end +-- local tree = utfchartabletopattern(decomposed) +-- finder = lpeg.finder(tree,false,true) +-- replacer = lpeg.replacer(tree,decomposed,false,true) +-- end +-- if str and str ~= "" and #str > 1 and lpegmatch(finder,str) then +-- return lpegmatch(replacer,str) +-- end +-- return str +-- end diff --git a/tex/context/base/mkiv/char-tex.lua b/tex/context/base/mkiv/char-tex.lua index 60f324be2..3e0d02bc1 100644 --- a/tex/context/base/mkiv/char-tex.lua +++ b/tex/context/base/mkiv/char-tex.lua @@ -424,7 +424,6 @@ local implement = interfaces.implement local tex = tex local texsetlccode = tex.setlccode -local texsetuccode = tex.setuccode local texsetsfcode = tex.setsfcode local texsetcatcode = tex.setcatcode @@ -592,7 +591,8 @@ if not csletters then elseif is_mark[category] then texsetlccode(u,u,u) -- for hyphenation end - elseif isletter and u >= 32 and u <= 65536 then + -- elseif isletter and u >= 32 and u <= 65536 then + elseif isletter then csletters[utfchar(u)] = u -- local lc, uc = chr.lccode, chr.uccode diff --git a/tex/context/base/mkiv/char-utf.lua b/tex/context/base/mkiv/char-utf.lua index 327529c32..5702f2087 100644 --- a/tex/context/base/mkiv/char-utf.lua +++ b/tex/context/base/mkiv/char-utf.lua @@ -17,6 +17,9 @@ of output (for instance <l n='pdf'/>).</p> <p>We implement these manipulations as filters. One can run multiple filters over a string.</p> + +<p>The old code has now been moved to char-obs.lua which we keep around for +educational purposes.</p> --ldx]]-- local gsub, find = string.gsub, string.find @@ -42,21 +45,6 @@ local charfromnumber = characters.fromnumber characters = characters or { } local characters = characters -local graphemes = allocate() -characters.graphemes = graphemes - -local collapsed = allocate() -characters.collapsed = collapsed - -local combined = allocate() -characters.combined = combined - -local decomposed = allocate() -characters.decomposed = decomposed - -local mathpairs = allocate() -characters.mathpairs = mathpairs - local filters = allocate() characters.filters = filters @@ -65,8 +53,6 @@ characters.filters.utf = utffilters local data = characters.data --- is characters.combined cached? - --[[ldx-- <p>It only makes sense to collapse at runtime, since we don't expect source code to depend on collapsing.</p> @@ -96,78 +82,20 @@ local decomposed = allocate { characters.decomposed = decomposed --- local function initialize() -- maybe only 'mn' --- local data = characters.data --- for unicode, v in next, data do --- -- using vs and first testing for length is faster (.02->.01 s) --- local vs = v.specials --- if vs and #vs == 3 then --- local vc = vs[1] --- if vc == "char" then --- local one, two = vs[2], vs[3] --- if data[two].category == "mn" then --- local cgf = combined[one] --- if not cgf then --- cgf = { [two] = unicode } --- combined[one] = cgf --- else --- cgf[two] = unicode --- end --- end --- local first, second, combination = utfchar(one), utfchar(two), utfchar(unicode) --- local cgf = graphemes[first] --- if not cgf then --- cgf = { [second] = combination } --- graphemes[first] = cgf --- else --- cgf[second] = combination --- end --- if v.mathclass or v.mathspec then --- local mps = mathpairs[two] --- if not mps then --- mps = { [one] = unicode } --- mathpairs[two] = mps --- else --- mps[one] = unicode -- here unicode --- end --- local mps = mathpairs[second] --- if not mps then --- mps = { [first] = combination } --- mathpairs[second] = mps --- else --- mps[first] = combination --- end --- end --- -- elseif vc == "compat" then --- -- else --- -- local description = v.description --- -- if find(description,"LIGATURE") then --- -- if vs then --- -- local t = { } --- -- for i=2,#vs do --- -- t[#t+1] = utfchar(vs[i]) --- -- end --- -- decomposed[utfchar(unicode)] = concat(t) --- -- else --- -- local vs = v.shcode --- -- if vs then --- -- local t = { } --- -- for i=1,#vs do --- -- t[i] = utfchar(vs[i]) --- -- end --- -- decomposed[utfchar(unicode)] = concat(t) --- -- end --- -- end --- -- end --- end --- end --- end --- initialize = false --- characters.initialize = function() end -- when used outside tex --- end +local graphemes = characters.graphemes +local collapsed = characters.collapsed +local mathpairs = characters.mathpairs + +if not graphemes then + + graphemes = allocate() + collapsed = allocate() + mathpairs = allocate() + + characters.graphemes = graphemes + characters.collapsed = collapsed + characters.mathpairs = mathpairs -local function initialize() -- maybe in tex mode store in format ! - local data = characters.data local function backtrack(v,last,target) local vs = v.specials if vs and #vs == 3 and vs[1] == "char" then @@ -177,6 +105,7 @@ local function initialize() -- maybe in tex mode store in format ! backtrack(data[one],second,target) end end + local function setpair(one,two,unicode,first,second,combination) local mps = mathpairs[one] if not mps then @@ -193,6 +122,7 @@ local function initialize() -- maybe in tex mode store in format ! mps[second] = combination end end + for unicode, v in next, data do local vs = v.specials if vs and #vs == 3 and vs[1] == "char" then @@ -222,18 +152,16 @@ local function initialize() -- maybe in tex mode store in format ! setpair(one,two,unicode,first,second,combination) end end - initialize = false - characters.initialize = function() end -end -characters.initialize = initialize + if storage then + storage.register("characters/graphemes", characters.graphemes, "characters.graphemes") + storage.register("characters/collapsed", characters.collapsed, "characters.collapsed") + storage.register("characters/mathpairs", characters.mathpairs, "characters.mathpairs") + end ---[[ldx-- -<p>The next variant has lazy token collecting, on a 140 page mk.tex this saves -about .25 seconds, which is understandable because we have no graphemes and -not collecting tokens is not only faster but also saves garbage collecting. -</p> ---ldx]]-- +end + +function characters.initialize() end -- dummy local skippable = { } local filesuffix = file.suffix @@ -251,119 +179,9 @@ function utffilters.setskippable(suffix,value) end end --- function utffilters.collapse(str,filename) -- we can make high a seperate pass (never needed with collapse) --- if skippable[filesuffix(filename)] then --- return str --- -- elseif find(filename,"^virtual://") then --- -- return str --- -- else --- -- -- print("\n"..filename) --- end --- if str and str ~= "" then --- local nstr = #str --- if nstr > 1 then --- if initialize then -- saves a call --- initialize() --- end --- local tokens, t, first, done, n = { }, 0, false, false, 0 --- for second in utfcharacters(str) do --- if done then --- if first then --- if second == " " then --- t = t + 1 --- tokens[t] = first --- first = second --- else --- -- local crs = high[second] --- -- if crs then --- -- t = t + 1 --- -- tokens[t] = first --- -- first = crs --- -- else --- local cgf = graphemes[first] --- if cgf and cgf[second] then --- first = cgf[second] --- else --- t = t + 1 --- tokens[t] = first --- first = second --- end --- -- end --- end --- elseif second == " " then --- first = second --- else --- -- local crs = high[second] --- -- if crs then --- -- first = crs --- -- else --- first = second --- -- end --- end --- elseif second == " " then --- first = nil --- n = n + 1 --- else --- -- local crs = high[second] --- -- if crs then --- -- for s in utfcharacters(str) do --- -- if n == 1 then --- -- break --- -- else --- -- t = t + 1 --- -- tokens[t] = s --- -- n = n - 1 --- -- end --- -- end --- -- if first then --- -- t = t + 1 --- -- tokens[t] = first --- -- end --- -- first = crs --- -- done = true --- -- else --- local cgf = graphemes[first] --- if cgf and cgf[second] then --- for s in utfcharacters(str) do --- if n == 1 then --- break --- else --- t = t + 1 --- tokens[t] = s --- n = n - 1 --- end --- end --- first = cgf[second] --- done = true --- else --- first = second --- n = n + 1 --- end --- -- end --- end --- end --- if done then --- if first then --- t = t + 1 --- tokens[t] = first --- end --- return concat(tokens) -- seldom called --- end --- elseif nstr > 0 then --- return high[str] or str -- this will go from here --- end --- end --- return str --- end - --- this is about twice as fast - local p_collapse = nil -- so we can reset if needed local function prepare() - if initialize then - initialize() - end local tree = utfchartabletopattern(collapsed) p_collapse = Cs((tree/collapsed + p_utf8character)^0 * P(-1)) -- the P(1) is needed in order to accept non utf end @@ -381,72 +199,9 @@ function utffilters.collapse(str,filename) end end --- function utffilters.decompose(str) --- if str and str ~= "" then --- local nstr = #str --- if nstr > 1 then --- -- if initialize then -- saves a call --- -- initialize() --- -- end --- local tokens, t, done, n = { }, 0, false, 0 --- for s in utfcharacters(str) do --- local dec = decomposed[s] --- if dec then --- if not done then --- if n > 0 then --- for s in utfcharacters(str) do --- if n == 0 then --- break --- else --- t = t + 1 --- tokens[t] = s --- n = n - 1 --- end --- end --- end --- done = true --- end --- t = t + 1 --- tokens[t] = dec --- elseif done then --- t = t + 1 --- tokens[t] = s --- else --- n = n + 1 --- end --- end --- if done then --- return concat(tokens) -- seldom called --- end --- end --- end --- return str --- end - --- local replacer = nil --- local finder = nil --- --- function utffilters.decompose(str) -- 3 to 4 times faster than the above --- if not replacer then --- if initialize then --- initialize() --- end --- local tree = utfchartabletopattern(decomposed) --- finder = lpeg.finder(tree,false,true) --- replacer = lpeg.replacer(tree,decomposed,false,true) --- end --- if str and str ~= "" and #str > 1 and lpegmatch(finder,str) then --- return lpegmatch(replacer,str) --- end --- return str --- end - local p_decompose = nil local function prepare() - if initialize then - initialize() - end local tree = utfchartabletopattern(decomposed) p_decompose = Cs((tree/decomposed + p_utf8character)^0 * P(-1)) end @@ -481,8 +236,8 @@ function utffilters.addgrapheme(result,first,second) -- can be U+ 0x string or u graphemes[first][second] = result end local pair = first .. second - if not composed[pair] then - composed[pair] = result + if not collapsed[pair] then + collapsed[pair] = result p_composed = nil end end @@ -520,7 +275,7 @@ local p_reorder = nil -- return p, new -- end --- -- the next one isnto stable for similar weights +-- -- the next one into stable for similar weights local sorter = function(a,b) return b[2] < a[2] @@ -570,7 +325,8 @@ local function prepare() for k, v in sortedhash(characters.data) do local combining = v.combining -- v.ordering or v.combining if combining then - hash[utfchar(k)] = { utfchar(k), combining, 0 } -- slot 3 can be used in sort + local u = utfchar(k) + hash[u] = { u, combining, 0 } -- slot 3 can be used in sort end end local e = utfchartabletopattern(exceptions) @@ -594,7 +350,7 @@ end -- local collapse = utffilters.collapse -- local decompose = utffilters.decompose --- local preprocess = utffilters.preprocess +-- local reorder = utffilters.reorder -- -- local c1, c2, c3 = "a", "̂", "̃" -- local r2, r3 = "â", "ẫ" @@ -612,7 +368,7 @@ end -- for i=1,10000 do -- collapse(data) -- decompose(data) --- -- preprocess(data) +-- -- reorder(data) -- end -- print(os.clock()-t,decompose(collapse(data))==okay,decompose(collapse(str))) -- end diff --git a/tex/context/base/mkiv/char-utf.mkiv b/tex/context/base/mkiv/char-utf.mkiv index fe9f402ef..3b77771a7 100644 --- a/tex/context/base/mkiv/char-utf.mkiv +++ b/tex/context/base/mkiv/char-utf.mkiv @@ -31,9 +31,9 @@ %D since the source files are rather simple, we postpone the %D initialization till runtime. -\appendtoks - \clf_enableutf % not needed when we create a format so we do it now -\to \everyjob +% \appendtoks +% \clf_enableutf % not needed when we create a format so we do it now +% \to \everyjob %D The next one influences input parsing. %D diff --git a/tex/context/base/mkiv/chem-str.lua b/tex/context/base/mkiv/chem-str.lua index e90464ad2..a40ca76b0 100644 --- a/tex/context/base/mkiv/chem-str.lua +++ b/tex/context/base/mkiv/chem-str.lua @@ -47,7 +47,6 @@ local context = context local implement = interfaces.implement local formatters = string.formatters -local texgetcount = tex.getcount local v_default = variables.default local v_small = variables.small @@ -58,7 +57,6 @@ local v_fit = variables.fit local v_on = variables.on local v_none = variables.none -local mpnamedcolor = attributes.colors.mpnamedcolor local topoints = number.topoints local todimen = string.todimen @@ -289,6 +287,8 @@ end local remapper = { ["+"] = "p", ["-"] = "m", + ["--"] = "mm", + ["++"] = "pp", } local dchrs = R("09") @@ -301,7 +301,7 @@ local set = Ct(digit^2) local colon = P(":") local equal = P("=") local other = 1 - digit - colon - equal -local remapped = sign / remapper +local remapped = (sign * sign + sign) / remapper local operation = Cs(other^1) local special = (colon * C(other^1)) + Cc("") local text = (equal * C(P(1)^0)) + Cc(false) @@ -325,20 +325,19 @@ local pattern = -- print(lpegmatch(pattern,"RZ13=x")) -- 1 RZ false false table x local f_initialize = 'if unknown context_chem : input mp-chem.mpiv ; fi ;' -local f_start_structure = formatters['chem_start_structure(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s);'] +local f_start_structure = formatters['chem_start_structure(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%q);'] local f_set_trace_bounds = formatters['chem_trace_boundingbox := %l ;'] local f_stop_structure = 'chem_stop_structure;' local f_start_component = 'chem_start_component;' local f_stop_component = 'chem_stop_component;' -local f_line = formatters['chem_%s%s(%s,%s,%s,%s,%s);'] +local f_line = formatters['chem_%s%s(%s,%s,%s,%s,%q);'] local f_set = formatters['chem_set(%s);'] local f_number = formatters['chem_%s%s(%s,%s,"\\chemicaltext{%s}");'] local f_text = f_number local f_empty_normal = formatters['chem_%s(%s,%s,"");'] local f_empty_center = formatters['chem_c%s(%s,%s,"");'] local f_transform = formatters['chem_%s(%s,%s,%s);'] - -local prepareMPvariable = commands and commands.prepareMPvariable +local f_fixed = formatters['chem_%s(%s,%s,%q);'] local function process(level,spec,text,n,rulethickness,rulecolor,offset,default_variant) insert(stack,{ spec = spec, text = text, n = n }) @@ -380,7 +379,7 @@ local function process(level,spec,text,n,rulethickness,rulecolor,offset,default_ if t == v_default or t == v_normal or t == "" then rulecolor = saved_rulecolor elseif t then - rulecolor = mpnamedcolor(t) + rulecolor = t end elseif operation == "rulethickness" then local t = text @@ -604,7 +603,7 @@ local function process(level,spec,text,n,rulethickness,rulecolor,offset,default_ m = m + 1 ; metacode[m] = f_transform(operation,variant,index or 1,factor) end elseif what == "fixed" then - m = m + 1 ; metacode[m] = f_transform(operation,variant,rulethickness,rulecolor) + m = m + 1 ; metacode[m] = f_fixed(operation,variant,rulethickness,rulecolor) elseif trace_structure then report_chemistry("level %a, ignoring undefined operation %s",level,operation) end @@ -686,8 +685,8 @@ function chemistry.start(settings) local unit = settings.unit or 655360 local bondlength = settings.factor or 3 local rulethickness = settings.rulethickness or 65536 - local rulecolor = settings.rulecolor or "" - local axiscolor = settings.framecolor or "" + local rulecolor = settings.rulecolor or "black" + local axiscolor = settings.framecolor or "black" local scale = settings.scale or "normal" local rotation = settings.rotation or 0 local offset = settings.offset or 0 @@ -735,7 +734,7 @@ function chemistry.start(settings) if trace_structure then report_chemistry("skipping trial run") end - context.hrule(sp_width,sp_height,0) -- maybe depth + context.rule(sp_width,sp_height,0) -- maybe depth return end -- @@ -752,7 +751,7 @@ function chemistry.start(settings) chemistry.structures, left, right, top, bottom, rotation, topoints(unit), bondlength, scale, topoints(offset), - tostring(settings.axis == v_on), topoints(rulethickness), tostring(axiscolor) + tostring(settings.axis == v_on), topoints(rulethickness), axiscolor ) metacode[#metacode+1] = f_set_trace_bounds(trace_boundingbox) ; -- diff --git a/tex/context/base/mkiv/chem-str.mkiv b/tex/context/base/mkiv/chem-str.mkiv index a0b0a9327..2ff229b12 100644 --- a/tex/context/base/mkiv/chem-str.mkiv +++ b/tex/context/base/mkiv/chem-str.mkiv @@ -72,7 +72,7 @@ \c!method=\s!double] \startMPdefinitions{chemistry} - input mp-chem.mpiv ; + loadmodule "chem" ; \stopMPdefinitions \defineframed @@ -172,8 +172,8 @@ scale {\chemicalparameter\c!scale}% rotation {\chemicalparameter\c!rotation}% symalign {\chemicalparameter\c!symalign}% - axis {\chemicalparameter\c!axis}% - framecolor {\MPcolor{\chemicalparameter\c!framecolor}}% + axis {\chemicalparameter\c!axis}% was \MPcolor{...} + framecolor {\chemicalparameter\c!framecolor}% rulethickness {\number\dimexpr\chemicalparameter\c!rulethickness}% offset {\number\dimexpr\chemicalparameter\c!offset}% unit {\number\dimexpr\chemicalparameter\c!unit}% @@ -228,7 +228,7 @@ {#2}% {\detokenize{#3}}% {\the\dimexpr\chemicalparameter\c!rulethickness}% todo: scaled points - {\MPcolor{\chemicalparameter\c!rulecolor}}% % we can precalculate this for speedup + {\chemicalparameter\c!rulecolor}% \relax \ignorespaces} @@ -237,7 +237,7 @@ {#1}% {\detokenize{#2}}% {\the\dimexpr\chemicalparameter\c!rulethickness}% todo: scaled points - {\MPcolor{\chemicalparameter\c!rulecolor}}% % we can precalculate this for speedup + {\chemicalparameter\c!rulecolor}% \relax \ignorespaces} diff --git a/tex/context/base/mkiv/cldf-bas.lua b/tex/context/base/mkiv/cldf-bas.lua index 1067a17d5..2387793c8 100644 --- a/tex/context/base/mkiv/cldf-bas.lua +++ b/tex/context/base/mkiv/cldf-bas.lua @@ -22,25 +22,26 @@ if not modules then modules = { } end modules ['cldf-bas'] = { -- flush(ctxcatcodes,"}") -- end --- maybe use context.generics - local type = type local format = string.format local utfchar = utf.char local concat = table.concat local context = context -local generics = context.generics +local ctxcore = context.core local variables = interfaces.variables local nodepool = nodes.pool local new_rule = nodepool.rule local new_glyph = nodepool.glyph +local current_attr = nodes.current_attr local current_font = font.current local texgetcount = tex.getcount local texsetcount = tex.setcount +-- a set of basic fast ones + function context.char(k) -- used as escape too, so don't change to utf if type(k) == "table" then local n = #k @@ -68,34 +69,15 @@ function context.utfchar(k) end end --- plain variants - -function context.chardef(cs,u) - context([[\chardef\%s=%s\relax]],k) -end - -function context.par() - context([[\par]]) -- no need to add {} there -end - -function context.bgroup() - context("{") -end - -function context.egroup() - context("}") -end - -function context.space() - context("\\space") -- no " " as that gets intercepted -end - -function context.hrule(w,h,d,dir) +function context.rule(w,h,d,dir) + local rule if type(w) == "table" then - context(new_rule(w.width,w.height,w.depth,w.dir)) + rule = new_rule(w.width,w.height,w.depth,w.dir) else - context(new_rule(w,h,d,dir)) + rule = new_rule(w,h,d,dir) end + rule.attr = current_attr() + context(rule) end function context.glyph(id,k) @@ -103,74 +85,63 @@ function context.glyph(id,k) if not k then id, k = current_font(), id end - context(new_glyph(id,k)) + local glyph = new_glyph(id,k) + glyph.attr = current_attr() + context(glyph) end end -context.vrule = context.hrule - ---~ local hbox, bgroup, egroup = context.hbox, context.bgroup, context.egroup - ---~ function context.hbox(a,...) ---~ if type(a) == "table" then ---~ local s = { } ---~ if a.width then ---~ s[#s+1] = "to " .. a.width -- todo: check for number ---~ elseif a.spread then ---~ s[#s+1] = "spread " .. a.spread -- todo: check for number ---~ end ---~ -- todo: dir, attr etc ---~ hbox(false,table.concat(s," ")) ---~ bgroup() ---~ context(string.format(...)) ---~ egroup() ---~ else ---~ hbox(a,...) ---~ end ---~ end +local function ctx_par () context("\\par") end +local function ctx_space() context("\\space") end --- not yet used ... but will get variant at the tex end as well +context.par = ctx_par +context.space = ctx_space -function context.sethboxregister(n) context([[\setbox %s\hbox]],n) end -function context.setvboxregister(n) context([[\setbox %s\vbox]],n) end +ctxcore.par = ctx_par +ctxcore.space = ctx_space -function context.starthboxregister(n) - if type(n) == "number" then - context([[\setbox%s\hbox{]],n) - else - context([[\setbox\%s\hbox{]],n) - end -end +local function ctx_bgroup() context("{") end +local function ctx_egroup() context("}") end -function context.startvboxregister(n) - if type(n) == "number" then - context([[\setbox%s\vbox{]],n) - else - context([[\setbox\%s\vbox{]],n) - end -end +context.bgroup = ctx_bgroup +context.egroup = ctx_egroup -context.stophboxregister = context.egroup -context.stopvboxregister = context.egroup +ctxcore.bgroup = ctx_bgroup +ctxcore.egroup = ctx_egroup -function context.flushboxregister(n) - if type(n) == "number" then - context([[\box%s ]],n) - else - context([[\box\%s]],n) - end +-- not yet used ... but will get variant at the tex end as well + +local function setboxregister(kind,n) + context(type(n) == "number" and [[\setbox%s\%s]] or [[\setbox\%s\%s]],n,kind) end -function context.beginvbox() - context([[\vbox{]]) -- we can do \bvbox ... \evbox (less tokens) +function ctxcore.sethboxregister(n) setboxregister("hbox",n) end +function ctxcore.setvboxregister(n) setboxregister("vbox",n) end +function ctxcore.setvtopregister(n) setboxregister("vtop",n) end + +local function startboxregister(kind,n) + context(type(n) == "number" and [[\setbox%s\%s{]] or [[\setbox\%s\%s{]],n,kind) end -function context.beginhbox() - context([[\hbox{]]) -- todo: use fast one +function ctxcore.starthboxregister(n) startboxregister("hbox",n) end +function ctxcore.startvboxregister(n) startboxregister("vbox",n) end +function ctxcore.startvtopregister(n) startboxregister("vtop",n) end + +ctxcore.stophboxregister = ctx_egroup +ctxcore.stopvboxregister = ctx_egroup +ctxcore.stopvtopregister = ctx_egroup + +function ctxcore.flushboxregister(n) + context(type(n) == "number" and [[\box%s ]] or [[\box\%s]],n) end -context.endvbox = context.egroup -context.endhbox = context.egroup +function ctxcore.beginhbox() context([[\hbox{]]) end +function ctxcore.beginvbox() context([[\vbox{]]) end +function ctxcore.beginvtop() context([[\vtop{]]) end + +ctxcore.endhbox = ctx_egroup +ctxcore.endvbox = ctx_egroup +ctxcore.endvtop = ctx_egroup local function allocate(name,what,cmd) local a = format("c_syst_last_allocated_%s",what) @@ -182,9 +153,14 @@ local function allocate(name,what,cmd) return n end -function context.newdimen (name) return allocate(name,"dimen") end -function context.newskip (name) return allocate(name,"skip") end -function context.newcount (name) return allocate(name,"count") end -function context.newmuskip(name) return allocate(name,"muskip") end -function context.newtoks (name) return allocate(name,"toks") end -function context.newbox (name) return allocate(name,"box","mathchar") end +context.registers = { + -- the number is available directly, the csname after the lua call + newdimen = function(name) return allocate(name,"dimen") end, + newskip = function(name) return allocate(name,"skip") end, + newcount = function(name) return allocate(name,"count") end, + newmuskip = function(name) return allocate(name,"muskip") end, + newtoks = function(name) return allocate(name,"toks") end, + newbox = function(name) return allocate(name,"box","mathchar") end, + -- not really a register but kind of belongs here + newchar = function(name,u) context([[\chardef\%s=%s\relax]],name,u) end, +} diff --git a/tex/context/base/mkiv/cldf-com.lua b/tex/context/base/mkiv/cldf-com.lua index bd357b712..f9bf5b41a 100644 --- a/tex/context/base/mkiv/cldf-com.lua +++ b/tex/context/base/mkiv/cldf-com.lua @@ -6,33 +6,27 @@ if not modules then modules = { } end modules ['cldf-com'] = { license = "see context related readme files" } --- todo ... needs more thinking ... a special table toolkit +-- Some day I'll make a table toolkit ... -local tostring = tostring -local context = context -local generics = context.generics -- needs documentation -local variables = interfaces.variables +local tostring, select = tostring, select -generics.starttabulate = "starttabulate" -- "start" .. variables.tabulate -- todo: e!start -generics.stoptabulate = "stoptabulate" -- "stop" .. variables.tabulate -- todo: e!stop +local context = context +local ctxcore = context.core -local NC, NR = context.NC, context.NR +local ctx_NC = ctxcore.NC +local ctx_NR = ctxcore.NR local function tabulaterow(how,...) + local ctx_flush = how and context[how] or context for i=1,select("#",...) do - local ti = tostring(select(i,...)) - NC() - if how then - context[how](ti) - else - context(ti) - end + ctx_NC() + ctx_flush(tostring(select(i,...))) end - NC() - NR() + ctx_NC() + ctx_NR() end -function context.tabulaterow (...) tabulaterow(false, ...) end -function context.tabulaterowbold(...) tabulaterow("bold",...) end -function context.tabulaterowtype(...) tabulaterow("type",...) end -function context.tabulaterowtyp (...) tabulaterow("typ", ...) end +function ctxcore.tabulaterow (...) tabulaterow(false, ...) end +function ctxcore.tabulaterowbold(...) tabulaterow("bold",...) end +function ctxcore.tabulaterowtype(...) tabulaterow("type",...) end +function ctxcore.tabulaterowtyp (...) tabulaterow("typ", ...) end diff --git a/tex/context/base/mkiv/cldf-ini.lua b/tex/context/base/mkiv/cldf-ini.lua index 0c39f72f5..3c91f5fba 100644 --- a/tex/context/base/mkiv/cldf-ini.lua +++ b/tex/context/base/mkiv/cldf-ini.lua @@ -6,46 +6,61 @@ if not modules then modules = { } end modules ['cldf-ini'] = { license = "see context related readme files" } --- also see cldf-tod.* ! --- old code moved to cldf-old.lua - --- maybe: --- --- 0.528 local foo = tex.ctxcatcodes --- 0.651 local foo = getcount("ctxcatcodes") --- 0.408 local foo = getcount(ctxcatcodes) -- local ctxcatcodes = tex.iscount("ctxcatcodes") - -- This started as an experiment: generating context code at the lua end. After all -- it is surprisingly simple to implement due to metatables. I was wondering if -- there was a more natural way to deal with commands at the lua end. Of course it's -- a bit slower but often more readable when mixed with lua code. It can also be handy -- when generating documents from databases or when constructing large tables or so. -- --- maybe optional checking against interface --- currently no coroutine trickery --- we could always use prtcatcodes (context.a_b_c) but then we loose protection --- tflush needs checking ... sort of weird that it's not a table --- __flushlines is an experiment and rather ugly so it will go away +-- In cldf-tod.lua I have some code that might end up here. In cldf-old.lua the +-- code that precedes more modern solutions (made possible by features in the engine), +-- most noticeably function handling, which worked well for a decade, but by now the +-- more efficient approach is stable enough to move the original code to the obsolete +-- module. -- --- tex.print == line with endlinechar appended - --- todo: context("%bold{total: }%s",total) --- todo: context.documentvariable("title") +-- to be considered: +-- +-- 0.528 local foo = tex.ctxcatcodes +-- 0.651 local foo = getcount("ctxcatcodes") +-- 0.408 local foo = getcount(ctxcatcodes) -- local ctxcatcodes = tex.iscount("ctxcatcodes") +-- maybe: (escape) or 0x2061 (apply function) or 0x2394 (software function ⎔) +-- note : tex.print == line with endlinechar appended +-- todo : context("%bold{total: }%s",total) +-- todo : context.documentvariable("title") +-- -- during the crited project we ran into the situation that luajittex was 10-20 times -- slower that luatex ... after 3 days of testing and probing we finally figured out that -- the the differences between the lua and luajit hashers can lead to quite a slowdown -- in some cases. - +-- -- context(lpeg.match(lpeg.patterns.texescape,"${}")) -- context(string.formatters["%!tex!"]("${}")) -- context("%!tex!","${}") +-- +-- We try not to polute the context namespace too much. For that reason the commands are +-- registered in the context.core namespace. You can call all context commands using +-- context.foo etc. and pipe to context with context("foo"). Defining a local command +-- foo being context.foo is okay, as is context.core.foo. We will have some definitions +-- that are plugged into the core namespace (mostly for speedup) but otherwise specialized +-- writers are in the context namespace only. In your documents you can best use the +-- context.foo(...) and context(...) variant but in some core modules we use the faster +-- ones in critical places (no one will notice of course). The standard syntax highlighter +-- that I use knows how to visualize ctx related code. + +-- I cleaned this code up a bit when updating the cld manual but got distracted a bit by +-- watching Trio Hiromi Uehara, Anthony Jackson & Simon Phillips (discovered via the +-- later on YT). Hopefully the video breaks made the following better in the end. local format, stripstring = string.format, string.strip -local next, type, tostring, tonumber, setmetatable, unpack, select, rawset = next, type, tostring, tonumber, setmetatable, unpack, select, rawset +local next, type, tostring, tonumber, unpack, select, rawset = next, type, tostring, tonumber, unpack, select, rawset local insert, remove, concat = table.insert, table.remove, table.concat local lpegmatch, lpegC, lpegS, lpegP, lpegV, lpegCc, lpegCs, patterns = lpeg.match, lpeg.C, lpeg.S, lpeg.P, lpeg.V, lpeg.Cc, lpeg.Cs, lpeg.patterns -local formatters = string.formatters -- using formatters is slower in this case + +local formatters = string.formatters -- using formatters is slower in this case +local setmetatableindex = table.setmetatableindex +local setmetatablecall = table.setmetatablecall +local setmetatablenewindex = table.setmetatablenewindex context = context or { } commands = commands or { } @@ -85,357 +100,234 @@ local flushdirect = texprint -- lines local report_context = logs.reporter("cld","tex") local report_cld = logs.reporter("cld","stack") +----- report_template = logs.reporter("cld","template") local processlines = true -- experiments.register("context.processlines", function(v) processlines = v end) -- In earlier experiments a function tables was referred to as lua.calls and the --- primitive \luafunctions was \luacall. +-- primitive \luafunctions was \luacall and we used our own implementation of +-- a function table (more indirectness). -local luafunctions = lua.get_functions_table and lua.get_functions_table() -local usedstack = nil +local knownfunctions = lua.get_functions_table() local showstackusage = false --- luafunctions = false - trackers.register("context.stack",function(v) showstackusage = v end) -local storefunction, flushfunction -local storenode, flushnode -local registerfunction, unregisterfunction, reservefunction, knownfunctions, callfunctiononce - --- if luafunctions then +local freed, nofused, noffreed = { }, 0, 0 -- maybe use the number of @@trialtypesetting - local freed, nofused, noffreed = { }, 0, 0 -- maybe use the number of @@trialtypesetting +local usedstack = function() + return nofused, noffreed +end - usedstack = function() - return nofused, noffreed +local flushfunction = function(slot,arg) + if arg() then + -- keep + elseif texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private! + noffreed = noffreed + 1 + freed[noffreed] = slot + knownfunctions[slot] = false + else + -- keep end +end - flushfunction = function(slot,arg) - if arg() then - -- keep - elseif texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private! - noffreed = noffreed + 1 - freed[noffreed] = slot - luafunctions[slot] = false - else - -- keep - end +local storefunction = function(arg) + local f = function(slot) flushfunction(slot,arg) end + if noffreed > 0 then + local n = freed[noffreed] + freed[noffreed] = nil + noffreed = noffreed - 1 + knownfunctions[n] = f + return n + else + nofused = nofused + 1 + knownfunctions[nofused] = f + return nofused end +end - storefunction = function(arg) - local f = function(slot) flushfunction(slot,arg) end - if noffreed > 0 then - local n = freed[noffreed] - freed[noffreed] = nil - noffreed = noffreed - 1 - luafunctions[n] = f - return n - else - nofused = nofused + 1 - luafunctions[nofused] = f - return nofused - end +local flushnode = function(slot,arg) + if texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private! + writenode(arg) + noffreed = noffreed + 1 + freed[noffreed] = slot + knownfunctions[slot] = false + else + writenode(copynodelist(arg)) end +end - flushnode = function(slot,arg) - if texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private! - writenode(arg) - noffreed = noffreed + 1 - freed[noffreed] = slot - luafunctions[slot] = false - else - writenode(copynodelist(arg)) - end +local storenode = function(arg) + local f = function(slot) flushnode(slot,arg) end + if noffreed > 0 then + local n = freed[noffreed] + freed[noffreed] = nil + noffreed = noffreed - 1 + knownfunctions[n] = f + return n + else + nofused = nofused + 1 + knownfunctions[nofused] = f + return nofused end +end - storenode = function(arg) - local f = function(slot) flushnode(slot,arg) end - if noffreed > 0 then - local n = freed[noffreed] - freed[noffreed] = nil - noffreed = noffreed - 1 - luafunctions[n] = f - return n - else - nofused = nofused + 1 - luafunctions[nofused] = f - return nofused - end - end +storage.storedfunctions = storage.storedfunctions or { } +local storedfunctions = storage.storedfunctions +local initex = environment.initex - -- registerfunction = function(f) - -- if type(f) == "string" then - -- f = loadstring(f) - -- end - -- if type(f) ~= "function" then - -- f = function() report_cld("invalid function %A",f) end - -- end - -- if noffreed > 0 then - -- local n = freed[noffreed] - -- freed[noffreed] = nil - -- noffreed = noffreed - 1 - -- luafunctions[n] = f - -- return n - -- else - -- nofused = nofused + 1 - -- luafunctions[nofused] = f - -- return nofused - -- end - -- end - - storage.storedfunctions = storage.storedfunctions or { } - local storedfunctions = storage.storedfunctions - local initex = environment.initex - - storage.register("storage/storedfunctions", storedfunctions, "storage.storedfunctions") - - local f_resolve = nil - local p_resolve = ((1-lpegP("."))^1 / function(s) f_resolve = f_resolve[s] end * lpegP(".")^0)^1 - - local function resolvestoredfunction(str) - f_resolve = global - lpegmatch(p_resolve,str) - return f_resolve - end - - local function expose(slot,f,...) -- so we can register yet undefined functions - local func = resolvestoredfunction(f) - if not func then - func = function() report_cld("beware: unknown function %i called: %s",slot,f) end - end - luafunctions[slot] = func - return func(...) +storage.register("storage/storedfunctions", storedfunctions, "storage.storedfunctions") + +local f_resolve = nil +local p_resolve = ((1-lpegP("."))^1 / function(s) f_resolve = f_resolve[s] end * lpegP(".")^0)^1 + +local function resolvestoredfunction(str) + f_resolve = global + lpegmatch(p_resolve,str) + return f_resolve +end + +local function expose(slot,f,...) -- so we can register yet undefined functions + local func = resolvestoredfunction(f) + if not func then + func = function() report_cld("beware: unknown function %i called: %s",slot,f) end end + knownfunctions[slot] = func + return func(...) +end - if initex then - -- todo: log stored functions - else - local slots = table.sortedkeys(storedfunctions) - local last = #slots - if last > 0 then - -- we restore the references - for i=1,last do - local slot = slots[i] - local data = storedfunctions[slot] - luafunctions[slot] = function(...) - -- print(data) -- could be trace - return expose(slot,data,...) - end +if initex then + -- todo: log stored functions +else + local slots = table.sortedkeys(storedfunctions) + local last = #slots + if last > 0 then + -- we restore the references + for i=1,last do + local slot = slots[i] + local data = storedfunctions[slot] + knownfunctions[slot] = function(...) + -- print(data) -- could be trace + return expose(slot,data,...) end - -- we now know how many are defined - nofused = slots[last] - -- normally there are no holes in the list yet - for i=1,nofused do - if not luafunctions[i] then - noffreed = noffreed + 1 - freed[noffreed] = i - end + end + -- we now know how many are defined + nofused = slots[last] + -- normally there are no holes in the list yet + for i=1,nofused do + if not knownfunctions[i] then + noffreed = noffreed + 1 + freed[noffreed] = i end - -- report_cld("%s registered functions, %s freed slots",last,noffreed) end + -- report_cld("%s registered functions, %s freed slots",last,noffreed) end +end - registerfunction = function(f,direct) -- either f=code or f=namespace,direct=name - local slot, func - if noffreed > 0 then - slot = freed[noffreed] - freed[noffreed] = nil - noffreed = noffreed - 1 - else - nofused = nofused + 1 - slot = nofused - end - if direct then - if initex then - func = function(...) - expose(slot,f,...) - end - if initex then - storedfunctions[slot] = f - end - else - func = resolvestoredfunction(f) - end - if type(func) ~= "function" then - func = function() report_cld("invalid resolve %A",f) end +local registerfunction = function(f,direct) -- either f=code or f=namespace,direct=name + local slot, func + if noffreed > 0 then + slot = freed[noffreed] + freed[noffreed] = nil + noffreed = noffreed - 1 + else + nofused = nofused + 1 + slot = nofused + end + if direct then + if initex then + func = function(...) + expose(slot,f,...) end - elseif type(f) == "string" then - func = loadstring(f) - if type(func) ~= "function" then - func = function() report_cld("invalid code %A",f) end + if initex then + storedfunctions[slot] = f end - elseif type(f) == "function" then - func = f else - func = function() report_cld("invalid function %A",f) end + func = resolvestoredfunction(f) end - luafunctions[slot] = func - return slot - end - - -- do - -- commands.test = function(str) report_cld("test function: %s", str) end - -- if initex then - -- registerfunction("commands.test") -- number 1 - -- end - -- luafunctions[1]("okay") - -- end - - unregisterfunction = function(slot) - if luafunctions[slot] then - noffreed = noffreed + 1 - freed[noffreed] = slot - luafunctions[slot] = false - else - report_cld("invalid function slot %A",slot) + if type(func) ~= "function" then + func = function() report_cld("invalid resolve %A",f) end end - end - - reservefunction = function() - if noffreed > 0 then - local n = freed[noffreed] - freed[noffreed] = nil - noffreed = noffreed - 1 - return n - else - nofused = nofused + 1 - return nofused + elseif type(f) == "string" then + func = loadstring(f) + if type(func) ~= "function" then + func = function() report_cld("invalid code %A",f) end end + elseif type(f) == "function" then + func = f + else + func = function() report_cld("invalid function %A",f) end end + knownfunctions[slot] = func + return slot +end - callfunctiononce = function(slot) - luafunctions[slot](slot) +local unregisterfunction = function(slot) + if knownfunctions[slot] then noffreed = noffreed + 1 freed[noffreed] = slot - luafunctions[slot] = false + knownfunctions[slot] = false + else + report_cld("invalid function slot %A",slot) end +end - table.setmetatablecall(luafunctions,function(t,n) return luafunctions[n](n) end) +local reservefunction = function() + if noffreed > 0 then + local n = freed[noffreed] + freed[noffreed] = nil + noffreed = noffreed - 1 + return n + else + nofused = nofused + 1 + return nofused + end +end - knownfunctions = luafunctions +local callfunctiononce = function(slot) + knownfunctions[slot](slot) + noffreed = noffreed + 1 + freed[noffreed] = slot + knownfunctions[slot] = false +end - -- The next hack is a convenient way to define scanners at the Lua end and - -- get them available at the TeX end. There is some dirty magic needed to - -- prevent overload during format loading. +setmetatablecall(knownfunctions,function(t,n) return knownfunctions[n](n) end) - -- interfaces.scanners.foo = function() context("[%s]",tokens.scanners.string()) end : \scan_foo +-- The next hack is a convenient way to define scanners at the Lua end and +-- get them available at the TeX end. There is some dirty magic needed to +-- prevent overload during format loading. - interfaces.storedscanners = interfaces.storedscanners or { } - local storedscanners = interfaces.storedscanners +-- interfaces.scanners.foo = function() context("[%s]",tokens.scanners.string()) end : \scan_foo - storage.register("interfaces/storedscanners", storedscanners, "interfaces.storedscanners") +interfaces.storedscanners = interfaces.storedscanners or { } +local storedscanners = interfaces.storedscanners - local interfacescanners = table.setmetatablenewindex(function(t,k,v) - if storedscanners[k] then - -- report_cld("warning: scanner %a is already set",k) - -- os.exit() - -- \scan_<k> is already in the format - -- report_cld("using interface scanner: %s",k) - else - -- todo: allocate slot here and pass it - storedscanners[k] = true - -- report_cld("installing interface scanner: %s",k) - context("\\installctxscanner{clf_%s}{interfaces.scanners.%s}",k,k) - end - rawset(t,k,v) - end) +storage.register("interfaces/storedscanners", storedscanners, "interfaces.storedscanners") - interfaces.scanners = interfacescanners +local interfacescanners = setmetatablenewindex(function(t,k,v) + if storedscanners[k] then + -- report_cld("warning: scanner %a is already set",k) + -- os.exit() + -- \scan_<k> is already in the format + -- report_cld("using interface scanner: %s",k) + else + -- todo: allocate slot here and pass it + storedscanners[k] = true + -- report_cld("installing interface scanner: %s",k) + context("\\installctxscanner{clf_%s}{interfaces.scanners.%s}",k,k) + end + rawset(t,k,v) +end) --- else -- by now this is obsolete --- --- local luafunctions, noffunctions = { }, 0 --- local luanodes, nofnodes = { }, 0 --- --- usedstack = function() --- return noffunctions + nofnodes, 0 --- end --- --- flushfunction = function(n) --- local sn = luafunctions[n] --- if not sn then --- report_cld("data with id %a cannot be found on stack",n) --- elseif not sn() and texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private! --- luafunctions[n] = nil --- end --- end --- --- storefunction = function(ti) --- noffunctions = noffunctions + 1 --- luafunctions[noffunctions] = ti --- return noffunctions --- end --- --- -- freefunction = function(n) --- -- luafunctions[n] = nil --- -- end --- --- flushnode = function(n) --- local sn = luanodes[n] --- if not sn then --- report_cld("data with id %a cannot be found on stack",n) --- elseif texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private! --- writenode(sn) --- luanodes[n] = nil --- else --- writenode(copynodelist(sn)) --- end --- end --- --- storenode = function(ti) --- nofnodes = nofnodes + 1 --- luanodes[nofnodes] = ti --- return nofnodes --- end --- --- _cldf_ = flushfunction -- global --- _cldn_ = flushnode -- global --- -- _cldl_ = function(n) return luafunctions[n]() end -- luafunctions(n) --- _cldl_ = luafunctions --- --- registerfunction = function(f) --- if type(f) == "string" then --- f = loadstring(f) --- end --- if type(f) ~= "function" then --- f = function() report_cld("invalid function %A",f) end --- end --- noffunctions = noffunctions + 1 --- luafunctions[noffunctions] = f --- return noffunctions --- end --- --- unregisterfunction = function(slot) --- if luafunctions[slot] then --- luafunctions[slot] = nil --- else --- report_cld("invalid function slot %A",slot) --- end --- end --- --- reservefunction = function() --- noffunctions = noffunctions + 1 --- return noffunctions --- end --- --- callfunctiononce = function(slot) --- luafunctions[slot](slot) --- luafunctions[slot] = nil --- end --- --- table.setmetatablecall(luafunctions,function(t,n) return luafunctions[n](n) end) --- --- knownfunctions = luafunctions --- --- end +interfaces.scanners = interfacescanners -context.registerfunction = registerfunction -context.unregisterfunction = unregisterfunction -context.reservefunction = reservefunction -context.knownfunctions = knownfunctions -context.callfunctiononce = callfunctiononce _cldo_ = callfunctiononce -context.storenode = storenode -- private helper +context.functions = { + register = registerfunction, + unregister = unregisterfunction, + reserve = reservefunction, + known = knownfunctions, + callonce = callfunctiononce, +} function commands.ctxfunction(code,namespace) context(registerfunction(code,namespace)) @@ -464,13 +356,6 @@ function context.trialtypesetting() return texgetcount("@@trialtypesetting") ~= 0 end --- local f_cldo = formatters["_cldo_(%i)"] --- local latelua_node = nodes.pool.latelua --- --- function context.lateluafunctionnnode(f) --- return latelua_node(f_cldo(registerfunction(f))) --- end - -- Should we keep the catcodes with the function? local catcodestack = { } @@ -516,6 +401,27 @@ local function popcatcodes() contentcatcodes = currentcatcodes end +function context.unprotect() + -- at the lua end + catcodelevel = catcodelevel + 1 + catcodestack[catcodelevel] = currentcatcodes + currentcatcodes = prtcatcodes + contentcatcodes = prtcatcodes + -- at the tex end + flush("\\unprotect") +end + +function context.protect() + -- at the tex end + flush("\\protect") + -- at the lua end + if catcodelevel > 0 then + currentcatcodes = catcodestack[catcodelevel] or currentcatcodes + catcodelevel = catcodelevel - 1 + end + contentcatcodes = currentcatcodes +end + context.catcodes = catcodes context.pushcatcodes = pushcatcodes context.popcatcodes = popcatcodes @@ -561,7 +467,7 @@ local n_exception = "" -- better a table specification -function context.newtexthandler(specification) -- can also be used for verbose +function context.newtexthandler(specification) specification = specification or { } -- local s_catcodes = specification.catcodes @@ -677,10 +583,6 @@ local flushlines = context.newtexthandler { simpleline = n_simpleline, } -context.__flushlines = flushlines -- maybe context.helpers.flushtexlines -context.__flush = flush -context.__flushdirect = flushdirect - -- The next variant is only used in rare cases (buffer to mp): local printlines_ctx = ( @@ -705,547 +607,314 @@ end local containseol = patterns.containseol -local writer = nil -local prtwriter = nil - --- if luafunctions then - - writer = function (parent,command,...) -- already optimized before call - flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes - local direct = false - -- local t = { ... } - -- for i=1,#t do - -- local ti = t[i] - for i=1,select("#",...) do - local ti = (select(i,...)) - if direct then - local typ = type(ti) - if typ == "string" or typ == "number" then - flush(currentcatcodes,ti) - else -- node.write - report_context("error: invalid use of direct in %a, only strings and numbers can be flushed directly, not %a",command,typ) - end - direct = false - elseif ti == nil then - -- nothing - elseif ti == "" then - flush(currentcatcodes,"{}") - else - local typ = type(ti) - if typ == "string" then - -- is processlines seen ? - if processlines and lpegmatch(containseol,ti) then - flush(currentcatcodes,"{") - local flushlines = parent.__flushlines or flushlines - flushlines(ti) - flush(currentcatcodes,"}") - elseif currentcatcodes == contentcatcodes then - flush(currentcatcodes,"{",ti,"}") - else - flush(currentcatcodes,"{") - flush(contentcatcodes,ti) - flush(currentcatcodes,"}") - end - elseif typ == "number" then - -- numbers never have funny catcodes +local function writer(parent,command,...) -- already optimized before call + flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes + local direct = false + -- local t = { ... } + -- for i=1,#t do + -- local ti = t[i] + for i=1,select("#",...) do + local ti = (select(i,...)) + if direct then + local typ = type(ti) + if typ == "string" or typ == "number" then + flush(currentcatcodes,ti) + else -- node.write + report_context("error: invalid use of direct in %a, only strings and numbers can be flushed directly, not %a",command,typ) + end + direct = false + elseif ti == nil then + -- nothing + elseif ti == "" then + flush(currentcatcodes,"{}") + else + local typ = type(ti) + if typ == "string" then + -- is processlines seen ? + if processlines and lpegmatch(containseol,ti) then + flush(currentcatcodes,"{") + flushlines(ti) + flush(currentcatcodes,"}") + elseif currentcatcodes == contentcatcodes then flush(currentcatcodes,"{",ti,"}") - elseif typ == "table" then - local tn = #ti - if tn == 0 then - local done = false - for k, v in next, ti do - if done then - if v == "" then - flush(currentcatcodes,",",k,'=') - else - flush(currentcatcodes,",",k,"={",v,"}") - end + else + flush(currentcatcodes,"{") + flush(contentcatcodes,ti) + flush(currentcatcodes,"}") + end + elseif typ == "number" then + -- numbers never have funny catcodes + flush(currentcatcodes,"{",ti,"}") + elseif typ == "table" then + local tn = #ti + if tn == 0 then + local done = false + for k, v in next, ti do + if done then + if v == "" then + flush(currentcatcodes,",",k,'=') else - if v == "" then - flush(currentcatcodes,"[",k,"=") - else - flush(currentcatcodes,"[",k,"={",v,"}") - end - done = true + flush(currentcatcodes,",",k,"={",v,"}") end - end - if done then - flush(currentcatcodes,"]") else - flush(currentcatcodes,"[]") + if v == "" then + flush(currentcatcodes,"[",k,"=") + else + flush(currentcatcodes,"[",k,"={",v,"}") + end + done = true end - elseif tn == 1 then -- some 20% faster than the next loop - local tj = ti[1] + end + if done then + flush(currentcatcodes,"]") + else + flush(currentcatcodes,"[]") + end + elseif tn == 1 then -- some 20% faster than the next loop + local tj = ti[1] + if type(tj) == "function" then + flush(currentcatcodes,"[\\cldl",storefunction(tj),"]") + -- flush(currentcatcodes,"[",storefunction(tj),"]") + else + flush(currentcatcodes,"[",tj,"]") + end + else -- is concat really faster than flushes here? probably needed anyway (print artifacts) + flush(currentcatcodes,"[") + for j=1,tn do + local tj = ti[j] if type(tj) == "function" then - flush(currentcatcodes,"[\\cldl",storefunction(tj),"]") - -- flush(currentcatcodes,"[",storefunction(tj),"]") + if j == tn then + flush(currentcatcodes,"\\cldl",storefunction(tj),"]") + -- flush(currentcatcodes,"",storefunction(tj),"]") + else + flush(currentcatcodes,"\\cldl",storefunction(tj),",") + -- flush(currentcatcodes,"",storefunction(tj),",") + end else - flush(currentcatcodes,"[",tj,"]") - end - else -- is concat really faster than flushes here? probably needed anyway (print artifacts) - flush(currentcatcodes,"[") - for j=1,tn do - local tj = ti[j] - if type(tj) == "function" then - if j == tn then - flush(currentcatcodes,"\\cldl",storefunction(tj),"]") - -- flush(currentcatcodes,"",storefunction(tj),"]") - else - flush(currentcatcodes,"\\cldl",storefunction(tj),",") - -- flush(currentcatcodes,"",storefunction(tj),",") - end + if j == tn then + flush(currentcatcodes,tj,"]") else - if j == tn then - flush(currentcatcodes,tj,"]") - else - flush(currentcatcodes,tj,",") - end + flush(currentcatcodes,tj,",") end end end - elseif typ == "function" then - flush(currentcatcodes,"{\\cldl ",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes - -- flush(currentcatcodes,"{",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes - elseif typ == "boolean" then - if ti then - flushdirect(currentcatcodes,"\r") - else - direct = true - end - elseif typ == "thread" then - report_context("coroutines not supported as we cannot yield across boundaries") - elseif isnode(ti) then -- slow - flush(currentcatcodes,"{\\cldl",storenode(ti),"}") - -- flush(currentcatcodes,"{",storenode(ti),"}") - else - report_context("error: %a gets a weird argument %a",command,ti) end - end - end - end - - -- if performance really matters we can consider a compiler but it will never - -- pay off - - prtwriter = function (command,...) -- already optimized before call - flush(prtcatcodes,command) - for i=1,select("#",...) do - local ti = (select(i,...)) - if ti == nil then - -- nothing - elseif ti == "" then - flush(prtcatcodes,"{}") - else - local tp = type(ti) - if tp == "string" or tp == "number"then - flush(prtcatcodes,"{",ti,"}") - elseif tp == "function" then - flush(prtcatcodes,"{\\cldl ",storefunction(ti),"}") - -- flush(currentcatcodes,"{",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes - elseif isnode(ti) then - flush(prtcatcodes,"{\\cldl",storenode(ti),"}") - -- flush(currentcatcodes,"{",storenode(ti),"}") + elseif typ == "function" then + flush(currentcatcodes,"{\\cldl ",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes + -- flush(currentcatcodes,"{",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes + elseif typ == "boolean" then + if ti then + flushdirect(currentcatcodes,"\r") else - report_context("fatal error: prt %a gets a weird argument %a",command,ti) + direct = true end + elseif typ == "thread" then + report_context("coroutines not supported as we cannot yield across boundaries") + elseif isnode(ti) then -- slow + flush(currentcatcodes,"{\\cldl",storenode(ti),"}") + -- flush(currentcatcodes,"{",storenode(ti),"}") + else + report_context("error: %a gets a weird argument %a",command,ti) end end end +end --- else --- --- writer = function (parent,command,first,...) -- already optimized before call --- local t = { first, ... } --- flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes --- local direct = false --- for i=1,#t do --- local ti = t[i] --- local typ = type(ti) --- if direct then --- if typ == "string" or typ == "number" then --- flush(currentcatcodes,ti) --- else -- node.write --- report_context("error: invalid use of direct in %a, only strings and numbers can be flushed directly, not %a",command,typ) --- end --- direct = false --- elseif ti == nil then --- -- nothing --- elseif ti == "" then --- flush(currentcatcodes,"{}") --- elseif typ == "string" then --- -- is processelines seen ? --- if processlines and lpegmatch(containseol,ti) then --- flush(currentcatcodes,"{") --- local flushlines = parent.__flushlines or flushlines --- flushlines(ti) --- flush(currentcatcodes,"}") --- elseif currentcatcodes == contentcatcodes then --- flush(currentcatcodes,"{",ti,"}") --- else --- flush(currentcatcodes,"{") --- flush(contentcatcodes,ti) --- flush(currentcatcodes,"}") --- end --- elseif typ == "number" then --- -- numbers never have funny catcodes --- flush(currentcatcodes,"{",ti,"}") --- elseif typ == "table" then --- local tn = #ti --- if tn == 0 then --- local done = false --- for k, v in next, ti do --- if done then --- if v == "" then --- flush(currentcatcodes,",",k,'=') --- else --- flush(currentcatcodes,",",k,"={",v,"}") --- end --- else --- if v == "" then --- flush(currentcatcodes,"[",k,"=") --- else --- flush(currentcatcodes,"[",k,"={",v,"}") --- end --- done = true --- end --- end --- if done then --- flush(currentcatcodes,"]") --- else --- flush(currentcatcodes,"[]") --- end --- elseif tn == 1 then -- some 20% faster than the next loop --- local tj = ti[1] --- if type(tj) == "function" then --- flush(currentcatcodes,"[\\cldf{",storefunction(tj),"}]") --- else --- flush(currentcatcodes,"[",tj,"]") --- end --- else -- is concat really faster than flushes here? probably needed anyway (print artifacts) --- for j=1,tn do --- local tj = ti[j] --- if type(tj) == "function" then --- ti[j] = "\\cldf{" .. storefunction(tj) .. "}" --- end --- end --- flush(currentcatcodes,"[",concat(ti,","),"]") --- end --- elseif typ == "function" then --- flush(currentcatcodes,"{\\cldf{",storefunction(ti),"}}") -- todo: ctx|prt|texcatcodes --- elseif typ == "boolean" then --- if ti then --- flushdirect(currentcatcodes,"\r") --- else --- direct = true --- end --- elseif typ == "thread" then --- report_context("coroutines not supported as we cannot yield across boundaries") --- elseif isnode(ti) then -- slow --- flush(currentcatcodes,"{\\cldn{",storenode(ti),"}}") +-- if performance really matters we can consider a compiler but it will never +-- pay off + +-- local function prtwriter(command,...) -- already optimized before call +-- flush(prtcatcodes,command) +-- for i=1,select("#",...) do +-- local ti = (select(i,...)) +-- if ti == nil then +-- -- nothing +-- elseif ti == "" then +-- flush(prtcatcodes,"{}") +-- else +-- local tp = type(ti) +-- if tp == "string" or tp == "number"then +-- flush(prtcatcodes,"{",ti,"}") +-- elseif tp == "function" then +-- flush(prtcatcodes,"{\\cldl ",storefunction(ti),"}") +-- -- flush(currentcatcodes,"{",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes +-- elseif isnode(ti) then +-- flush(prtcatcodes,"{\\cldl",storenode(ti),"}") +-- -- flush(currentcatcodes,"{",storenode(ti),"}") -- else --- report_context("error: %a gets a weird argument %a",command,ti) +-- report_context("fatal error: prt %a gets a weird argument %a",command,ti) -- end -- end -- end --- -- end -local generics = { } context.generics = generics -local indexer = nil -local prtindexer = nil - --- if environment.initex then - - indexer = function(parent,k) - if type(k) == "string" then - local c = "\\" .. tostring(generics[k] or k) - local f = function(first,...) - if first == nil then - flush(currentcatcodes,c) - else - return writer(parent,c,first,...) - end - end - parent[k] = f - return f +local core = setmetatableindex(function(parent,k) + local c = "\\" .. k -- tostring(k) + local f = function(first,...) + if first == nil then + flush(currentcatcodes,c) else - return context -- catch + return writer(context,c,first,...) end end + parent[k] = f + return f +end) + +core.cs = setmetatableindex(function(parent,k) + local c = "\\" .. k -- tostring(k) + local f = function() + flush(currentcatcodes,c) + end + parent[k] = f + return f +end) --- else +local indexer = function(parent,k) + if type(k) == "string" then + return core[k] + else + return context -- catch + end +end + +context.core = core + +-- only for internal usage: + +-- local prtindexer = nil -- --- local create = token.create --- local twrite = token.write --- local setmacro = token.set_macro +-- do -- --- indexer = function(parent,k) --- if type(k) == "string" then --- local s = tostring(generics[k] or k) --- local t = create(s) --- if t.cmdname == "undefined_cs" then --- report_cld("macro \\%s is not yet defined",s) --- token.set_macro(s,"") --- t = create(s) --- end --- local i = t.id --- local f = function(first,...) --- twrite(t.tok) --= we need to keep t uncollected --- if first ~= nil then --- return writer(parent,first,...) --- end +-- -- the only variant is not much faster than the full but it's more +-- -- memory efficient +-- +-- local protected = { } +-- local protectedcs = { } +-- context.protected = protected +-- context.protectedcs = protectedcs +-- +-- local function fullindexer(t,k) +-- local c = "\\" .. k -- tostring(k) +-- local v = function(first,...) +-- if first == nil then +-- flush(prtcatcodes,c) +-- else +-- return prtwriter(c,first,...) -- end --- parent[k] = f --- return f --- else --- return context -- catch -- end +-- rawset(t,k,v) -- protected namespace +-- return v -- end -- --- end - --- Potential optimization: after the first call we know if there will be an --- argument. Of course there is the side effect that for instance abuse like --- context.NC(str) fails as well as optional arguments. So, we don't do this --- in practice. We just keep the next trick commented. The gain on some --- 100000 calls is not that large: 0.100 => 0.95 which is neglectable. --- --- local function constructor(parent,k,c,first,...) --- if first == nil then --- local f = function() --- flush(currentcatcodes,c) +-- local function onlyindexer(t,k) +-- local c = "\\" .. k -- tostring(k) +-- local v = function() +-- flush(prtcatcodes,c) -- end --- parent[k] = f --- return f() --- else --- local f = function(...) --- return writer(parent,c,...) --- end --- parent[k] = f --- return f(first,...) +-- rawset(protected,k,v) +-- rawset(t,k,v) +-- return v -- end --- end -- --- local function indexer(parent,k) --- local c = "\\" .. tostring(generics[k] or k) --- local f = function(...) --- return constructor(parent,k,c,...) +-- protected.cs = setmetatableindex(function(parent,k) +-- local c = "\\" .. k -- tostring(k) +-- local v = function() +-- flush(prtcatcodes,c) +-- end +-- parent[k] = v +-- return v -- end --- parent[k] = f --- return f +-- +-- setmetatableindex(protected,fullindexer) +-- setmetatablecall (protected,prtwriter) +-- +-- setmetatableindex(protectedcs,onlyindexer) +-- setmetatablecall (protectedcs,prtwriter) +-- -- end --- only for internal usage: - -do - - function context.constructcsonly(k) -- not much faster than the next but more mem efficient - local c = "\\" .. tostring(generics[k] or k) - local v = function() - flush(prtcatcodes,c) - end - rawset(context,k,v) -- context namespace - return v - end +-- local splitformatters = utilities.strings.formatters.new(true) -- not faster (yet) - function context.constructcs(k) - local c = "\\" .. tostring(generics[k] or k) - local v = function(first,...) - if first == nil then - flush(prtcatcodes,c) +local caller = function(parent,f,a,...) + if not parent then + -- so we don't need to test in the calling (slower but often no issue) + elseif f ~= nil then + local typ = type(f) + if typ == "string" then + if f == "" then + -- new, can save a bit sometimes + -- if trace_context then + -- report_context("empty argument to context()") + -- end + elseif a then + flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes + -- flush(contentcatcodes,splitformatters[f](a,...)) -- was currentcatcodes + elseif processlines and lpegmatch(containseol,f) then + flushlines(f) else - return prtwriter(c,first,...) + flush(contentcatcodes,f) end - end - rawset(context,k,v) -- context namespace - return v - end - - local function prtindexer(t,k) - local c = "\\" .. tostring(generics[k] or k) - local v = function(first,...) - if first == nil then - flush(prtcatcodes,c) + elseif typ == "number" then + if a then + flush(currentcatcodes,f,a,...) else - return prtwriter(c,first,...) + flush(currentcatcodes,f) end - end - rawset(t,k,v) -- protected namespace - return v - end - - context.protected = { } -- we could check for _ in the context namespace - - setmetatable(context.protected, { __index = prtindexer, __call = prtwriter } ) - -end - --- local splitformatters = utilities.strings.formatters.new(true) -- not faster (yet) - -local caller - --- if luafunctions then - - caller = function(parent,f,a,...) - if not parent then - -- so we don't need to test in the calling (slower but often no issue) - elseif f ~= nil then - local typ = type(f) - if typ == "string" then - if f == "" then - -- new, can save a bit sometimes - -- if trace_context then - -- report_context("empty argument to context()") - -- end - elseif a then - flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes - -- flush(contentcatcodes,splitformatters[f](a,...)) -- was currentcatcodes - elseif processlines and lpegmatch(containseol,f) then - local flushlines = parent.__flushlines or flushlines - flushlines(f) - else - flush(contentcatcodes,f) - end - elseif typ == "number" then - if a then - flush(currentcatcodes,f,a,...) + elseif typ == "function" then + -- ignored: a ... + flush(currentcatcodes,"{\\cldl",storefunction(f),"}") -- todo: ctx|prt|texcatcodes + -- flush(currentcatcodes,"{",storefunction(f),"}") -- todo: ctx|prt|texcatcodes + elseif typ == "boolean" then + if f then + if a ~= nil then + flushlines(a) else - flush(currentcatcodes,f) + flushdirect(currentcatcodes,"\n") -- no \r, else issues with \startlines ... use context.par() otherwise end - elseif typ == "function" then - -- ignored: a ... - flush(currentcatcodes,"{\\cldl",storefunction(f),"}") -- todo: ctx|prt|texcatcodes - -- flush(currentcatcodes,"{",storefunction(f),"}") -- todo: ctx|prt|texcatcodes - elseif typ == "boolean" then - if f then - if a ~= nil then - local flushlines = parent.__flushlines or flushlines - flushlines(a) - else - flushdirect(currentcatcodes,"\n") -- no \r, else issues with \startlines ... use context.par() otherwise - end + else + if a ~= nil then + -- no command, same as context(a,...) + writer(parent,"",a,...) else - if a ~= nil then - -- no command, same as context(a,...) - writer(parent,"",a,...) - else - -- ignored - end + -- ignored end - elseif typ == "thread" then - report_context("coroutines not supported as we cannot yield across boundaries") - elseif isnode(f) then -- slow - -- writenode(f) - flush(currentcatcodes,"\\cldl",storenode(f)," ") - -- flush(currentcatcodes,"",storenode(f)," ") - else - report_context("error: %a gets a weird argument %a","context",f) end + elseif typ == "thread" then + report_context("coroutines not supported as we cannot yield across boundaries") + elseif isnode(f) then -- slow + -- writenode(f) + flush(currentcatcodes,"\\cldl",storenode(f)," ") + -- flush(currentcatcodes,"",storenode(f)," ") + else + report_context("error: %a gets a weird argument %a","context",f) end end +end - function context.flushnode(n) +context.nodes = { + store = storenode, + flush = function(n) flush(currentcatcodes,"\\cldl",storenode(n)," ") -- flush(currentcatcodes,"",storenode(n)," ") - end - --- else --- --- caller = function(parent,f,a,...) --- if not parent then --- -- so we don't need to test in the calling (slower but often no issue) --- elseif f ~= nil then --- local typ = type(f) --- if typ == "string" then --- if f == "" then --- -- new, can save a bit sometimes --- -- if trace_context then --- -- report_context("empty argument to context()") --- -- end --- elseif a then --- flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes --- -- flush(contentcatcodes,splitformatters[f](a,...)) -- was currentcatcodes --- elseif processlines and lpegmatch(containseol,f) then --- local flushlines = parent.__flushlines or flushlines --- flushlines(f) --- else --- flush(contentcatcodes,f) --- end --- elseif typ == "number" then --- if a then --- flush(currentcatcodes,f,a,...) --- else --- flush(currentcatcodes,f) --- end --- elseif typ == "function" then --- -- ignored: a ... --- flush(currentcatcodes,"{\\cldf{",storefunction(f),"}}") -- todo: ctx|prt|texcatcodes --- elseif typ == "boolean" then --- if f then --- if a ~= nil then --- local flushlines = parent.__flushlines or flushlines --- flushlines(a) --- else --- flushdirect(currentcatcodes,"\n") -- no \r, else issues with \startlines ... use context.par() otherwise --- end --- else --- if a ~= nil then --- -- no command, same as context(a,...) --- writer(parent,"",a,...) --- else --- -- ignored --- end --- end --- elseif typ == "thread" then --- report_context("coroutines not supported as we cannot yield across boundaries") --- elseif isnode(f) then -- slow --- -- writenode(f) --- flush(currentcatcodes,"\\cldn{",storenode(f),"}") --- else --- report_context("error: %a gets a weird argument %a","context",f) --- end --- end --- end --- --- function context.flushnode(n) --- flush(currentcatcodes,"\\cldn{",storenode(n),"}") --- end --- --- end + end, +} local defaultcaller = caller -setmetatable(context, { __index = indexer, __call = caller } ) - --- now we tweak unprotect and protect - -function context.unprotect() - -- at the lua end - insert(catcodestack,currentcatcodes) - currentcatcodes = prtcatcodes - contentcatcodes = currentcatcodes - -- at the tex end - flush("\\unprotect") -end - -function context.protect() - -- at the tex end - flush("\\protect") - -- at the lua end - currentcatcodes = remove(catcodestack) or currentcatcodes - contentcatcodes = currentcatcodes -end +setmetatableindex(context,indexer) +setmetatablecall (context,caller) function context.sprint(...) -- takes catcodes as first argument flush(...) end -function context.fprint(catcodes,fmt,first,...) +function context.fprint(fmt,first,...) if type(catcodes) == "number" then if first then - flush(catcodes,formatters[fmt](first,...)) + flush(currentcatcodes,formatters[fmt](first,...)) else - flush(catcodes,fmt) + flush(currentcatcodes,fmt) end else if fmt then @@ -1256,23 +925,17 @@ function context.fprint(catcodes,fmt,first,...) end end -function tex.fprint(fmt,first,...) -- goodie - if first then - flush(currentcatcodes,formatters[fmt](first,...)) - else - flush(currentcatcodes,fmt) - end -end +tex.fprint = context.fprint -- logging -local trace_stack = { } +local trace_stack = { report_context } local normalflush = flush local normalflushdirect = flushdirect ----- normalflushraw = flushraw local normalwriter = writer -local currenttrace = nil +local currenttrace = report_context local nofwriters = 0 local nofflushes = 0 @@ -1380,76 +1043,39 @@ local tracedflushdirect = function(one,two,...) end end -local function pushlogger(trace) +function context.pushlogger(trace) trace = trace or report_context insert(trace_stack,currenttrace) currenttrace = trace - -- - flush = tracedflush - flushdirect = tracedflushdirect - writer = tracedwriter - -- - context.__flush = flush - context.__flushdirect = flushdirect - -- - return flush, writer, flushdirect end -local function poplogger() - currenttrace = remove(trace_stack) - if not currenttrace then - flush = normalflush - flushdirect = normalflushdirect - writer = normalwriter - -- - context.__flush = flush - context.__flushdirect = flushdirect +function context.poplogger() + if #trace_stack > 1 then + currenttrace = remove(trace_stack) or report_context + else + currenttrace = report_context end - return flush, writer, flushdirect end -local function settracing(v) +function context.settracing(v) if v then - return pushlogger(report_context) + flush = tracedflush + flushdirect = tracedflushdirect + writer = tracedwriter else - return poplogger() + flush = normalflush + flushdirect = normalflushdirect + writer = normalwriter end + return flush, writer, flushdirect end --- todo: share flushers so that we can define in other files - -trackers.register("context.trace",settracing) - -context.pushlogger = pushlogger -context.poplogger = poplogger -context.settracing = settracing - --- -- untested, no time now: --- --- local tracestack, tracestacktop = { }, false --- --- function context.pushtracing(v) --- insert(tracestack,tracestacktop) --- if type(v) == "function" then --- pushlogger(v) --- v = true --- else --- pushlogger() --- end --- tracestacktop = v --- settracing(v) --- end --- --- function context.poptracing() --- poplogger() --- tracestacktop = remove(tracestack) or false --- settracing(tracestacktop) --- end - function context.getlogger() - return flush, writer, flush_direct + return flush, writer, flushdirect end +trackers.register("context.trace",context.settracing) + local trace_cld = false trackers.register("context.files", function(v) trace_cld = v end) do @@ -1507,13 +1133,9 @@ do if level == 0 then collected = { } nofcollected = 0 - -- flush = collect flushdirect = collectdirect permitted = tracingpermitted - -- - context.__flush = flush - context.__flushdirect = flushdirect end level = level + 1 end @@ -1521,18 +1143,14 @@ do function context.stopcollecting() level = level - 1 if level < 1 then + local result = concat(collected,sentinel) flush = normalflush flushdirect = normalflushdirect tracingpermitted = permitted - -- - context.__flush = flush - context.__flushdirect = flushdirect - -- - viafile(concat(collected,sentinel)) - -- - collected = nil - nofcollected = 0 - level = 0 + collected = nil + nofcollected = 0 + level = 0 + viafile(result) end end @@ -1576,105 +1194,85 @@ end -- context.delayed (todo: lines) -local delayed = { } context.delayed = delayed -- creates function (maybe also store them) +do + + local delayed = { } + + local function indexer(parent,k) + local f = function(...) + local a = { ... } + return function() + -- return context[k](unpack(a)) + return core[k](unpack(a)) + end + end + parent[k] = f + return f + end -local function indexer(parent,k) - local f = function(...) + local function caller(parent,...) -- todo: nodes local a = { ... } return function() - return context[k](unpack(a)) + -- return context(unpack(a)) + return defaultcaller(context,unpack(a)) end end - parent[k] = f - return f -end -local function caller(parent,...) -- todo: nodes - local a = { ... } - return function() - return context(unpack(a)) - end + setmetatableindex(delayed,indexer) + setmetatablecall (delayed,caller) + + context.delayed = delayed + end --- local function indexer(parent,k) --- local f = function(a,...) --- if not a then --- return function() --- return context[k]() --- end --- elseif select("#",...) == 0 then --- return function() --- return context[k](a) --- end --- elseif a then --- local t = { ... } --- return function() --- return context[k](a,unpack(t)) --- end --- end --- end --- parent[k] = f --- return f --- end --- --- local function caller(parent,a,...) -- todo: nodes --- if not a then --- return function() --- return context() --- end --- elseif select("#",...) == 0 then --- return function() --- return context(a) --- end --- elseif a then --- local t = { ... } --- return function() --- return context(a,unpack(t)) --- end --- end --- end +do -setmetatable(delayed, { __index = indexer, __call = caller } ) + -- context.nested (todo: lines), creates strings --- context.nested (todo: lines) + local nested = { } -local nested = { } context.nested = nested -- creates strings + local function indexer(parent,k) -- not ok when traced + local f = function(...) + local t, savedflush, n = { }, flush, 0 + flush = function(c,f,s,...) -- catcodes are ignored + n = n + 1 + t[n] = s and concat{f,s,...} or f -- optimized for #args == 1 + end + -- context[k](...) + core[k](...) + flush = savedflush + return concat(t) + end + parent[k] = f + return f + end -local function indexer(parent,k) -- not ok when traced - local f = function(...) + local function caller(parent,...) local t, savedflush, n = { }, flush, 0 flush = function(c,f,s,...) -- catcodes are ignored n = n + 1 t[n] = s and concat{f,s,...} or f -- optimized for #args == 1 end - context[k](...) + -- context(...) + defaultcaller(context,...) flush = savedflush return concat(t) end - parent[k] = f - return f -end -local function caller(parent,...) - local t, savedflush, n = { }, flush, 0 - flush = function(c,f,s,...) -- catcodes are ignored - n = n + 1 - t[n] = s and concat{f,s,...} or f -- optimized for #args == 1 - end - context(...) - flush = savedflush - return concat(t) -end + setmetatableindex(nested,indexer) + setmetatablecall (nested,caller) -setmetatable(nested, { __index = indexer, __call = caller } ) + context.nested = nested + +end -- verbatim -function context.newindexer(catcodes) +function context.newindexer(catcodes,cmdcodes) local handler = { } local function indexer(parent,k) - local command = context[k] + local command = core[k] local f = function(...) local savedcatcodes = contentcatcodes contentcatcodes = catcodes @@ -1692,238 +1290,277 @@ function context.newindexer(catcodes) contentcatcodes = savedcatcodes end - setmetatable(handler, { __index = indexer, __call = caller } ) + handler.cs = setmetatableindex(function(parent,k) + local c = "\\" .. k -- tostring(k) + local f = function() + flush(cmdcodes,c) + end + parent[k] = f + return f + end) + + setmetatableindex(handler,indexer) + setmetatablecall (handler,caller) return handler end -context.verbatim = context.newindexer(vrbcatcodes) -context.puretext = context.newindexer(txtcatcodes) --------.protected = context.newindexer(prtcatcodes) +context.verbatim = context.newindexer(vrbcatcodes,ctxcatcodes) +context.puretext = context.newindexer(txtcatcodes,ctxcatcodes) +context.protected = context.newindexer(prtcatcodes,prtcatcodes) -- formatted -local formatted = { } context.formatted = formatted +do + + local formatted = { } --- local function indexer(parent,k) --- local command = context[k] --- local f = function(fmt,...) --- command(formatters[fmt](...)) + -- formatted.command([catcodes,]format[,...]) + +-- local function formattedflush(parent,c,catcodes,fmt,...) +-- if type(catcodes) == "number" then +-- if fmt then +-- local result +-- pushcatcodes(catcodes) +-- result = writer(parent,c,formatters[fmt](...)) +-- popcatcodes() +-- return result +-- else +-- -- no need to change content catcodes +-- return writer(parent,c) +-- end +-- else +-- return writer(parent,c,formatters[catcodes](fmt,...)) +-- end -- end --- parent[k] = f --- return f --- end -local function indexer(parent,k) - if type(k) == "string" then - local c = "\\" .. tostring(generics[k] or k) - local f = function(first,second,...) - if first == nil then - flush(currentcatcodes,c) - elseif second then - return writer(parent,c,formatters[first](second,...)) - else - return writer(parent,c,first) - end + local function formattedflush(parent,c,catcodes,fmt,...) + if not catcodes then + return writer(parent,c) + elseif not fmt then + return writer(parent,c,catcodes) + elseif type(catcodes) == "number" then + local result + pushcatcodes(catcodes) + result = writer(parent,c,formatters[fmt](...)) + popcatcodes() + return result + else + return writer(parent,c,formatters[catcodes](fmt,...)) end - parent[k] = f - return f - else - return context -- catch end -end - --- local function caller(parent,...) --- context.fprint(...) --- end -local function caller(parent,catcodes,fmt,first,...) - if type(catcodes) == "number" then - if first then - flush(catcodes,formatters[fmt](first,...)) + local function indexer(parent,k) + if type(k) == "string" then + local c = "\\" .. k + local f = function(first,...) + if first == nil then + flush(currentcatcodes,c) + else + return formattedflush(parent,c,first,...) + end + end + parent[k] = f + return f else - flush(catcodes,fmt) + return context -- catch end - else - if fmt then - flush(formatters[catcodes](fmt,first,...)) - else + end + + -- formatted([catcodes,]format[,...]) + + local function caller(parent,catcodes,fmt,...) + if not catcodes then + -- nothing + elseif not fmt then flush(catcodes) + elseif type(catcodes) == "number" then + flush(catcodes,formatters[fmt](...)) + else + flush(formatters[catcodes](fmt,...)) end end + + setmetatableindex(formatted,indexer) + setmetatablecall (formatted,caller) + + context.formatted = formatted + end -setmetatable(formatted, { __index = indexer, __call = caller } ) +do --- metafun (this will move to another file) + -- metafun (this will move to another file) -local metafun = { } context.metafun = metafun + local metafun = { } -local mpdrawing = "\\MPdrawing" + function metafun.start() + context.startMPcode() + end -local function caller(parent,f,a,...) - if not parent then - -- skip - elseif f then - local typ = type(f) - if typ == "string" then - if a then - flush(currentcatcodes,mpdrawing,"{",formatters[f](a,...),"}") - else - flush(currentcatcodes,mpdrawing,"{",f,"}") - end - elseif typ == "number" then - if a then - flush(currentcatcodes,mpdrawing,"{",f,a,...,"}") - else - flush(currentcatcodes,mpdrawing,"{",f,"}") - end - elseif typ == "function" then - -- ignored: a ... - flush(currentcatcodes,mpdrawing,"{\\cldl",store_(f),"}") - -- flush(currentcatcodes,mpdrawing,"{",store_(f),"}") - elseif typ == "boolean" then - -- ignored: a ... - if f then - flush(currentcatcodes,mpdrawing,"{^^M}") - else - report_context("warning: %a gets argument 'false' which is currently unsupported","metafun") - end - else - report_context("error: %a gets a weird argument %a","metafun",tostring(f)) - end + function metafun.stop() + context.stopMPcode() end -end -setmetatable(metafun, { __call = caller } ) + setmetatablecall(metafun,defaultcaller) -function metafun.start() - context.resetMPdrawing() -end + function metafun.color(name) -- obsolete + return name -- formatters[ [[\MPcolor{%s}]] ](name) + end -function metafun.stop() - context.MPdrawingdonetrue() - context.getMPdrawing() -end + -- metafun.delayed -function metafun.color(name) - return formatters[ [[\MPcolor{%s}]] ](name) -end + local delayed = { } --- metafun.delayed + local function indexer(parent,k) + local f = function(...) + local a = { ... } + return function() + return metafun[k](unpack(a)) + end + end + parent[k] = f + return f + end -local delayed = { } metafun.delayed = delayed -local function indexer(parent,k) - local f = function(...) + local function caller(parent,...) local a = { ... } return function() - return metafun[k](unpack(a)) + return metafun(unpack(a)) end end - parent[k] = f - return f -end + setmetatableindex(delayed,indexer) + setmetatablecall (delayed,caller) -local function caller(parent,...) - local a = { ... } - return function() - return metafun(unpack(a)) - end -end + context.metafun = metafun + metafun.delayed = delayed -setmetatable(delayed, { __index = indexer, __call = caller } ) +end -- helpers: -function context.concat(...) - context(concat(...)) -end +do + + function context.concat(...) + context(concat(...)) + end + + local p_texescape = patterns.texescape + + function context.escaped(s) + if s then + context(lpegmatch(p_texescape,s) or s) + else + -- context("") + end + end -local p_texescape = patterns.texescape + function context.escape(s) + if s then + return lpegmatch(p_texescape,s) or s + else + return "" + end + end -function context.escaped(s) - return lpegmatch(p_texescape,s) or s end -- templates -local single = lpegP("%") -local double = lpegP("%%") -local lquoted = lpegP("%[") -local rquoted = lpegP("]%") +do -local start = [[ -local texescape = lpeg.patterns.texescape -local lpegmatch = lpeg.match -return function(variables) return -]] + local single = lpegP("%") + local double = lpegP("%%") + local lquoted = lpegP("%[") + local rquoted = lpegP("]%") + local space = lpegP(" ") -local stop = [[ -end -]] - -local replacer = lpegP { "parser", - parser = lpegCs(lpegCc(start) * lpegV("step") * (lpegCc("..") * lpegV("step"))^0 * lpegCc(stop)), - unquoted = (lquoted/'') * ((lpegC((1-rquoted)^1)) / "lpegmatch(texescape,variables['%0'] or '')" ) * (rquoted/''), - escape = double/'%%', - key = (single/'') * ((lpegC((1-single)^1)) / "(variables['%0'] or '')" ) * (single/''), - step = lpegV("unquoted") - + lpegV("escape") - + lpegV("key") - + lpegCc("\n[===[") * (1 - lpegV("unquoted") - lpegV("escape") - lpegV("key"))^1 * lpegCc("]===]\n"), -} + local start = [[ + local texescape = lpeg.patterns.texescape + local lpegmatch = lpeg.match + return function(variables) return + ]] -local templates = { } + local stop = [[ + end + ]] + + local replacer = lpegP { "parser", + parser = lpegCs(lpegCc(start) * lpegV("step") * (lpegCc("..") * lpegV("step"))^0 * lpegCc(stop)), + unquoted = (lquoted*space/'') + * ((lpegC((1-space*rquoted)^1)) / "lpegmatch(texescape,variables%0 or '')" ) + * (space*rquoted/'') + + (lquoted/'') + * ((lpegC((1-rquoted)^1)) / "lpegmatch(texescape,variables['%0'] or '')" ) + * (rquoted/''), + key = (single*space/'') + * ((lpegC((1-space*single)^1)) / "(variables%0 or '')" ) + * (space*single/'') + + (single/'') + * ((lpegC((1-single)^1)) / "(variables['%0'] or '')" ) + * (single/''), + escape = double/'%%', + step = lpegV("unquoted") + + lpegV("escape") + + lpegV("key") + + lpegCc("\n[===[") * (1 - lpegV("unquoted") - lpegV("escape") - lpegV("key"))^1 * lpegCc("]===]\n"), + } + + local templates = { } -local function indexer(parent,k) - local v = lpegmatch(replacer,k) - if not v then - v = "error: no valid template (1)" - else - v = loadstring(v) - if type(v) ~= "function" then - v = "error: no valid template (2)" + local function indexer(parent,k) + local v = lpegmatch(replacer,k) + if not v then + -- report_template("invalid template:\n%s",k) + v = "error: no valid template (1)" else - v = v() - if not v then - v = "error: no valid template (3)" - end - end - end - if type(v) == "function" then - local f = function(first,second) - if second then - pushcatcodes(first) - flushlines(v(second)) - popcatcodes() + local f = loadstring(v) + if type(f) ~= "function" then + -- report_template("invalid template:\n%s\n=>\n%s",k,v) + v = "error: no valid template (2)" else - flushlines(v(first)) + f = f() + if not f then + -- report_template("invalid template:\n%s\n=>\n%s",k,v) + v = "error: no valid template (3)" + else + v = f + end end end - parent[k] = f - return f - else - return function() - flush(v) + if type(v) == "function" then + local f = function(first,second) + if second then + pushcatcodes(first) + flushlines(v(second)) + popcatcodes() + else + flushlines(v(first)) + end + end + parent[k] = f + return f + else + return function() + flush(v) + end end + end -end + local function caller(parent,k,...) + return parent[k](...) + end -local function caller(parent,k,...) - return parent[k](...) -end + setmetatableindex(templates,indexer) + setmetatablecall (templates,caller) -setmetatable(templates, { __index = indexer, __call = caller } ) + context.templates = templates -function context.template(template,...) - context(templates[template](...)) end -context.templates = templates - -- The above is a bit over the top as we could also stick to a simple context.replace -- which is fast enough anyway, but the above fits in nicer, also with the catcodes. -- diff --git a/tex/context/base/mkiv/cldf-int.lua b/tex/context/base/mkiv/cldf-int.lua index 2743e4924..a97eadf35 100644 --- a/tex/context/base/mkiv/cldf-int.lua +++ b/tex/context/base/mkiv/cldf-int.lua @@ -26,7 +26,7 @@ local trace_define = false trackers.register("context.define", function(v) tr interfaces = interfaces or { } -_clmh_ = utilities.parsers.settings_to_array +_clmh_ = utilities.parsers.settings_to_hash _clma_ = utilities.parsers.settings_to_array local starters, stoppers, macros, stack = { }, { }, { }, { } @@ -66,6 +66,8 @@ _clmn_ = tonumber local estart = interfaces.elements.start local estop = interfaces.elements.stop +-- this is a bit old definition ... needs to be modernized + function interfaces.definecommand(name,specification) -- name is optional if type(name) == "table" then specification = name @@ -172,51 +174,51 @@ function interfaces.tolist(t) return concat(r,", ") end ---~ \startluacode ---~ function test(opt_1, opt_2, arg_1) ---~ context.startnarrower() ---~ context("options 1: %s",interfaces.tolist(opt_1)) ---~ context.par() ---~ context("options 2: %s",interfaces.tolist(opt_2)) ---~ context.par() ---~ context("argument 1: %s",arg_1) ---~ context.stopnarrower() ---~ end - ---~ interfaces.definecommand { ---~ name = "test", ---~ arguments = { ---~ { "option", "list" }, ---~ { "option", "hash" }, ---~ { "content", "string" }, ---~ }, ---~ macro = test, ---~ } ---~ \stopluacode - ---~ test: \test[1][a=3]{whatever} - ---~ \startluacode ---~ local function startmore(opt_1) ---~ context.startnarrower() ---~ context("start more, options: %s",interfaces.tolist(opt_1)) ---~ context.startnarrower() ---~ end - ---~ local function stopmore(opt_1) ---~ context.stopnarrower() ---~ context("stop more, options: %s",interfaces.tolist(opt_1)) ---~ context.stopnarrower() ---~ end - ---~ interfaces.definecommand ( "more", { ---~ environment = true, ---~ arguments = { ---~ { "option", "list" }, ---~ }, ---~ starter = startmore, ---~ stopper = stopmore, ---~ } ) ---~ \stopluacode - ---~ more: \startmore[1] one \startmore[2] two \stopmore one \stopmore +-- \startluacode +-- function test(opt_1, opt_2, arg_1) +-- context.startnarrower() +-- context("options 1: %s",interfaces.tolist(opt_1)) +-- context.par() +-- context("options 2: %s",interfaces.tolist(opt_2)) +-- context.par() +-- context("argument 1: %s",arg_1) +-- context.stopnarrower() +-- end +-- +-- interfaces.definecommand { +-- name = "test", +-- arguments = { +-- { "option", "list" }, +-- { "option", "hash" }, +-- { "content", "string" }, +-- }, +-- macro = test, +-- } +-- \stopluacode +-- +-- test: \test[1][a=3]{whatever} +-- +-- \startluacode +-- local function startmore(opt_1) +-- context.startnarrower() +-- context("start more, options: %s",interfaces.tolist(opt_1)) +-- context.startnarrower() +-- end +-- +-- local function stopmore(opt_1) +-- context.stopnarrower() +-- context("stop more, options: %s",interfaces.tolist(opt_1)) +-- context.stopnarrower() +-- end +-- +-- interfaces.definecommand ( "more", { +-- environment = true, +-- arguments = { +-- { "option", "list" }, +-- }, +-- starter = startmore, +-- stopper = stopmore, +-- } ) +-- \stopluacode +-- +-- more: \startmore[1] one \startmore[2] two \stopmore one \stopmore diff --git a/tex/context/base/mkiv/cldf-scn.lua b/tex/context/base/mkiv/cldf-scn.lua index 755d7fed7..4a90c5b7e 100644 --- a/tex/context/base/mkiv/cldf-scn.lua +++ b/tex/context/base/mkiv/cldf-scn.lua @@ -122,7 +122,7 @@ function interfaces.implement(specification) command = args for i=1,#actions do command = f_action_f(i,command) - f[#f+1] = f_action_s(i,i) + f[i] = f_action_s(i,i) end command = f_command(f,args,command) command = load(command) diff --git a/tex/context/base/mkiv/cldf-stp.lua b/tex/context/base/mkiv/cldf-stp.lua index 7b5225dd3..eeed47594 100644 --- a/tex/context/base/mkiv/cldf-stp.lua +++ b/tex/context/base/mkiv/cldf-stp.lua @@ -28,16 +28,16 @@ if not modules then modules = { } end modules ['cldf-stp'] = { -- ... -- end) -local create = coroutine.create -local yield = coroutine.yield -local resume = coroutine.resume -local status = coroutine.status +local create = coroutine.create +local yield = coroutine.yield +local resume = coroutine.resume +local status = coroutine.status -local stepper = nil -local stack = { } -- will never be deep so no gc needed -local depth = 0 +local stepper = nil +local stack = { } -- will never be deep so no gc needed +local depth = 0 -local nextstep = function() +local function nextstep() if status(stepper) == "dead" then stepper = stack[depth] depth = depth - 1 @@ -51,13 +51,13 @@ interfaces.implement { actions = nextstep, } -local cldresume = context.constructcsonly("clf_step") +local ctx_resume = context.protected.cs.clf_step function context.step(first,...) if first ~= nil then context(first,...) end - cldresume() + ctx_resume() yield() end @@ -65,5 +65,5 @@ function context.stepwise(f) depth = depth + 1 stack[depth] = stepper stepper = create(f) - resume(stepper) + ctx_resume(stepper) end diff --git a/tex/context/base/mkiv/cldf-ver.lua b/tex/context/base/mkiv/cldf-ver.lua index 66432eb1c..3710b2415 100644 --- a/tex/context/base/mkiv/cldf-ver.lua +++ b/tex/context/base/mkiv/cldf-ver.lua @@ -11,7 +11,7 @@ if not modules then modules = { } end modules ['cldf-ver'] = { -- better when used mixed with other code (synchronization issue). local concat, tohandle = table.concat, table.tohandle -local find, splitlines = string.find, string.splitlines +local splitlines, strip = string.splitlines, string.strip local tostring, type = tostring, type local context = context @@ -28,11 +28,15 @@ local function t_tocontext(...) context.popcatcodes() end -local function s_tocontext(...) -- we need to catch {\} +local function s_tocontext(first,...) -- we need to catch {\} context.type() context("{") context.pushcatcodes("verbatim") - context(concat({...}," ")) + if first then + context(first) -- no need to waste a { } + else + context(concat({first,...}," ")) + end context.popcatcodes() context("}") end @@ -44,34 +48,41 @@ end table .tocontext = t_tocontext string .tocontext = s_tocontext boolean.tocontext = b_tocontext +number .tocontext = s_tocontext + +local tocontext = { + ["string"] = s_tocontext, + ["table"] = t_tocontext, + ["boolean"] = b_tocontext, + ["number"] = s_tocontext, + ["function"] = function() s_tocontext("<function>") end, + ["nil"] = function() s_tocontext("<nil>") end, + -- ------------ = -------- can be extended elsewhere +} -function context.tocontext(first,...) - local t = type(first) - if t == "string" then - s_tocontext(first,...) - elseif t == "table" then - t_tocontext(first,...) - elseif t == "boolean" then - b_tocontext(first,...) +table.setmetatableindex(tocontext,function(t,k) + local v = function(s) + s_tocontext("<"..tostring(s)..">") end -end + t[k] = v + return v +end) + +table.setmetatablecall(tocontext,function(t,k,...) + tocontext[type(k)](k) +end) --- function context.tobuffer(name,str) --- context.startbuffer { name } --- context.pushcatcodes("verbatim") --- local lines = (type(str) == "string" and find(str,"[\n\r]") and splitlines(str)) or str --- for i=1,#lines do --- context(lines[i] .. " ") --- end --- context.stopbuffer() --- context.popcatcodes() --- end +context.tocontext = tocontext context.tobuffer = buffers.assign -- (name,str,catcodes) -function context.tolines(str) +function context.tolines(str,strip) local lines = type(str) == "string" and splitlines(str) or str for i=1,#lines do - context(lines[i] .. " ") + if strip then + context(strip(lines[i]) .. " ") + else + context(lines[i] .. " ") + end end end diff --git a/tex/context/base/mkiv/colo-ext.mkiv b/tex/context/base/mkiv/colo-ext.mkiv index 74ce2d3e5..98aaaa8aa 100644 --- a/tex/context/base/mkiv/colo-ext.mkiv +++ b/tex/context/base/mkiv/colo-ext.mkiv @@ -46,8 +46,8 @@ \installcorenamespace{colorintent} -\unexpanded\def\registercolorintent#1#2% - {\setevalue{\??colorintent#1}{\attribute\colorintentattribute\clf_registercolorintent{#2}}} +\unexpanded\def\registercolorintent#1#2% \relax is needed ! + {\setevalue{\??colorintent#1}{\attribute\colorintentattribute\clf_registercolorintent{#2}\relax}} \unexpanded\def\colo_intents_set {\clf_enablecolorintents diff --git a/tex/context/base/mkiv/colo-imp-rainbow.mkiv b/tex/context/base/mkiv/colo-imp-rainbow.mkiv new file mode 100644 index 000000000..c9686d755 --- /dev/null +++ b/tex/context/base/mkiv/colo-imp-rainbow.mkiv @@ -0,0 +1,252 @@ +%D \module +%D [ file=colo-imp-rainbow, +%D version=2016.03.21, +%D title=\CONTEXT\ Color Macros, +%D subtitle=X11, +%D author=Alan Braslau] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D \subsubject{For scientists by scientists} +%D +%D We define color groups having equal gray scale values by either reducing +%D their rgb values to darken them or by adding equal amounts of $r=g=b$ to +%D lighten them. +%D +%D \startformula +%D s = .3r + .59g + .11b +%D \stopformula +%D +%D By the way, \CONTEXT\ has always used this formula internally when colors +%D are converted to gray. + +\definecolorgroup + [gray] + [0.1:0.1:0.1, + 0.2:0.2:0.2, + 0.3:0.3:0.3, + 0.4:0.4:0.4, + 0.5:0.5:0.5, + 0.6:0.6:0.6, + 0.7:0.7:0.7, + 0.8:0.8:0.8, + 0.9:0.9:0.9, + 1.0:1.0:1.0] + +\definecolorgroup + [red] + [0.333:0.000:0.000, + 0.667:0.000:0.000, + 1.000:0.000:0.000, + 1.000:0.143:0.143, + 1.000:0.286:0.286, + 1.000:0.429:0.429, + 1.000:0.571:0.571, + 1.000:0.714:0.714, + 1.000:0.857:0.857] + +\definecolorgroup + [green] + [0.000:0.169:0.000, + 0.000:0.339:0.000, + 0.000:0.508:0.000, + 0.000:0.678:0.000, + 0.000:0.847:0.000, + 0.024:1.000:0.024, + 0.268:1.000:0.268, + 0.512:1.000:0.512, + 0.756:1.000:0.756] + +\definecolorgroup + [blue] + [0.000:0.000:0.909, + 0.101:0.101:1.000, + 0.213:0.213:1.000, + 0.326:0.326:1.000, + 0.438:0.438:1.000, + 0.551:0.551:1.000, + 0.663:0.663:1.000, + 0.775:0.775:1.000, + 0.888:0.888:1.000] + +\definecolorgroup + [cyan] + [0.000:0.143:0.143, + 0.000:0.286:0.286, + 0.000:0.429:0.429, + 0.000:0.571:0.571, + 0.000:0.714:0.714, + 0.000:0.857:0.857, + 0.000:1.000:1.000, + 0.333:1.000:1.000, + 0.667:1.000:1.000] + +\definecolorgroup + [magenta] + [0.244:0.000:0.244, + 0.488:0.000:0.488, + 0.732:0.000:0.732, + 0.976:0.000:0.976, + 1.000:0.153:1.000, + 1.000:0.322:1.000, + 1.000:0.492:1.000, + 1.000:0.661:1.000, + 1.000:0.831:1.000] + +\definecolorgroup + [yellow] + [0.112:0.112:0.000, + 0.225:0.225:0.000, + 0.337:0.337:0.000, + 0.449:0.449:0.000, + 0.562:0.562:0.000, + 0.674:0.674:0.000, + 0.787:0.787:0.000, + 0.899:0.899:0.000, + 1.000:1.000:0.091] + +\definecolorgroup + [orange] + [0.147:0.095:0.000, + 0.293:0.190:0.000, + 0.440:0.285:0.000, + 0.587:0.380:0.000, + 0.733:0.475:0.000, + 0.880:0.569:0.000, + 1.000:0.673:0.026, + 1.000:0.816:0.169, + 1.000:0.959:0.312] + +\definecolorgroup + [violet] + [0.137:0.075:0.137, + 0.273:0.149:0.273, + 0.410:0.224:0.410, + 0.546:0.298:0.546, + 0.683:0.373:0.683, + 0.819:0.448:0.819, + 0.950:0.527:0.950, + 1.000:0.661:1.000, + 1.000:0.831:1.000] + +\definecolorgroup + [brown] + [0.209:0.053:0.053, + 0.417:0.106:0.106, + 0.627:0.160:0.160, + 0.737:0.255:0.255, + 0.837:0.355:0.355, + 0.937:0.455:0.455, + 1.000:0.571:0.571, + 1.000:0.714:0.714, + 1.000:0.857:0.857] + +%D Define \quote{rainbow} color palets having equal grayscale values. +%D The names correspond to the number color codes used on electrical resistances. + +\dorecurse {9} { + \definepalet + [rainbow#1] + [ one#1=brown:#1, + two#1=red:#1, + three#1=orange:#1, + four#1=yellow:#1, + five#1=green:#1, + six#1=blue:#1, + seven#1=violet:#1, + eight#1=gray:#1] +} + +%D Define two more color palets showing grayscale contrast. +%D Note that \emph{none} of these palets are very aesthetic! + +\definepalet + [rainbow0] + [ one0=brown:8, + two0=red:7, + three0=orange:6, + four0=yellow:5, + five0=green:4, + six0=blue:3, + seven0=violet:2, + eight0=gray:1] + +\definepalet + [rainbow] + [ zero=black, + one=brown:1, + two=red:2, + three=orange:3, + four=yellow:4, + five=green:5, + six=blue:6, + seven=violet:7, + eight=gray:8, + nine=white] + +\continueifinputfile{colo-imp-rainbow.mkiv} + +\usemodule[art-01] \setupbodyfont[8pt] + +\starttexdefinition ShowSomething #1 + \startpacked + \dorecurse {9} { + \dontleavehmode + \start + \ttbf + \color [#1:##1] {\hbox to 6em{#1:##1\hss}} + \tttf + \quad + \colorvalue {#1:##1} + \quad + \grayvalue {#1:##1} + \quad + \stop + \par + } + \stoppacked +\stoptexdefinition + +\starttext + + \startcolumns [n=2,distance=0pt] + \ShowSomething {gray} + \ShowSomething {brown} + \ShowSomething {red} + \ShowSomething {orange} + \ShowSomething {yellow} + \ShowSomething {green} + \column + \ShowSomething {cyan} + \ShowSomething {blue} + \ShowSomething {magenta} + \ShowSomething {violet} + \stopcolumns + + \startalignment [flushleft] + \dontleavehmode + \showcolorgroup [brown] [vertical,name,number] + \showcolorgroup [red] [vertical,name] + \showcolorgroup [orange] [vertical,name] + \showcolorgroup [yellow] [vertical,name] + \showcolorgroup [green] [vertical,name] + \showcolorgroup [cyan] [vertical,name] + \showcolorgroup [blue] [vertical,name] + \showcolorgroup [violet] [vertical,name] + \showcolorgroup [magenta] [vertical,name] + \showcolorgroup [gray] [vertical,name] + \stopalignment + + \page + + \dorecurse {9} { + \comparepalet [rainbow#1] + } + + \comparepalet [rainbow0] + + \comparepalet [rainbow] + +\stoptext diff --git a/tex/context/base/mkiv/colo-imp-rgb.mkiv b/tex/context/base/mkiv/colo-imp-rgb.mkiv index 58b2ca42c..934071ed9 100644 --- a/tex/context/base/mkiv/colo-imp-rgb.mkiv +++ b/tex/context/base/mkiv/colo-imp-rgb.mkiv @@ -112,8 +112,8 @@ \definecolor [gruen] [green] \definecolor [blau] [blue] - \definecolor [cyan] [cyan] - \definecolor [magenta] [magenta] + %definecolor [cyan] [cyan] + %definecolor [magenta] [magenta] \definecolor [gelb] [yellow] \definecolor [weiss] [white] @@ -245,8 +245,8 @@ \definecolor [vert] [green] \definecolor [bleu] [blue] - \definecolor [cyan] [cyan] - \definecolor [magenta] [magenta] + %\definecolor [cyan] [cyan] + %\definecolor [magenta] [magenta] \definecolor [jaune] [yellow] \definecolor [blanche] [white] @@ -290,7 +290,7 @@ \definecolor [albastru] [blue] \definecolor [cian] [cyan] - \definecolor [magenta] [magenta] + %\definecolor [magenta] [magenta] \definecolor [galben] [yellow] \definecolor [alb] [white] diff --git a/tex/context/base/mkiv/colo-imp-solarized.mkiv b/tex/context/base/mkiv/colo-imp-solarized.mkiv new file mode 100644 index 000000000..872e6b701 --- /dev/null +++ b/tex/context/base/mkiv/colo-imp-solarized.mkiv @@ -0,0 +1,38 @@ +%D \module +%D [ file=colo-imp-solarized, +%D version=2017.02.10, +%D title=\CONTEXT\ Color Macros, +%D subtitle=Solarized, +%D author=Aditya Mahajan, +%D ] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA, See mreadme.pdf for +%C details. + +%D Colors based on solarized scheme: +%D +%D \hyphenatedurl{http://ethanschoonover.com/solarized} + +\startprotectedcolors + + \definecolor [base03] [h=002b36] + \definecolor [base02] [h=073642] + \definecolor [base01] [h=586e75] + \definecolor [base00] [h=657b83] + \definecolor [base0] [h=839496] + \definecolor [base1] [h=93a1a1] + \definecolor [base2] [h=eee8d5] + \definecolor [base3] [h=fdf6e3] + \definecolor [yellow] [h=b58900] + \definecolor [orange] [h=cb4b16] + \definecolor [red] [h=dc322f] + \definecolor [magenta] [h=d33682] + \definecolor [violet] [h=6c71c4] + \definecolor [blue] [h=268bd2] + \definecolor [cyan] [h=2aa198] + \definecolor [green] [h=859900] + +\stopprotectedcolors + +\endinput diff --git a/tex/context/base/mkiv/colo-ini.lua b/tex/context/base/mkiv/colo-ini.lua index 1a055242b..c074d3407 100644 --- a/tex/context/base/mkiv/colo-ini.lua +++ b/tex/context/base/mkiv/colo-ini.lua @@ -26,6 +26,9 @@ local context = context local commands = commands local implement = interfaces.implement +local getnamespace = interfaces.getnamespace + +local mark = utilities.storage.mark local settings_to_hash_strict = utilities.parsers.settings_to_hash_strict @@ -33,12 +36,17 @@ local colors = attributes.colors local transparencies = attributes.transparencies local colorintents = attributes.colorintents local registrations = backends.registrations + +local v_reset = interfaces.variables.reset + local texsetattribute = tex.setattribute local texgetattribute = tex.getattribute +local texgetcount = tex.getcount +local texgettoks = tex.gettoks local a_color = attributes.private('color') local a_transparency = attributes.private('transparency') -local a_colorspace = attributes.private('colormodel') +local a_colormodel = attributes.private('colormodel') local register_color = colors.register local attributes_list = attributes.list @@ -46,12 +54,36 @@ local attributes_list = attributes.list local colorvalues = colors.values local transparencyvalues = transparencies.values -colors.sets = colors.sets or { } -- sets are mostly used for +colors.sets = mark(colors.sets or { }) -- sets are mostly used for local colorsets = colors.sets -- showing lists of defined local colorset = { } -- colors colorsets.default = colorset +local valid = mark(colors.valid or { }) +colors.valid = valid +local counts = mark(colors.counts or { }) +colors.counts = counts + +storage.register("attributes/colors/sets", colorsets, "attributes.colors.sets") +storage.register("attributes/colors/valid", valid, "attributes.colors.valid") +storage.register("attributes/colors/counts", counts, "attributes.colors.counts") + +local function currentmodel() + return texgetattribute(a_colormodel) +end + +colors.currentmodel = currentmodel -storage.register("attributes/colors/sets",colorsets,"attributes.colors.sets") +local function synccolor(name) + valid[name] = true +end + +local function synccolorclone(name,clone) + valid[name] = clone +end + +local function synccolorcount(name,n) + counts[name] = n +end local stack = { } @@ -76,18 +108,18 @@ colors.pushset = pushset colors.popset = popset colors.setlist = setlist -local context_colordefagc = context.colordefagc -local context_colordefagt = context.colordefagt -local context_colordefalc = context.colordefalc -local context_colordefalt = context.colordefalt -local context_colordeffgc = context.colordeffgc -local context_colordeffgt = context.colordeffgt -local context_colordefflc = context.colordefflc -local context_colordefflt = context.colordefflt -local context_colordefrgc = context.colordefrgc -local context_colordefrgt = context.colordefrgt -local context_colordefrlc = context.colordefrlc -local context_colordefrlt = context.colordefrlt +local ctx_colordefagc = context.colordefagc +local ctx_colordefagt = context.colordefagt +local ctx_colordefalc = context.colordefalc +local ctx_colordefalt = context.colordefalt +local ctx_colordeffgc = context.colordeffgc +local ctx_colordeffgt = context.colordeffgt +local ctx_colordefflc = context.colordefflc +local ctx_colordefflt = context.colordefflt +local ctx_colordefrgc = context.colordefrgc +local ctx_colordefrgt = context.colordefrgt +local ctx_colordefrlc = context.colordefrlc +local ctx_colordefrlt = context.colordefrlt local function definecolor(name, ca, global) if ca and ca > 0 then @@ -95,18 +127,18 @@ local function definecolor(name, ca, global) if trace_define then report_colors("define global color %a with attribute %a",name,ca) end - context_colordefagc(name,ca) + ctx_colordefagc(name,ca) else if trace_define then report_colors("define local color %a with attribute %a",name,ca) end - context_colordefalc(name,ca) + ctx_colordefalc(name,ca) end else if global then - context_colordefrgc(name) + ctx_colordefrgc(name) else - context_colordefrlc(name) + ctx_colordefrlc(name) end end colorset[name] = true-- maybe we can store more @@ -118,18 +150,18 @@ local function inheritcolor(name, ca, global) if trace_define then report_colors("inherit global color %a with attribute %a",name,ca) end - context_colordeffgc(name,ca) -- some day we will set the macro directly + ctx_colordeffgc(name,ca) -- some day we will set the macro directly else if trace_define then report_colors("inherit local color %a with attribute %a",name,ca) end - context_colordefflc(name,ca) + ctx_colordefflc(name,ca) end else if global then - context_colordefrgc(name) + ctx_colordefrgc(name) else - context_colordefrlc(name) + ctx_colordefrlc(name) end end colorset[name] = true-- maybe we can store more @@ -141,18 +173,18 @@ local function definetransparent(name, ta, global) if trace_define then report_colors("define global transparency %a with attribute %a",name,ta) end - context_colordefagt(name,ta) + ctx_colordefagt(name,ta) else if trace_define then report_colors("define local transparency %a with attribute %a",name,ta) end - context_colordefalt(name,ta) + ctx_colordefalt(name,ta) end else if global then - context_colordefrgt(name) + ctx_colordefrgt(name) else - context_colordefrlt(name) + ctx_colordefrlt(name) end end end @@ -163,18 +195,18 @@ local function inherittransparent(name, ta, global) if trace_define then report_colors("inherit global transparency %a with attribute %a",name,ta) end - context_colordeffgt(name,ta) + ctx_colordeffgt(name,ta) else if trace_define then report_colors("inherit local transparency %a with attribute %a",name,ta) end - context_colordefflt(name,ta) + ctx_colordefflt(name,ta) end else if global then - context_colordefrgt(name) + ctx_colordefrgt(name) else - context_colordefrlt(name) + ctx_colordefrlt(name) end end end @@ -199,11 +231,18 @@ local transparent = { luminosity = 16, } -local gray_okay, rgb_okay, cmyk_okay, spot_okay, multichannel_okay, forced = true, true, true, true, true, false +transparencies.names = transparent + +local gray_okay = true +local rgb_okay = true +local cmyk_okay = true +local spot_okay = true +local multi_okay = true +local forced = false -function colors.forcesupport(gray,rgb,cmyk,spot,multichannel) -- pdfx driven - gray_okay, rgb_okay, cmyk_okay, spot_okay, multichannel_okay, forced = gray, rgb, cmyk, spot, multichannel, true - report_colors("supported models: gray %a, rgb %a, cmyk %a, spot %a",gray,rgb,cmyk,spot) -- multichannel=%l multichannel +function colors.forcesupport(gray,rgb,cmyk,spot,multi) -- pdfx driven + gray_okay, rgb_okay, cmyk_okay, spot_okay, multi_okay, forced = gray, rgb, cmyk, spot, multi, true + report_colors("supported models: gray %a, rgb %a, cmyk %a, spot %a",gray,rgb,cmyk,spot) end local function forcedmodel(model) -- delayed till the backend but mp directly @@ -253,8 +292,32 @@ colors.forcedmodel = forcedmodel colors.couple = true -local function definetransparency(name,n) - transparent[name] = n +local function definetransparency(name,n,global) + if n == v_reset then + definetransparent(name, 0, global) -- or attributes.unsetvalue + return + end + local a = tonumber(n) + if a then + transparent[name] = a -- 0 .. 16 + return + end + local a = transparent[name] + if a then + transparent[name] = a + return + end + local settings = settings_to_hash_strict(n) + if settings then + local a, t = settings.a, settings.t + if a and t then + definetransparent(name, transparencies.register(name,transparent[a] or tonumber(a) or 1,tonumber(t) or 1), global) + else + definetransparent(name, 0, global) + end + else + inherittransparent(name, n, global) + end end colors.definetransparency = definetransparency @@ -265,7 +328,7 @@ local function do_registerspotcolor(parent,parentnumber,e,f,d,p) if not registered[parent] then local v = colorvalues[parentnumber] if v then - local model = colors.default -- else problems with shading etc + local model = currentmodel() if model == 1 then model = v[1] end @@ -288,7 +351,7 @@ end -- if not registered[parent] then -- local v = colorvalues[parentnumber] -- if v then --- local model = colors.default -- else problems with shading etc +-- local model = currentmodel() -- if model == 1 then -- model = v[1] -- end @@ -309,8 +372,8 @@ function colors.definesimplegray(name,s) end local hexdigit = R("09","AF","af") -local hexnumber = hexdigit * hexdigit / function(s) return tonumber(s,16)/255 end + Cc(0) -local hexpattern = hexnumber^-3 * P(-1) +local hexnumber = hexdigit * hexdigit / function(s) return tonumber(s,16)/255 end +local hexpattern = hexnumber * (P(-1) + hexnumber * hexnumber * P(-1)) local hexcolor = Cc("H") * P("#") * hexpattern local left = P("(") @@ -342,6 +405,21 @@ end) local defineintermediatecolor +local function resolvedname(name) + local color + if valid[name] then + color = counts[name] + if color then + color = texgetcount(color) + else + color = l_color[name] -- fall back on old method + end + else + color = l_color[name] -- fall back on old method + end + return color, l_transparency[name] +end + local function defineprocesscolor(name,str,global,freeze) -- still inconsistent color vs transparent local what, one, two, three = lpegmatch(specialcolor,str) if what == "H" then @@ -349,10 +427,16 @@ local function defineprocesscolor(name,str,global,freeze) -- still inconsistent definecolor(name, register_color(name,'rgb',one,two,three),global) elseif what == "M" then -- intermediate - return defineintermediatecolor(name,one,l_color[two],l_color[three],l_transparency[two],l_transparency[three],"",global,freeze) + -- return defineintermediatecolor(name,one,l_color[two],l_color[three],l_transparency[two],l_transparency[three],"",global,freeze) + local c1, t1 = resolvedname(two) + local c2, t2 = resolvedname(three) + return defineintermediatecolor(name,one,c1,c2,t1,t2,"",global,freeze) elseif what == "P" then -- pgf for tikz - return defineintermediatecolor(name,two,l_color[one],l_color[three],l_transparency[one],l_transparency[three],"",global,freeze) + -- return defineintermediatecolor(name,two,l_color[one],l_color[three],l_transparency[one],l_transparency[three],"",global,freeze) + local c1, t1 = resolvedname(one) + local c2, t2 = resolvedname(three) + return defineintermediatecolor(name,two,c1,c2,t1,t2,"",global,freeze) else local settings = settings_to_hash_strict(str) if settings then @@ -373,7 +457,11 @@ local function defineprocesscolor(name,str,global,freeze) -- still inconsistent local x = settings.x or h if x then r, g, b = lpegmatch(hexpattern,x) -- can be inlined - definecolor(name, register_color(name,'rgb',r,g,b), global) + if r and g and b then + definecolor(name, register_color(name,'rgb',r,g,b), global) + else + definecolor(name, register_color(name,'gray',r or 0), global) + end else definecolor(name, register_color(name,'gray',tonumber(s) or 0), global) end @@ -415,6 +503,11 @@ end colors.isblack = isblack +-- local m, c, t = attributes.colors.namedcolorattributes(parent) +-- if c and c > 1 then -- 1 is black +-- local v = attributes.colors.values[c] + + local function definespotcolor(name,parent,str,global) if parent == "" or find(parent,"=",1,true) then colors.registerspotcolor(name, parent) -- does that work? no attr @@ -431,7 +524,7 @@ local function definespotcolor(name,parent,str,global) if ta and tt then definetransparent(name, transparencies.register(name,transparent[ta] or tonumber(ta) or 1,tonumber(tt) or 1), global) elseif colors.couple then - --~ definetransparent(name, transparencies.register(nil, 1, 1), global) -- can be sped up + -- definetransparent(name, transparencies.register(nil, 1, 1), global) -- can be sped up definetransparent(name, 0, global) -- can be sped up end end @@ -455,8 +548,15 @@ end local function f(i,colors,fraction) local otf = 0 - for c=1,#colors do - otf = otf + (tonumber(fraction[c]) or 1) * colors[c][i] + if type(fraction) == "table" then + for c=1,#colors do + otf = otf + (tonumber(fraction[c]) or 1) * colors[c][i] + end + else + fraction = tonumber(fraction) + for c=1,#colors do + otf = otf + fraction * colors[c] + end end if otf > 1 then otf = 1 @@ -508,7 +608,11 @@ local function definemultitonecolor(name,multispec,colorspec,selfspec) nn = concat(nn,'_') local parent = gsub(lower(nn),"[^%d%a%.]+","_") if not colorspec or colorspec == "" then - local cc = { } for i=1,max do cc[i] = l_color[dd[i]] end + local cc = { } + for i=1,max do +-- cc[i] = l_color[dd[i]] + cc[i] = resolvedname(dd[i]) + end definemixcolor(name,parent,pp,cc,global,freeze) -- can become local else if selfspec ~= "" then @@ -585,11 +689,55 @@ local function mpcolor(model,ca,ta,default) return formatters["(%s,%s,%s)"](default,default,default) end +-- local function mpnamedcolor(name) +-- return mpcolor(texgetattribute(a_colormodel),l_color[name] or l_color.black,l_transparency[name] or false) +-- end + +local colornamespace = getnamespace("colornumber") +local paletnamespace = getnamespace("colorpalet") + +local function namedcolorattributes(name) + local space = texgetattribute(a_colormodel) + local prefix = texgettoks("t_colo_prefix") + local color + if prefix ~= "" then + color = valid[prefix..name] + if not color then + local n = paletnamespace .. prefix .. name + color = valid[n] + if not color then + color = name + elseif color == true then + color = n + end + elseif color == true then + color = paletnamespace .. prefix .. name + end + elseif valid[name] then + color = name + else + return space, l_color.black + end + color = counts[color] + if color then + color = texgetcount(color) + else + color = l_color[name] -- fall back on old method + end + if color then + return space, color, l_transparency[name] + else + return space, l_color.black + end +end + +colors.namedcolorattributes = namedcolorattributes -- can be used local + local function mpnamedcolor(name) - return mpcolor(texgetattribute(a_colorspace),l_color[name] or l_color.black) + return mpcolor(namedcolorattributes(name)) end -local function mpoptions(model,ca,ta,default) -- will move to mlib-col +local function mpoptions(model,ca,ta,default) -- will move to mlib-col .. not really needed return formatters["withcolor %s"](mpcolor(model,ca,ta,default)) end @@ -597,6 +745,13 @@ colors.mpcolor = mpcolor colors.mpnamedcolor = mpnamedcolor colors.mpoptions = mpoptions +-- elsewhere: +-- +-- mp.NamedColor = function(str) +-- mpprint(mpnamedcolor(str)) +-- end + + -- local function formatcolor(ca,separator) -- local cv = colorvalues[ca] -- if cv then @@ -693,6 +848,10 @@ end local function spotcolorname(ca,default) local cv, v = colorvalues[ca], "unknown" + if not cv and type(ca) == "string" then + ca = resolvedname(ca) -- we could metatable colorvalues + cv = colorvalues[ca] + end if cv and cv[1] == 5 then v = cv[10] end @@ -701,6 +860,10 @@ end local function spotcolorparent(ca,default) local cv, v = colorvalues[ca], "unknown" + if not cv and type(ca) == "string" then + ca = resolvedname(ca) -- we could metatable colorvalues + cv = colorvalues[ca] + end if cv and cv[1] == 5 then v = cv[12] if v == "" then @@ -712,6 +875,10 @@ end local function spotcolorvalue(ca,default) local cv, v = colorvalues[ca], 0 + if not cv and type(ca) == "string" then + ca = resolvedname(ca) -- we could metatable colorvalues + cv = colorvalues[ca] + end if cv and cv[1] == 5 then v = cv[13] end @@ -733,11 +900,19 @@ local min = math.min local function inbetween(one,two,i,fraction) local o, t = one[i], two[i] + local c = fraction < 0 + if c then + fraction = - fraction + end local otf = o + fraction * (t - o) if otf > 1 then otf = 1 end - return otf + if c then + return 1 - otf + else + return otf + end end local function justone(one,fraction,i) @@ -758,7 +933,7 @@ end defineintermediatecolor = function(name,fraction,c_one,c_two,a_one,a_two,specs,global,freeze) fraction = tonumber(fraction) or 1 - local one, two = colorvalues[c_one], colorvalues[c_two] + local one, two = colorvalues[c_one], colorvalues[c_two] -- beware, it uses the globals if one then if two then local csone, cstwo = one[1], two[1] @@ -869,10 +1044,28 @@ end local setcolormodel = colors.setmodel implement { + name = "synccolorcount", + actions = synccolorcount, + arguments = { "string", "integer" } +} + +implement { + name = "synccolor", + actions = synccolor, + arguments = "string", +} + +implement { + name = "synccolorclone", + actions = synccolorclone, + arguments = { "string", "string" }, +} + +implement { name = "setcolormodel", - arguments = { "string", "boolean" }, + arguments = { "string", "string" }, actions = function(model,weight) - texsetattribute(a_colorspace,setcolormodel(model,weight)) + texsetattribute(a_colormodel,setcolormodel(model,weight)) end } @@ -923,7 +1116,13 @@ implement { implement { name = "definetransparency", actions = definetransparency, - arguments = { "string", "integer" } + arguments = { "string", "string" } +} + +implement { + name = "definetransparencyglobal", + actions = definetransparency, + arguments = { "string", "string", true } } implement { @@ -935,9 +1134,9 @@ implement { implement { name = "spotcolorname", actions = { spotcolorname, context }, arguments = "integer" } implement { name = "spotcolorparent", actions = { spotcolorparent, context }, arguments = "integer" } implement { name = "spotcolorvalue", actions = { spotcolorvalue, context }, arguments = "integer" } -implement { name = "colorcomponents", actions = { colorcomponents, context }, arguments = "integer" } -implement { name = "transparencycomponents", actions = { transparencycomponents, context }, arguments = "integer" } -implement { name = "processcolorcomponents", actions = { processcolorcomponents, context }, arguments = "integer" } +implement { name = "colorcomponents", actions = { colorcomponents, context }, arguments = { "integer", tokens.constant(",") } } +implement { name = "transparencycomponents", actions = { transparencycomponents, context }, arguments = { "integer", tokens.constant(",") } } +implement { name = "processcolorcomponents", actions = { processcolorcomponents, context }, arguments = { "integer", tokens.constant(",") } } implement { name = "formatcolor", actions = { formatcolor, context }, arguments = { "integer", "string" } } implement { name = "formatgray", actions = { formatgray, context }, arguments = { "integer", "string" } } @@ -1000,7 +1199,7 @@ do if model and model ~= 0 then model = model else - model = forcedmodel(texgetattribute(a_colorspace)) + model = forcedmodel(texgetattribute(a_colormodel)) if model == 1 then model = cv[1] end @@ -1046,5 +1245,18 @@ function colors.spec(name) } end +function colors.currentnamedmodel() + return models[texgetattribute(a_colormodel)] or "gray" +end + -- inspect(attributes.colors.spec("red")) -- inspect(attributes.colors.spec("red socks")) + +implement { + name = "negatedcolorcomponent", + arguments = "string", + actions = function(s) + s = 1 - (tonumber(s) or 0) + context((s < 0 and 0) or (s > 1 and 1) or s) + end +} diff --git a/tex/context/base/mkiv/colo-ini.mkiv b/tex/context/base/mkiv/colo-ini.mkiv index 26208edd4..54ad1e9f9 100644 --- a/tex/context/base/mkiv/colo-ini.mkiv +++ b/tex/context/base/mkiv/colo-ini.mkiv @@ -21,6 +21,17 @@ %D This module implements color. Since \MKII\ and \MKIV\ use a completely %D different approach, this module only implements a few generic mechanisms. +\installcorenamespace{color} +\installcorenamespace{colorattribute} +\installcorenamespace{transparencyattribute} +\installcorenamespace{colorsetter} +\installcorenamespace{transparencysetter} +\installcorenamespace{colorpaletspecification} +\installcorenamespace{colorpalet} +\installcorenamespace{colorstack} +\installcorenamespace{colorconversions} +\installcorenamespace{colornumber} + \registerctxluafile{colo-ini}{1.000} \registerctxluafile{colo-icc}{1.000} @@ -48,26 +59,17 @@ \newconditional\c_colo_rgb_supported \newconditional\c_colo_cmyk_supported \newconditional\c_colo_spot_supported % backend driven -\newconditional\c_colo_weight_gray \settrue\c_colo_weight_gray \newconditional\c_colo_convert_gray \settrue\c_colo_convert_gray \newconditional\c_colo_enabled \newconditional\c_colo_expanded +\let\m_colo_weight_gray\v!yes + \let\currentcolormodel \empty \let\currentcolorname \empty \let\currentcolorpalet \empty \let\currentcolorprefix\empty % \currentcolorpalet: -\installcorenamespace{color} -\installcorenamespace{colorattribute} -\installcorenamespace{transparencyattribute} -\installcorenamespace{colorsetter} -\installcorenamespace{transparencysetter} -\installcorenamespace{colorpaletspecification} -\installcorenamespace{colorpalet} -\installcorenamespace{colorstack} -\installcorenamespace{colorconversions} - %D \macros %D {definecolor,defineglobalcolor,definenamedcolor,definespotcolor,definemultitonecolor, %D definetransparency} @@ -97,13 +99,14 @@ %D \stopcombination %D \stoptyping -\unexpanded\def\definecolor {\dodoubleargument\colo_basics_define} -\unexpanded\def\defineglobalcolor {\dodoubleargument\colo_basics_define_global} -\unexpanded\def\defineprocesscolor {\dotripleargument\colo_basics_define_process} -\unexpanded\def\definenamedcolor {\dodoubleargument\colo_basics_define_named} -\unexpanded\def\definespotcolor {\dotripleargument\colo_basics_define_spot} -\unexpanded\def\definemultitonecolor{\doquadrupleempty\colo_basics_define_multitone} -\unexpanded\def\definetransparency {\dodoubleargument\colo_basics_define_transpancy} +\unexpanded\def\definecolor {\dodoubleargument\colo_basics_define} +\unexpanded\def\defineglobalcolor {\dodoubleargument\colo_basics_define_global} +\unexpanded\def\defineprocesscolor {\dotripleargument\colo_basics_define_process} +\unexpanded\def\definenamedcolor {\dodoubleargument\colo_basics_define_named} +\unexpanded\def\definespotcolor {\dotripleargument\colo_basics_define_spot} +\unexpanded\def\definemultitonecolor {\doquadrupleempty\colo_basics_define_multitone} +\unexpanded\def\definetransparency {\dodoubleargument\colo_basics_define_transpancy} +\unexpanded\def\defineglobaltransparency{\dodoubleargument\colo_basics_define_transpancy_global} %D \macros %D {startcolor,stopcolor,color,graycolor} @@ -126,42 +129,154 @@ \let\g_color\empty \let\g_style\empty -\unexpanded\def\switchtocolor[#1]{\csname#1\endcsname} +\unexpanded\def\switchtocolor[#1]{\begincsname#1\endcsname} + +% \unexpanded\def\color [#1]{\bgroup +% \def\g_color{\colo_helpers_activate{#1}}% +% \afterassignment\g_color +% \let\nexttoken} +% +% \unexpanded\def\graycolor [#1]{\bgroup +% \def\g_color{\colo_helpers_set_model\s!gray\colo_helpers_activate{#1}}% +% \afterassignment\g_color +% \let\nexttoken} +% +% \unexpanded\def\startcolor [#1]{\begingroup +% \colo_helpers_activate{#1}} +% +% \unexpanded\def\stopcolor {\endgroup} +% +% \unexpanded\def\colored [#1]{\bgroup +% \def\g_color{\colo_basics_defined_and_activated{#1}}% +% \afterassignment\g_color +% \let\nexttoken} +% +% \unexpanded\def\fastcolored[#1]#2{\begingroup % is this command still needed? +% \colo_basics_defined_and_activated{#1}% +% #2% +% \endgroup} +% +% \unexpanded\def\directcolored[#1]{\colo_basics_defined_and_activated{#1}} +% +% \unexpanded\def\fastcolor [#1]#2{\begingroup % is this command still needed? +% \colo_helpers_activate{#1}% +% #2% +% \endgroup} +% +% \unexpanded\def\directcolor [#1]{\colo_helpers_activate{#1}} +% +% \afterassignment was a left-over artifact + +% transparency + +\unexpanded\def\transparent[#1]% + {\bgroup + \edef\currenttransparencyname{#1}% + % the \relax catches a non existent csname + \ifx\currenttransparencyname\v!reset + \attribute\transparencyattribute\attributeunsetvalue + \else + \begincsname\??transparencysetter\currenttransparencyname\endcsname\relax + \fi + \let\nexttoken} + +\unexpanded\def\starttransparent[#1]%$ + {\begingroup + \edef\currenttransparencyname{#1}% + \ifx\currenttransparencyname\v!reset + \attribute\transparencyattribute\attributeunsetvalue + \else + \begincsname\??transparencysetter\currenttransparencyname\endcsname\relax + \fi} + +\unexpanded\def\stoptransparent + {\endgroup} + +% color + +\unexpanded\def\coloronly[#1]% + {\bgroup + \edef\currentcolorname{#1}% + \ifx\currentcolorprefix\empty + \colo_helpers_activate_nop_only + \else + \colo_helpers_activate_yes_only + \fi + \let\nexttoken} -\unexpanded\def\color [#1]{\bgroup - \def\g_color{\colo_helpers_activate{#1}}% - \afterassignment\g_color - \let\nexttoken} +\unexpanded\def\startcoloronly[#1]%$ + {\begingroup + \edef\currentcolorname{#1}% + \ifx\currentcolorprefix\empty + \colo_helpers_activate_nop_only + \else + \colo_helpers_activate_yes_only + \fi} + +\unexpanded\def\stopcoloronly + {\endgroup} -\unexpanded\def\graycolor [#1]{\bgroup - \def\g_color{\colo_helpers_set_model\s!gray\colo_helpers_activate{#1}}% - \afterassignment\g_color - \let\nexttoken} +% color + transparency -\unexpanded\def\startcolor [#1]{\begingroup - \colo_helpers_activate{#1}} +\unexpanded\def\color[#1]% + {\bgroup + \edef\currentcolorname{#1}% + \ifx\currentcolorprefix\empty + \colo_helpers_activate_nop + \else + \colo_helpers_activate_yes + \fi + \let\nexttoken} -\unexpanded\def\stopcolor {\endgroup} +\unexpanded\def\graycolor[#1]% + {\bgroup + \colo_helpers_set_model\s!gray\colo_helpers_activate{#1}% + \let\nexttoken} -\unexpanded\def\colored [#1]{\bgroup - \def\g_color{\colo_basics_defined_and_activated{#1}}% - \afterassignment\g_color - \let\nexttoken} +\unexpanded\def\startcolor[#1]%$ + {\begingroup + \edef\currentcolorname{#1}% + \ifx\currentcolorprefix\empty + \colo_helpers_activate_nop + \else + \colo_helpers_activate_yes + \fi} -\unexpanded\def\fastcolored[#1]#2{\begingroup % is this command still needed? - \colo_basics_defined_and_activated{#1}% - #2% - \endgroup} +\unexpanded\def\stopcolor + {\endgroup} -\unexpanded\def\directcolored[#1]{\colo_basics_defined_and_activated{#1}} +\unexpanded\def\colored[#1]% + {\bgroup + \colo_basics_defined_and_activated{#1}% + \let\nexttoken} -\unexpanded\def\fastcolor [#1]#2{\begingroup % is this command still needed? - \colo_helpers_activate{#1}% - #2% - \endgroup} +\unexpanded\def\fastcolored[#1]#2% + {\begingroup % is this command still needed? + \colo_basics_defined_and_activated{#1}% + #2% + \endgroup} -\unexpanded\def\directcolor [#1]{\colo_helpers_activate{#1}} +\unexpanded\def\directcolored[#1]% + {\colo_basics_defined_and_activated{#1}} +\unexpanded\def\fastcolor [#1]#2% + {\begingroup % is this command still needed? + \edef\currentcolorname{#1}% + \ifx\currentcolorprefix\empty + \colo_helpers_activate_nop + \else + \colo_helpers_activate_yes + \fi + #2% + \endgroup} + +\unexpanded\def\directcolor[#1]% + {\edef\currentcolorname{#1}% + \ifx\currentcolorprefix\empty + \colo_helpers_activate_nop + \else + \colo_helpers_activate_yes + \fi} %D The following command is obsolete: @@ -218,7 +333,6 @@ % \newtoks\everysetupcolors \let\v_colo_freeze_state\s!false -\let\v_colo_weight_state\s!false \setvalue{\??colorconversions\v!yes}% {\settrue \c_colo_convert_gray} @@ -232,16 +346,11 @@ % \doifelse{\directcolorsparameter\c!spot }\v!yes \settrue \setfalse\c_colo_spot_supported \doifelse{\directcolorsparameter\c!expansion}\v!yes \settrue \setfalse\c_colo_expanded - \doifelse{\directcolorsparameter\c!factor }\v!no \setfalse\settrue \c_colo_weight_gray \doifelse{\directcolorsparameter\c!rgb }\v!yes \settrue \setfalse\c_colo_rgb_supported \doifelse{\directcolorsparameter\c!cmyk }\v!yes \settrue \setfalse\c_colo_cmyk_supported \doifelse{\directcolorsparameter\c!state }\v!start\settrue \setfalse\c_colo_enabled % - \ifconditional\c_colo_weight_gray - \let\v_colo_weight_state\s!true - \else - \let\v_colo_weight_state\s!false - \fi + \edef\m_colo_weight_gray{\directcolorsparameter\c!factor}% % \ifconditional\c_colo_expanded \let\v_colo_freeze_state\s!true @@ -375,7 +484,9 @@ \def\colo_palet_prepare#1% {\edef\colo_palet_name{#1}% - \ifcsname\??paletlist\colo_palet_name\endcsname\else + \ifcsname\??paletlist\colo_palet_name\endcsname + \csname\??paletsize#1\endcsname\zerocount + \else \colo_palet_allocate\colo_palet_name \fi \edef\m_colo_palet{\begincsname\??paletlist\colo_palet_name\endcsname}% @@ -466,17 +577,37 @@ \unexpanded\def\setuppalet {\dosingleempty\colo_palets_setup} +% \def\colo_palets_setup[#1]% +% {\edef\currentcolorpalet{#1}% +% \ifx\currentcolorpalet\empty +% % seems to be a reset +% \let\currentcolorprefix\empty +% \else\ifcsname\??paletlist\currentcolorpalet\endcsname +% \edef\currentcolorprefix{#1:}% +% \else +% \colo_helpers_show_message\m!colors7\currentcolorpalet +% \let\currentcolorpalet\empty +% \let\currentcolorprefix\empty +% \fi\fi +% \the\everysetuppalet +% \colo_helpers_initialize_maintextcolor} + +\newtoks\t_colo_prefix % used in mp interface + \def\colo_palets_setup[#1]% {\edef\currentcolorpalet{#1}% \ifx\currentcolorpalet\empty % seems to be a reset \let\currentcolorprefix\empty + \t_colo_prefix\emptytoks \else\ifcsname\??paletlist\currentcolorpalet\endcsname \edef\currentcolorprefix{#1:}% + \t_colo_prefix\expandafter{\currentcolorprefix}% \else \colo_helpers_show_message\m!colors7\currentcolorpalet \let\currentcolorpalet\empty \let\currentcolorprefix\empty + \t_colo_prefix\emptytoks \fi\fi \the\everysetuppalet \colo_helpers_initialize_maintextcolor} @@ -550,20 +681,26 @@ %D %D These speak for themselves. See \type {colo-ext} for usage. +% \def\negatedcolorcomponent#1% +% {\ifdim\dimexpr\onepoint-#1\onepoint\relax<\zeropoint +% \!!zerocount +% \else +% \expandafter\withoutpt\the\dimexpr\onepoint-#1\onepoint\relax +% \fi} +% +% \unexpanded\def\negatecolorcomponent#1% #1 = \macro +% {\scratchdimen\onepoint\advance\scratchdimen-#1\onepoint +% \ifdim\scratchdimen<\zeropoint\scratchdimen\zeropoint\fi +% \edef#1{\withoutpt\the\scratchdimen}} +% +% \unexpanded\def\negatecolorcomponent#1% #1 = \macro +% {\edef#1{\negatedcolorcomponent{#1}}} + \unexpanded\def\negatecolorcomponent#1% #1 = \macro - {\scratchdimen\onepoint\advance\scratchdimen-#1\onepoint - \ifdim\scratchdimen<\zeropoint\scratchdimen\zeropoint\fi - \edef#1{\withoutpt\the\scratchdimen}} + {\edef#1{\clf_negatecolorcomponent{#1}}} \def\negatedcolorcomponent#1% - {\ifdim\dimexpr\onepoint-#1\onepoint\relax<\zeropoint - \!!zerocount - \else - \expandafter\withoutpt\the\dimexpr\onepoint-#1\onepoint\relax - \fi} - -\unexpanded\def\negatecolorcomponent#1% #1 = \macro - {\edef#1{\negatedcolorcomponent{#1}}} + {\clf_negatecolorcomponent{#1}} %D \macros %D {MPcolor} @@ -605,7 +742,7 @@ \def\colo_helpers_set_model#1% direct {\edef\currentcolormodel{#1}% - \clf_setcolormodel{\currentcolormodel}\v_colo_weight_state\relax} % sets attribute at lua end + \clf_setcolormodel{\currentcolormodel}{\m_colo_weight_gray}} % sets attribute at lua end \colo_helpers_set_model\s!all @@ -674,20 +811,24 @@ \csname\??transparencysetter#1\endcsname \fi} +\def\colo_helpers_activate_dummy + {\csname\??colorsetter \v_colo_dummy_name\endcsname + \csname\??transparencysetter\v_colo_dummy_name\endcsname} + \let\dofastcoloractivation\colo_helpers_fast_activate % so far -\def\colo_helpers_activate % two-step is not that much faster but less tracing - {\ifx\currentcolorprefix\empty +\def\colo_helpers_activate#1% two-step is not that much faster but less tracing + {\edef\currentcolorname{#1}% + \ifx\currentcolorprefix\empty \expandafter\colo_helpers_activate_nop \else \expandafter\colo_helpers_activate_yes \fi} -\def\colo_helpers_activate_yes#1% - {\edef\currentcolorname{#1}% - \ifcsname\??colorsetter\currentcolorprefix\currentcolorname\endcsname +\def\colo_helpers_activate_yes + {\ifcsname\??colorsetter\currentcolorprefix\currentcolorname\endcsname \lastnamedcs \csname\??transparencysetter\currentcolorprefix\currentcolorname\endcsname \else\ifcsname\??colorsetter\currentcolorname\endcsname @@ -695,16 +836,23 @@ \csname\??transparencysetter\currentcolorname\endcsname \fi\fi} -\def\colo_helpers_activate_nop#1% - {\edef\currentcolorname{#1}% - \ifcsname\??colorsetter\currentcolorname\endcsname +\def\colo_helpers_activate_nop + {\ifcsname\??colorsetter\currentcolorname\endcsname \lastnamedcs \csname\??transparencysetter\currentcolorname\endcsname \fi} -\def\colo_helpers_activate_dummy - {\csname\??colorsetter \v_colo_dummy_name\endcsname - \csname\??transparencysetter\v_colo_dummy_name\endcsname} +\def\colo_helpers_activate_yes_only + {\ifcsname\??colorsetter\currentcolorprefix\currentcolorname\endcsname + \lastnamedcs + \else\ifcsname\??colorsetter\currentcolorname\endcsname + \lastnamedcs + \fi\fi} + +\def\colo_helpers_activate_nop_only + {\ifcsname\??colorsetter\currentcolorname\endcsname + \lastnamedcs + \fi} \let\dousecolorparameter\colo_helpers_activate @@ -732,6 +880,23 @@ % todo: check if color is overloading a non-color command +% \let\colo_basics_synchronize\gobbleoneargument % used in mp interface +% \let\colo_basics_inherit \gobbletwoarguments % used in mp interface + +\def\colo_basics_allocate#1% + {\expandafter\newcount\csname\??colornumber#1\endcsname + \clf_synccolorcount{#1}\c_syst_last_allocated_count} + +\def\colo_basics_synchronize#1% + {\ifcsname\??colornumber#1\endcsname\else + \colo_basics_allocate{#1}% + \fi + \clf_synccolor{#1}% + %\csname\??colornumber#1\endcsname\csname\??colorattribute#1\endcsname + \lastnamedcs\csname\??colorattribute#1\endcsname} + +\let\colo_basics_inherit\clf_synccolorclone + \newcount\c_colo_protection \unexpanded\def\startprotectedcolors @@ -741,31 +906,43 @@ {\advance\c_colo_protection\minusone} \def\colo_basics_define[#1][#2]% - {\clf_defineprocesscolorlocal{#1}{#2}\v_colo_freeze_state\relax - \ifcase\c_colo_protection - \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}% + {\edef\m_colo_old{#1}% + \edef\m_colo_new{#2}% + \ifx\m_colo_old\m_colo_new + % maybe a warning + \else + \clf_defineprocesscolorlocal{#1}{#2}\v_colo_freeze_state\relax + \colo_basics_synchronize{#1}% + \ifcase\c_colo_protection + \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}% + \fi \fi} \def\colo_basics_define_global[#1][#2]% - {\clf_defineprocesscolorglobal{#1}{#2}\v_colo_freeze_state\relax - \ifcase\c_colo_protection - \unexpanded\setgvalue{#1}{\colo_helpers_activate{#1}}% + {\edef\m_colo_old{#1}% + \edef\m_colo_new{#2}% + \ifx\m_colo_old\m_colo_new + % maybe a warning + \else + \clf_defineprocesscolorglobal{#1}{#2}\v_colo_freeze_state\relax + \colo_basics_synchronize{#1}% + \ifcase\c_colo_protection + \unexpanded\setgvalue{#1}{\colo_helpers_activate{#1}}% + \fi \fi} -\def\colo_basics_define_named[#1][#2]% currently same as define - {\clf_defineprocesscolorlocal{#1}{#2}\v_colo_freeze_state\relax - \ifcase\c_colo_protection - \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}% - \fi} +\let\colo_basics_define_named\colo_basics_define \def\dodefinefastcolor[#1][#2]% still not fast but ok (might change) {\clf_defineprocesscolorlocal{#1}{#2}\v_colo_freeze_state\relax + \colo_basics_synchronize{#1}% \ifcase\c_colo_protection \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}% \fi} \def\colo_basics_defined_and_activated#1% - {\clf_defineprocesscolordummy{#1}% + {\clf_defineprocesscolordummy{#1}% we could pass dummy here too + \colo_basics_synchronize{d_u_m_m_y}% \colo_helpers_activate_dummy} \def\colo_basics_define_process @@ -777,12 +954,14 @@ \def\colo_basics_define_process_yes[#1][#2][#3]% {\clf_defineprocesscolorlocal{#1}{\processcolorcomponents{#2},#3}\v_colo_freeze_state\relax + \colo_basics_synchronize{#1}% \ifcase\c_colo_protection \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}% \fi} \def\colo_basics_define_process_nop[#1][#2][#3]% {\clf_defineprocesscolorlocal{#1}{#2}\v_colo_freeze_state\relax + \colo_basics_synchronize{#1}% \ifcase\c_colo_protection \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}% \fi} @@ -794,12 +973,14 @@ \def\colo_basics_define_spot[#1][#2][#3]% {\clf_definespotcolorglobal{#1}{#2}{#3}% + \colo_basics_synchronize{#1}% \ifcase\c_colo_protection \unexpanded\setgvalue{#1}{\colo_helpers_activate{#1}}% \fi} \def\colo_basics_define_multitone[#1][#2][#3][#4]% {\clf_definemultitonecolorglobal{#1}{#2}{#3}{#4}% + \colo_basics_synchronize{#1}% \ifcase\c_colo_protection \unexpanded\setgvalue{#1}{\colo_helpers_activate{#1}}% \fi} @@ -807,7 +988,10 @@ %D Transparencies (only): \def\colo_basics_define_transpancy[#1][#2]% - {\clf_definetransparency{#1}#2\relax} + {\clf_definetransparency{#1}{#2}} + +\def\colo_basics_define_transpancy_global[#1][#2]% + {\clf_definetransparencyglobal{#1}{#2}} % A goodie that replaces the startMPcolor hackery @@ -860,14 +1044,16 @@ \def\colo_basics_define_intermediate_indeed[#1][#2,#3,#4][#5]% {\clf_defineintermediatecolor % not global - {#1}{#2}% - \thecolorattribute{#3} % - \thecolorattribute{#4} % - \thetransparencyattribute{#3} % - \thetransparencyattribute{#4} % + {#1}% + {#2}% + \rawcolorattribute{#3} % + \rawcolorattribute{#4} % + \rawtransparencyattribute{#3} % + \rawtransparencyattribute{#4} % {#5}% \v_colo_freeze_state \relax + \colo_basics_synchronize{#1}% \unexpanded\setvalue{#1}{\colo_helpers_activate{#1}}} %D Here is a more efficient helper for pgf: @@ -1017,11 +1203,6 @@ \letvalue{\??colorsetter }\empty \letvalue{\??colorattribute }\!!zerocount \letvalue{\??transparencysetter}\empty \letvalue{\??transparencyattribute}\!!zerocount -%def\colo_helpers_inherited_direct_cs#1{\csname\??colorsetter \ifcsname\??colorsetter #1\endcsname#1\fi\endcsname} -%def\colo_helpers_inherited_direct_ca#1{\csname\??colorattribute \ifcsname\??colorattribute #1\endcsname#1\fi\endcsname} -%def\colo_helpers_inherited_direct_ts#1{\csname\??transparencysetter \ifcsname\??transparencysetter #1\endcsname#1\fi\endcsname} -%def\colo_helpers_inherited_direct_ta#1{\csname\??transparencyattribute\ifcsname\??transparencyattribute#1\endcsname#1\fi\endcsname} - \def\colo_helpers_inherited_direct_cs#1{\ifcsname\??colorsetter #1\endcsname\lastnamedcs\fi} \def\colo_helpers_inherited_direct_ca#1{\ifcsname\??colorattribute #1\endcsname\lastnamedcs\else\!!zerocount\fi} \def\colo_helpers_inherited_direct_ts#1{\ifcsname\??transparencysetter #1\endcsname\lastnamedcs\fi} @@ -1047,26 +1228,6 @@ \fi \to \everysetupcolors -% \def\colo_palets_define_set#1#2#3% -% {\doifelseassignment{#3}% \definepalet[test][xx={y=.4}] -% {\definecolor[\??colorpalet#1:#2][#3]% -% \colo_helpers_set_value{\??colorsetter #1:#2}{\colo_helpers_inherited_palet_ca{#1}{#2}}% -% \colo_helpers_set_value{\??colorattribute #1:#2}{\colo_helpers_inherited_palet_cs{#1}{#2}}% -% \colo_helpers_set_value{\??transparencysetter #1:#2}{\colo_helpers_inherited_palet_ta{#1}{#2}}% -% \colo_helpers_set_value{\??transparencyattribute#1:#2}{\colo_helpers_inherited_palet_ts{#1}{#2}}} -% {\ifcsname\??colorsetter#3\endcsname % \definepalet[test][xx=green] -% \colo_helpers_set_value{\??colorsetter #1:#2}{\colo_helpers_inherited_direct_cs{#3}}% -% \colo_helpers_set_value{\??colorattribute #1:#2}{\colo_helpers_inherited_direct_ca{#3}}% -% \colo_helpers_set_value{\??transparencysetter #1:#2}{\colo_helpers_inherited_direct_ts{#3}}% -% \colo_helpers_set_value{\??transparencyattribute#1:#2}{\colo_helpers_inherited_direct_ta{#3}}% -% \else -% % not entered when making format -% \localundefine{\??colorsetter #1:#2}% -% \localundefine{\??colorattribute #1:#2}% -% \localundefine{\??transparencysetter #1:#2}% -% \localundefine{\??transparencyattribute#1:#2}% -% \fi}} - \def\colo_palets_define_set#1#2#3% {\doifelseassignment{#3}% \definepalet[test][xx={y=.4}] {\colo_palets_define_assign}% @@ -1080,7 +1241,8 @@ {#1}{#2}{#3}} \def\colo_palets_define_inherit#1#2#3% - {\colo_helpers_set_value{\??colorsetter #1:#2}{\colo_helpers_inherited_direct_cs{#3}}% + {\colo_basics_inherit{#1:#2}{#3}% + \colo_helpers_set_value{\??colorsetter #1:#2}{\colo_helpers_inherited_direct_cs{#3}}% \colo_helpers_set_value{\??colorattribute #1:#2}{\colo_helpers_inherited_direct_ca{#3}}% \colo_helpers_set_value{\??transparencysetter #1:#2}{\colo_helpers_inherited_direct_ts{#3}}% \colo_helpers_set_value{\??transparencyattribute#1:#2}{\colo_helpers_inherited_direct_ta{#3}}} @@ -1176,12 +1338,14 @@ \colo_helpers_inherited_current_ca{#1} % \colo_helpers_inherited_current_ta{#1} } - \def\thecolormodelattribute {\the\attribute\colormodelattribute} %def\thecolorattribute #1{\number\csname\??colorattribute \ifcsname\??colorattribute \currentcolorprefix#1\endcsname\currentcolorprefix#1\else\ifcsname\??colorattribute #1\endcsname#1\fi\fi\endcsname} %def\thetransparencyattribute#1{\number\csname\??transparencyattribute\ifcsname\??transparencyattribute\currentcolorprefix#1\endcsname\currentcolorprefix#1\else\ifcsname\??transparencyattribute#1\endcsname#1\fi\fi\endcsname} +\def\rawcolorattribute #1{\ifcsname\??colorattribute \currentcolorprefix#1\endcsname\lastnamedcs\else\ifcsname\??colorattribute #1\endcsname\lastnamedcs\else\zerocount\fi\fi} +\def\rawtransparencyattribute#1{\ifcsname\??transparencyattribute\currentcolorprefix#1\endcsname\lastnamedcs\else\ifcsname\??transparencyattribute#1\endcsname\lastnamedcs\else\zerocount\fi\fi} + \def\thecolorattribute #1{\number\ifcsname\??colorattribute \currentcolorprefix#1\endcsname\lastnamedcs\else\ifcsname\??colorattribute #1\endcsname\lastnamedcs\else\zerocount\fi\fi} \def\thetransparencyattribute#1{\number\ifcsname\??transparencyattribute\currentcolorprefix#1\endcsname\lastnamedcs\else\ifcsname\??transparencyattribute#1\endcsname\lastnamedcs\else\zerocount\fi\fi} \def\internalspotcolorname #1{\clf_spotcolorname \thecolorattribute{#1} } diff --git a/tex/context/base/mkiv/colo-run.lua b/tex/context/base/mkiv/colo-run.lua index 6368b3307..2e4cca5ab 100644 --- a/tex/context/base/mkiv/colo-run.lua +++ b/tex/context/base/mkiv/colo-run.lua @@ -9,11 +9,12 @@ if not modules then modules = { } end modules ['colo-run'] = { -- For historic reasons the core has a couple of tracing features. Nowadays -- these would end up in modules. -local colors, commands, context, utilities = colors, commands, context, utilities +local utilities = utilities +local commands = commands +local context = context +local colors = attributes.colors -local colors = attributes.colors - -local private = table.tohash { "d_u_m_m_y", "maintextcolor", "themaintextcolor" } +local private = table.tohash { "d_u_m_m_y", "maintextcolor", "themaintextcolor" } function commands.showcolorset(name) local set = colors.setlist(name) diff --git a/tex/context/base/mkiv/cont-fil.mkiv b/tex/context/base/mkiv/cont-fil.mkiv index 19c1c93ac..e2c7f401e 100644 --- a/tex/context/base/mkiv/cont-fil.mkiv +++ b/tex/context/base/mkiv/cont-fil.mkiv @@ -12,7 +12,7 @@ %C details. % todo: use full names and remove calls at the tex end (now integrated in -% lua library code +% lua library code .. then we can load it at runtime when needed. \writestatus{loading}{ConTeXt File Synonyms} @@ -45,25 +45,34 @@ \definefilesynonym [res-log] [res-09] \definefilesynonym [res-identify] [res-12] -\definefilesynonym [med-show] [res-50] + \definefilesynonym [med-show] [res-50] \definefilesynonym [pre-general] [pre-00] - -\definefilesynonym [pre-original] [pre-01] -\definefilesynonym [pre-green] [pre-02] -\definefilesynonym [pre-funny] [pre-03] -\definefilesynonym [pre-colorful] [pre-04] -\definefilesynonym [pre-fuzzy] [pre-05] +\definefilesynonym [pre-01] [present-original] +\definefilesynonym [pre-original] [present-original] +\definefilesynonym [pre-02] [present-green] +\definefilesynonym [pre-green] [present-green] +\definefilesynonym [pre-03] [present-funny] +\definefilesynonym [pre-funny] [present-funny] +\definefilesynonym [pre-04] [present-colorful] +\definefilesynonym [pre-colorful] [present-colorful] +\definefilesynonym [pre-05] [present-fuzzy] +\definefilesynonym [pre-fuzzy] [present-fuzzy] \definefilesynonym [pre-polish] [pre-06] \definefilesynonym [pre-spider] [pre-07] \definefilesynonym [pre-wonder] [pre-08] -\definefilesynonym [pre-windows] [pre-09] -\definefilesynonym [pre-grow] [pre-10] -\definefilesynonym [pre-stack] [pre-11] +\definefilesynonym [pre-09] [present-windows] +\definefilesynonym [pre-windows] [present-windows] +\definefilesynonym [pre-10] [present-grow] +\definefilesynonym [pre-grow] [present-grow] +\definefilesynonym [pre-11] [present-stack] +\definefilesynonym [pre-stack] [present-stack] \definefilesynonym [pre-arrows] [pre-12] \definefilesynonym [pre-writing] [pre-13] -\definefilesynonym [pre-split] [pre-14] -\definefilesynonym [pre-balls] [pre-15] +\definefilesynonym [pre-split] [present-split] +\definefilesynonym [pre-14] [present-split] +\definefilesynonym [pre-balls] [present-balls] +\definefilesynonym [pre-15] [present-balls] \definefilesynonym [pre-knot] [pre-16] \definefilesynonym [pre-weird] [pre-17] \definefilesynonym [pre-shade] [pre-18] @@ -72,7 +81,6 @@ \definefilesynonym [pre-zoom] [pre-21] \definefilesynonym [pre-cycle] [pre-22] \definefilesynonym [pre-super] [pre-23] - %definefilesynonym [pre-more] [pre-24] %definefilesynonym [pre-more] [pre-25] \definefilesynonym [pre-more] [pre-26] @@ -80,14 +88,17 @@ %definefilesynonym [pre-more] [pre-28] %definefilesynonym [pre-more] [pre-29] %definefilesynonym [pre-more] [pre-30] - -\definefilesynonym [pre-tiles] [pre-41] - -\definefilesynonym [pre-stepwise] [pre-60] -\definefilesynonym [pre-stepper] [pre-61] - -\definefilesynonym [pre-punk] [pre-70] -\definefilesynonym [pre-random] [pre-71] +\definefilesynonym [pre-41] [present-tiles] +\definefilesynonym [pre-60] [present-stepwise] +\definefilesynonym [pre-stepwise] [present-stepwise] +\definefilesynonym [pre-61] [present-stepper] +\definefilesynonym [pre-stepper] [present-stepper] +\definefilesynonym [pre-62] [present-overlap] +\definefilesynonym [pre-69] [present-wobbling] +\definefilesynonym [pre-punk] [present-punk] +\definefilesynonym [pre-70] [present-punk] +\definefilesynonym [pre-random] [present-random] +\definefilesynonym [pre-71] [present-random] \definefilesynonym [abr-pseudocaps] [abr-01] \definefilesynonym [abr-smallcaps] [abr-02] diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 8e4d59750..ea14b4c7b 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2016.05.19 13:43} +\newcontextversion{2017.05.14 19:09} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/mkiv/cont-run.lua b/tex/context/base/mkiv/cont-run.lua index 0420ed01c..2225a0fb2 100644 --- a/tex/context/base/mkiv/cont-run.lua +++ b/tex/context/base/mkiv/cont-run.lua @@ -90,7 +90,7 @@ local function logsandbox(details) end end -local ioopen = sandbox.original(io.open) +local ioopen = sandbox.original(io.open) -- dummy call local function logsandboxfiles(name,what,asked,okay) -- we're only interested in permitted access @@ -161,14 +161,13 @@ if sandboxing then -- Nicer would be if we could just disable write 18 and keep os.execute -- which in fact we can do by defining write18 as macro instead of - -- primitive ... todo. + -- primitive ... todo ... well, it has been done now. -- We block some potential escapes from protection. context [[ \let\primitive \relax \let\normalprimitive\relax - \let\normalwrite \relax ]] end @@ -181,6 +180,10 @@ local function processjob() local suffix = environment.suffix local filename = environment.filename -- hm, not inputfilename ! + if arguments.synctex then + directives.enable("system.synctex="..tostring(arguments.synctex)) + end + if not filename or filename == "" then -- skip elseif suffix == "xml" or arguments.forcexml then diff --git a/tex/context/base/mkiv/cont-run.mkiv b/tex/context/base/mkiv/cont-run.mkiv index fcca7b581..490c6bee2 100644 --- a/tex/context/base/mkiv/cont-run.mkiv +++ b/tex/context/base/mkiv/cont-run.mkiv @@ -15,6 +15,7 @@ \unprotect +\registerctxluafile{node-syn}{1.001} \registerctxluafile{cont-run}{1.001} \protect \endinput diff --git a/tex/context/base/mkiv/context-todo.tex b/tex/context/base/mkiv/context-todo.tex index 0cbd94814..a356d5964 100644 --- a/tex/context/base/mkiv/context-todo.tex +++ b/tex/context/base/mkiv/context-todo.tex @@ -1,18 +1,102 @@ -% language=uk +\setuplayout + [width=middle, + height=middle, + topspace=2cm, + header=0pt, + footer=1cm] -\usemodule[art-01,abr-01] +\setupbodyfont + [bookman] + +\usemodule + [punk,abr-02] + +\setuphead + [section] + [color=ColorThree, + style=\bfb] + +\setupitemgroup + [itemize] [each] + [packed] [color=ColorThree,symcolor=ColorThree] + +\setupfooter + [color=ColorThree, + style=bold] + +\setupfootertexts + [pagenumber] + +\setupwhitespace + [big] + +\definefont[PunkFont][demo@punk at 20pt] + +% \def\aterm{\sym{?}} +% \def\rterm{\sym{--}} +% \def\dterm{\sym{+}} +% \def\pterm{\sym{!}} +% +% \startitemize[packed] +% \aterm on the agenda (update, extension, rewrite) +% \rterm no longer on the agenda, rejected +% \dterm no longer on the agenda, done +% \pterm work in progress (so keep an eye on the betas) +% \stopitemize + +\definecolor[ColorOne] [c=0.5,m=0.2,y=0.5,k=0.2] +\definecolor[ColorTwo] [c=0.5,m=0.5,y=0.1,k=0.1] +\definecolor[ColorThree][c=0.1,m=1.0,y=1.0,k=0.2] \starttext -\subject {On the agenda} +\startMPpage + StartPage ; + numeric n ; n := 200 ; + numeric o ; o := 25 ; + + pair p[] ; + for i=1 upto n : + p[i] = (o + uniformdeviate (PaperWidth-2*o), o + uniformdeviate (PaperHeight-2*o)) ; + endfor ; + + picture d ; d := image ( for i=1 upto n : draw p[i] ; endfor ) ; + picture l ; l := image ( draw for i=1 upto n : if i > 1 : -- fi p[i] endfor ) ; + picture t ; t := textext("\framed[frame=off,align={middle,lohi},foregroundcolor=ColorThree,foregroundstyle=\PunkFont]{\ConTeXt\endgraf MkIV\endgraf\kern-\strutdepth RoadMap}") ; + + fill Page enlarged 10 withcolor "ColorOne" ; + + draw d withcolor white withpen pencircle scaled o ; + draw d withcolor "ColorTwo" withpen pencircle scaled (o - 5) ; + draw l withcolor white withpen pencircle scaled (o / 5) ; + draw l withcolor "ColorTwo" withpen pencircle scaled (o /10) ; + draw thelabel.ulft(t xsized .5PaperWidth,lrcorner Page shifted - (PaperWidth/20,-PaperWidth/40)) ; + StopPage ; +\stopMPpage + + +\startsubject[title={Introduction}] + +There is not really a long term roadmap for development. One reason is that there is already +a lot available. When we started with \LUATEX, the \CONTEXT\ code was mostly rewritten, +and that process is more of less finished. Of course there is always work left. + +This file is not a complete overview of our plans but users can at least get an +idea of what we're working on and what is coming. Feel free to submit +suggestions. + +\startlines +Hans Hagen +Hasselt NL +\currentdate +\stoplines -\subsubject{\LUATEX} +\stopsubject + +\startsubject[title={On the agenda for \LUATEX}] \startitemize \startitem - head||tail cleanup in disc nodes (get rid of temp i.e.\ delay till linebreak) - \stopitem - \startitem cleanup passive nodes \stopitem \startitem @@ -26,9 +110,6 @@ {texlang.w} and also store the \type {*mins} \stopitem \startitem - get rid of \type {temp} node in hyphenator i.e. postpone to when needed - \stopitem - \startitem remove local par in head of line when done with linebreak \stopitem \startitem @@ -36,20 +117,29 @@ (also check redundant \type {delete_attribute_ref} after \type {new_glue}) \stopitem \startitem - implement \type {\hyphenationbounds} + only return nil when we expect multiple calls in in one line \stopitem \startitem - only return nil when we expect multiple calls in in one line + pdf injection in virtual characters (currently qQ interferes with font switch + flushing) so a pdf page hack is needed \stopitem \stopitemize -\subsubject{\CONTEXT} +\stopsubject + +\startsubject[title={On the agenda for \CONTEXT\ \MKIV}] \startitemize \startitem play with par callback and properties \stopitem \startitem + optimize positions for columnareas and parpos (sequential) + \stopitem + \startitem + add flag to font for math engine + \stopitem + \startitem get rid of components \stopitem \startitem @@ -66,30 +156,11 @@ reorganize position data (more subtables) \stopitem \startitem - use \type {\matheqnogapstep}, \type {\Ustack}, \type {\mathscriptsmode}, \ + use \type {\matheqnogapstep}, \type {\Ustack}, \type {\mathscriptsmode}, \type {\mathdisplayskipmode} and other new math primitives \stopitem \stopitemize -\vfill {\em Feel free to suggest additions.} +\stopsubject \stoptext - -% also - -check components and pre|post|replace in math-tag - -% new: - -<cd:command name="showgrid" file="page-grd.mkiv"> - ... - <cd:constant type="columns" default="yes"/> - ... -</cd:command> - -<cd:command name="itemtag" variant="itemgroup" file="strc-itm.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - </cd:arguments> -</cd:command> - diff --git a/tex/context/base/mkiv/context.css b/tex/context/base/mkiv/context.css index be1dad796..b0aa38573 100644 --- a/tex/context/base/mkiv/context.css +++ b/tex/context/base/mkiv/context.css @@ -18,6 +18,9 @@ a.dir-view:link, a.dir-view:active, a.dir-view:visited { .invalid { color: #FF0000 ; } +.invisible { + visibility: hidden ; +} button, .commonlink, .smallbutton { font-weight: bold ; font-size: 12px ; diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index e0bd762a9..3d521d98c 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -39,8 +39,8 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2016.05.19 13:43} -\edef\contextkind {current} +\edef\contextversion{2017.05.14 19:09} +\edef\contextkind {beta} %D For those who want to use this: @@ -145,6 +145,8 @@ \loadmarkfile{cldf-int} % interface +\loadmarkfile{trac-ctx} % maybe move up + % \loadmarkfile{luat-ini} \loadmarkfile{toks-tra} @@ -175,7 +177,6 @@ \loadmarkfile{trac-tex} \loadmarkfile{trac-deb} % will move up -\loadmarkfile{trac-ctx} % maybe move up %loadmarkfile{blob-ini} % not to be used, we only use a helper @@ -402,6 +403,7 @@ \loadmarkfile{tabl-ntb} \loadmarkfile{tabl-nte} \loadmarkfile{tabl-ltb} +\loadmarkfile{tabl-frm} \loadmarkfile{tabl-tsp} \loadmkvifile{tabl-xtb} \loadmarkfile{tabl-mis} @@ -433,12 +435,16 @@ \loadmarkfile{typo-sus} \loadmarkfile{typo-lig} \loadmarkfile{typo-chr} +\loadmarkfile{typo-rub} +\loadmkivfile{typo-fkr} \loadmkvifile{type-ini} \loadmarkfile{type-set} \loadmarkfile{scrp-ini} +\loadmarkfile{symb-emj} + \loadmarkfile{lang-wrd} % can be optional (discussion with mm sideeffect) \loadmarkfile{lang-rep} % can be optional (bt 2013 side effect) @@ -509,6 +515,7 @@ \loadmarkfile{grph-fig} \loadmarkfile{grph-raw} \loadmarkfile{grph-rul} +\loadmarkfile{grph-pat} \loadmarkfile{pack-box} \loadmarkfile{pack-bar} @@ -571,7 +578,7 @@ \to \everyjob \appendtoks - \ctxlua{statistics.savefmtstatus("\jobname","\contextversion","context.mkiv","\contextkind")}% can become automatic + \ctxlua{statistics.savefmtstatus("\jobname","\contextversion","context.mkiv","\contextkind","\contextbanner")}% can become automatic \to \everydump \errorstopmode \dump \endinput diff --git a/tex/context/base/mkiv/core-con.lua b/tex/context/base/mkiv/core-con.lua index 6913ac569..10f8fc2ed 100644 --- a/tex/context/base/mkiv/core-con.lua +++ b/tex/context/base/mkiv/core-con.lua @@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['core-con'] = { license = "see context related readme files" } --- todo: split into char-lan.lua and core-con.lua +-- todo: split into lang-con.lua and core-con.lua --[[ldx-- <p>This module implements a bunch of conversions. Some are more @@ -42,6 +42,13 @@ local converters = converters languages = languages or { } local languages = languages +local ctx_labeltext = context.labeltext +local ctx_LABELTEXT = context.LABELTEXT +local ctx_WORD = context.WORD +local ctx_space = context.space +local ctx_convertnumber = context.convertnumber +local ctx_highordinalstr = context.highordinalstr + converters.number = tonumber converters.numbers = tonumber @@ -74,6 +81,14 @@ local counters = allocate { 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A }, + ['russian'] = { + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, + 0x0435, 0x0436, 0x0437, 0x0438, 0x043a, + 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, + 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, + 0x044d, 0x044e, 0x044f + }, ['greek'] = { -- this should be the lowercase table -- 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, -- 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, @@ -146,6 +161,7 @@ counters['gr'] = counters['greek'] counters['g'] = counters['greek'] counters['sl'] = counters['slovenian'] counters['es'] = counters['spanish'] +counters['ru'] = counters['russian'] counters['kr'] = counters['korean'] counters['kr-p'] = counters['korean-parenthesis'] counters['kr-c'] = counters['korean-circle'] @@ -165,6 +181,7 @@ counters['koreancirclenumerals'] = counters['korean-circle'] counters['sloveniannumerals'] = counters['slovenian'] counters['spanishnumerals'] = counters['spanish'] +counters['russiannumerals'] = counters['russian'] local decimals = allocate { ['arabic'] = { @@ -582,23 +599,29 @@ converters['A'] = converters.Characters converters['AK'] = converters.Characters -- obsolete converters['KA'] = converters.Characters -- obsolete -function converters.spanishnumerals(n) return alphabetic(n,"es") end -function converters.Spanishnumerals(n) return Alphabetic(n,"es") end -function converters.sloviannumerals(n) return alphabetic(n,"sl") end -function converters.Sloviannumerals(n) return Alphabetic(n,"sl") end +function converters.spanishnumerals (n) return alphabetic(n,"es") end +function converters.Spanishnumerals (n) return Alphabetic(n,"es") end +function converters.sloveniannumerals(n) return alphabetic(n,"sl") end +function converters.Sloveniannumerals(n) return Alphabetic(n,"sl") end +function converters.russiannumerals (n) return alphabetic(n,"ru") end +function converters.Russiannumerals (n) return Alphabetic(n,"ru") end converters['alphabetic:es'] = converters.spanishnumerals converters['alphabetic:sl'] = converters.sloveniannumerals +converters['alphabetic:ru'] = converters.russiannumerals converters['Alphabetic:es'] = converters.Spanishnumerals converters['Alphabetic:sl'] = converters.Sloveniannumerals +converters['Alphabetic:ru'] = converters.Russiannumerals -- bonus converters['a:es'] = converters.spanishnumerals converters['a:sl'] = converters.sloveniannumerals +converters['a:ru'] = converters.russiannumerals converters['A:es'] = converters.Spanishnumerals converters['A:sl'] = converters.Sloveniannumerals +converters['A:ru'] = converters.Russiannumerals -- end of bonus @@ -683,94 +706,104 @@ implement { -- -- the original. -- -- -- -- Conversion by Hans Hagen --- --- local g_days_in_month = { [0]=31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } --- local j_days_in_month = { [0]=31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 } --- --- local function div(a,b) --- return math.floor(a/b) --- end --- --- local function remainder(a,b) --- return a - div(a,b)*b --- end --- --- function gregorian_to_jalali(gy,gm,gd) --- local jy, jm, jd, g_day_no, j_day_no, j_np, i --- gy, gm, gd = gy - 1600, gm - 1, gd - 1 --- g_day_no = 365*gy + div((gy+3),4) - div((gy+99),100) + div((gy+399),400) --- i = 0 --- while i < gm do --- g_day_no = g_day_no + g_days_in_month[i] --- i = i + 1 --- end --- if (gm>1 and ((gy%4==0 and gy%100~=0) or (gy%400==0))) then --- g_day_no = g_day_no + 1 --- end --- g_day_no = g_day_no + gd --- j_day_no = g_day_no - 79 --- j_np = div(j_day_no,12053) --- j_day_no = remainder(j_day_no,12053) --- jy = 979 + 33*j_np + 4*div(j_day_no,1461) --- j_day_no = remainder(j_day_no,1461) --- if j_day_no >= 366 then --- jy = jy + div((j_day_no-1),365) --- j_day_no = remainder((j_day_no-1),365) --- end --- i = 0 --- while i < 11 and j_day_no >= j_days_in_month[i] do --- j_day_no = j_day_no - j_days_in_month[i] --- i = i + 1 --- end --- jm = i + 1 --- jd = j_day_no + 1 --- return jy, jm, jd --- end --- --- function jalali_to_gregorian(jy,jm,jd) --- local gy, gm, gd, g_day_no, j_day_no, leap, i --- jy, jm, jd = jy - 979, jm - 1, jd - 1 --- j_day_no = 365*jy + div(jy,33)*8 + div((remainder(jy,33)+3),4) --- i = 0 --- while i < jm do --- j_day_no = j_day_no + j_days_in_month[i] --- i = i + 1 --- end --- j_day_no = j_day_no + jd --- g_day_no = j_day_no + 79 --- gy = 1600 + 400*div(g_day_no,146097) --- g_day_no = remainder (g_day_no, 146097) --- leap = 1 --- if g_day_no >= 36525 then --- g_day_no = g_day_no - 1 --- gy = gy + 100*div(g_day_no,36524) --- g_day_no = remainder (g_day_no, 36524) --- if g_day_no >= 365 then --- g_day_no = g_day_no + 1 --- else --- leap = 0 --- end --- end --- gy = gy + 4*div(g_day_no,1461) --- g_day_no = remainder (g_day_no, 1461) --- if g_day_no >= 366 then --- leap = 0 --- g_day_no = g_day_no - 1 --- gy = gy + div(g_day_no, 365) --- g_day_no = remainder(g_day_no, 365) --- end --- i = 0 --- while g_day_no >= g_days_in_month[i] + ((i == 1 and leap) or 0) do --- g_day_no = g_day_no - g_days_in_month[i] + ((i == 1 and leap) or 0) --- i = i + 1 --- end --- gm = i + 1 --- gd = g_day_no + 1 --- return gy, gm, gd + +local g_days_in_month = { [0] = 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +local j_days_in_month = { [0] = 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 } + +local div = math.div +local mod = math.mod + +function gregorian_to_jalali(gy,gm,gd) + local jy, jm, jd, g_day_no, j_day_no, j_np, i + gy, gm, gd = gy - 1600, gm - 1, gd - 1 + g_day_no = 365*gy + div((gy+3),4) - div((gy+99),100) + div((gy+399),400) + i = 0 + while i < gm do + g_day_no = g_day_no + g_days_in_month[i] + i = i + 1 + end + if (gm>1 and ((gy%4==0 and gy%100~=0) or (gy%400==0))) then + g_day_no = g_day_no + 1 + end + g_day_no = g_day_no + gd + j_day_no = g_day_no - 79 + j_np = div(j_day_no,12053) + j_day_no = mod(j_day_no,12053) + jy = 979 + 33*j_np + 4*div(j_day_no,1461) + j_day_no = mod(j_day_no,1461) + if j_day_no >= 366 then + jy = jy + div((j_day_no-1),365) + j_day_no = mod((j_day_no-1),365) + end + i = 0 + while i < 11 and j_day_no >= j_days_in_month[i] do + j_day_no = j_day_no - j_days_in_month[i] + i = i + 1 + end + jm = i + 1 + jd = j_day_no + 1 + return jy, jm, jd +end + +function jalali_to_gregorian(jy,jm,jd) + local gy, gm, gd, g_day_no, j_day_no, leap, i + jy, jm, jd = jy - 979, jm - 1, jd - 1 + j_day_no = 365*jy + div(jy,33)*8 + div((mod(jy,33)+3),4) + for i=0,jm-1,1 do + j_day_no = j_day_no + j_days_in_month[i] + end + j_day_no = j_day_no + jd + g_day_no = j_day_no + 79 + gy = 1600 + 400*div(g_day_no,146097) + g_day_no = mod(g_day_no, 146097) + leap = 1 + if g_day_no >= 36525 then + g_day_no = g_day_no - 1 + gy = gy + 100*div(g_day_no,36524) + g_day_no = mod(g_day_no, 36524) + if g_day_no >= 365 then + g_day_no = g_day_no + 1 + else + leap = 0 + end + end + gy = gy + 4*div(g_day_no,1461) + g_day_no = mod(g_day_no, 1461) + if g_day_no >= 366 then + leap = 0 + g_day_no = g_day_no - 1 + gy = gy + div(g_day_no, 365) + g_day_no = mod(g_day_no, 365) + end + i = 0 + while true do + local d = g_days_in_month[i] + ((i == 1 and leap) or 0) + if g_day_no >= d then + g_day_no = g_day_no - d + i = i + 1 + else + break + end + end + gm = i + 1 + gd = g_day_no + 1 + return gy, gm, gd +end + +-- local function test(yg,mg,dg,yj,mj,dj) +-- local y1, m1, d1 = jalali_to_gregorian(yj,mj,dj) +-- local y2, m2, d2 = gregorian_to_jalali(yg,mg,dg) +-- print(y1 == yg and m1 == mg and d1 == dg, yg,mg,dg, y1,m1,d1) +-- print(y2 == yj and m2 == mj and d2 == dj, yj,mj,dj, y2,m2,d2) -- end --- --- print(gregorian_to_jalali(2009,02,24)) --- print(jalali_to_gregorian(1387,12,06)) + +-- test(1953,08,19, 1332,05,28) +-- test(1979,02,11, 1357,11,22) +-- test(2000,02,28, 1378,12,09) +-- test(2000,03,01, 1378,12,11) +-- test(2009,02,24, 1387,12,06) +-- test(2015,03,21, 1394,01,01) +-- test(2016,03,20, 1395,01,01) -- -- more efficient but needs testing @@ -850,7 +883,7 @@ local function ctxordinal(n,language) local o = t and t(n) context(n) if o then - context.highordinalstr(o) + ctx_highordinalstr(o) end end @@ -1204,25 +1237,25 @@ end implement { name = "dayname", - actions = { dayname, context.labeltext }, + actions = { dayname, ctx_labeltext }, arguments = "integer", } implement { name = "weekdayname", - actions = { weekdayname, context.labeltext }, + actions = { weekdayname, ctx_labeltext }, arguments = { "integer", "integer", "integer" } } implement { name = "monthname", - actions = { monthname, context.labeltext }, + actions = { monthname, ctx_labeltext }, arguments = { "integer" } } implement { name = "monthmnem", - actions = { monthmnem, context.labeltext }, + actions = { monthmnem, ctx_labeltext }, arguments = { "integer" } } @@ -1241,6 +1274,16 @@ local spaced = { [v_day] = true, } +local dateconverters = { + ["jalali:to"] = gregorian_to_jalali, + ["jalali:from"] = jalali_to_gregorian, +} + +local variants = { + mnem = monthmnems, + jalali = setmetatableindex(function(t,k) return months[k] .. ":jalali" end), +} + local function currentdate(str,currentlanguage) -- second argument false : no label local list = utilities.parsers.settings_to_array(str) local splitlabel = languages.labels.split or string.itself -- we need to get the loading order right @@ -1253,89 +1296,96 @@ local function currentdate(str,currentlanguage) -- second argument false : no la end for i=1,#list do local entry = list[i] - local tag, plus = splitlabel(entry) - local ordinal, mnemonic, whatordinal, highordinal = false, false, nil, false - if not tag then - tag = entry - elseif plus == "+" or plus == "ord" then - ordinal = true - elseif plus == "++" or plus == "highord" then - ordinal = true - highordinal = true - elseif plus == "mnem" then - mnemonic = true - end - if not auto and spaced[tag] then - context.space() - end - auto = false - if tag == v_year or tag == "y" or tag == "Y" then - context(year) - elseif tag == "yy" or tag == "YY" then - context("%02i",year % 100) - elseif tag == v_month or tag == "m" then - if currentlanguage == false then - context(months[month]) - elseif mnemonic then - context.labeltext(variables[monthmnems[month]]) - else - context.labeltext(variables[months[month]]) - end - elseif tag == v_MONTH then - if currentlanguage == false then - context.WORD(variables[months[month]]) - elseif mnemonic then - context.LABELTEXT(variables[monthmnems[month]]) - else - context.LABELTEXT(variables[months[month]]) + local convert = dateconverters[entry] + if convert then + year, month, day = convert(year,month,day) + else + local tag, plus = splitlabel(entry) + local ordinal, mnemonic, whatordinal, highordinal = false, false, nil, false + if not tag then + tag = entry + elseif plus == "+" or plus == "ord" then + ordinal = true + elseif plus == "++" or plus == "highord" then + ordinal = true + highordinal = true + -- elseif plus == "mnem" then + -- mnemonic = true + elseif plus then -- elseif plus == "mnem" then + mnemonic = variants[plus] end - elseif tag == "mm" then - context("%02i",month) - elseif tag == "M" then - context(month) - elseif tag == v_day or tag == "d" then - if currentlanguage == false then - context(days[day]) - else - context.convertnumber(v_day,day) -- why not direct + if not auto and spaced[tag] then + ctx_space() end - whatordinal = day - elseif tag == "dd" then - context("%02i",day) - whatordinal = day - elseif tag == "D" then - context(day) - whatordinal = day - elseif tag == v_weekday or tag == "w" then - local wd = weekday(day,month,year) - if currentlanguage == false then - context(days[wd]) - else - context.labeltext(variables[days[wd]]) + auto = false + if tag == v_year or tag == "y" or tag == "Y" then + context(year) + elseif tag == "yy" or tag == "YY" then + context("%02i",year % 100) + elseif tag == v_month or tag == "m" then + if currentlanguage == false then + context(months[month]) + elseif mnemonic then + ctx_labeltext(variables[mnemonic[month]]) + else + ctx_labeltext(variables[months[month]]) + end + elseif tag == v_MONTH then + if currentlanguage == false then + ctx_WORD(variables[months[month]]) + elseif mnemonic then + ctx_LABELTEXT(variables[mnemonic[month]]) + else + ctx_LABELTEXT(variables[months[month]]) + end + elseif tag == "mm" then + context("%02i",month) + elseif tag == "M" then + context(month) + elseif tag == v_day or tag == "d" then + if currentlanguage == false then + context(days[day]) + else + ctx_convertnumber(v_day,day) -- why not direct + end + whatordinal = day + elseif tag == "dd" then + context("%02i",day) + whatordinal = day + elseif tag == "D" then + context(day) + whatordinal = day + elseif tag == v_weekday or tag == "w" then + local wd = weekday(day,month,year) + if currentlanguage == false then + context(days[wd]) + else + ctx_labeltext(variables[days[wd]]) + end + elseif tag == v_WEEKDAY then + local wd = weekday(day,month,year) + if currentlanguage == false then + ctx_WORD(days[wd]) + else + ctx_LABELTEXT(variables[days[wd]]) + end + elseif tag == "W" then + context(weekday(day,month,year)) + elseif tag == v_referral then + context("%04i%02i%02i",year,month,day) + elseif tag == v_space or tag == "\\ " then + ctx_space() + auto = true + elseif tag ~= "" then + context(tag) + auto = true end - elseif tag == v_WEEKDAY then - local wd = weekday(day,month,year) - if currentlanguage == false then - context.WORD(days[wd]) - else - context.LABELTEXT(variables[days[wd]]) - end - elseif tag == "W" then - context(weekday(day,month,year)) - elseif tag == v_referral then - context("%04i%02i%02i",year,month,day) - elseif tag == v_space or tag == "\\ " then - context.space() - auto = true - elseif tag ~= "" then - context(tag) - auto = true - end - if ordinal and whatordinal then - if currentlanguage == false then - -- ignore - else - context[highordinal and "highordinalstr" or "ordinalstr"](converters.ordinal(whatordinal,currentlanguage)) + if ordinal and whatordinal then + if currentlanguage == false then + -- ignore + else + context[highordinal and "highordinalstr" or "ordinalstr"](converters.ordinal(whatordinal,currentlanguage)) + end end end end diff --git a/tex/context/base/mkiv/core-con.mkiv b/tex/context/base/mkiv/core-con.mkiv index 8565a3096..a4d358e04 100644 --- a/tex/context/base/mkiv/core-con.mkiv +++ b/tex/context/base/mkiv/core-con.mkiv @@ -739,6 +739,9 @@ \def\spanishnumerals #1{\clf_alphabetic\numexpr#1\relax{es}} \def\spanishNumerals #1{\clf_Alphabetic\numexpr#1\relax{es}} +\def\russiannumerals #1{\clf_alphabetic\numexpr#1\relax{ru}} +\def\russianNumerals #1{\clf_Alphabetic\numexpr#1\relax{ru}} + %defineconversion [\s!sl] [character] [\sloveniannumerals] %defineconversion [\s!sl] [Character] [\slovenianNumerals] %defineconversion [\s!sl] [characters] [\sloveniannumerals] @@ -765,12 +768,28 @@ \defineconversion [\s!es] [AK] [\smallcapped\spanishnumerals] \defineconversion [\s!es] [KA] [\smallcapped\spanishnumerals] +%defineconversion [\s!ru] [character] [\russiannumerals] +%defineconversion [\s!ru] [Character] [\russianNumerals] +%defineconversion [\s!ru] [characters] [\russiannumerals] +%defineconversion [\s!ru] [Characters] [\russianNumerals] + +\defineconversion [\s!ru] [alphabetic] [\russiannumerals] +\defineconversion [\s!ru] [Alphabetic] [\russianNumerals] + +\defineconversion [\s!ru] [a] [\russiannumerals] +\defineconversion [\s!ru] [A] [\russianNumerals] +\defineconversion [\s!ru] [AK] [\smallcapped\russiannumerals] +\defineconversion [\s!ru] [KA] [\smallcapped\russiannumerals] + \defineconversion [sloveniannumerals] [\sloveniannumerals] \defineconversion [slovenianNumerals] [\slovenianNumerals] \defineconversion [spanishnumerals] [\spanishnumerals] \defineconversion [spanishNumerals] [\spanishNumerals] +\defineconversion [russiannumerals] [\russiannumerals] +\defineconversion [russianNumerals] [\russianNumerals] + %D In case a font has no greek (WS): \defineconversion [mathgreek] diff --git a/tex/context/base/mkiv/core-ctx.lua b/tex/context/base/mkiv/core-ctx.lua index 1f22402e6..3362e43b9 100644 --- a/tex/context/base/mkiv/core-ctx.lua +++ b/tex/context/base/mkiv/core-ctx.lua @@ -266,7 +266,12 @@ function ctxrunner.load(ctxname) for i=1,#runners do local command = runners[i] report_prepfiles("command: %s",command) + -- + -- remark: we don't use sandbox.registerrunner here as we cannot predict what + -- gets done here, so just: + -- local result = os.execute(command) or 0 + -- -- if result > 0 then -- report_prepfiles("error, return code: %s",result) -- end diff --git a/tex/context/base/mkiv/core-env.lua b/tex/context/base/mkiv/core-env.lua index 06c9708d6..583a6ed1e 100644 --- a/tex/context/base/mkiv/core-env.lua +++ b/tex/context/base/mkiv/core-env.lua @@ -11,36 +11,38 @@ if not modules then modules = { } end modules ['core-env'] = { -- -- if tex.modes['xxxx'] then .... else .... end -local P, C, S, Cc, lpegmatch, patterns = lpeg.P, lpeg.C, lpeg.S, lpeg.Cc, lpeg.match, lpeg.patterns +local rawset = rawset -local context = context +local P, C, S, lpegmatch, patterns = lpeg.P, lpeg.C, lpeg.S, lpeg.match, lpeg.patterns -local texgetcount = tex.getcount -local texsetcount = tex.setcount +local context = context +local ctxcore = context.core -local allocate = utilities.storage.allocate -local setmetatableindex = table.setmetatableindex -local setmetatablecall = table.setmetatablecall +local texgetcount = tex.getcount -local createtoken = token.create +local allocate = utilities.storage.allocate +local setmetatableindex = table.setmetatableindex +local setmetatablenewindex = table.setmetatablenewindex +local setmetatablecall = table.setmetatablecall -tex.modes = allocate { } -tex.systemmodes = allocate { } -tex.constants = allocate { } -tex.conditionals = allocate { } -tex.ifs = allocate { } -tex.isdefined = allocate { } +local createtoken = token.create -local modes = { } -local systemmodes = { } +texmodes = allocate { } tex.modes = texmodes +texsystemmodes = allocate { } tex.systemmodes = texsystemmodes +texconstants = allocate { } tex.constants = texconstants +texconditionals = allocate { } tex.conditionals = texconditionals +texifs = allocate { } tex.ifs = texifs +texisdefined = allocate { } tex.isdefined = texisdefined + +local modes = { } +local systemmodes = { } -- we could use the built-in tex.is[count|dimen|skip|toks] here but caching --- at the lua en dis not that bad (and we need more anyway) +-- at the lua end is not that bad (and we need more anyway) -- undefined: mode == 0 or cmdname = "undefined_cs" - -local cache = table.setmetatableindex(function(t,k) +local cache = setmetatableindex(function(t,k) local v = createtoken(k) t[k] = v return v @@ -51,7 +53,7 @@ end) local iftrue = cache["iftrue"].mode local undefined = cache["*undefined*crap*"].mode -- is this ok? -setmetatableindex(tex.modes, function(t,k) +setmetatableindex(texmodes, function(t,k) local m = modes[k] if m then return m() @@ -60,13 +62,16 @@ setmetatableindex(tex.modes, function(t,k) if cache[n].mode == 0 then return false else - modes[k] = function() return texgetcount(n) == 1 end + rawset(modes,k, function() return texgetcount(n) == 1 end) return texgetcount(n) == 1 -- 2 is prevented end end end) +setmetatablenewindex(texmodes, function(t,k) + report_mode("you cannot set the %s named %a this way","mode",k) +end) -setmetatableindex(tex.systemmodes, function(t,k) +setmetatableindex(texsystemmodes, function(t,k) local m = systemmodes[k] if m then return m() @@ -75,37 +80,45 @@ setmetatableindex(tex.systemmodes, function(t,k) if cache[n].mode == 0 then return false else - systemmodes[k] = function() return texgetcount(n) == 1 end + rawset(systemmodes,k,function() return texgetcount(n) == 1 end) return texgetcount(n) == 1 -- 2 is prevented end end end) +setmetatablenewindex(texsystemmodes, function(t,k) + report_mode("you cannot set the %s named %a this way","systemmode",k) +end) -setmetatableindex(tex.constants, function(t,k) +setmetatableindex(texconstants, function(t,k) return cache[k].mode ~= 0 and texgetcount(k) or 0 end) +setmetatablenewindex(texconstants, function(t,k) + report_mode("you cannot set the %s named %a this way","constant",k) +end) -setmetatableindex(tex.conditionals, function(t,k) -- 0 == true +setmetatableindex(texconditionals, function(t,k) -- 0 == true return cache[k].mode ~= 0 and texgetcount(k) == 0 end) +setmetatablenewindex(texconditionals, function(t,k) + report_mode("you cannot set the %s named %a this way","conditional",k) +end) -table.setmetatableindex(tex.ifs, function(t,k) - -- local mode = cache[k].mode - -- if mode == 0 then - -- return nil - -- else - -- return mode == iftrue - -- end +table.setmetatableindex(texifs, function(t,k) return cache[k].mode == iftrue end) +setmetatablenewindex(texifs, function(t,k) + -- just ignore +end) -setmetatableindex(tex.isdefined, function(t,k) +setmetatableindex(texisdefined, function(t,k) return k and cache[k].mode ~= 0 end) - -setmetatablecall(tex.isdefined, function(t,k) +setmetatablecall(texisdefined, function(t,k) return k and cache[k].mode ~= 0 end) +setmetatablenewindex(texisdefined, function(t,k) + -- just ignore +end) local dimencode = cache["scratchdimen"] .command local countcode = cache["scratchcounter"] .command @@ -152,107 +165,35 @@ function tex.type(name) return types[cache[name].command] or "macro" end --- -- old token code --- --- local csname_id = token.csname_id --- local create = token.create --- --- local undefined = csname_id("*undefined*crap*") --- local iftrue = create("iftrue")[2] -- inefficient hack --- --- setmetatableindex(tex.modes, function(t,k) --- local m = modes[k] --- if m then --- return m() --- else --- local n = "mode>" .. k --- if csname_id(n) == undefined then --- return false --- else --- modes[k] = function() return texgetcount(n) == 1 end --- return texgetcount(n) == 1 -- 2 is prevented --- end --- end --- end) --- --- setmetatableindex(tex.systemmodes, function(t,k) --- local m = systemmodes[k] --- if m then --- return m() --- else --- local n = "mode>*" .. k --- if csname_id(n) == undefined then --- return false --- else --- systemmodes[k] = function() return texgetcount(n) == 1 end --- return texgetcount(n) == 1 -- 2 is prevented --- end --- end --- end) --- --- setmetatableindex(tex.constants, function(t,k) --- return csname_id(k) ~= undefined and texgetcount(k) or 0 --- end) --- --- setmetatableindex(tex.conditionals, function(t,k) -- 0 == true --- return csname_id(k) ~= undefined and texgetcount(k) == 0 --- end) --- --- setmetatableindex(tex.ifs, function(t,k) --- -- k = "if" .. k -- better not --- return csname_id(k) ~= undefined and create(k)[2] == iftrue -- inefficient, this create, we need a helper --- end) --- --- setmetatableindex(tex.isdefined, function(t,k) --- return k and csname_id(k) ~= undefined --- end) --- setmetatablecall(tex.isdefined, function(t,k) --- return k and csname_id(k) ~= undefined --- end) --- --- local lookuptoken = token.lookup --- --- local dimencode = lookuptoken("scratchdimen" )[1] --- local countcode = lookuptoken("scratchcounter")[1] --- local tokencode = lookuptoken("scratchtoken" )[1] --- local skipcode = lookuptoken("scratchskip" )[1] --- --- local types = { --- [dimencode] = "dimen", --- [countcode] = "count", --- [tokencode] = "token", --- [skipcode ] = "skip", --- } --- --- function tex.isdimen(name) --- return lookuptoken(name)[1] == dimencode --- end --- --- function tex.iscount(name) --- return lookuptoken(name)[1] == countcode --- end --- --- function tex.istoken(name) --- return lookuptoken(name)[1] == tokencode --- end --- --- function tex.isskip(name) --- return lookuptoken(name)[1] == skipcode --- end --- --- function tex.type(name) --- return types[lookuptoken(name)[1]] or "macro" --- end - function context.setconditional(name,value) if value then - context.settruevalue(name) + ctxcore.settruevalue(name) + else + ctxcore.setfalsevalue(name) + end +end + +function context.setmode(name,value) + if value then + ctxcore.setmode(name) else - context.setfalsevalue(name) + ctxcore.resetmode(name) end end ----- arg = P("{") * C(patterns.nested) * P("}") + Cc("") +function context.setsystemmode(name,value) + if value then + ctxcore.setsystemmode(name) + else + ctxcore.resetsystemmode(name) + end +end + +context.modes = texmodes +context.systemmodes = texsystemmodes +context.conditionals = texconditionals +-------.constants = texconstants +-------.ifs = texifs local sep = S("), ") local str = C((1-sep)^1) @@ -260,9 +201,9 @@ local tag = P("(") * C((1-S(")" ))^1) * P(")") local arg = P("(") * C((1-S("){"))^1) * P("{") * C((1-P("}"))^0) * P("}") * P(")") local pattern = ( - P("lua") * tag / context.luasetup - + P("xml") * arg / context.setupwithargument -- or xmlw as xmlsetup has swapped arguments - + (P("tex") * tag + str) / context.texsetup + P("lua") * tag / ctxcore.luasetup + + P("xml") * arg / ctxcore.setupwithargument -- or xmlw as xmlsetup has swapped arguments + + (P("tex") * tag + str) / ctxcore.texsetup + sep^1 )^1 @@ -271,4 +212,3 @@ interfaces.implement { actions = function(str) lpegmatch(pattern,str) end, arguments = "string" } - diff --git a/tex/context/base/mkiv/core-env.mkiv b/tex/context/base/mkiv/core-env.mkiv index e876dc80d..0b8894265 100644 --- a/tex/context/base/mkiv/core-env.mkiv +++ b/tex/context/base/mkiv/core-env.mkiv @@ -119,15 +119,27 @@ {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi \syst_mode_prefix\lastnamedcs\preventedmode} +% \def\syst_modes_enable_indeed#1% we can speed it up by moving the new outside +% {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi +% \ifnum\csname\??mode#1\endcsname=\preventedmode \else +% \syst_mode_prefix\lastnamedcs\enabledmode +% \fi} +% +% \def\syst_modes_disable_indeed#1% +% {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi +% \ifnum\csname\??mode#1\endcsname=\preventedmode \else +% \syst_mode_prefix\lastnamedcs\disabledmode +% \fi} + \def\syst_modes_enable_indeed#1% we can speed it up by moving the new outside {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi - \ifnum\csname\??mode#1\endcsname=\preventedmode \else + \ifnum\lastnamedcs=\preventedmode\else \syst_mode_prefix\lastnamedcs\enabledmode \fi} \def\syst_modes_disable_indeed#1% {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi - \ifnum\csname\??mode#1\endcsname=\preventedmode \else + \ifnum\lastnamedcs=\preventedmode\else \syst_mode_prefix\lastnamedcs\disabledmode \fi} @@ -146,6 +158,18 @@ \edef\m_modes_asked{#2}% \rawprocesscommacommand[#1]\syst_modes_define_indeed} +% \def\syst_modes_define_indeed#1% +% {\ifcsname\??mode#1\endcsname +% % already set +% \else +% \syst_modes_new{#1} +% \fi +% \ifx\m_modes_asked\v!keep +% % not changes, disabled when undefined +% \else +% \csname\??mode#1\endcsname\ifx\m_modes_asked\v!yes\enabledmode\else\disabledmode\fi +% \fi} + \def\syst_modes_define_indeed#1% {\ifcsname\??mode#1\endcsname % already set @@ -155,7 +179,7 @@ \ifx\m_modes_asked\v!keep % not changes, disabled when undefined \else - \csname\??mode#1\endcsname\ifx\m_modes_asked\v!yes\enabledmode\else\disabledmode\fi + \lastnamedcs\ifx\m_modes_asked\v!yes\enabledmode\else\disabledmode\fi \fi} % handy for mp diff --git a/tex/context/base/mkiv/core-sys.lua b/tex/context/base/mkiv/core-sys.lua index 3e39fa9da..0dbe76685 100644 --- a/tex/context/base/mkiv/core-sys.lua +++ b/tex/context/base/mkiv/core-sys.lua @@ -40,6 +40,7 @@ function environment.initializefilenames() -- jobfilename = gsub(jobfilename, "^./","") -- inputfilename = gsub(inputfilename,"^./","") + environment.jobfilefullname = fulljobname environment.jobfilename = jobfilebase environment.jobfilesuffix = lower(suffixonly(jobfilebase)) @@ -60,6 +61,7 @@ end -- we could set a macro (but will that work when we're expanding? needs testing!) implement { name = "operatingsystem", actions = function() context(os.platform) end } +implement { name = "jobfilefullname", actions = function() context(environment.jobfilefullname) end } implement { name = "jobfilename", actions = function() context(environment.jobfilename) end } implement { name = "jobfilesuffix", actions = function() context(environment.jobfilesuffix) end } implement { name = "inputfilebarename", actions = function() context(environment.inputfilebarename) end } diff --git a/tex/context/base/mkiv/core-sys.mkiv b/tex/context/base/mkiv/core-sys.mkiv index cc9dafdd2..172cb7a38 100644 --- a/tex/context/base/mkiv/core-sys.mkiv +++ b/tex/context/base/mkiv/core-sys.mkiv @@ -40,8 +40,9 @@ %D The jobname is what gets loaded by the cont-yes stub file. This name %D also determines the name of tuc etc files. -\let\jobfilename \clf_jobfilename -\let\jobfilesuffix\clf_jobfilesuffix +\let\jobfilefullname\clf_jobfilefullname +\let\jobfilename \clf_jobfilename +\let\jobfilesuffix \clf_jobfilesuffix %D However, that one can itself load another file. diff --git a/tex/context/base/mkiv/core-uti.lua b/tex/context/base/mkiv/core-uti.lua index 23057872f..a2869e6ea 100644 --- a/tex/context/base/mkiv/core-uti.lua +++ b/tex/context/base/mkiv/core-uti.lua @@ -22,25 +22,29 @@ local format, match = string.format, string.match local next, type, tostring = next, type, tostring local concat = table.concat -local definetable = utilities.tables.definetable -local accesstable = utilities.tables.accesstable -local migratetable = utilities.tables.migratetable -local serialize = table.serialize -local packers = utilities.packers -local allocate = utilities.storage.allocate -local mark = utilities.storage.mark +local definetable = utilities.tables.definetable +local accesstable = utilities.tables.accesstable +local migratetable = utilities.tables.migratetable +local serialize = table.serialize +local packers = utilities.packers +local allocate = utilities.storage.allocate +local mark = utilities.storage.mark -local implement = interfaces.implement +local getrandom = utilities.randomizer.get +local setrandomseedi = utilities.randomizer.setseedi +local getrandomseed = utilities.randomizer.getseed -local texgetcount = tex.getcount +local implement = interfaces.implement -local report_passes = logs.reporter("job","passes") +local texgetcount = tex.getcount -job = job or { } -local job = job +local report_passes = logs.reporter("job","passes") -job.version = 1.30 -job.packversion = 1.02 +job = job or { } +local job = job + +job.version = 1.30 +job.packversion = 1.02 -- some day we will implement loading of other jobs and then we need -- job.jobs @@ -132,11 +136,11 @@ local function initializer() -- rvalue = collected.randomseed if not rvalue then - rvalue = math.random() - math.setrandomseedi(rvalue,"initialize") + rvalue = getrandom("initialize") + setrandomseedi(rvalue) rmethod = "initialized" else - math.setrandomseedi(rvalue,"previous run") + setrandomseedi(rvalue) rmethod = "resumed" end tobesaved.randomseed = rvalue @@ -169,6 +173,10 @@ function jobvariables.restore(cs) return collectedmacros[cs] or tobesavedmacros[cs] end +function job.getrandomseed() + return tobesaved.randomseed or getrandomseed() +end + -- checksums function jobvariables.getchecksum(tag) @@ -283,21 +291,27 @@ function job.load(filename) local utilitydata = load(filename) if utilitydata then local jobpacker = utilitydata.job.packed - for l=1,#savelist do - local list = savelist[l] + local handlers = { } + for i=1,#savelist do + local list = savelist[i] local target = list[1] local initializer = list[3] local result = accesstable(target,utilitydata) - local done = packers.unpack(result,jobpacker,true) + local done = packers.unpack(result,jobpacker,true) if done then migratetable(target,mark(result)) if type(initializer) == "function" then - initializer(result) + handlers[#handlers+1] = { initializer, result } end else report_passes("pack version mismatch") end end + -- so we have all tables available (unpacked) + for i=1,#handlers do + local handler = handlers[i] + handler[1](handler[2]) + end end statistics.stoptiming(_load_) end @@ -386,23 +400,25 @@ end) -- a sort of joke (for ctx meeting) -local kg_per_watt_per_second = 1 / 15000000 -local watts_per_core = 50 -local speedup_by_other_engine = 1.2 -local used_wood_factor = watts_per_core * kg_per_watt_per_second / speedup_by_other_engine -local used_wood_factor = (50 / 15000000) / 1.2 +-- local kg_per_watt_per_second = 1 / 15000000 +-- local watts_per_core = 50 +-- local speedup_by_other_engine = 1.2 +-- local used_wood_factor = watts_per_core * kg_per_watt_per_second / speedup_by_other_engine +-- local used_wood_factor = (50 / 15000000) / 1.2 function statistics.formatruntime(runtime) if not environment.initex then -- else error when testing as not counters yet + -- stoptiming(statistics) -- to be sure local shipped = texgetcount('nofshipouts') local pages = texgetcount('realpageno') if pages > shipped then pages = shipped end if shipped > 0 or pages > 0 then - local persecond = shipped / runtime + runtime = tonumber(runtime) + local persecond = (runtime > 0) and (shipped/runtime) or pages if pages == 0 then pages = shipped end - -- if jit then + -- if TEXENGINE == "luajittex" then -- local saved = watts_per_core * runtime * kg_per_watt_per_second / speedup_by_other_engine -- local saved = used_wood_factor * runtime -- return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second, %f mg tree saved by using luajittex",runtime,pages,shipped,persecond,saved*1000*1000) diff --git a/tex/context/base/mkiv/core-uti.mkiv b/tex/context/base/mkiv/core-uti.mkiv index de9a893ee..c50a0eacc 100644 --- a/tex/context/base/mkiv/core-uti.mkiv +++ b/tex/context/base/mkiv/core-uti.mkiv @@ -22,7 +22,7 @@ \appendtoks \clf_setjobcomment - file {tex.jobname}% + file {\jobname}% format {\contextformat}% stamp {\contextversion}% escape {\!!bs\space...\space\!!es}% diff --git a/tex/context/base/mkiv/data-con.lua b/tex/context/base/mkiv/data-con.lua index 240538df2..c79fca7c5 100644 --- a/tex/context/base/mkiv/data-con.lua +++ b/tex/context/base/mkiv/data-con.lua @@ -91,7 +91,7 @@ function containers.read(container,name) local storage = container.storage local stored = storage[name] if not stored and container.enabled and caches and containers.usecache then - stored = caches.loaddata(container.readables,name) + stored = caches.loaddata(container.readables,name,container.writable) if stored and stored.cache_version == container.version then if trace_cache or trace_containers then report_containers("action %a, category %a, name %a","load",container.subcategory,name) diff --git a/tex/context/base/mkiv/data-crl.lua b/tex/context/base/mkiv/data-crl.lua index fba5a6230..ec517fba3 100644 --- a/tex/context/base/mkiv/data-crl.lua +++ b/tex/context/base/mkiv/data-crl.lua @@ -8,29 +8,45 @@ if not modules then modules = { } end modules ['data-crl'] = { -- this one is replaced by data-sch.lua -- -local gsub = string.gsub +local gsub = string.gsub +local exists = io.exists local resolvers = resolvers +local finders = resolvers.finders +local openers = resolvers.openers +local loaders = resolvers.loaders -local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders +local setfirstwritablefile = caches.setfirstwritablefile -resolvers.curl = resolvers.curl or { } -local curl = resolvers.curl +local curl = resolvers.curl or { } +resolvers.curl = curl +local cached = { } -local cached = { } +local runner = sandbox.registerrunner { + name = "curl resolver", + method = "execute", + program = "curl", + template = "--silent -- insecure --create-dirs --output %cachename% %original%", + checkers = { + cachename = "cache", + original = "url", + } +} local function runcurl(specification) local original = specification.original -- local scheme = specification.scheme local cleanname = gsub(original,"[^%a%d%.]+","-") - local cachename = caches.setfirstwritablefile(cleanname,"curl") + local cachename = setfirstwritablefile(cleanname,"curl") if not cached[original] then - if not io.exists(cachename) then + if not exists(cachename) then cached[original] = cachename - local command = "curl --silent --create-dirs --output " .. cachename .. " " .. original - os.execute(command) + runner { + cachename = cachename, + original = original, + } end - if io.exists(cachename) then + if exists(cachename) then cached[original] = cachename else cached[original] = "" diff --git a/tex/context/base/mkiv/data-exp.lua b/tex/context/base/mkiv/data-exp.lua index 19ceb90c3..e34c52efb 100644 --- a/tex/context/base/mkiv/data-exp.lua +++ b/tex/context/base/mkiv/data-exp.lua @@ -14,7 +14,6 @@ local Ct, Cs, Cc, Carg, P, C, S = lpeg.Ct, lpeg.Cs, lpeg.Cc, lpeg.Carg, lpeg.P, local type, next = type, next local isdir = lfs.isdir -local ostype = os.type local collapsepath, joinpath, basename = file.collapsepath, file.join, file.basename local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) @@ -244,7 +243,6 @@ end local cache = { } ------ splitter = lpeg.tsplitat(S(ostype == "windows" and ";" or ":;")) -- maybe add , local splitter = lpeg.tsplitat(";") -- as we move towards urls, prefixes and use tables we no longer do : local backslashswapper = lpeg.replacer("\\","/") diff --git a/tex/context/base/mkiv/data-ini.lua b/tex/context/base/mkiv/data-ini.lua index 5ed2cce26..09357368c 100644 --- a/tex/context/base/mkiv/data-ini.lua +++ b/tex/context/base/mkiv/data-ini.lua @@ -217,11 +217,11 @@ end environment.texroot = file.collapsepath(texroot) -if type(profiler) == "table" and not jit then - directives.register("system.profile",function() - profiler.start("luatex-profile.log") - end) -end +-- if type(profiler) == "table" and not jit then +-- directives.register("system.profile",function() +-- profiler.start("luatex-profile.log") +-- end) +-- end -- a forward definition diff --git a/tex/context/base/mkiv/data-lua.lua b/tex/context/base/mkiv/data-lua.lua index 7c12a5940..3022ae550 100644 --- a/tex/context/base/mkiv/data-lua.lua +++ b/tex/context/base/mkiv/data-lua.lua @@ -50,11 +50,9 @@ function helpers.cleanpath(path) -- hm, don't we have a helper for this? return resolveprefix(lpegmatch(pattern,path)) end -local loadedaslib = helpers.loadedaslib -local getextraluapaths = package.extraluapaths -local getextralibpaths = package.extralibpaths -local registerpath = helpers.registerpath -local lualibfile = helpers.lualibfile +local loadedaslib = helpers.loadedaslib +local registerpath = helpers.registerpath +local lualibfile = helpers.lualibfile local luaformatpaths local libformatpaths diff --git a/tex/context/base/mkiv/data-met.lua b/tex/context/base/mkiv/data-met.lua index 4e8a48f50..bb8929577 100644 --- a/tex/context/base/mkiv/data-met.lua +++ b/tex/context/base/mkiv/data-met.lua @@ -9,7 +9,6 @@ if not modules then modules = { } end modules ['data-met'] = { local find, format = string.find, string.format local sequenced = table.sequenced local addurlscheme, urlhashed = url.addscheme, url.hashed -local getcurrentdir = lfs.currentdir local trace_locating = false local trace_methods = false diff --git a/tex/context/base/mkiv/data-res.lua b/tex/context/base/mkiv/data-res.lua index 831ad881c..4f171c445 100644 --- a/tex/context/base/mkiv/data-res.lua +++ b/tex/context/base/mkiv/data-res.lua @@ -69,12 +69,13 @@ local initializesetter = utilities.setters.initialize local ostype, osname, osenv, ossetenv, osgetenv = os.type, os.name, os.env, os.setenv, os.getenv -resolvers.cacheversion = "1.100" -resolvers.configbanner = "" -resolvers.homedir = environment.homedir -resolvers.criticalvars = allocate { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF", "TEXMF", "TEXOS" } -resolvers.luacnfname = "texmfcnf.lua" -resolvers.luacnfstate = "unknown" +resolvers.cacheversion = "1.100" +resolvers.configbanner = "" +resolvers.homedir = environment.homedir +resolvers.criticalvars = allocate { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF", "TEXMF", "TEXOS" } +resolvers.luacnfname = "texmfcnf.lua" +resolvers.luacnffallback = "contextcnf.lua" +resolvers.luacnfstate = "unknown" -- The web2c tex binaries as well as kpse have built in paths for the configuration -- files and there can be a depressing truckload of them. This is actually the weak @@ -198,7 +199,6 @@ end local dollarstripper = lpeg.stripper("$") local inhibitstripper = P("!")^0 * Cs(P(1)^0) -local backslashswapper = lpeg.replacer("\\","/") local somevariable = P("$") / "" local somekey = C(R("az","AZ","09","__","--")^1) @@ -377,24 +377,32 @@ local function identify_configuration_files() end reportcriticalvariables(cnfspec) local cnfpaths = expandedpathfromlist(resolvers.splitpath(cnfspec)) - local luacnfname = resolvers.luacnfname - for i=1,#cnfpaths do - local filepath = cnfpaths[i] - local filename = collapsepath(filejoin(filepath,luacnfname)) - local realname = resolveprefix(filename) -- can still have "//" ... needs checking - -- todo: environment.skipweirdcnfpaths directive - if trace_locating then - local fullpath = gsub(resolveprefix(collapsepath(filepath)),"//","/") - local weirdpath = find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true) - report_resolving("looking for %a on %s path %a from specification %a",luacnfname,weirdpath and "weird" or "given",fullpath,filepath) - end - if isfile(realname) then - specification[#specification+1] = filename -- unresolved as we use it in matching, relocatable + + local function locatecnf(luacnfname,kind) + for i=1,#cnfpaths do + local filepath = cnfpaths[i] + local filename = collapsepath(filejoin(filepath,luacnfname)) + local realname = resolveprefix(filename) -- can still have "//" ... needs checking + -- todo: environment.skipweirdcnfpaths directive if trace_locating then - report_resolving("found configuration file %a",realname) + local fullpath = gsub(resolveprefix(collapsepath(filepath)),"//","/") + local weirdpath = find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true) + report_resolving("looking for %s %a on %s path %a from specification %a", + kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath) + end + if isfile(realname) then + specification[#specification+1] = filename -- unresolved as we use it in matching, relocatable + if trace_locating then + report_resolving("found %s configuration file %a",kind,realname) + end end end end + + locatecnf(resolvers.luacnfname,"regular") + if #specification == 0 then + locatecnf(resolvers.luacnffallback,"fallback") + end if trace_locating then report_resolving() end diff --git a/tex/context/base/mkiv/data-sch.lua b/tex/context/base/mkiv/data-sch.lua index d79e0c7ef..23ecdc122 100644 --- a/tex/context/base/mkiv/data-sch.lua +++ b/tex/context/base/mkiv/data-sch.lua @@ -61,12 +61,21 @@ function resolvers.schemes.cleanname(specification) return hash end -local cached, loaded, reused, thresholds, handlers = { }, { }, { }, { }, { } - -local function runcurl(name,cachename) -- we use sockets instead or the curl library when possible - local command = "curl --silent --insecure --create-dirs --output " .. cachename .. " " .. name - os.execute(command) -end +local cached = { } +local loaded = { } +local reused = { } +local thresholds = { } +local handlers = { } +local runner = sandbox.registerrunner { + name = "curl resolver", + method = "execute", + program = "curl", + template = "--silent -- insecure --create-dirs --output %cachename% %original%", + checkers = { + cachename = "cache", + original = "url", + } +} local function fetch(specification) local original = specification.original @@ -89,7 +98,10 @@ local function fetch(specification) report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl") end logs.flush() - runcurl(original,cachename) + runner { + original = original, + cachename = cachename, + } end end if io.exists(cachename) then @@ -184,10 +196,6 @@ end) local httprequest = http.request local toquery = url.toquery --- local function httprequest(url) --- return os.resultof(format("curl --silent %q", url)) --- end - local function fetchstring(url,data) local q = data and toquery(data) if q then diff --git a/tex/context/base/mkiv/data-tmp.lua b/tex/context/base/mkiv/data-tmp.lua index 9e1515a26..eabfce96e 100644 --- a/tex/context/base/mkiv/data-tmp.lua +++ b/tex/context/base/mkiv/data-tmp.lua @@ -256,22 +256,22 @@ caches.getwritablepath = getwritablepath -- use e.g. a home path where we have updated file databases and so maybe we need -- to check first if we do have a writable one -function caches.getfirstreadablefile(filename,...) - local rd = getreadablepaths(...) - for i=1,#rd do - local path = rd[i] - local fullname = file.join(path,filename) - if is_readable(fullname) then - usedreadables[i] = true - return fullname, path - end - end - return caches.setfirstwritablefile(filename,...) -end +-- function caches.getfirstreadablefile(filename,...) +-- local rd = getreadablepaths(...) +-- for i=1,#rd do +-- local path = rd[i] +-- local fullname = file.join(path,filename) +-- if is_readable(fullname) then +-- usedreadables[i] = true +-- return fullname, path +-- end +-- end +-- return caches.setfirstwritablefile(filename,...) +-- end -- next time we have an issue, we can test this instead: -function caches.getfirstreadablefile_TEST_ME_FIRST(filename,...) +function caches.getfirstreadablefile(filename,...) -- check if we have already written once local fullname, path = caches.setfirstwritablefile(filename,...) if is_readable(fullname) then @@ -297,7 +297,7 @@ function caches.setfirstwritablefile(filename,...) return fullname, wr end -function caches.define(category,subcategory) -- for old times sake +function caches.define(category,subcategory) -- not used return function() return getwritablepath(category,subcategory) end @@ -307,19 +307,31 @@ function caches.setluanames(path,name) return format("%s/%s.%s",path,name,luasuffixes.tma), format("%s/%s.%s",path,name,luasuffixes.tmc) end -function caches.loaddata(readables,name) +-- This works best if the first writable is the first readable too. In practice +-- we can have these situations for file databases: +-- +-- tma in readable +-- tma + tmb/c in readable +-- +-- runtime files like fonts are written to the writable cache anyway + +function caches.loaddata(readables,name,writable) if type(readables) == "string" then readables = { readables } end for i=1,#readables do - local path = readables[i] - local tmaname, tmcname = caches.setluanames(path,name) + local path = readables[i] local loader = false + local tmaname, tmcname = caches.setluanames(path,name) if isfile(tmcname) then loader = loadfile(tmcname) end if not loader and isfile(tmaname) then - -- in case we have a different engine + -- can be different paths when we read a file database from disk + local tmacrap, tmcname = caches.setluanames(writable,name) + if isfile(tmcname) then + loader = loadfile(tmcname) + end utilities.lua.compile(tmaname,tmcname) if isfile(tmcname) then loader = loadfile(tmcname) diff --git a/tex/context/base/mkiv/data-use.lua b/tex/context/base/mkiv/data-use.lua index 7598506e4..930c5739f 100644 --- a/tex/context/base/mkiv/data-use.lua +++ b/tex/context/base/mkiv/data-use.lua @@ -56,7 +56,7 @@ statistics.register("used cache path", function() return caches.usedpaths() end -- experiment (code will move) -function statistics.savefmtstatus(texname,formatbanner,sourcefile) -- texname == formatname +function statistics.savefmtstatus(texname,formatbanner,sourcefile,kind,banner) -- texname == formatname local enginebanner = status.banner if formatbanner and enginebanner and sourcefile then local luvname = file.replacesuffix(texname,"luv") -- utilities.lua.suffixes.luv @@ -67,6 +67,10 @@ function statistics.savefmtstatus(texname,formatbanner,sourcefile) -- texname == sourcefile = sourcefile, } io.savedata(luvname,table.serialize(luvdata,true)) + lua.registerfinalizer(function() + logs.report("format banner","%s",banner) + logs.newline() + end) end end diff --git a/tex/context/base/mkiv/enco-ini.mkiv b/tex/context/base/mkiv/enco-ini.mkiv index 835ee61f5..50375251a 100644 --- a/tex/context/base/mkiv/enco-ini.mkiv +++ b/tex/context/base/mkiv/enco-ini.mkiv @@ -282,7 +282,7 @@ % some more \ifdefined\softhyphen \else - \let\softhyphen\- + \let\softhyphen\explicitdiscretionary \fi \def\hyphen {\softhyphen} diff --git a/tex/context/base/mkiv/example.rng b/tex/context/base/mkiv/example.rng new file mode 100644 index 000000000..09b80d14a --- /dev/null +++ b/tex/context/base/mkiv/example.rng @@ -0,0 +1,304 @@ +<?xml version="1.0" ?> + +<grammar xmlns="http://relaxng.org/ns/structure/1.0"> + + <start> + <choice> + <ref name="script"/> + <ref name="environment"/> + <ref name="sequence"/> + <ref name="request"/> + <ref name="reply"/> + </choice> + </start> + + <define name="script"> + <element name="script"> + <zeroOrMore> + <ref name="script"/> + <ref name="environment"/> + <ref name="sequence"/> + <ref name="request"/> + <ref name="reply"/> + </zeroOrMore> + </element> + </define> + + <define name="environment"> + <element name="environment"> + <zeroOrMore> + <ref name="environment.content"/> + </zeroOrMore> + </element> + </define> + + <define name="environment.content"> + <element name="variable"> + <ref name="content"/> + <attribute name="label"/> + </element> + </define> + + <define name="sequence"> + <element name="sequence"> + <zeroOrMore> + <ref name="sequence.process"/> + </zeroOrMore> + </element> + </define> + + <define name="sequence.process"> + <element name="process"> + <interleave> + <optional> + <ref name="sequence.result"/> + </optional> + <ref name="sequence.command"/> + </interleave> + </element> + </define> + + <define name="sequence.result"> + <element name="result"> + <ref name="content"/> + </element> + </define> + + <define name="sequence.command"> + <element name="command"> + <ref name="content"/> + </element> + </define> + + <define name="reply"> + <element name="reply"> + <interleave> + <optional> + <ref name="reply.result"/> + </optional> + <optional> + <ref name="status"/> + </optional> + <optional> + <ref name="comment"/> + </optional> + <optional> + <ref name="forwarded"/> + </optional> + </interleave> + </element> + </define> + + <define name="reply.result"> + <element name="result"> + <text/> + </element> + </define> + + <define name="request"> + <element name="request"> + <ref name="request.application"/> + <optional> + <ref name="request.client"/> + </optional> + <optional> + <ref name="request.server"/> + </optional> + <optional> + <ref name="request.data"/> + </optional> + <optional> + <zeroOrMore> + <ref name="request.blob"/> + </zeroOrMore> + </optional> + <optional> + <ref name="request.results"/> + </optional> + </element> + </define> + + <define name="request.application"> + <element name="application"> + <choice> + <ref name="request.command"/> + <ref name="request.action"/> + </choice> + <ref name="request.content"/> + </element> + </define> + + <define name="request.client"> + <element name="client"> + <ref name="request.content"/> + </element> + </define> + + <define name="request.server"> + <element name="server"> + <ref name="request.content"/> + </element> + </define> + + <define name="request.content"> + <interleave> + <optional> + <ref name="filename"/> + </optional> + <optional> + <ref name="archive"/> + </optional> + <optional> + <ref name="comment"/> + </optional> + <optional> + <ref name="forwarded"/> + </optional> + <optional> + <ref name="domain"/> + </optional> + <optional> + <ref name="project"/> + </optional> + <optional> + <ref name="usertoken"/> + </optional> + </interleave> + </define> + + <define name="request.command"> + <element name="command"> + <text/> + </element> + <optional> + <element name="option"> + <text/> + </element> + </optional> + </define> + + <define name="request.action"> + <element name="action"> + <text/> + </element> + </define> + + <define name="request.data"> + <element name="data"> + <choice> + <zeroOrMore> + <ref name="data.variable"/> + </zeroOrMore> + <optional> + <ref name="filename"/> + </optional> + </choice> + </element> + </define> + + <define name="request.results"> + <element name="results"> + <zeroOrMore> + <ref name="request.result"/> + </zeroOrMore> + </element> + </define> + + <define name="data.result"> + <element name="result"> + <attribute name="status"/> + <attribute name="name"/> + </element> + </define> + + <define name="request.blob"> + <element name="blob"> + <text/> + <attribute name="label"/> + </element> + </define> + + <define name="data.variable"> + <element name="variable"> + <text/> + <attribute name="label"/> + </element> + </define> + + <define name="content"> + <zeroOrMore> + <mixed> + <ref name="resolve"/> + </mixed> + </zeroOrMore> + </define> + + <define name="resolve"> + <optional> + <element name="resolve"> + <empty/> + <attribute name="label"/> + <optional> + <attribute name="type"> + <choice> + <value>path</value> + <value>name</value> + <value>suffix</value> + <value>nopath</value> + <value>nosuffix</value> + </choice> + </attribute> + </optional> + </element> + </optional> + </define> + + <define name="filename"> + <element name="filename"> + <text/> + </element> + </define> + + <define name="archive"> + <element name="archive"> + <text/> + </element> + </define> + + <define name="comment"> + <element name="comment"> + <text/> + </element> + </define> + + <define name="status"> + <element name="status"> + <text/> + </element> + </define> + + <define name="forwarded"> + <element name="forwarded"> + <text/> + </element> + </define> + + <define name="domain"> + <element name="domain"> + <text/> + </element> + </define> + + <define name="project"> + <element name="project"> + <text/> + </element> + </define> + + <define name="usertoken"> + <element name="usertoken"> + <text/> + </element> + </define> + +</grammar> diff --git a/tex/context/base/mkiv/file-job.lua b/tex/context/base/mkiv/file-job.lua index 602c41a11..c7c36a03f 100644 --- a/tex/context/base/mkiv/file-job.lua +++ b/tex/context/base/mkiv/file-job.lua @@ -44,7 +44,6 @@ local basename = file.basename local addsuffix = file.addsuffix local removesuffix = file.removesuffix local dirname = file.dirname -local joinpath = file.join local is_qualified_path = file.is_qualified_path local cleanpath = resolvers.cleanpath @@ -60,7 +59,7 @@ local resetextrapath = resolvers.resetextrapath local pushextrapath = resolvers.pushextrapath local popextrapath = resolvers.popextrapath -local v_outer = variables.outer +----- v_outer = variables.outer local v_text = variables.text local v_project = variables.project local v_environment = variables.environment @@ -539,9 +538,9 @@ job.register('job.structure.collected',root,initialize) -- component: small unit, either or not components itself -- product : combination of components -local context_processfilemany = context.processfilemany -local context_processfileonce = context.processfileonce -local context_processfilenone = context.processfilenone +local ctx_processfilemany = context.processfilemany +local ctx_processfileonce = context.processfileonce +local ctx_processfilenone = context.processfilenone -- we need a plug in the nested loaded, push pop pseudo current dir @@ -558,9 +557,9 @@ local function processfilecommon(name,action) action(name) end -local function processfilemany(name) processfilecommon(name,context_processfilemany) end -local function processfileonce(name) processfilecommon(name,context_processfileonce) end -local function processfilenone(name) processfilecommon(name,context_processfilenone) end +local function processfilemany(name) processfilecommon(name,ctx_processfilemany) end +local function processfileonce(name) processfilecommon(name,ctx_processfileonce) end +local function processfilenone(name) processfilecommon(name,ctx_processfilenone) end local processors = utilities.storage.allocate { -- [v_outer] = { diff --git a/tex/context/base/mkiv/file-job.mkvi b/tex/context/base/mkiv/file-job.mkvi index 0958d8433..75362d5a9 100644 --- a/tex/context/base/mkiv/file-job.mkvi +++ b/tex/context/base/mkiv/file-job.mkvi @@ -315,6 +315,9 @@ \def\documentvariable#name% {\getvariable\s!document{#name}} +\unexpanded\def\unexpandeddocumentvariable#name% + {\getvariable\s!document{#name}} + \unexpanded\def\setupdocument[#settings]% {\setvariables[\s!document][#settings]% \the\everysetupdocument\relax} @@ -322,6 +325,17 @@ \unexpanded\def\presetdocument[#settings]% {\checkvariables[\s!document][#settings]} +% We silently ignore missing documents. Beware: there are no begin/end setups +% invoked as we expect the loaded document to be wrapped in \startdocument ... +% \stopdocument. This is just a convenient variant of input. +% +% \unexpanded\def\document +% {\dosingleempty\syst_document} +% +% \def\syst_document[#1]#2% +% \startdocument[#1] +% \readfile{#2}{}{}} + % metadata:author metadata:title metadata:subject \setvariables diff --git a/tex/context/base/mkiv/file-lib.lua b/tex/context/base/mkiv/file-lib.lua index 361608ea3..62cf938ba 100644 --- a/tex/context/base/mkiv/file-lib.lua +++ b/tex/context/base/mkiv/file-lib.lua @@ -17,7 +17,6 @@ local trace_libraries = false trackers.register("resolvers.libraries", function local report_library = logs.reporter("files","library") ----- report_files = logs.reporter("files","readfile") -local suffixonly = file.suffix local removesuffix = file.removesuffix local getreadfilename = resolvers.getreadfilename @@ -49,12 +48,7 @@ function resolvers.uselibrary(specification) -- todo: reporter end for i=1,#files do local filename = files[i] - if loaded[filename] then - -- next one - else - if onlyonce then - loaded[filename] = true -- todo: base this on return value - end + if not loaded[filename] then local foundname = nil local barename = removesuffix(filename) -- direct search (we have an explicit suffix) @@ -77,10 +71,18 @@ function resolvers.uselibrary(specification) -- todo: reporter end end end - if foundname then - action(name,foundname) - elseif failure then - failure(name) + if not loaded[foundname] then + if foundname then + action(name,foundname) + if onlyonce then + loaded[foundname] = true -- todo: base this on return value + end + elseif failure then + failure(name) + end + if onlyonce then + loaded[filename] = true -- todo: base this on return value + end end end end diff --git a/tex/context/base/mkiv/file-res.lua b/tex/context/base/mkiv/file-res.lua index 08a3e22af..44117ed46 100644 --- a/tex/context/base/mkiv/file-res.lua +++ b/tex/context/base/mkiv/file-res.lua @@ -118,7 +118,11 @@ local function readfilename(specification,backtrack,treetoo) return fnd or "" end ---~ resolvers.readfilename = readfilename -- bonus use getreadfilename instead +-- resolvers.readfilename = readfilename -- bonus use getreadfilename instead + +function resolvers.finders.original(specification) -- handy, see memstreams + return specification.path +end function finders.job(specification) return readfilename(specification,false, false) end -- current path, no backtracking function finders.loc(specification) return readfilename(specification,resolvers.maxreadlevel,false) end -- current path, backtracking diff --git a/tex/context/base/mkiv/file-syn.lua b/tex/context/base/mkiv/file-syn.lua index b6ad27c83..7b000f9ad 100644 --- a/tex/context/base/mkiv/file-syn.lua +++ b/tex/context/base/mkiv/file-syn.lua @@ -15,8 +15,6 @@ local findfile = resolvers.findfile local implement = interfaces.implement -local report_files = logs.reporter("files") - storage.register("environment/filesynonyms", filesynonyms, "environment.filesynonyms") local function truefilename(name) diff --git a/tex/context/base/mkiv/font-afm.lua b/tex/context/base/mkiv/font-afm.lua index 0d6b7cb99..a9fbe89f1 100644 --- a/tex/context/base/mkiv/font-afm.lua +++ b/tex/context/base/mkiv/font-afm.lua @@ -32,7 +32,7 @@ local match, gmatch, lower, gsub, strip, find = string.match, string.gmatch, str local char, byte, sub = string.char, string.byte, string.sub local abs = math.abs local bxor, rshift = bit32.bxor, bit32.rshift -local P, S, R, Cmt, C, Ct, Cs, lpegmatch, patterns = lpeg.P, lpeg.S, lpeg.R, lpeg.Cmt, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.match, lpeg.patterns +local P, S, R, Cmt, C, Ct, Cs, Cg, Cf, lpegmatch, patterns = lpeg.P, lpeg.S, lpeg.R, lpeg.Cmt, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Cg, lpeg.Cf, lpeg.match, lpeg.patterns local derivetable = table.derive local trace_features = false trackers.register("afm.features", function(v) trace_features = v end) @@ -41,6 +41,7 @@ local trace_loading = false trackers.register("afm.loading", function(v local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) local report_afm = logs.reporter("fonts","afm loading") +local report_pfb = logs.reporter("fonts","pfb loading") local setmetatableindex = table.setmetatableindex @@ -50,10 +51,10 @@ local definers = fonts.definers local readers = fonts.readers local constructors = fonts.constructors -local afm = constructors.newhandler("afm") -local pfb = constructors.newhandler("pfb") +local afm = constructors.handlers.afm +local pfb = constructors.handlers.pfb -local afmfeatures = constructors.newfeatures("afm") +local afmfeatures = constructors.features.afm local registerafmfeature = afmfeatures.register afm.version = 1.501 -- incrementing this number one up will force a re-cache @@ -293,20 +294,36 @@ do local initialize = function(str,position,size) n = 0 - m = tonumber(size) + m = size -- % tonumber(size) return position + 1 end - local charstrings = P("/CharStrings") - local name = P("/") * C((R("az")+R("AZ")+R("09")+S("-_."))^1) - local size = C(R("09")^1) - local spaces = P(" ")^1 + local charstrings = P("/CharStrings") + local encoding = P("/Encoding") + local dup = P("dup") + local put = P("put") + local array = P("array") + local name = P("/") * C((R("az")+R("AZ")+R("09")+S("-_."))^1) + local digits = R("09")^1 + local cardinal = digits / tonumber + local spaces = P(" ")^1 + local spacing = patterns.whitespace^0 local p_filternames = Ct ( - (1-charstrings)^0 * charstrings * spaces * Cmt(size,initialize) - * (Cmt(name * P(" ")^1 * C(R("09")^1), progress) + P(1))^1 + (1-charstrings)^0 * charstrings * spaces * Cmt(cardinal,initialize) + * (Cmt(name * spaces * cardinal, progress) + P(1))^1 ) + -- /Encoding 256 array + -- 0 1 255 {1 index exch /.notdef put} for + -- dup 0 /Foo put + + local p_filterencoding = + (1-encoding)^0 * encoding * spaces * digits * spaces * array * (1-dup)^0 + * Cf( + Ct("") * Cg(spacing * dup * spaces * cardinal * spaces * name * spaces * put)^1 + ,rawset) + -- if one of first 4 not 0-9A-F then binary else hex local decrypt @@ -343,20 +360,20 @@ do local data = io.loaddata(resolvers.findfile(filename)) - if not find(data,"!PS%-AdobeFont%-") then - print("no font",filename) + if not data then + report_pfb("no data in %a",filename) return end - if not data then - print("no data",filename) + if not (find(data,"!PS%-AdobeFont%-") or find(data,"%%!FontType1")) then + report_pfb("no font in %a",filename) return end local ascii, binary = match(data,"(.*)eexec%s+......(.*)") if not binary then - print("no binary",filename) + report_pfb("no binary data in %a",filename) return end @@ -364,17 +381,26 @@ do local vector = lpegmatch(p_filternames,binary) - vector[0] = table.remove(vector,1) + if vector[1] == ".notdef" then + -- tricky + vector[0] = table.remove(vector,1) + end if not vector then - print("no vector",filename) + report_pfb("no vector in %a",filename) return end - return vector + local encoding = lpegmatch(p_filterencoding,ascii) + + return vector, encoding end + local pfb = handlers.pfb or { } + handlers.pfb = pfb + pfb.loadvector = loadpfbvector + get_indexes = function(data,pfbname) local vector = loadpfbvector(pfbname) if vector then @@ -410,6 +436,7 @@ do end + end local function readafm(filename) @@ -1141,8 +1168,6 @@ registerafmfeature { -- readers -local check_tfm = readers.check_tfm - fonts.formats.afm = "type1" fonts.formats.pfb = "type1" @@ -1178,7 +1203,8 @@ function readers.afm(specification,method) tfmdata = check_afm(specification,specification.name .. "." .. forced) end if not tfmdata then - method = method or definers.method or "afm or tfm" + local check_tfm = readers.check_tfm + method = (check_tfm and (method or definers.method or "afm or tfm")) or "afm" if method == "tfm" then tfmdata = check_tfm(specification,specification.name) elseif method == "afm" then diff --git a/tex/context/base/mkiv/font-age.lua b/tex/context/base/mkiv/font-age.lua index bb6883a74..b20a57538 100644 --- a/tex/context/base/mkiv/font-age.lua +++ b/tex/context/base/mkiv/font-age.lua @@ -12,7 +12,7 @@ if context then os.exit() end -return { -- generated: inspect(fonts.encodings.agl.unicodes) +return { ["A"]=65, ["AE"]=198, ["AEacute"]=508, @@ -1527,6 +1527,7 @@ return { -- generated: inspect(fonts.encodings.agl.unicodes) ["dotbelowcomb"]=803, ["dotkatakana"]=12539, ["dotlessi"]=305, + ["dotlessj"]=567, ["dotlessjstrokehook"]=644, ["dotmath"]=8901, ["dottedcircle"]=9676, diff --git a/tex/context/base/mkiv/font-agl.lua b/tex/context/base/mkiv/font-agl.lua index dd3490523..ec6c519ee 100644 --- a/tex/context/base/mkiv/font-agl.lua +++ b/tex/context/base/mkiv/font-agl.lua @@ -631,6 +631,8 @@ local extras = allocate { -- private extensions spade = 0x2660, theta1 = 0x03D1, twodotenleader = 0x2025, + + dotlessj = 0x0237, } -- We load this table only when needed. We could use a loading mechanism diff --git a/tex/context/base/mkiv/font-cff.lua b/tex/context/base/mkiv/font-cff.lua index 8c57b473e..1d4f01007 100644 --- a/tex/context/base/mkiv/font-cff.lua +++ b/tex/context/base/mkiv/font-cff.lua @@ -13,31 +13,39 @@ if not modules then modules = { } end modules ['font-cff'] = { -- This is a heavy one as it is a rather packed format. We don't need al the information -- now but we might need it later (who know what magic we can do with metapost). So at -- some point this might become a module. We just follow Adobe Technical Notes #5176 and --- #5177. In case of doubt I looked in the fontforge code that comes with LuaTeX. +-- #5177. In case of doubt I looked in the fontforge code that comes with LuaTeX but +-- it's not the easiest source to read (and doesn't cover cff2). -- For now we save the segments in a list of segments with the operator last in an entry -- because that reflects the original. But it might make more sense to use a single array -- per segment. For pdf a simple concat works ok, but for other purposes a operator first -- flush is nicer. +-- +-- In retrospect I could have looked into the backend code of LuaTeX but it never +-- occurred to me that parsing charstrings was needed there (which has to to +-- with merging subroutines and flattening, not so much with calculations.) On +-- the other hand, we can now feed back cff2 stuff. local next, type, tonumber = next, type, tonumber -local byte = string.byte +local byte, char, gmatch = string.byte, string.char, string.gmatch local concat, remove = table.concat, table.remove -local floor, abs, round, ceil = math.floor, math.abs, math.round, math.ceil +local floor, abs, round, ceil, min, max = math.floor, math.abs, math.round, math.ceil, math.min, math.max local P, C, R, S, C, Cs, Ct = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct local lpegmatch = lpeg.match +local formatters = string.formatters +local bytetable = string.bytetable local readers = fonts.handlers.otf.readers local streamreader = readers.streamreader -local readbytes = streamreader.readbytes local readstring = streamreader.readstring local readbyte = streamreader.readcardinal1 -- 8-bit unsigned integer local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer local readuint = streamreader.readcardinal3 -- 24-bit unsigned integer -local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer +local readulong = streamreader.readcardinal4 -- 32-bit unsigned integer local setposition = streamreader.setposition local getposition = streamreader.getposition +local readbytetable = streamreader.readbytetable local setmetatableindex = table.setmetatableindex @@ -49,6 +57,8 @@ local parsecharstring local parsecharstrings local resetcharstrings local parseprivates +local startparsing +local stopparsing local defaultstrings = { [0] = -- taken from ff ".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", @@ -129,13 +139,21 @@ local cffreaders = { local function readheader(f) local offset = getposition(f) + local major = readbyte(f) local header = { offset = offset, - major = readbyte(f), + major = major, minor = readbyte(f), size = readbyte(f), -- headersize - osize = readbyte(f), -- for offsets to start } + if major == 1 then + header.dsize = readbyte(f) -- list of dict offsets + elseif major == 2 then + header.dsize = readushort(f) -- topdict size + else + -- I'm probably no longer around by then and we use AI's to + -- handle this kind of stuff, if we typeset documents at all. + end setposition(f,offset+header.size) return header end @@ -143,8 +161,8 @@ end -- The indexes all look the same, so we share a loader. We could pass a handler -- and run over the array but why bother, we only have a few uses. -local function readlengths(f) - local count = readushort(f) +local function readlengths(f,longcount) + local count = longcount and readulong(f) or readushort(f) if count == 0 then return { } end @@ -158,7 +176,12 @@ local function readlengths(f) local previous = read(f) for i=1,count do local offset = read(f) - lengths[i] = offset - previous + local length = offset - previous + if length < 0 then + report("bad offset: %i",length) + length = 0 + end + lengths[i] = length previous = offset end return lengths @@ -216,7 +239,8 @@ end do - -- We use a closure so that we don't need to pass too much around. + -- We use a closure so that we don't need to pass too much around. For cff2 we can + -- at some point use a simple version as there is less. local stack = { } local top = 0 @@ -270,7 +294,7 @@ do result.encoding = stack[top] top = 0 end - + P("\17") / function() + + P("\17") / function() -- valid cff2 result.charstrings = stack[top] top = 0 end @@ -283,19 +307,32 @@ do end + P("\19") / function() result.subroutines = stack[top] + top = 0 -- new, forgotten ? end + P("\20") / function() result.defaultwidthx = stack[top] + top = 0 -- new, forgotten ? end + P("\21") / function() result.nominalwidthx = stack[top] + top = 0 -- new, forgotten ? + end + -- + P("\22") / function() -- reserved + -- end + -- + P("\23") / function() -- reserved + -- end + + P("\24") / function() -- new in cff2 + result.vstore = stack[top] + top = 0 + end + + P("\25") / function() -- new in cff2 + result.maxstack = stack[top] + top = 0 end - -- + P("\22") / function() end -- reserved - -- + P("\23") / function() end -- reserved - -- + P("\24") / function() end -- reserved - -- + P("\25") / function() end -- reserved - -- + P("\26") / function() end -- reserved - -- + P("\27") / function() end -- reserved + -- + P("\26") / function() -- reserved + -- end + -- + P("\27") / function() -- reserved + -- end local p_double = P("\12") * ( P("\00") / function() @@ -326,7 +363,7 @@ do result.charstringtype = stack[top] top = 0 end - + P("\07") / function() + + P("\07") / function() -- valid cff2 result.fontmatrix = { unpack(stack,1,6) } top = 0 end @@ -376,11 +413,11 @@ do result.cid.uidbase = stack[top] top = 0 end - + P("\36") / function() + + P("\36") / function() -- valid cff2 result.cid.fdarray = stack[top] top = 0 end - + P("\37") / function() + + P("\37") / function() -- valid cff2 result.cid.fdselect = stack[top] top = 0 end @@ -501,12 +538,12 @@ do + p_unsupported )^1 - parsedictionaries = function(data,dictionaries) + parsedictionaries = function(data,dictionaries,what) stack = { } strings = data.strings for i=1,#dictionaries do top = 0 - result = { + result = what == "cff" and { monospaced = false, italicangle = 0, underlineposition = -100, @@ -524,6 +561,13 @@ do fonttype = 0, count = 8720, } + } or { + charstringtype = 2, + charset = 0, + vstore = 0, + cid = { + -- nothing yet + }, } lpegmatch(p_dictionary,dictionaries[i]) dictionaries[i] = result @@ -578,22 +622,32 @@ do -- because there quite some variants are done in one helper with a lot of -- testing for states. - local x = 0 - local y = 0 - local width = false - local r = 0 - local stems = 0 - local globalbias = 0 - local localbias = 0 - local globals = false - local locals = false - local depth = 1 - local xmin = 0 - local xmax = 0 - local ymin = 0 - local ymax = 0 - local checked = false - local keepcurve = false + local x = 0 + local y = 0 + local width = false + local r = 0 + local stems = 0 + local globalbias = 0 + local localbias = 0 + local nominalwidth = 0 + local defaultwidth = 0 + local charset = false + local globals = false + local locals = false + local depth = 1 + local xmin = 0 + local xmax = 0 + local ymin = 0 + local ymax = 0 + local checked = false + local keepcurve = false + local version = 2 + local regions = false + local nofregions = 0 + local region = false + local factors = false + local axis = false + local vsindex = 0 local function showstate(where) report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top) @@ -609,16 +663,17 @@ do -- All these indirect calls make this run slower but it's cleaner this way -- and we cache the result. As we moved the boundingbox code inline we gain - -- some back. + -- some back. I inlined some of then and a bit speed can be gained by more + -- inlining but not that much. - local function moveto(x,y) + local function xymoveto() if keepcurve then r = r + 1 result[r] = { x, y, "m" } end if checked then - if x < xmin then xmin = x elseif x > xmax then xmax = x end - if y < ymin then ymin = y elseif y > ymax then ymax = y end + if x > xmax then xmax = x elseif x < xmin then xmin = x end + if y > ymax then ymax = y elseif y < ymin then ymin = y end else xmin = x ymin = y @@ -628,14 +683,58 @@ do end end - local function lineto(x,y) + local function xmoveto() -- slight speedup + if keepcurve then + r = r + 1 + result[r] = { x, y, "m" } + end + if not checked then + xmin = x + ymin = y + xmax = x + ymax = y + checked = true + elseif x > xmax then + xmax = x + elseif x < xmin then + xmin = x + end + end + + local function ymoveto() -- slight speedup + if keepcurve then + r = r + 1 + result[r] = { x, y, "m" } + end + if not checked then + xmin = x + ymin = y + xmax = x + ymax = y + checked = true + elseif y > ymax then + ymax = y + elseif y < ymin then + ymin = y + end + end + + local function moveto() + if trace_charstrings then + showstate("moveto") + end + top = 0 -- forgotten + xymoveto() + end + + local function xylineto() -- we could inline, no blend if keepcurve then r = r + 1 result[r] = { x, y, "l" } end if checked then - if x < xmin then xmin = x elseif x > xmax then xmax = x end - if y < ymin then ymin = y elseif y > ymax then ymax = y end + if x > xmax then xmax = x elseif x < xmin then xmin = x end + if y > ymax then ymax = y elseif y < ymin then ymin = y end else xmin = x ymin = y @@ -645,14 +744,53 @@ do end end - local function curveto(x1,y1,x2,y2,x3,y3) + local function xlineto() -- slight speedup + if keepcurve then + r = r + 1 + result[r] = { x, y, "l" } + end + if not checked then + xmin = x + ymin = y + xmax = x + ymax = y + checked = true + elseif x > xmax then + xmax = x + elseif x < xmin then + xmin = x + end + end + + local function ylineto() -- slight speedup + if keepcurve then + r = r + 1 + result[r] = { x, y, "l" } + end + if not checked then + xmin = x + ymin = y + xmax = x + ymax = y + checked = true + elseif y > ymax then + ymax = y + elseif y < ymin then + ymin = y + end + end + + local function xycurveto(x1,y1,x2,y2,x3,y3) -- called local so no blend here + if trace_charstrings then + showstate("curveto") + end if keepcurve then r = r + 1 result[r] = { x1, y1, x2, y2, x3, y3, "c" } end if checked then - if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end - if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end + if x1 > xmax then xmax = x1 elseif x1 < xmin then xmin = x1 end + if y1 > ymax then ymax = y1 elseif y1 < ymin then ymin = y1 end else xmin = x1 ymin = y1 @@ -660,22 +798,22 @@ do ymax = y1 checked = true end - if x2 < xmin then xmin = x2 elseif x2 > xmax then xmax = x2 end - if y2 < ymin then ymin = y2 elseif y2 > ymax then ymax = y2 end - if x3 < xmin then xmin = x3 elseif x3 > xmax then xmax = x3 end - if y3 < ymin then ymin = y3 elseif y3 > ymax then ymax = y3 end + if x2 > xmax then xmax = x2 elseif x2 < xmin then xmin = x2 end + if y2 > ymax then ymax = y2 elseif y2 < ymin then ymin = y2 end + if x3 > xmax then xmax = x3 elseif x3 < xmin then xmin = x3 end + if y3 > ymax then ymax = y3 elseif y3 < ymin then ymin = y3 end end local function rmoveto() - if top > 2 then - if not width then + if not width then + if top > 2 then width = stack[1] if trace_charstrings then - showvalue("width",width) + showvalue("backtrack width",width) end + else + width = true end - elseif not width then - width = true end if trace_charstrings then showstate("rmoveto") @@ -683,45 +821,45 @@ do x = x + stack[top-1] -- dx1 y = y + stack[top] -- dy1 top = 0 - moveto(x,y) + xymoveto() end local function hmoveto() - if top > 1 then - if not width then + if not width then + if top > 1 then width = stack[1] if trace_charstrings then - showvalue("width",width) + showvalue("backtrack width",width) end + else + width = true end - elseif not width then - width = true end if trace_charstrings then showstate("hmoveto") end x = x + stack[top] -- dx1 top = 0 - moveto(x,y) + xmoveto() end local function vmoveto() - if top > 1 then - if not width then + if not width then + if top > 1 then width = stack[1] if trace_charstrings then - showvalue("width",width) + showvalue("backtrack width",width) end + else + width = true end - elseif not width then - width = true end if trace_charstrings then showstate("vmoveto") end y = y + stack[top] -- dy1 top = 0 - moveto(x,y) + ymoveto() end local function rlineto() @@ -731,21 +869,7 @@ do for i=1,top,2 do x = x + stack[i] -- dxa y = y + stack[i+1] -- dya - lineto(x,y) - end - top = 0 - end - - local function xlineto(swap) -- x (y,x)+ | (x,y)+ - for i=1,top do - if swap then - x = x + stack[i] - swap = false - else - y = y + stack[i] - swap = true - end - lineto(x,y) + xylineto() end top = 0 end @@ -754,14 +878,48 @@ do if trace_charstrings then showstate("hlineto") end - xlineto(true) + if top == 1 then + x = x + stack[1] + xlineto() + else + local swap = true + for i=1,top do + if swap then + x = x + stack[i] + xlineto() + swap = false + else + y = y + stack[i] + ylineto() + swap = true + end + end + end + top = 0 end local function vlineto() -- y (x,y)+ | (y,x)+ if trace_charstrings then showstate("vlineto") end - xlineto(false) + if top == 1 then + y = y + stack[1] + ylineto() + else + local swap = false + for i=1,top do + if swap then + x = x + stack[i] + xlineto() + swap = false + else + y = y + stack[i] + ylineto() + swap = true + end + end + end + top = 0 end local function rrcurveto() @@ -773,9 +931,9 @@ do local ay = y + stack[i+1] -- dya local bx = ax + stack[i+2] -- dxb local by = ay + stack[i+3] -- dyb - x = bx + stack[i+4] -- dxc - y = by + stack[i+5] -- dyc - curveto(ax,ay,bx,by,x,y) + x = bx + stack[i+4] -- dxc + y = by + stack[i+5] -- dyc + xycurveto(ax,ay,bx,by,x,y) end top = 0 end @@ -786,17 +944,17 @@ do end local s = 1 if top % 2 ~= 0 then - y = y + stack[1] -- dy1 + y = y + stack[1] -- dy1 s = 2 end for i=s,top,4 do - local ax = x + stack[i] -- dxa + local ax = x + stack[i] -- dxa local ay = y local bx = ax + stack[i+1] -- dxb local by = ay + stack[i+2] -- dyb - x = bx + stack[i+3] -- dxc + x = bx + stack[i+3] -- dxc y = by - curveto(ax,ay,bx,by,x,y) + xycurveto(ax,ay,bx,by,x,y) end top = 0 end @@ -808,28 +966,64 @@ do local s = 1 local d = 0 if top % 2 ~= 0 then - d = stack[1] -- dx1 + d = stack[1] -- dx1 s = 2 end for i=s,top,4 do local ax = x + d - local ay = y + stack[i] -- dya + local ay = y + stack[i] -- dya local bx = ax + stack[i+1] -- dxb local by = ay + stack[i+2] -- dyb x = bx - y = by + stack[i+3] -- dyc - curveto(ax,ay,bx,by,x,y) + y = by + stack[i+3] -- dyc + xycurveto(ax,ay,bx,by,x,y) d = 0 end top = 0 end +-- local function xxcurveto(swap) +-- local last = top % 4 ~= 0 and stack[top] +-- if last then +-- top = top - 1 +-- end +-- for i=1,top,4 do +-- local ax, ay, bx, by +-- if swap then +-- ax = x + stack[i] +-- ay = y +-- bx = ax + stack[i+1] +-- by = ay + stack[i+2] +-- y = by + stack[i+3] +-- if last and i+3 == top then +-- x = bx + last +-- else +-- x = bx +-- end +-- swap = false +-- else +-- ax = x +-- ay = y + stack[i] +-- bx = ax + stack[i+1] +-- by = ay + stack[i+2] +-- x = bx + stack[i+3] +-- if last and i+3 == top then +-- y = by + last +-- else +-- y = by +-- end +-- swap = true +-- end +-- xycurveto(ax,ay,bx,by,x,y) +-- end +-- top = 0 +-- end + local function xxcurveto(swap) local last = top % 4 ~= 0 and stack[top] if last then top = top - 1 end - local sw = swap for i=1,top,4 do local ax, ay, bx, by if swap then @@ -857,11 +1051,12 @@ do end swap = true end - curveto(ax,ay,bx,by,x,y) + xycurveto(ax,ay,bx,by,x,y) end top = 0 end + local function hvcurveto() if trace_charstrings then showstate("hvcurveto") @@ -887,11 +1082,11 @@ do local by = ay + stack[i+3] -- dyb x = bx + stack[i+4] -- dxc y = by + stack[i+5] -- dyc - curveto(ax,ay,bx,by,x,y) + xycurveto(ax,ay,bx,by,x,y) end x = x + stack[top-1] -- dxc y = y + stack[top] -- dyc - lineto(x,y) + xylineto() top = 0 end @@ -903,7 +1098,7 @@ do for i=1,top-6,2 do x = x + stack[i] y = y + stack[i+1] - lineto(x,y) + xylineto() end end local ax = x + stack[top-5] @@ -912,7 +1107,7 @@ do local by = ay + stack[top-2] x = bx + stack[top-1] y = by + stack[top] - curveto(ax,ay,bx,by,x,y) + xycurveto(ax,ay,bx,by,x,y) top = 0 end @@ -928,14 +1123,14 @@ do local by = ay + stack[4] -- dy2 local cx = bx + stack[5] -- dx3 local cy = by + stack[6] -- dy3 - curveto(ax,ay,bx,by,cx,cy) + xycurveto(ax,ay,bx,by,cx,cy) local dx = cx + stack[7] -- dx4 local dy = cy + stack[8] -- dy4 local ex = dx + stack[9] -- dx5 local ey = dy + stack[10] -- dy5 x = ex + stack[11] -- dx6 y = ey + stack[12] -- dy6 - curveto(dx,dy,ex,ey,x,y) + xycurveto(dx,dy,ex,ey,x,y) top = 0 end @@ -943,19 +1138,19 @@ do if trace_charstrings then showstate("hflex") end - local ax = x + stack[1] -- dx1 + local ax = x + stack[1] -- dx1 local ay = y local bx = ax + stack[2] -- dx2 local by = ay + stack[3] -- dy2 local cx = bx + stack[4] -- dx3 local cy = by - curveto(ax,ay,bx,by,cx,cy) + xycurveto(ax,ay,bx,by,cx,cy) local dx = cx + stack[5] -- dx4 local dy = by local ex = dx + stack[6] -- dx5 local ey = y - x = ex + stack[7] -- dx6 - curveto(dx,dy,ex,ey,x,y) + x = ex + stack[7] -- dx6 + xycurveto(dx,dy,ex,ey,x,y) top = 0 end @@ -969,13 +1164,13 @@ do local by = ay + stack[4] -- dy2 local cx = bx + stack[5] -- dx3 local cy = by - curveto(ax,ay,bx,by,cx,cy) + xycurveto(ax,ay,bx,by,cx,cy) local dx = cx + stack[6] -- dx4 local dy = by local ex = dx + stack[7] -- dx5 local ey = dy + stack[8] -- dy5 - x = ex + stack[9] -- dx6 - curveto(dx,dy,ex,ey,x,y) + x = ex + stack[9] -- dx6 + xycurveto(dx,dy,ex,ey,x,y) top = 0 end @@ -989,7 +1184,7 @@ do local by = ay + stack[4] --dy2 local cx = bx + stack[5] --dx3 local cy = by + stack[6] --dy3 - curveto(ax,ay,bx,by,cx,cy) + xycurveto(ax,ay,bx,by,cx,cy) local dx = cx + stack[7] --dx4 local dy = cy + stack[8] --dy4 local ex = dx + stack[9] --dx5 @@ -999,7 +1194,7 @@ do else y = ey + stack[11] end - curveto(dx,dy,ex,ey,x,y) + xycurveto(dx,dy,ex,ey,x,y) top = 0 end @@ -1052,13 +1247,216 @@ do end end - local function unsupported() + local function unsupported(t) + if trace_charstrings then + showstate("unsupported " .. t) + end + top = 0 + end + + local function unsupportedsub(t) + if trace_charstrings then + showstate("unsupported sub " .. t) + end + top = 0 + end + + -- type 1 (not used in type 2) + + local function getstem3() if trace_charstrings then - showstate("unsupported") + showstate("stem3") + end + top = 0 + end + + local function divide() + if version == 1 then + local d = stack[top] + top = top - 1 + stack[top] = stack[top] / d + end + end + + local function closepath() + if version == 1 then + if trace_charstrings then + showstate("closepath") + end + end + top = 0 + end + + local function hsbw() + if version == 1 then + if trace_charstrings then + showstate("dotsection") + end + width = stack[top] + end + top = 0 + end + + local function seac() + if version == 1 then + if trace_charstrings then + showstate("seac") + end + end + top = 0 + end + + local function sbw() + if version == 1 then + if trace_charstrings then + showstate("sbw") + end + width = stack[top-1] + end + top = 0 + end + + -- these are probably used for special cases i.e. call out to postscript + + local function callothersubr() + if version == 1 then + -- we don't support this (ok, we could mimick these othersubs) + if trace_charstrings then + showstate("callothersubr (unsupported)") + end + end + top = 0 + end + + local function pop() + if version == 1 then + -- we don't support this + if trace_charstrings then + showstate("pop (unsupported)") + end + top = top + 1 + stack[top] = 0 -- a dummy + else + top = 0 + end + end + + local function setcurrentpoint() + if version == 1 then + -- we don't support this + if trace_charstrings then + showstate("pop (unsupported)") + end + x = x + stack[top-1] + y = y + stack[top] end top = 0 end + -- So far for unsupported postscript. Now some cff2 magic. As I still need + -- to wrap my head around the rather complex variable font specification + -- with regions and axis, the following approach kind of works but is more + -- some trial and error trick. It's still not clear how much of the complex + -- truetype description applies to cff. + + local reginit = false + + local function updateregions(n) -- n + 1 + if regions then + local current = regions[n] or regions[1] + nofregions = #current + if axis and n ~= reginit then + factors = { } + for i=1,nofregions do + local region = current[i] + local s = 1 + for j=1,#axis do + local f = axis[j] + local r = region[j] + local start = r.start + local peak = r.peak + local stop = r.stop + if start > peak or peak > stop then + -- * 1 + elseif start < 0 and stop > 0 and peak ~= 0 then + -- * 1 + elseif peak == 0 then + -- * 1 + elseif f < start or f > stop then + -- * 0 + s = 0 + break + elseif f < peak then + s = s * (f - start) / (peak - start) + elseif f > peak then + s = s * (stop - f) / (stop - peak) + else + -- * 1 + end + end + factors[i] = s + end + end + end + reginit = n + end + + local function setvsindex() + local vsindex = stack[top] + if trace_charstrings then + showstate(formatters["vsindex %i"](vsindex)) + end + updateregions(vsindex) + top = top - 1 + end + + local function blend() + local n = stack[top] + top = top - 1 + if axis then + -- x (r1x,r2x,r3x) + -- (x,y) (r1x,r2x,r3x) (r1y,r2y,r3y) + if trace_charstrings then + local t = top - nofregions * n + local m = t - n + for i=1,n do + local k = m + i + local d = m + n + (i-1)*nofregions + local old = stack[k] + local new = old + for r=1,nofregions do + new = new + stack[d+r] * factors[r] + end + stack[k] = new + showstate(formatters["blend %i of %i: %s -> %s"](i,n,old,new)) + end + top = t + elseif n == 1 then + top = top - nofregions + local v = stack[top] + for r=1,nofregions do + v = v + stack[top+r] * factors[r] + end + stack[top] = v + else + top = top - nofregions * n + local d = top + local k = top - n + for i=1,n do + k = k + 1 + local v = stack[k] + for r=1,nofregions do + v = v + stack[d+r] * factors[r] + end + stack[k] = v + d = d + nofregions + end + end + else + -- error + end + end + -- Bah, we cannot use a fast lpeg because a hint has an unknown size and a -- runtime capture cannot handle that well. @@ -1076,10 +1474,10 @@ do unsupported, -- 10 -- calllocal, unsupported, -- 11 -- callreturn, unsupported, -- 12 -- elsewhere - unsupported, -- 13 -- hsbw + hsbw, -- 13 -- hsbw (type 1 cff) unsupported, -- 14 -- endchar, - unsupported, -- 15 - unsupported, -- 16 + setvsindex, -- 15 -- cff2 + blend, -- 16 -- cff2 unsupported, -- 17 getstem, -- 18 -- hstemhm getmask, -- 19 -- hintmask @@ -1098,82 +1496,190 @@ do } local subactions = { + -- cff 1 + [000] = dotsection, + [001] = getstem3, + [002] = getstem3, + [006] = seac, + [007] = sbw, + [012] = divide, + [016] = callothersubr, + [017] = pop, + [033] = setcurrentpoint, + -- cff 2 [034] = hflex, [035] = flex, [036] = hflex1, [037] = flex1, } - local p_bytes = Ct((P(1)/byte)^0) + local c_endchar = char(14) - local function call(scope,list,bias,process) - local index = stack[top] + bias - top = top - 1 - if trace_charstrings then - showvalue(scope,index,true) + local passon do + + -- todo: round in blend + -- todo: delay this hash + + local rshift = bit32.rshift + local band = bit32.band + local round = math.round + + local encode = table.setmetatableindex(function(t,i) + for i=-2048,-1130 do + t[i] = char(28,band(rshift(i,8),0xFF),band(i,0xFF)) + end + for i=-1131,-108 do + local v = 0xFB00 - i - 108 + t[i] = char(band(rshift(v,8),0xFF),band(v,0xFF)) + end + for i=-107,107 do + t[i] = char(i + 139) + end + for i=108,1131 do + local v = 0xF700 + i - 108 + t[i] = char(band(rshift(v,8),0xFF),band(v,0xFF)) + end + for i=1132,2048 do + t[i] = char(28,band(rshift(i,8),0xFF),band(i,0xFF)) + end + return t[i] + end) + + local function setvsindex() + local vsindex = stack[top] + updateregions(vsindex) + top = top - 1 + end + + local function blend() + local n = stack[top] + top = top - 1 + if not axis then + -- fatal error + elseif n == 1 then + top = top - nofregions + local v = stack[top] + for r=1,nofregions do + v = v + stack[top+r] * factors[r] + end + stack[top] = round(v) + else + top = top - nofregions * n + local d = top + local k = top - n + for i=1,n do + k = k + 1 + local v = stack[k] + for r=1,nofregions do + v = v + stack[d+r] * factors[r] + end + stack[k] = round(v) + d = d + nofregions + end + end end - local str = list[index] - if str then - if type(str) == "string" then - str = lpegmatch(p_bytes,str) - list[index] = str + + passon = function(operation) + if operation == 15 then + setvsindex() + elseif operation == 16 then + blend() + else + for i=1,top do + r = r + 1 + result[r] = encode[stack[i]] + end + r = r + 1 + result[r] = char(operation) -- maybe use a hash + top = 0 end - depth = depth + 1 - process(str) - depth = depth - 1 + end + + end + + -- end of experiment + + local process + + local function call(scope,list,bias) -- ,process) + depth = depth + 1 + if top == 0 then + showstate(formatters["unknown %s call"](scope)) + top = 0 else - report("unknown %s %i",scope,index) + local index = stack[top] + bias + top = top - 1 + if trace_charstrings then + showvalue(scope,index,true) + end + local tab = list[index] + if tab then + process(tab) + else + showstate(formatters["unknown %s call %i"](scope,index)) + top = 0 + end end + depth = depth - 1 end - local function process(tab) + -- precompiling and reuse is much slower than redoing the calls + + local justpass = false + + process = function(tab) local i = 1 local n = #tab while i <= n do local t = tab[i] - if t >= 32 and t<=246 then - -- -107 .. +107 + if t >= 32 then top = top + 1 - stack[top] = t - 139 - i = i + 1 - elseif t >= 247 and t <= 250 then - -- +108 .. +1131 - top = top + 1 - stack[top] = (t-247)*256 + tab[i+1] + 108 - i = i + 2 - elseif t >= 251 and t <= 254 then - -- -1131 .. -108 - top = top + 1 - stack[top] = -(t-251)*256 - tab[i+1] - 108 - i = i + 2 + if t <= 246 then + -- -107 .. +107 + stack[top] = t - 139 + i = i + 1 + elseif t <= 250 then + -- +108 .. +1131 + -- stack[top] = (t-247)*256 + tab[i+1] + 108 + -- stack[top] = t*256 - 247*256 + tab[i+1] + 108 + stack[top] = t*256 - 63124 + tab[i+1] + i = i + 2 + elseif t <= 254 then + -- -1131 .. -108 + -- stack[top] = -(t-251)*256 - tab[i+1] - 108 + -- stack[top] = -t*256 + 251*256 - tab[i+1] - 108 + stack[top] = -t*256 + 64148 - tab[i+1] + i = i + 2 + else + local n = 0x100 * tab[i+1] + tab[i+2] + if n >= 0x8000 then + -- stack[top] = n - 0xFFFF - 1 + (0x100 * tab[i+3] + tab[i+4])/0xFFFF + stack[top] = n - 0x10000 + (0x100 * tab[i+3] + tab[i+4])/0xFFFF + else + stack[top] = n + (0x100 * tab[i+3] + tab[i+4])/0xFFFF + end + i = i + 5 + end elseif t == 28 then -- -32768 .. +32767 : b1<<8 | b2 top = top + 1 local n = 0x100 * tab[i+1] + tab[i+2] if n >= 0x8000 then - stack[top] = n - 0xFFFF - 1 + -- stack[top] = n - 0xFFFF - 1 + stack[top] = n - 0x10000 else stack[top] = n end i = i + 3 - elseif t == 255 then - local n = 0x100 * tab[i+1] + tab[i+2] - top = top + 1 - if n >= 0x8000 then - stack[top] = n - 0xFFFF - 1 + (0x100 * tab[i+3] + tab[i+4])/0xFFFF - else - stack[top] = n + (0x100 * tab[i+3] + tab[i+4])/0xFFFF - end - i = i + 5 - elseif t == 11 then + elseif t == 11 then -- not in cff2 if trace_charstrings then showstate("return") end return elseif t == 10 then - call("local",locals,localbias,process) + call("local",locals,localbias) -- ,process) i = i + 1 - elseif t == 14 then -- endchar + elseif t == 14 then -- not in cff2 if width then -- okay elseif top > 0 then @@ -1189,14 +1695,14 @@ do end return elseif t == 29 then - call("global",globals,globalbias,process) + call("global",globals,globalbias) -- ,process) i = i + 1 elseif t == 12 then i = i + 1 local t = tab[i] local a = subactions[t] if a then - a() + a(t) else if trace_charstrings then showvalue("<subaction>",t) @@ -1204,20 +1710,25 @@ do top = 0 end i = i + 1 + elseif justpass then + passon(t) + i = i + 1 else local a = actions[t] if a then - local s = a() + local s = a(t) if s then - i = i + s + i = i + s + 1 + else + i = i + 1 end else if trace_charstrings then showvalue("<action>",t) end top = 0 + i = i + 1 end - i = i + 1 end end end @@ -1236,7 +1747,7 @@ do -- if y < ymin then ymin = y end -- if y > ymax then ymax = y end -- -- we now have a reasonable start so we could - -- -- simplyfy the next checks + -- -- simplify the next checks -- for i=1,nofsegments do -- local s = segments[i] -- local x = s[1] @@ -1260,142 +1771,76 @@ do -- end -- end - parsecharstrings = function(data,glyphs,doshapes) - -- for all charstrings - local dictionary = data.dictionaries[1] - local charstrings = dictionary.charstrings - local charset = dictionary.charset - keepcurve = doshapes - stack = { } - glyphs = glyphs or { } - strings = data.strings - locals = dictionary.subroutines - globals = data.routines - globalbias = #globals - localbias = #locals - globalbias = ((globalbias < 1240 and 107) or (globalbias < 33900 and 1131) or 32768) + 1 - localbias = ((localbias < 1240 and 107) or (localbias < 33900 and 1131) or 32768) + 1 - local nominalwidth = dictionary.private.data.nominalwidthx or 0 - local defaultwidth = dictionary.private.data.defaultwidthx or 0 - - for i=1,#charstrings do - local str = charstrings[i] - local tab = lpegmatch(p_bytes,str) - local index = i - 1 - x = 0 - y = 0 - width = false - r = 0 - top = 0 - stems = 0 - result = { } - -- - xmin = 0 - xmax = 0 - ymin = 0 - ymax = 0 - checked = false - -- - if trace_charstrings then - report("glyph: %i",index) - report("data: % t",tab) - end - -- - process(tab) - -- - local boundingbox = { round(xmin), round(ymin), round(xmax), round(ymax) } - -- - if width == true or width == false then - width = defaultwidth - else - width = nominalwidth + width - end - -- - -- trace_charstrings = index == 3078 -- todo: make tracker - local glyph = glyphs[index] -- can be autodefined in otr - if not glyph then - glyphs[index] = { - segments = doshapes ~= false and result or nil, -- optional - boundingbox = boundingbox, - width = width, - name = charset[index], - -- sidebearing = 0, - } - else - glyph.segments = doshapes ~= false and result or nil - glyph.boundingbox = boundingbox - if not glyph.width then - glyph.width = width - end - if charset and not glyph.name then - glyph.name = charset[index] - end - -- glyph.sidebearing = 0 -- todo - end - if trace_charstrings then - report("width: %s",tostring(width)) - report("boundingbox: % t",boundingbox) - end - charstrings[i] = nil -- free memory + local function setbias(globals,locals) + if version == 1 then + return + false, + false + else + local g, l = #globals, #locals + return + ((g < 1240 and 107) or (g < 33900 and 1131) or 32768) + 1, + ((l < 1240 and 107) or (l < 33900 and 1131) or 32768) + 1 end - return glyphs end - parsecharstring = function(data,dictionary,charstring,glyphs,index,doshapes) - local private = dictionary.private - keepcurve = doshapes - strings = data.strings -- or in dict? - locals = dictionary.subroutines or { } - globals = data.routines or { } - globalbias = #globals - localbias = #locals - globalbias = ((globalbias < 1240 and 107) or (globalbias < 33900 and 1131) or 32768) + 1 - localbias = ((localbias < 1240 and 107) or (localbias < 33900 and 1131) or 32768) + 1 - local nominalwidth = private and private.data.nominalwidthx or 0 - local defaultwidth = private and private.data.defaultwidthx or 0 - -- - local tab = lpegmatch(p_bytes,charstring) - x = 0 - y = 0 - width = false - r = 0 - top = 0 - stems = 0 - result = { } - -- - xmin = 0 - xmax = 0 - ymin = 0 - ymax = 0 - checked = false - -- + local function processshape(tab,index) + + tab = bytetable(tab) + + x = 0 + y = 0 + width = false + r = 0 + top = 0 + stems = 0 + result = { } -- we could reuse it when only boundingbox calculations are needed + + xmin = 0 + xmax = 0 + ymin = 0 + ymax = 0 + checked = false + if trace_charstrings then report("glyph: %i",index) - report("data: % t",tab) + report("data : % t",tab) end - -- + + if regions then + updateregions(vsindex) + end + process(tab) - -- - local boundingbox = { xmin, ymin, xmax, ymax } - -- + + local boundingbox = { + round(xmin), + round(ymin), + round(xmax), + round(ymax), + } + if width == true or width == false then width = defaultwidth else width = nominalwidth + width end - -- -index = index - 1 + local glyph = glyphs[index] -- can be autodefined in otr - if not glyph then - glyphs[index] = { - segments = doshapes ~= false and result or nil, -- optional - boundingbox = boundingbox, - width = width, - name = charset[index], - -- sidebearing = 0, - } - else - glyph.segments = doshapes ~= false and result or nil + if justpass then + r = r + 1 + result[r] = c_endchar + local stream = concat(result) + -- if trace_charstrings then + -- report("vdata: %s",stream) + -- end + if glyph then + glyph.stream = stream + else + glyphs[index] = { stream = stream } + end + elseif glyph then + glyph.segments = keepcurve ~= false and result or nil glyph.boundingbox = boundingbox if not glyph.width then glyph.width = width @@ -1404,20 +1849,107 @@ index = index - 1 glyph.name = charset[index] end -- glyph.sidebearing = 0 -- todo + elseif keepcurve then + glyphs[index] = { + segments = result, + boundingbox = boundingbox, + width = width, + name = charset and charset[index] or nil, + -- sidebearing = 0, + } + else + glyphs[index] = { + boundingbox = boundingbox, + width = width, + name = charset and charset[index] or nil, + } end - -- + if trace_charstrings then - report("width: %s",tostring(width)) + report("width : %s",tostring(width)) report("boundingbox: % t",boundingbox) end - -- - return charstring + end - resetcharstrings = function() - result = { } - top = 0 - stack = { } + startparsing = function(fontdata,data,streams) + reginit = false + axis = false + regions = data.regions + justpass = streams == true + if regions then + regions = { regions } -- needs checking + axis = data.factors or false + end + end + + stopparsing = function(fontdata,data) + stack = { } + glyphs = false + result = { } + top = 0 + locals = false + globals = false + strings = false + end + + local function setwidths(private) + if not private then + return 0, 0 + end + local privatedata = private.data + if not privatedata then + return 0, 0 + end + return privatedata.nominalwidthx or 0, privatedata.defaultwidthx or 0 + end + + parsecharstrings = function(fontdata,data,glphs,doshapes,tversion,streams) + + local dictionary = data.dictionaries[1] + local charstrings = dictionary.charstrings + + keepcurve = doshapes + version = tversion + strings = data.strings + globals = data.routines or { } + locals = dictionary.subroutines or { } + charset = dictionary.charset + vsindex = dictionary.vsindex or 0 + glyphs = glphs or { } + + globalbias, localbias = setbias(globals,locals) + nominalwidth, defaultwidth = setwidths(dictionary.private) + + startparsing(fontdata,data,streams) + + for index=1,#charstrings do + processshape(charstrings[index],index-1) + charstrings[index] = nil -- free memory (what if used more often?) + end + + stopparsing(fontdata,data) + + return glyphs + end + + parsecharstring = function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion) + + keepcurve = doshapes + version = tversion + strings = data.strings + globals = data.routines or { } + locals = dictionary.subroutines or { } + charset = false + vsindex = dictionary.vsindex or 0 + glyphs = glphs or { } + + globalbias, localbias = setbias(globals,locals) + nominalwidth, defaultwidth = setwidths(dictionary.private) + + processshape(tab,index-1) + + -- return glyphs[index] end end @@ -1425,7 +1957,7 @@ end local function readglobals(f,data) local routines = readlengths(f) for i=1,#routines do - routines[i] = readstring(f,routines[i]) + routines[i] = readbytetable(f,routines[i]) end data.routines = routines end @@ -1439,8 +1971,7 @@ local function readcharsets(f,data,dictionary) local strings = data.strings local nofglyphs = data.nofglyphs local charsetoffset = dictionary.charset - - if charsetoffset ~= 0 then + if charsetoffset and charsetoffset ~= 0 then setposition(f,header.offset+charsetoffset) local format = readbyte(f) local charset = { [0] = ".notdef" } @@ -1466,6 +1997,9 @@ local function readcharsets(f,data,dictionary) else report("cff parser: unsupported charset format %a",format) end + else + dictionary.nocharset = true + dictionary.charset = nil end end @@ -1488,7 +2022,7 @@ local function readlocals(f,data,dictionary) setposition(f,header.offset+private.offset+subroutineoffset) local subroutines = readlengths(f) for i=1,#subroutines do - subroutines[i] = readstring(f,subroutines[i]) + subroutines[i] = readbytetable(f,subroutines[i]) end dictionary.subroutines = subroutines private.data.subroutines = nil @@ -1503,16 +2037,18 @@ end -- These charstrings are little programs and described in: Technical Note #5177. A truetype -- font has only one dictionary. -local function readcharstrings(f,data) +local function readcharstrings(f,data,what) local header = data.header local dictionaries = data.dictionaries local dictionary = dictionaries[1] - local type = dictionary.charstringtype + local stringtype = dictionary.charstringtype local offset = dictionary.charstrings - if type == 2 then + if type(offset) ~= "number" then + -- weird + elseif stringtype == 2 then setposition(f,header.offset+offset) -- could be a metatable .. delayed loading - local charstrings = readlengths(f) + local charstrings = readlengths(f,what=="cff2") local nofglyphs = #charstrings for i=1,nofglyphs do charstrings[i] = readstring(f,charstrings[i]) @@ -1520,7 +2056,7 @@ local function readcharstrings(f,data) data.nofglyphs = nofglyphs dictionary.charstrings = charstrings else - report("unsupported charstr type %i",type) + report("unsupported charstr type %i",stringtype) data.nofglyphs = 0 dictionary.charstrings = { } end @@ -1542,29 +2078,38 @@ local function readcidprivates(f,data) parseprivates(data,dictionaries) end -local function readnoselect(f,data,glyphs,doshapes) +readers.parsecharstrings = parsecharstrings -- used in font-onr.lua (type 1) + +local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams) local dictionaries = data.dictionaries local dictionary = dictionaries[1] readglobals(f,data) - readcharstrings(f,data) - readencodings(f,data) - readcharsets(f,data,dictionary) + readcharstrings(f,data,version) + if version == "cff2" then + dictionary.charset = nil + else + readencodings(f,data) + readcharsets(f,data,dictionary) + end readprivates(f,data) parseprivates(data,data.dictionaries) readlocals(f,data,dictionary) - parsecharstrings(data,glyphs,doshapes) - resetcharstrings() + startparsing(fontdata,data,streams) + parsecharstrings(fontdata,data,glyphs,doshapes,version,streams) + stopparsing(fontdata,data) end -local function readfdselect(f,data,glyphs,doshapes) +local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams) local header = data.header local dictionaries = data.dictionaries local dictionary = dictionaries[1] local cid = dictionary.cid local cidselect = cid and cid.fdselect readglobals(f,data) - readcharstrings(f,data) - readencodings(f,data) + readcharstrings(f,data,version) + if version ~= "cff2" then + readencodings(f,data) + end local charstrings = dictionary.charstrings local fdindex = { } local nofglyphs = data.nofglyphs @@ -1601,6 +2146,7 @@ local function readfdselect(f,data,glyphs,doshapes) else -- unsupported format end + -- hm, always if maxindex >= 0 then local cidarray = cid.fdarray setposition(f,header.offset+cidarray) @@ -1614,85 +2160,157 @@ local function readfdselect(f,data,glyphs,doshapes) for i=1,#dictionaries do readlocals(f,data,dictionaries[i]) end + startparsing(fontdata,data,streams) for i=1,#charstrings do - parsecharstring(data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes) + parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version) + charstrings[i] = nil end - resetcharstrings() + stopparsing(fontdata,data) end end +local gotodatatable = readers.helpers.gotodatatable + +local function cleanup(data,dictionaries) + -- for i=1,#dictionaries do + -- local d = dictionaries[i] + -- d.subroutines = nil + -- end + -- data.strings = nil + -- if data then + -- data.charstrings = nil + -- data.routines = nil + -- end +end + function readers.cff(f,fontdata,specification) --- if specification.glyphs then - if specification.details then - local datatable = fontdata.tables.cff - if datatable then - local offset = datatable.offset - local glyphs = fontdata.glyphs - if not f then - report("invalid filehandle") - return - end - if offset then - setposition(f,offset) - end - local header = readheader(f) - if header.major > 1 then - report("version mismatch") - return - end - local names = readfontnames(f) - local dictionaries = readtopdictionaries(f) - local strings = readstrings(f) - local data = { - header = header, - names = names, - dictionaries = dictionaries, - strings = strings, - nofglyphs = fontdata.nofglyphs, - } - -- - parsedictionaries(data,data.dictionaries) - -- - local d = dictionaries[1] - local c = d.cid - fontdata.cffinfo = { - familynamename = d.familyname, - fullname = d.fullname, - boundingbox = d.boundingbox, - weight = d.weight, - italicangle = d.italicangle, - underlineposition = d.underlineposition, - underlinethickness = d.underlinethickness, - monospaced = d.monospaced, - } - fontdata.cidinfo = c and { - registry = c.registry, - ordering = c.ordering, - supplement = c.supplement, - } - -- - if not specification.glyphs then - -- we only want some metadata + local tableoffset = gotodatatable(f,fontdata,"cff",specification.details) + if tableoffset then + local header = readheader(f) + if header.major ~= 1 then + report("only version %s is supported for table %a",1,"cff") + return + end + local glyphs = fontdata.glyphs + local names = readfontnames(f) + local dictionaries = readtopdictionaries(f) + local strings = readstrings(f) + local data = { + header = header, + names = names, + dictionaries = dictionaries, + strings = strings, + nofglyphs = fontdata.nofglyphs, + } + -- + parsedictionaries(data,dictionaries,"cff") + -- + local dic = dictionaries[1] + local cid = dic.cid + fontdata.cffinfo = { + familynamename = dic.familyname, + fullname = dic.fullname, + boundingbox = dic.boundingbox, + weight = dic.weight, + italicangle = dic.italicangle, + underlineposition = dic.underlineposition, + underlinethickness = dic.underlinethickness, + monospaced = dic.monospaced, + } + fontdata.cidinfo = cid and { + registry = cid.registry, + ordering = cid.ordering, + supplement = cid.supplement, + } + -- + if specification.glyphs then + local all = specification.shapes or false + if cid and cid.fdselect then + readfdselect(f,fontdata,data,glyphs,all,"cff") else - local cid = d.cid - if cid and cid.fdselect then - readfdselect(f,data,glyphs,specification.shapes or false) - else - readnoselect(f,data,glyphs,specification.shapes or false) - end + readnoselect(f,fontdata,data,glyphs,all,"cff") end + end + cleanup(data,dictionaries) + end +end + +function readers.cff2(f,fontdata,specification) + local tableoffset = gotodatatable(f,fontdata,"cff2",specification.glyphs) + if tableoffset then + local header = readheader(f) + if header.major ~= 2 then + report("only version %s is supported for table %a",2,"cff2") + return + end + local glyphs = fontdata.glyphs + local dictionaries = { readstring(f,header.dsize) } + local data = { + header = header, + dictionaries = dictionaries, + nofglyphs = fontdata.nofglyphs, + } + -- + parsedictionaries(data,dictionaries,"cff2") + -- + local offset = dictionaries[1].vstore + if offset > 0 then + local storeoffset = dictionaries[1].vstore + data.header.offset + 2 -- cff has a preceding size field + local regions, deltas = readers.helpers.readvariationdata(f,storeoffset,factors) -- - -- cleanup (probably more can go) - -- - -- for i=1,#dictionaries do - -- local d = dictionaries[i] - -- d.subroutines = nil - -- end - -- data.strings = nil - -- if data then - -- data.charstrings = nil - -- data.routines = nil - -- end + data.regions = regions + data.deltas = deltas + else + data.regions = { } + data.deltas = { } + end + data.factors = specification.factors + -- + local cid = data.dictionaries[1].cid + local all = specification.shapes or false + if cid and cid.fdselect then + readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) + else + readnoselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) + end + cleanup(data,dictionaries) + end +end + +-- temporary helper needed for checking backend patches + +function readers.cffcheck(filename) + local f = io.open(filename,"rb") + if f then + local fontdata = { + glyphs = { }, + } + local header = readheader(f) + if header.major ~= 1 then + report("only version %s is supported for table %a",1,"cff") + return + end + local names = readfontnames(f) + local dictionaries = readtopdictionaries(f) + local strings = readstrings(f) + local glyphs = { } + local data = { + header = header, + names = names, + dictionaries = dictionaries, + strings = strings, + glyphs = glyphs, + nofglyphs = 4, + } + -- + parsedictionaries(data,dictionaries,"cff") + -- + local cid = data.dictionaries[1].cid + if cid and cid.fdselect then + readfdselect(f,fontdata,data,glyphs,false) + else + readnoselect(f,fontdata,data,glyphs,false) end + return data end end diff --git a/tex/context/base/mkiv/font-cft.lua b/tex/context/base/mkiv/font-cft.lua new file mode 100644 index 000000000..63c056022 --- /dev/null +++ b/tex/context/base/mkiv/font-cft.lua @@ -0,0 +1,543 @@ +if not modules then modules = { } end modules ['font-cft'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- context font tables + +-- todo: extra: +-- +-- extra_space => space.extra +-- space => space.width +-- space_stretch => space.stretch +-- space_shrink => space.shrink + +-- We do keep the x-height, extra_space, space_shrink and space_stretch +-- around as these are low level official names. + +local type = type + +local fonts = fonts or { } +local tables = fonts.tables or { } +fonts.tables = tables + +local data = utilities.storage.allocate() +tables.data = data + +do + + local t_units = "<units>" + local t_unicode = "<unicode>" + local t_unispec = "<unispec>" -- t_unicode | { t_unicode } + local t_index = "<index>" + local t_cardinal = "<cardinal>" + local t_integer = "<integer>" + local t_float = "<float>" + local t_boolean = "<boolean>" + local t_string = "<string>" + local t_array = "<array>" + local t_hash = "<hash>" + local t_scaled = "<scaled>" + local t_keyword = "<keyword>" + local t_scale = "<scale>" -- 1000 based tex scale + local t_value = "<value>" -- number, string, boolean + local t_function = "<function>" + + data.types = { + ["units"] = "<units>", + ["unicode"] = "<unicode>", + ["unispec"] = "<unispec>" , -- t_unicode | { t_unicode } + ["index"] = "<index>", + ["cardinal"] = "<cardinal>", + ["integer"] = "<integer>", + ["float"] = "<float>", + ["boolean"] = "<boolean>", + ["string"] = "<string>", + ["array"] = "<array>", + ["hash"] = "<hash>", + ["scaled"] = "<scaled>", + ["keyword"] = "<keyword>", + ["scale"] = "<scale>", -- 1000 based tex scale + ["value"] = "<value>", -- number, string, boolean + ["function"] = "<function>", + } + + local boundingbox = { + t_units, + t_units, + t_units, + t_units + } + + local mathvariants = { + t_array + } + + local mathparts = { + { + advance = t_units, + ["end"] = t_units, + extender = t_units, + glyph = t_unicode, + start = t_units, + } + } + + local mathkerns = { + { + height = t_units, + kern = t_units, + }, + } + + local mathparts = { + { + advance = t_scaled, + ["end"] = t_scaled, + extender = t_scaled, + glyph = t_unicode, + start = t_scaled, + } + } + + local mathkerns = { + { + height = t_scaled, + kern = t_scaled, + }, + } + + local vfcommands = { + { t_keyword, t_value }, + } + + local description = { + width = t_units, + height = t_units, + depth = t_units, + italic = t_units, + index = t_index, + boundingbox = boundingbox, + unicode = t_unispec, + math = { + accent = t_units, + hvariants = mathvariants, + vvariants = mathvariants, + hparts = mathparts, + vparts = mathparts, + kerns = { + bottomright = mathkerns, + bottomleft = mathkerns, + topright = mathkerns, + topleft = mathkerns, + } + }, + } + + local character = { + width = t_scaled, + height = t_scaled, + depth = t_scaled, + italic = t_scaled, + index = t_index, + expansion_factor = t_scaled, + left_protruding = t_scaled, + right_protruding = t_scaled, + tounicode = t_string, + unicode = t_unispec, + commands = vfcommands, + accent = t_scaled, + hvariants = mathvariants, + vvariants = mathvariants, + hparts = math_parts, + vparts = math_parts, + kerns = { + bottomright = math_kerns, + bottomleft = math_kerns, + topright = math_kerns, + topleft = math_kerns, + }, + ligatures = t_hash, + kerns = t_hash, + next = t_array, + } + + data.original = { + cache_uuid = t_string, + cache_version = t_float, + compacted = t_boolean, + creator = t_string, + descriptions = { description }, + format = t_string, + goodies = t_hash, + metadata = { + ascender = t_units, + averagewidth = t_units, + capheight = t_units, + descender = t_units, + family = t_string, + familyname = t_string, + fontname = t_string, + fullname = t_string, + italicangle = t_float, + monospaced = t_boolean, + panoseweight = t_string, + panosewidth = t_string, + pfmweight = t_units, + pfmwidth = t_units, + subfamily = t_string, + subfamilyname = t_string, + subfontindex = t_index, + units = t_cardinal, + version = t_string, + weight = t_string, + width = t_string, + xheight = t_units, + }, + private = t_unicode, + properties = { + hascolor = t_boolean, + hasitalics = t_boolean, + hasspacekerns = t_boolean, + }, + resources = { + duplicates = t_hash, + features = { + gpos = t_hash, + gsub = t_hash, + }, + filename = t_string, + markclasses = t_hash, + marks = t_hash, + marksets = t_hash, + mathconstants = t_hash, + private = t_cardinal, + sequences = t_array, + -- unicodes = t_hash, + version = t_string, + }, + size = t_cardinal, + -- tables = t_array, + tableversion = t_float, + time = t_cardinal, + } + + data.scaled = { + properties = { + encodingbytes = t_cardinal, + embedding = t_cardinal, -- ? + cidinfo = t_hash, + format = t_string, + fontname = t_string, + fullname = t_string, + filename = t_string, + psname = t_string, + name = t_string, + virtualized = t_boolean, + hasitalics = t_boolean, + autoitalicamount = t_float, + nostackmath = t_boolean, + noglyphnames = t_boolean, + mode = t_string, + hasmath = t_boolean, + mathitalics = t_boolean, + textitalics = t_boolean, + finalized = t_boolean, + }, + parameters = { + mathsize = t_cardinal, + scriptpercentage = t_float, + scriptscriptpercentage = t_float, + units = t_cardinal, + designsize = t_scaled, + expansion = { + stretch = t_scale, + shrink = t_scale, + step = t_scale, + auto = t_boolean, + }, + protrusion = { + auto = t_boolean, + }, + slantfactor = t_float, + extendfactor = t_float, + factor = t_float, + hfactor = t_float, + vfactor = t_float, + size = t_scaled, + units = t_scaled, + scaledpoints = t_scaled, + slantperpoint = t_scaled, + xheight = t_scaled, + quad = t_scaled, + ascender = t_scaled, + descender = t_scaled, + spacing = { + width = t_scaled, + stretch = t_scaled, + shrink = t_scaled, + extra = t_scaled, + }, + -- synonyms = { + -- space = "spacing.width", + -- spacestretch = "spacing.stretch", + -- spaceshrink = "spacing.shrink", + -- extraspace = "spacing.extra", + -- x_height = "xheight", + -- space_stretch = "spacing.stretch", + -- space_shrink = "spacing.shrink", + -- extra_space = "spacing.extra", + -- em = "quad", + -- ex = "xheight", + -- slant = "slantperpoint", + -- }, + }, + descriptions = { description }, + characters = { character }, + } + + data.goodies = { + -- preamble + name = t_string, + version = t_string, + comment = t_string, + author = t_string, + copyright = t_string, + -- + remapping = { + tounicode = t_boolean, + unicodes = { + [t_string] = t_index, + }, + }, + mathematics = { + mapfiles = { + t_string, + }, + virtuals = { + [t_string] = { + { + name = t_string, + features = t_hash, + main = t_boolean, + extension = t_boolean, + vector = t_string, + skewchar = t_unicode, + parameters = t_boolean, + }, + }, + }, + italics = { + [t_string] = { + defaultfactor = t_float, + disableengine = t_boolean, + corrections = { + [t_unicode] = t_float, + } + }, + }, + kerns = { + [t_unicode] = { + bottomright = math_kerns, + topright = math_kerns, + bottomleft = math_kerns, + topleft = math_kerns, + }, + }, + alternates = { + [t_string] = { + feature = t_hash, + value = t_float, + comment = t_string, + }, + }, + variables = { + [t_string] = t_value, + }, + parameters = { + [t_string] = t_value, + [t_string] = t_function, + }, + dimensions = { + [t_string] = { + [t_unicode] = { + width = t_units, + height = t_units, + depth = t_units, + xoffset = t_units, + yoffset = t_units, + }, + }, + }, + }, + filenames = { + [t_string] = { + t_string, + }, + }, + compositions = { + [t_string] = { + dy = t_unit, + dx = t_unit, + [t_unicode] = { + dy = t_unit + }, + [t_unicode] = { + anchors = { + top = { + x = t_unit, + y = t_unit, + }, + bottom = { + x = t_unit, + y = t_unit, + }, + }, + }, + }, + }, + postprocessors = { + [t_string] = t_function, + }, + designsizes = { + [t_string] = { + [t_string] = t_string, + default = t_string + }, + }, + featuresets = { + [t_string] = { + t_string, + [t_keyword] = t_value + }, + }, + solutions = { + experimental = { + less = { t_string }, + more = { t_string }, + }, + }, + stylistics = { + [t_string] = t_string, + [t_string] = t_string, + }, + colorschemes = { + default = { + [1] = { t_string }, + } + }, + files = { + name = t_string, + list = { + [t_string] = { + name = t_string, + weight = t_string, + style = t_string, + width = t_string, + }, + }, + }, + typefaces = { + [t_string] = { + shortcut = t_string, + shape = t_string, + fontname = t_string, + normalweight = t_string, + boldweight = t_string, + width = t_string, + size = t_string, + features = t_string, + }, + }, + } + +end + +-- compatibility (for now) + +if fonts.constructors then + fonts.constructors.keys = data.scaled +end + +-- handy helpers + +local report = logs.reporter("fonts") + +function tables.savefont(specification) + local method = specification.method + local filename = specification.filename + local fontname = specification.fontname + if not method or method ~= "original" then + method = "scaled" + end + if not filename or filename == "" then + filename = "temp-font-" .. method .. ".lua" + else + filename = file.addsuffix(filename,"lua") + end + if not fontname or fontname == "" then + fontname = true + end + if fontname == true then + report("saving current font in %a",filename) + elseif tonumber(fontname) then + report("saving font id %a in %a",fontname,filename) + fontname = tonumber(fontname) + else + report("saving font %a in %a",fontname,filename) + tfmdata = fonts.definers.define { + name = fontname + } + end + if tfmdata then + tfmdata = fonts.hashes.identifiers[tfmdata] + end + if not tfmdata then + -- bad news + elseif method == "original" then + tfmdata = tfmdata.shared and tfmdata.shared.rawdata + else + tfmdata = { + characters = tfmdata.characters, + parameters = tfmdata.parameters, + properties = tfmdata.properties, + specification = tfmdata.specification, + } + end + if tfmdata then + table.save(filename,tfmdata) + else + -- os.remove(filename) + report("saving font failed") + end +end + +function tables.saveoriginal(filename,specification) + local tfmdata = get(specification) + if tfmdata then + local rawdata = tfmdata.shared and tfmdata.shared.rawdata + if rawdata then + table.save(filename,rawdata) + end + end +end + +if context then + + interfaces.implement { + name = "savefont", + actions = tables.savefont, + arguments = { + { + { "filename" }, + { "fontname" }, + { "method" }, + } + }, + } + +end + diff --git a/tex/context/base/mkiv/font-chk.lua b/tex/context/base/mkiv/font-chk.lua index 15291052f..d9e88c91e 100644 --- a/tex/context/base/mkiv/font-chk.lua +++ b/tex/context/base/mkiv/font-chk.lua @@ -11,58 +11,63 @@ if not modules then modules = { } end modules ['font-chk'] = { local next = next -local formatters = string.formatters -local bpfactor = number.dimenfactors.bp -local fastcopy = table.fastcopy +local formatters = string.formatters +local bpfactor = number.dimenfactors.bp +local fastcopy = table.fastcopy -local report_fonts = logs.reporter("fonts","checking") +local report_fonts = logs.reporter("fonts","checking") -- replace -local allocate = utilities.storage.allocate +local allocate = utilities.storage.allocate -local fonts = fonts +local fonts = fonts -fonts.checkers = fonts.checkers or { } -local checkers = fonts.checkers +fonts.checkers = fonts.checkers or { } +local checkers = fonts.checkers -local fonthashes = fonts.hashes -local fontdata = fonthashes.identifiers -local fontcharacters = fonthashes.characters +local fonthashes = fonts.hashes +local fontdata = fonthashes.identifiers +local fontcharacters = fonthashes.characters -local helpers = fonts.helpers +local helpers = fonts.helpers -local addprivate = helpers.addprivate -local hasprivate = helpers.hasprivate -local getprivatenode = helpers.getprivatenode +local addprivate = helpers.addprivate +local hasprivate = helpers.hasprivate +local getprivateslot = helpers.getprivateslot +local getprivatecharornode = helpers.getprivatecharornode -local otffeatures = fonts.constructors.newfeatures("otf") -local registerotffeature = otffeatures.register -local afmfeatures = fonts.constructors.newfeatures("afm") -local registerafmfeature = afmfeatures.register +local otffeatures = fonts.constructors.features.otf +local afmfeatures = fonts.constructors.features.afm -local is_character = characters.is_character -local chardata = characters.data +local registerotffeature = otffeatures.register +local registerafmfeature = afmfeatures.register -local tasks = nodes.tasks -local enableaction = tasks.enableaction -local disableaction = tasks.disableaction +local is_character = characters.is_character +local chardata = characters.data -local implement = interfaces.implement +local tasks = nodes.tasks +local enableaction = tasks.enableaction +local disableaction = tasks.disableaction -local glyph_code = nodes.nodecodes.glyph +local implement = interfaces.implement -local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode +local glyph_code = nodes.nodecodes.glyph -local getfont = nuts.getfont -local getchar = nuts.getchar +local new_special = nodes.pool.special +local hpack_node = node.hpack -local setfield = nuts.setfield -local setchar = nuts.setchar +local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode -local traverse_id = nuts.traverse_id -local remove_node = nuts.remove -local insert_node_after = nuts.insert_after +local getfont = nuts.getfont +local getchar = nuts.getchar + +local setfield = nuts.setfield +local setchar = nuts.setchar + +local traverse_id = nuts.traverse_id +local remove_node = nuts.remove +local insert_node_after = nuts.insert_after -- maybe in fonts namespace -- deletion can be option @@ -179,11 +184,21 @@ local pdf_blob = "pdf: q %0.6F 0 0 %0.6F 0 0 cm %s %s %s rg %s %s %s RG 10 M 1 j local cache = { } -- saves some tables but not that impressive +local function missingtonode(tfmdata,character) + local commands = character.commands + local fake = hpack_node(new_special(commands[1][2])) + fake.width = character.width + fake.height = character.height + fake.depth = character.depth + return fake +end + local function addmissingsymbols(tfmdata) -- we can have an alternative with rules local characters = tfmdata.characters + local properties = tfmdata.properties local size = tfmdata.parameters.size - local privates = tfmdata.properties.privates local scale = size * bpfactor + local tonode = properties.finalized and missingtonode or nil for i=1,#variants do local v = variants[i] local tag, r, g, b = v.tag, v.r, v.g, v.b @@ -196,6 +211,7 @@ local function addmissingsymbols(tfmdata) -- we can have an alternative with rul local char = cache[hash] if not char then char = { + tonode = tonode, width = size*fake.width, height = size*fake.height, depth = size*fake.depth, @@ -225,27 +241,21 @@ fonts.loggers.category_to_placeholder = mapping function commands.getplaceholderchar(name) local id = font.current() addmissingsymbols(fontdata[id]) - context(helpers.getprivatenode(fontdata[id],name)) + context(getprivatenode(fontdata[id],name)) end +-- todo in luatex: option to add characters (just slots, no kerns etc) + local function placeholder(font,char) - local tfmdata = fontdata[font] - local properties = tfmdata.properties - local privates = properties.privates - local category = chardata[char].category - local fakechar = mapping[category] - local p = privates and privates[fakechar] - if not p then + local tfmdata = fontdata[font] + local category = chardata[char].category + local fakechar = mapping[category] + local slot = getprivateslot(font,fakechar) + if not slot then addmissingsymbols(tfmdata) - p = properties.privates[fakechar] - end - if properties.lateprivates then - -- frozen already - return "node", getprivatenode(tfmdata,fakechar) - else - -- good, we have \definefontfeature[default][default][missing=yes] - return "char", p + slot = getprivateslot(font,fakechar) end + return getprivatecharornode(tfmdata,fakechar) end checkers.placeholder = placeholder @@ -427,7 +437,7 @@ local dummyzero = { commands = { { "special", "" } }, } -local function adddummysymbols(tfmdata,...) +local function adddummysymbols(tfmdata) local characters = tfmdata.characters if not characters[0] then characters[0] = dummyzero diff --git a/tex/context/base/mkiv/font-col.lua b/tex/context/base/mkiv/font-col.lua index cf1b60bb9..bce16fae7 100644 --- a/tex/context/base/mkiv/font-col.lua +++ b/tex/context/base/mkiv/font-col.lua @@ -24,7 +24,7 @@ local getfont = nuts.getfont local getchar = nuts.getchar local setfield = nuts.setfield -local setchar = nuts.setchar +local setfont = nuts.setfont local traverse_id = nuts.traverse_id local traverse_char = nuts.traverse_char @@ -35,6 +35,9 @@ local trace_collecting = false trackers.register("fonts.collecting", function local report_fonts = logs.reporter("fonts","collections") +local enableaction = nodes.tasks.enableaction +local disableaction = nodes.tasks.disableaction + local collections = fonts.collections or { } fonts.collections = collections @@ -46,7 +49,6 @@ collections.vectors = vectors local fontdata = fonts.hashes.identifiers local chardata = fonts.hashes.characters -local glyph_code = nodes.nodecodes.glyph local currentfont = font.current local fontpatternhassize = fonts.helpers.fontpatternhassize @@ -61,12 +63,12 @@ local function checkenabled() -- a bit ugly but nicer than a fuzzy state while defining math if next(vectors) then if not enabled then - nodes.tasks.enableaction("processors","fonts.collections.process") + enableaction("processors","fonts.collections.process") enabled = true end else if enabled then - nodes.tasks.disableaction("processors","fonts.collections.process") + disableaction("processors","fonts.collections.process") enabled = false end end @@ -102,7 +104,7 @@ function collections.define(name,font,ranges,details) details = settings_to_hash(details) -- todo, combine per font start/stop as arrays for s in gmatch(ranges,"[^, ]+") do - local start, stop, description, gaps = characters.getrange(s) + local start, stop, description, gaps = characters.getrange(s,true) if start and stop then if trace_collecting then if description then @@ -117,20 +119,21 @@ function collections.define(name,font,ranges,details) end local offset = details.offset if type(offset) == "string" then - local start = characters.getrange(offset) + local start = characters.getrange(offset,true) offset = start or false else offset = tonumber(offset) or false end d[#d+1] = { - font = font, - start = start, - stop = stop, - gaps = gaps, - offset = offset, - rscale = tonumber (details.rscale) or 1, - force = toboolean(details.force,true), - check = toboolean(details.check,true), + font = font, + start = start, + stop = stop, + gaps = gaps, + offset = offset, + rscale = tonumber (details.rscale) or 1, + force = toboolean(details.force,true), + check = toboolean(details.check,true), + features = details.features, } end end @@ -257,7 +260,6 @@ end function collections.process(head) -- this way we keep feature processing local done = false - -- for n in traverse_id(glyph_code,tonut(head)) do for n in traverse_char(tonut(head)) do local font = getfont(n) local vector = vectors[font] @@ -274,8 +276,7 @@ function collections.process(head) -- this way we keep feature processing char,font,newchar,newfont,not chardata[newfont][newchar] and " (missing)" or "" ) end - setfield(n,"font",newfont) - setchar(n,newchar) + setfont(n,newfont,newchar) done = true else if trace_collecting then @@ -283,7 +284,7 @@ function collections.process(head) -- this way we keep feature processing font,vect,char,not chardata[vect][char] and " (missing)" or "" ) end - setfield(n,"font",vect) + setfont(n,vect) done = true end end diff --git a/tex/context/base/mkiv/font-col.mkvi b/tex/context/base/mkiv/font-col.mkvi index bc8e8151e..b13047e50 100644 --- a/tex/context/base/mkiv/font-col.mkvi +++ b/tex/context/base/mkiv/font-col.mkvi @@ -34,7 +34,9 @@ \unexpanded\def\resetfontfallback {\dodoubleempty \font_fallbacks_reset } \def\font_fallbacks_define[#name][#font][#ranges][#settings]% - {\clf_fontcollectiondefine{#name}{#font}{#ranges}{#settings}} + {\let\mathsizesuffix\relax + \clf_fontcollectiondefine{#name}{#font}{#ranges}{#settings}% + \let\mathsizesuffix\empty} \def\font_fallbacks_reset[#name][#font]% {\clf_fontcollectionreset{#name}{#font}} @@ -92,6 +94,17 @@ \def\font_fallbacks_register_main #name{\clf_fontcollectionregister{#name}} \def\font_fallbacks_prepare_clone_vectors#name{\clf_fontcollectionclone{#name}} +% math (experiment, todo clf_) + +\def\font_fallbacks_register_math#1#2#3#4% + {\doifelsenothing{#3}% + {\definedfont[#2 at #4sp]}% + {\definedfont[#2*#3\space at #4\scaledpoint]}% + \clf_registerfontfallbackid#1\space\fontid\font\space{#2}} + +% \def\font_fallbacks_finish_math +% {\ctxlua{mathematics.finishfallbacks()}} + % check : only replace when present in replacement font (default: no) % force : force replacent even when basefont has glyph (default: yes) diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua index b11853533..85ac33a10 100644 --- a/tex/context/base/mkiv/font-con.lua +++ b/tex/context/base/mkiv/font-con.lua @@ -9,13 +9,14 @@ if not modules then modules = { } end modules ['font-con'] = { -- some names of table entries will be changed (no _) local next, tostring, rawget = next, tostring, rawget -local format, match, lower, gsub = string.format, string.match, string.lower, string.gsub -local utfbyte = utf.byte -local sort, insert, concat, sortedkeys, serialize, fastcopy = table.sort, table.insert, table.concat, table.sortedkeys, table.serialize, table.fastcopy +local format, match, lower, gsub, find = string.format, string.match, string.lower, string.gsub, string.find +local sort, insert, concat = table.sort, table.insert, table.concat +local sortedkeys, sortedhash, serialize, fastcopy = table.sortedkeys, table.sortedhash, table.serialize, table.fastcopy local derivetable = table.derive +local ioflush = io.flush -local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) -local trace_scaling = false trackers.register("fonts.scaling" , function(v) trace_scaling = v end) +local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) +local trace_scaling = false trackers.register("fonts.scaling", function(v) trace_scaling = v end) local report_defining = logs.reporter("fonts","defining") @@ -47,102 +48,6 @@ constructors.privateoffset = 0xF0000 -- 0x10FFFF constructors.cacheintex = true -- so we see the original table in fonts.font --- Some experimental helpers (handy for tracing): --- --- todo: extra: --- --- extra_space => space.extra --- space => space.width --- space_stretch => space.stretch --- space_shrink => space.shrink - --- We do keep the x-height, extra_space, space_shrink and space_stretch --- around as these are low level official names. - -constructors.keys = { - properties = { - encodingbytes = "number", - embedding = "number", - cidinfo = { }, - format = "string", - fontname = "string", - fullname = "string", - filename = "filename", - psname = "string", - name = "string", - virtualized = "boolean", - hasitalics = "boolean", - autoitalicamount = "basepoints", - nostackmath = "boolean", - noglyphnames = "boolean", - mode = "string", - hasmath = "boolean", - mathitalics = "boolean", - textitalics = "boolean", - finalized = "boolean", - }, - parameters = { - mathsize = "number", - scriptpercentage = "float", - scriptscriptpercentage = "float", - units = "cardinal", - designsize = "scaledpoints", - expansion = { - stretch = "integerscale", -- might become float - shrink = "integerscale", -- might become float - step = "integerscale", -- might become float - auto = "boolean", - }, - protrusion = { - auto = "boolean", - }, - slantfactor = "float", - extendfactor = "float", - factor = "float", - hfactor = "float", - vfactor = "float", - size = "scaledpoints", - units = "scaledpoints", - scaledpoints = "scaledpoints", - slantperpoint = "scaledpoints", - spacing = { - width = "scaledpoints", - stretch = "scaledpoints", - shrink = "scaledpoints", - extra = "scaledpoints", - }, - xheight = "scaledpoints", - quad = "scaledpoints", - ascender = "scaledpoints", - descender = "scaledpoints", - synonyms = { - space = "spacing.width", - spacestretch = "spacing.stretch", - spaceshrink = "spacing.shrink", - extraspace = "spacing.extra", - x_height = "xheight", - space_stretch = "spacing.stretch", - space_shrink = "spacing.shrink", - extra_space = "spacing.extra", - em = "quad", - ex = "xheight", - slant = "slantperpoint", - }, - }, - description = { - width = "basepoints", - height = "basepoints", - depth = "basepoints", - boundingbox = { }, - }, - character = { - width = "scaledpoints", - height = "scaledpoints", - depth = "scaledpoints", - italic = "scaledpoints", - }, -} - -- This might become an interface: local designsizes = allocate() @@ -240,7 +145,9 @@ end local unscaled = { ScriptPercentScaleDown = true, ScriptScriptPercentScaleDown = true, - RadicalDegreeBottomRaisePercent = true + RadicalDegreeBottomRaisePercent = true, + NoLimitSupFactor = true, + NoLimitSubFactor = true, } function constructors.assignmathparameters(target,original) -- simple variant, not used in context @@ -338,6 +245,41 @@ function constructors.enhanceparameters(parameters) } end +local function mathkerns(v,vdelta) + local k = { } + for i=1,#v do + local entry = v[i] + local height = entry.height + local kern = entry.kern + k[i] = { + height = height and vdelta*height or 0, + kern = kern and vdelta*kern or 0, + } + end + return k +end + +local psfake = 0 + +local function fixedpsname(psname,fallback) + local usedname = psname + if psname and psname ~= "" then + if find(psname," ") then + usedname = gsub(psname,"[%s]+","-") + else + -- we assume that the name is sane enough (we might sanitize completely some day) + end + elseif not fallback or fallback == "" then + psfake = psfake + 1 + psname = "fakename-" .. psfake + else + -- filenames can be a mess so we do a drastic cleanup + psname = fallback + usedname = gsub(psname,"[^a-zA-Z0-9]+","-") + end + return usedname, psname ~= usedname +end + function constructors.scale(tfmdata,specification) local target = { } -- the new table -- @@ -440,23 +382,22 @@ function constructors.scale(tfmdata,specification) target.format = properties.format target.cache = constructors.cacheintex and "yes" or "renew" -- - local fontname = properties.fontname or tfmdata.fontname -- for the moment we fall back on - local fullname = properties.fullname or tfmdata.fullname -- names in the tfmdata although - local filename = properties.filename or tfmdata.filename -- that is not the right place to - local psname = properties.psname or tfmdata.psname -- pass them + local fontname = properties.fontname or tfmdata.fontname + local fullname = properties.fullname or tfmdata.fullname + local filename = properties.filename or tfmdata.filename + local psname = properties.psname or tfmdata.psname local name = properties.name or tfmdata.name -- - if not psname or psname == "" then - -- name used in pdf file as well as for selecting subfont in ttc/dfont - psname = fontname or (fullname and fonts.names.cleanname(fullname)) - end + -- the psname used in pdf file as well as for selecting subfont in ttc + -- + local psname, psfixed = fixedpsname(psname,fontname or fullname or file.nameonly(filename)) + -- target.fontname = fontname target.fullname = fullname target.filename = filename target.psname = psname target.name = name -- - -- properties.fontname = fontname properties.fullname = fullname properties.filename = filename @@ -507,12 +448,16 @@ function constructors.scale(tfmdata,specification) local haskerns = properties.haskerns or properties.mode == "base" -- we can have afm in node mode local hasligatures = properties.hasligatures or properties.mode == "base" -- we can have afm in node mode local realdimensions = properties.realdimensions + local writingmode = properties.writingmode or "horizontal" + local identity = properties.identity or "horizontal" -- if changed and not next(changed) then changed = false end -- - target.type = isvirtual and "virtual" or "real" + target.type = isvirtual and "virtual" or "real" + target.writingmode = writingmode == "vertical" and "vertical" or "horizontal" + target.identity = identity == "vertical" and "vertical" or "horizontal" -- target.postprocessors = tfmdata.postprocessors -- @@ -552,13 +497,13 @@ function constructors.scale(tfmdata,specification) -- if hasmath then constructors.assignmathparameters(target,tfmdata) -- does scaling and whatever is needed - properties.hasmath = true - target.nomath = false - target.MathConstants = target.mathparameters + properties.hasmath = true + target.nomath = false + target.MathConstants = target.mathparameters else - properties.hasmath = false - target.nomath = true - target.mathparameters = nil -- nop + properties.hasmath = false + target.nomath = true + target.mathparameters = nil -- nop end -- -- Here we support some context specific trickery (this might move to a plugin). During the @@ -589,8 +534,9 @@ function constructors.scale(tfmdata,specification) -- end of context specific trickery -- if trace_defining then - report_defining("defining tfm, name %a, fullname %a, filename %a, hscale %a, vscale %a, math %a, italics %a", - name,fullname,filename,hdelta,vdelta,hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled") + report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a", + name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta, + hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled") end -- constructors.beforecopyingcharacters(target,tfmdata) @@ -749,22 +695,15 @@ function constructors.scale(tfmdata,specification) chr.top_accent = vdelta*va end if stackmath then - local mk = character.mathkerns -- not in math ? + local mk = character.mathkerns if mk then - local kerns = { } - local v = mk.top_right if v then local k = { } for i=1,#v do local vi = v[i] - k[i] = { height = vdelta*vi.height, kern = vdelta*vi.kern } - end kerns.top_right = k end - local v = mk.top_left if v then local k = { } for i=1,#v do local vi = v[i] - k[i] = { height = vdelta*vi.height, kern = vdelta*vi.kern } - end kerns.top_left = k end - local v = mk.bottom_left if v then local k = { } for i=1,#v do local vi = v[i] - k[i] = { height = vdelta*vi.height, kern = vdelta*vi.kern } - end kerns.bottom_left = k end - local v = mk.bottom_right if v then local k = { } for i=1,#v do local vi = v[i] - k[i] = { height = vdelta*vi.height, kern = vdelta*vi.kern } - end kerns.bottom_right = k end - chr.mathkern = kerns -- singular -> should be patched in luatex ! + local tr, tl, br, bl = mk.topright, mk.topleft, mk.bottomright, mk.bottomleft + chr.mathkern = { -- singular -> should be patched in luatex ! + top_right = tr and mathkerns(tr,vdelta) or nil, + top_left = tl and mathkerns(tl,vdelta) or nil, + bottom_right = br and mathkerns(br,vdelta) or nil, + bottom_left = bl and mathkerns(bl,vdelta) or nil, + } end end if hasitalics then @@ -960,6 +899,8 @@ function constructors.finalize(tfmdata) cidinfo = tfmdata.cidinfo or nil, format = tfmdata.format or "type1", direction = tfmdata.direction or 0, + writingmode = tfmdata.writingmode or "horizontal", + identity = tfmdata.identity or "horizontal", } end if not tfmdata.resources then @@ -973,42 +914,42 @@ function constructors.finalize(tfmdata) -- tfmdata.unscaled -- if not properties.hasmath then - properties.hasmath = not tfmdata.nomath + properties.hasmath = not tfmdata.nomath end -- - tfmdata.MathConstants = nil - tfmdata.postprocessors = nil - -- - tfmdata.fontname = nil - tfmdata.filename = nil - tfmdata.fullname = nil - tfmdata.name = nil -- most tricky part - tfmdata.psname = nil - -- - tfmdata.encodingbytes = nil - tfmdata.embedding = nil - tfmdata.tounicode = nil - tfmdata.cidinfo = nil - tfmdata.format = nil - tfmdata.direction = nil - tfmdata.type = nil - tfmdata.nomath = nil - tfmdata.designsize = nil - -- - tfmdata.size = nil - tfmdata.stretch = nil - tfmdata.shrink = nil - tfmdata.step = nil - tfmdata.auto_expand = nil - tfmdata.auto_protrude = nil - tfmdata.extend = nil - tfmdata.slant = nil - tfmdata.units = nil - tfmdata.units_per_em = nil - -- - tfmdata.cache = nil - -- - properties.finalized = true + tfmdata.MathConstants = nil + tfmdata.postprocessors = nil + -- + tfmdata.fontname = nil + tfmdata.filename = nil + tfmdata.fullname = nil + tfmdata.name = nil -- most tricky part + tfmdata.psname = nil + -- + tfmdata.encodingbytes = nil + tfmdata.embedding = nil + tfmdata.tounicode = nil + tfmdata.cidinfo = nil + tfmdata.format = nil + tfmdata.direction = nil + tfmdata.type = nil + tfmdata.nomath = nil + tfmdata.designsize = nil + -- + tfmdata.size = nil + tfmdata.stretch = nil + tfmdata.shrink = nil + tfmdata.step = nil + tfmdata.auto_expand = nil + tfmdata.auto_protrude = nil + tfmdata.extend = nil + tfmdata.slant = nil + tfmdata.units = nil + tfmdata.units_per_em = nil + -- + tfmdata.cache = nil + -- + properties.finalized = true -- return tfmdata end @@ -1023,20 +964,22 @@ constructors.hashmethods = hashmethods function constructors.hashfeatures(specification) -- will be overloaded local features = specification.features if features then - local t, tn = { }, 0 - for category, list in next, features do + local t, n = { }, 0 +-- inspect(features) +-- for category, list in next, features do + for category, list in sortedhash(features) do if next(list) then local hasher = hashmethods[category] if hasher then local hash = hasher(list) if hash then - tn = tn + 1 - t[tn] = category .. ":" .. hash + n = n + 1 + t[n] = category .. ":" .. hash end end end end - if tn > 0 then + if n > 0 then return concat(t," & ") end end @@ -1053,15 +996,11 @@ hashmethods.normal = function(list) -- no need to add to hash (maybe we need a skip list) else n = n + 1 - s[n] = k + s[n] = k .. '=' .. tostring(v) end end if n > 0 then sort(s) - for i=1,n do - local k = s[i] - s[i] = k .. '=' .. tostring(list[k]) - end return concat(s,"+") end end @@ -1136,127 +1075,267 @@ setmetatableindex(formats, function(t,k) return rawget(t,file.suffix(l)) end) -local locations = { } +do -local function setindeed(mode,target,group,name,action,position) - local t = target[mode] - if not t then - report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode) - os.exit() - elseif position then - -- todo: remove existing - insert(t, position, { name = name, action = action }) - else - for i=1,#t do - local ti = t[i] - if ti.name == name then - ti.action = action - return + local function setindeed(mode,source,target,group,name,position) + local action = source[mode] + if not action then + return + end + local t = target[mode] + if not t then + report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode) + os.exit() + elseif position then + -- todo: remove existing + insert(t, position, { name = name, action = action }) + else + for i=1,#t do + local ti = t[i] + if ti.name == name then + ti.action = action + return + end end + insert(t, { name = name, action = action }) end - insert(t, { name = name, action = action }) end -end -local function set(group,name,target,source) - target = target[group] - if not target then - report_defining("fatal target error in setting feature %a, group %a",name,group) - os.exit() + local function set(group,name,target,source) + target = target[group] + if not target then + report_defining("fatal target error in setting feature %a, group %a",name,group) + os.exit() + end + local source = source[group] + if not source then + report_defining("fatal source error in setting feature %a, group %a",name,group) + os.exit() + end + local position = source.position + setindeed("node",source,target,group,name,position) + setindeed("base",source,target,group,name,position) + setindeed("plug",source,target,group,name,position) end - local source = source[group] - if not source then - report_defining("fatal source error in setting feature %a, group %a",name,group) - os.exit() + + local function register(where,specification) + local name = specification.name + if name and name ~= "" then + local default = specification.default + local description = specification.description + local initializers = specification.initializers + local processors = specification.processors + local manipulators = specification.manipulators + local modechecker = specification.modechecker + if default then + where.defaults[name] = default + end + if description and description ~= "" then + where.descriptions[name] = description + end + if initializers then + set('initializers',name,where,specification) + end + if processors then + set('processors', name,where,specification) + end + if manipulators then + set('manipulators',name,where,specification) + end + if modechecker then + where.modechecker = modechecker + end + end end - local node = source.node - local base = source.base - local position = source.position - if node then - setindeed("node",target,group,name,node,position) + + constructors.registerfeature = register + + function constructors.getfeatureaction(what,where,mode,name) + what = handlers[what].features + if what then + where = what[where] + if where then + mode = where[mode] + if mode then + for i=1,#mode do + local m = mode[i] + if m.name == name then + return m.action + end + end + end + end + end end - if base then - setindeed("base",target,group,name,base,position) + + local newfeatures = { } + constructors.newfeatures = newfeatures -- downward compatible + constructors.features = newfeatures + + local function setnewfeatures(what) + local handler = handlers[what] + local features = handler.features + if not features then + local tables = handler.tables -- can be preloaded + local statistics = handler.statistics -- can be preloaded + features = allocate { + defaults = { }, + descriptions = tables and tables.features or { }, + used = statistics and statistics.usedfeatures or { }, + initializers = { base = { }, node = { }, plug = { } }, + processors = { base = { }, node = { }, plug = { } }, + manipulators = { base = { }, node = { }, plug = { } }, + } + features.register = function(specification) return register(features,specification) end + handler.features = features -- will also become hidden + end + return features end + + setmetatable(newfeatures, { + __call = function(t,k) local v = t[k] return v end, + __index = function(t,k) local v = setnewfeatures(k) t[k] = v return v end, + }) + end -local function register(where,specification) - local name = specification.name - if name and name ~= "" then - local default = specification.default - local description = specification.description - local initializers = specification.initializers - local processors = specification.processors - local manipulators = specification.manipulators - local modechecker = specification.modechecker - if default then - where.defaults[name] = default - end - if description and description ~= "" then - where.descriptions[name] = description - end - if initializers then - set('initializers',name,where,specification) - end - if processors then - set('processors', name,where,specification) - end - if manipulators then - set('manipulators',name,where,specification) - end - if modechecker then - where.modechecker = modechecker +do + + local newhandler = { } + constructors.handlers = newhandler -- downward compatible + constructors.newhandler = newhandler + + local function setnewhandler(what) -- could be a metatable newindex + local handler = handlers[what] + if not handler then + handler = { } + handlers[what] = handler end + return handler end + + setmetatable(newhandler, { + __call = function(t,k) local v = t[k] return v end, + __index = function(t,k) local v = setnewhandler(k) t[k] = v return v end, + }) + end -constructors.registerfeature = register - -function constructors.getfeatureaction(what,where,mode,name) - what = handlers[what].features - if what then - where = what[where] - if where then - mode = where[mode] - if mode then - for i=1,#mode do - local m = mode[i] - if m.name == name then - return m.action +do + -- a pitty that we need to be generic as we have nicer mechanisms for this ... + + local newenhancer = { } + constructors.enhancers = newenhancer + constructors.newenhancer = newenhancer + + local function setnewenhancer(format) + + local handler = handlers[format] + local enhancers = handler.enhancers + + if not enhancers then + + local actions = allocate() + local before = allocate() + local after = allocate() + local order = allocate() + local patches = { before = before, after = after } + + local trace = false + local report = logs.reporter("fonts",format .. " enhancing") + + trackers.register(format .. ".loading", function(v) trace = v end) + + local function enhance(name,data,filename,raw) + local enhancer = actions[name] + if enhancer then + if trace then + report("apply enhancement %a to file %a",name,filename) + ioflush() end + enhancer(data,filename,raw) + else + -- no message as we can have private ones end end + + local function apply(data,filename,raw) + local basename = file.basename(lower(filename)) + if trace then + report("%s enhancing file %a","start",filename) + end + ioflush() -- we want instant messages + for e=1,#order do + local enhancer = order[e] + local b = before[enhancer] + if b then + for pattern, action in next, b do + if find(basename,pattern) then + action(data,filename,raw) + end + end + end + enhance(enhancer,data,filename,raw) + local a = after[enhancer] + if a then + for pattern, action in next, a do + if find(basename,pattern) then + action(data,filename,raw) + end + end + end + ioflush() -- we want instant messages + end + if trace then + report("%s enhancing file %a","stop",filename) + end + ioflush() -- we want instant messages + end + + local function register(what,action) + if action then + if actions[what] then + -- overloading, e.g."check extra features" + else + order[#order+1] = what + end + actions[what] = action + else + report("bad enhancer %a",what) + end + end + + -- fonts.constructors.otf.enhancers.patch("before","migrate metadata","cambria",function() end) + + local function patch(what,where,pattern,action) + local pw = patches[what] + if pw then + local ww = pw[where] + if ww then + ww[pattern] = action + else + pw[where] = { [pattern] = action} + end + end + end + + enhancers = { + register = register, + apply = apply, + patch = patch, + patches = { register = patch }, -- for old times sake + } + + handler.enhancers = enhancers end + return enhancers end -end -function constructors.newhandler(what) -- could be a metatable newindex - local handler = handlers[what] - if not handler then - handler = { } - handlers[what] = handler - end - return handler -end + setmetatable(newenhancer, { + __call = function(t,k) local v = t[k] return v end, + __index = function(t,k) local v = setnewenhancer(k) t[k] = v return v end, + }) -function constructors.newfeatures(what) -- could be a metatable newindex - local handler = handlers[what] - local features = handler.features - if not features then - local tables = handler.tables -- can be preloaded - local statistics = handler.statistics -- can be preloaded - features = allocate { - defaults = { }, - descriptions = tables and tables.features or { }, - used = statistics and statistics.usedfeatures or { }, - initializers = { base = { }, node = { } }, - processors = { base = { }, node = { } }, - manipulators = { base = { }, node = { } }, - } - features.register = function(specification) return register(features,specification) end - handler.features = features -- will also become hidden - end - return features end --[[ldx-- @@ -1286,7 +1365,6 @@ function constructors.initializefeatures(what,tfmdata,features,trace,report) local properties = tfmdata.properties or { } -- brrr local whathandler = handlers[what] local whatfeatures = whathandler.features - local whatinitializers = whatfeatures.initializers local whatmodechecker = whatfeatures.modechecker -- properties.mode can be enforces (for instance in font-otd) local mode = properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base" diff --git a/tex/context/base/mkiv/font-ctx.lua b/tex/context/base/mkiv/font-ctx.lua index be233e570..578babc75 100644 --- a/tex/context/base/mkiv/font-ctx.lua +++ b/tex/context/base/mkiv/font-ctx.lua @@ -14,7 +14,7 @@ if not modules then modules = { } end modules ['font-ctx'] = { local context, commands = context, commands -local format, gmatch, match, find, lower, gsub, byte = string.format, string.gmatch, string.match, string.find, string.lower, string.gsub, string.byte +local format, gmatch, match, find, lower, upper, gsub, byte, topattern = string.format, string.gmatch, string.match, string.find, string.lower, string.upper, string.gsub, string.byte, string.topattern local concat, serialize, sort, fastcopy, mergedtable = table.concat, table.serialize, table.sort, table.fastcopy, table.merged local sortedhash, sortedkeys, sequenced = table.sortedhash, table.sortedkeys, table.sequenced local settings_to_hash, hash_to_string = utilities.parsers.settings_to_hash, utilities.parsers.hash_to_string @@ -42,11 +42,14 @@ local report_cummulative = logs.reporter("fonts","cummulative") local report_defining = logs.reporter("fonts","defining") local report_status = logs.reporter("fonts","status") local report_mapfiles = logs.reporter("fonts","mapfiles") +local report_newline = logs.newline local setmetatableindex = table.setmetatableindex local implement = interfaces.implement +local chardata = characters.data + local fonts = fonts local handlers = fonts.handlers local otf = handlers.otf -- brrr @@ -63,6 +66,8 @@ local hashes = fonts.hashes local currentfont = font.current local definefont = font.define +local cleanname = names.cleanname + local encodings = fonts.encodings ----- aglunicodes = encodings.agl.unicodes local aglunicodes = nil -- delayed loading @@ -102,15 +107,13 @@ local parameters = hashes.parameters local designsizefilename = fontgoodies.designsizes.filename -local context_char = context.char -local context_getvalue = context.getvalue +local ctx_char = context.char +local ctx_getvalue = context.getvalue local otffeatures = otf.features local otftables = otf.tables local registerotffeature = otffeatures.register -local baseprocessors = otffeatures.processors.base -local baseinitializers = otffeatures.initializers.base local sequencers = utilities.sequencers local appendgroup = sequencers.appendgroup @@ -153,17 +156,19 @@ local function getfontname(tfmdata) return basename(type(tfmdata) == "number" and properties[tfmdata].name or tfmdata.properties.name) end -fonts.helpers.name = getfontname +helpers.name = getfontname + +local addformatter = utilities.strings.formatters.add if _LUAVERSION < 5.2 then - utilities.strings.formatters.add(formatters,"font:name", [["'"..fontname(%s).."'"]], "local fontname = fonts.helpers.name") - utilities.strings.formatters.add(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]],"local sequenced = table.sequenced") + addformatter(formatters,"font:name", [["'"..fontname(%s).."'"]], "local fontname = fonts.helpers.name") + addformatter(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]],"local sequenced = table.sequenced") else - utilities.strings.formatters.add(formatters,"font:name", [["'"..fontname(%s).."'"]], { fontname = fonts.helpers.name }) - utilities.strings.formatters.add(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]],{ sequenced = table.sequenced }) + addformatter(formatters,"font:name", [["'"..fontname(%s).."'"]], { fontname = helpers.name }) + addformatter(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]],{ sequenced = table.sequenced }) end @@ -176,58 +181,109 @@ constructors.nofsharedhashes = 0 constructors.nofsharedvectors = 0 constructors.noffontsloaded = 0 -local shares = { } -local hashes = { } - -function constructors.trytosharefont(target,tfmdata) - constructors.noffontsloaded = constructors.noffontsloaded + 1 - if constructors.sharefonts then - local fonthash = target.specification.hash - if fonthash then - local properties = target.properties - local fullname = target.fullname - local sharedname = hashes[fonthash] - if sharedname then - -- this is ok for context as we know that only features can mess with font definitions - -- so a similar hash means that the fonts are similar too - if trace_defining then - report_defining("font %a uses backend resources of font %a (%s)",target.fullname,sharedname,"common hash") - end - target.fullname = sharedname - properties.sharedwith = sharedname - constructors.nofsharedfonts = constructors.nofsharedfonts + 1 - constructors.nofsharedhashes = constructors.nofsharedhashes + 1 - else - -- the one takes more time (in the worst case of many cjk fonts) but it also saves - -- embedding time - local characters = target.characters - local n = 1 - local t = { target.psname } - local u = sortedkeys(characters) - for i=1,#u do - local k = u[i] - n = n + 1 ; t[n] = k - n = n + 1 ; t[n] = characters[k].index or k - end - local checksum = md5.HEX(concat(t," ")) - local sharedname = shares[checksum] +do + + local shares = { } + local hashes = { } + + local nofinstances = 0 + local instances = table.setmetatableindex(function(t,k) + nofinstances = nofinstances + 1 + t[k] = nofinstances + return nofinstances + end) + + function constructors.trytosharefont(target,tfmdata) + constructors.noffontsloaded = constructors.noffontsloaded + 1 + if constructors.sharefonts then + local fonthash = target.specification.hash + if fonthash then + local properties = target.properties local fullname = target.fullname + local fontname = target.fontname + local psname = target.psname + -- for the moment here: + local instance = properties.instance + if instance then + local format = tfmdata.properties.format + if format == "opentype" then + target.streamprovider = 1 + elseif format == "truetype" then + target.streamprovider = 2 + else + target.streamprovider = 0 + end + if target.streamprovider > 0 then + if fullname then + fullname = fullname .. ":" .. instances[instance] + target.fullname = fullname + end + if fontname then + fontname = fontname .. ":" .. instances[instance] + target.fontname = fontname + end + if psname then + -- this one is used for the funny prefix in font names in pdf + -- so it has ot be kind of unique in order to avoid subset prefix + -- clashes being reported + psname = psname .. ":" .. instances[instance] + target.psname = psname + end + end + end + -- + local sharedname = hashes[fonthash] if sharedname then + -- this is ok for context as we know that only features can mess with font definitions + -- so a similar hash means that the fonts are similar too if trace_defining then - report_defining("font %a uses backend resources of font %a (%s)",fullname,sharedname,"common vector") + report_defining("font %a uses backend resources of font %a (%s)",target.fullname,sharedname,"common hash") end - fullname = sharedname - properties.sharedwith= sharedname + target.fullname = sharedname + properties.sharedwith = sharedname constructors.nofsharedfonts = constructors.nofsharedfonts + 1 - constructors.nofsharedvectors = constructors.nofsharedvectors + 1 + constructors.nofsharedhashes = constructors.nofsharedhashes + 1 else - shares[checksum] = fullname + -- the one takes more time (in the worst case of many cjk fonts) but it also saves + -- embedding time .. haha, this is interesting: when i got a clash on subset tag + -- collision i saw in the source that these tags are also using a hash like below + -- so maybe we should have an option to pass it from lua + local characters = target.characters + local n = 1 + local t = { target.psname } + -- for the moment here: + if instance then + n = n + 1 + t[n] = instance + end + -- + local u = sortedkeys(characters) + for i=1,#u do + local k = u[i] + n = n + 1 ; t[n] = k + n = n + 1 ; t[n] = characters[k].index or k + end + local checksum = md5.HEX(concat(t," ")) + local sharedname = shares[checksum] + local fullname = target.fullname + if sharedname then + if trace_defining then + report_defining("font %a uses backend resources of font %a (%s)",fullname,sharedname,"common vector") + end + fullname = sharedname + properties.sharedwith= sharedname + constructors.nofsharedfonts = constructors.nofsharedfonts + 1 + constructors.nofsharedvectors = constructors.nofsharedvectors + 1 + else + shares[checksum] = fullname + end + target.fullname = fullname + hashes[fonthash] = fullname end - target.fullname = fullname - hashes[fonthash] = fullname end end end + end directives.register("fonts.checksharing",function(v) @@ -294,21 +350,13 @@ otftables.scripts.auto = "automatic fallback to latn when no dflt present" -- setmetatableindex(otffeatures.descriptions,otftables.features) -local privatefeatures = { - tlig = true, - trep = true, - anum = true, -} - local function checkedscript(tfmdata,resources,features) local latn = false local script = false if resources.features then for g, list in next, resources.features do for f, scripts in next, list do - if privatefeatures[f] then - -- skip - elseif scripts.dflt then + if scripts.dflt then script = "dflt" break elseif scripts.latn then @@ -537,10 +585,11 @@ local function presetcontext(name,parent,features) -- will go to con and shared for p in gmatch(parent,"[^, ]+") do local s = setups[p] if s then - for k,v in next, s do - if features[k] == nil then + for k, v in next, s do +-- no, as then we cannot overload: e.g. math,mathextra +-- if features[k] == nil then features[k] = v - end +-- end end else -- just ignore an undefined one .. i.e. we can refer to not yet defined @@ -570,7 +619,7 @@ local function presetcontext(name,parent,features) -- will go to con and shared -- optimization) local t = { } -- can we avoid t ? for k,v in next, features do --- if v then t[k] = v end + -- if v then t[k] = v end t[k] = v end -- needed for dynamic features @@ -585,42 +634,57 @@ local function presetcontext(name,parent,features) -- will go to con and shared return number, t end -local function contextnumber(name) -- will be replaced - local t = setups[name] - if not t then - return 0 - elseif t.auto then - local lng = tonumber(tex.language) - local tag = name .. ":" .. lng - local s = setups[tag] - if s then - return s.number or 0 - else - local script, language = languages.association(lng) - if t.script ~= script or t.language ~= language then - local s = fastcopy(t) - local n = #numbers + 1 - setups[tag] = s - numbers[n] = tag - s.number = n - s.script = script - s.language = language - return n - else - setups[tag] = t - return t.number or 0 - end +local function adaptcontext(pattern,features) + local pattern = topattern(pattern,false,true) + for name in next, setups do + if find(name,pattern) then + presetcontext(name,name,features) end - else - return t.number or 0 end end +-- local function contextnumber(name) -- will be replaced +-- local t = setups[name] +-- if not t then +-- return 0 +-- elseif t.auto then -- check where used, autolanguage / autoscript? +-- local lng = tonumber(tex.language) +-- local tag = name .. ":" .. lng +-- local s = setups[tag] +-- if s then +-- return s.number or 0 +-- else +-- local script, language = languages.association(lng) +-- if t.script ~= script or t.language ~= language then +-- local s = fastcopy(t) +-- local n = #numbers + 1 +-- setups[tag] = s +-- numbers[n] = tag +-- s.number = n +-- s.script = script +-- s.language = language +-- return n +-- else +-- setups[tag] = t +-- return t.number or 0 +-- end +-- end +-- else +-- return t.number or 0 +-- end +-- end + +local function contextnumber(name) -- will be replaced + local t = setups[name] + return t and t.number or 0 +end + local function mergecontext(currentnumber,extraname,option) -- number string number (used in scrp-ini local extra = setups[extraname] if extra then local current = setups[numbers[currentnumber]] - local mergedfeatures, mergedname = { }, nil + local mergedfeatures = { } + local mergedname = nil if option < 0 then if current then for k, v in next, current do @@ -941,13 +1005,13 @@ local rightparent = (P")") local value = C((leftparent * (1-rightparent)^0 * rightparent + (1-space))^1) local dimension = C((space/"" + P(1))^1) local rest = C(P(1)^0) -local scale_none = Cc(0) -local scale_at = P("at") * Cc(1) * spaces * dimension -- dimension -local scale_sa = P("sa") * Cc(2) * spaces * dimension -- number -local scale_mo = P("mo") * Cc(3) * spaces * dimension -- number -local scale_scaled = P("scaled") * Cc(4) * spaces * dimension -- number -local scale_ht = P("ht") * Cc(5) * spaces * dimension -- dimension -local scale_cp = P("cp") * Cc(6) * spaces * dimension -- dimension +local scale_none = Cc(0) +local scale_at = (P("at") +P("@")) * Cc(1) * spaces * dimension -- dimension +local scale_sa = P("sa") * Cc(2) * spaces * dimension -- number +local scale_mo = P("mo") * Cc(3) * spaces * dimension -- number +local scale_scaled = P("scaled") * Cc(4) * spaces * dimension -- number +local scale_ht = P("ht") * Cc(5) * spaces * dimension -- dimension +local scale_cp = P("cp") * Cc(6) * spaces * dimension -- dimension local specialscale = { [5] = "ht", [6] = "cp" } @@ -973,6 +1037,8 @@ local getspecification = definers.getspecification -- we can make helper macros which saves parsing (but normaly not -- that many calls, e.g. in mk a couple of 100 and in metafun 3500) +local specifiers = { } + do -- else too many locals ----- ctx_setdefaultfontname = context.fntsetdefname @@ -987,6 +1053,7 @@ do -- else too many locals local scanners = tokens.scanners local scanstring = scanners.string local scaninteger = scanners.integer + local scannumber = scanners.number local scanboolean = scanners.boolean local setmacro = tokens.setters.macro @@ -1051,6 +1118,187 @@ do -- else too many locals -- function commands.definefont_two(global,cs,str,size,inheritancemode,classfeatures,fontfeatures,classfallbacks,fontfallbacks, -- mathsize,textsize,relativeid,classgoodies,goodies,classdesignsize,fontdesignsize,scaledfontmode) +-- scanners.definefont_two = function() + +-- local global = scanboolean() -- \ifx\fontclass\empty\s!false\else\s!true\fi +-- local cs = scanstring () -- {#csname}% +-- local str = scanstring () -- \somefontfile +-- local size = scaninteger() -- \d_font_scaled_font_size +-- local inheritancemode = scaninteger() -- \c_font_feature_inheritance_mode +-- local classfeatures = scanstring () -- \m_font_class_features +-- local fontfeatures = scanstring () -- \m_font_features +-- local classfallbacks = scanstring () -- \m_font_class_fallbacks +-- local fontfallbacks = scanstring () -- \m_font_fallbacks +-- local mathsize = scaninteger() -- \fontface +-- local textsize = scaninteger() -- \d_font_scaled_text_face +-- local relativeid = scaninteger() -- \relativefontid +-- local classgoodies = scanstring () -- \m_font_class_goodies +-- local goodies = scanstring () -- \m_font_goodies +-- local classdesignsize = scanstring () -- \m_font_class_designsize +-- local fontdesignsize = scanstring () -- \m_font_designsize +-- local scaledfontmode = scaninteger() -- \scaledfontmode + +-- if trace_defining then +-- report_defining("start stage two: %s, size %s, features %a & %a",str,size,classfeatures,fontfeatures) +-- end +-- -- name is now resolved and size is scaled cf sa/mo +-- local lookup, name, sub, method, detail = getspecification(str or "") +-- -- new (todo: inheritancemode) +-- local designsize = fontdesignsize ~= "" and fontdesignsize or classdesignsize or "" +-- local designname = designsizefilename(name,designsize,size) +-- if designname and designname ~= "" then +-- if trace_defining or trace_designsize then +-- report_defining("remapping name %a, specification %a, size %a, designsize %a",name,designsize,size,designname) +-- end +-- -- we don't catch detail here +-- local o_lookup, o_name, o_sub, o_method, o_detail = getspecification(designname) +-- if o_lookup and o_lookup ~= "" then lookup = o_lookup end +-- if o_method and o_method ~= "" then method = o_method end +-- if o_detail and o_detail ~= "" then detail = o_detail end +-- name = o_name +-- sub = o_sub +-- end +-- -- so far +-- -- some settings can have been overloaded +-- if lookup and lookup ~= "" then +-- specification.lookup = lookup +-- end +-- if relativeid and relativeid ~= "" then -- experimental hook +-- local id = tonumber(relativeid) or 0 +-- specification.relativeid = id > 0 and id +-- end +-- -- +-- specification.name = name +-- specification.size = size +-- specification.sub = (sub and sub ~= "" and sub) or specification.sub +-- specification.mathsize = mathsize +-- specification.textsize = textsize +-- specification.goodies = goodies +-- specification.cs = cs +-- specification.global = global +-- specification.scalemode = scaledfontmode -- context specific +-- if detail and detail ~= "" then +-- specification.method = method or "*" +-- specification.detail = detail +-- elseif specification.detail and specification.detail ~= "" then +-- -- already set +-- elseif inheritancemode == 0 then +-- -- nothing +-- elseif inheritancemode == 1 then +-- -- fontonly +-- if fontfeatures and fontfeatures ~= "" then +-- specification.method = "*" +-- specification.detail = fontfeatures +-- end +-- if fontfallbacks and fontfallbacks ~= "" then +-- specification.fallbacks = fontfallbacks +-- end +-- elseif inheritancemode == 2 then +-- -- classonly +-- if classfeatures and classfeatures ~= "" then +-- specification.method = "*" +-- specification.detail = classfeatures +-- end +-- if classfallbacks and classfallbacks ~= "" then +-- specification.fallbacks = classfallbacks +-- end +-- elseif inheritancemode == 3 then +-- -- fontfirst +-- if fontfeatures and fontfeatures ~= "" then +-- specification.method = "*" +-- specification.detail = fontfeatures +-- elseif classfeatures and classfeatures ~= "" then +-- specification.method = "*" +-- specification.detail = classfeatures +-- end +-- if fontfallbacks and fontfallbacks ~= "" then +-- specification.fallbacks = fontfallbacks +-- elseif classfallbacks and classfallbacks ~= "" then +-- specification.fallbacks = classfallbacks +-- end +-- elseif inheritancemode == 4 then +-- -- classfirst +-- if classfeatures and classfeatures ~= "" then +-- specification.method = "*" +-- specification.detail = classfeatures +-- elseif fontfeatures and fontfeatures ~= "" then +-- specification.method = "*" +-- specification.detail = fontfeatures +-- end +-- if classfallbacks and classfallbacks ~= "" then +-- specification.fallbacks = classfallbacks +-- elseif fontfallbacks and fontfallbacks ~= "" then +-- specification.fallbacks = fontfallbacks +-- end +-- end +-- local tfmdata = definers.read(specification,size) -- id not yet known (size in spec?) +-- -- +-- local lastfontid = 0 +-- if not tfmdata then +-- report_defining("unable to define %a as %a",name,nice_cs(cs)) +-- lastfontid = -1 +-- texsetcount("scaledfontsize",0) +-- -- ctx_letvaluerelax(cs) -- otherwise the current definition takes the previous one +-- elseif type(tfmdata) == "number" then +-- if trace_defining then +-- report_defining("reusing %s, id %a, target %a, features %a / %a, fallbacks %a / %a, goodies %a / %a, designsize %a / %a", +-- name,tfmdata,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,classgoodies,goodies,classdesignsize,fontdesignsize) +-- end +-- csnames[tfmdata] = specification.cs +-- texdefinefont(global,cs,tfmdata) +-- -- resolved (when designsize is used): +-- local size = fontdata[tfmdata].parameters.size or 0 +-- -- ctx_setsomefontsize(size .. "sp") +-- setmacro("somefontsize",size.."sp") +-- texsetcount("scaledfontsize",size) +-- lastfontid = tfmdata +-- else +-- -- setting the extra characters will move elsewhere +-- local characters = tfmdata.characters +-- local parameters = tfmdata.parameters +-- -- we use char0 as signal; cf the spec pdf can handle this (no char in slot) +-- characters[0] = nil +-- -- characters[0x00A0] = { width = parameters.space } +-- -- characters[0x2007] = { width = characters[0x0030] and characters[0x0030].width or parameters.space } -- figure +-- -- characters[0x2008] = { width = characters[0x002E] and characters[0x002E].width or parameters.space } -- period +-- -- +-- constructors.checkvirtualids(tfmdata) -- experiment, will become obsolete when slots can selfreference +-- local id = definefont(tfmdata) +-- csnames[id] = specification.cs +-- tfmdata.properties.id = id +-- definers.register(tfmdata,id) -- to be sure, normally already done +-- texdefinefont(global,cs,id) +-- constructors.cleanuptable(tfmdata) +-- constructors.finalize(tfmdata) +-- if trace_defining then +-- report_defining("defining %a, id %a, target %a, features %a / %a, fallbacks %a / %a", +-- name,id,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks) +-- end +-- -- resolved (when designsize is used): +-- local size = tfmdata.parameters.size or 655360 +-- setmacro("somefontsize",size.."sp") +-- -- ctx_setsomefontsize(size .. "sp") +-- texsetcount("scaledfontsize",size) +-- lastfontid = id +-- end +-- if trace_defining then +-- report_defining("memory usage after: %s",statistics.memused()) +-- report_defining("stop stage two") +-- end +-- -- +-- texsetcount("global","lastfontid",lastfontid) +-- specifiers[lastfontid] = { str, size } +-- if not mathsize then +-- -- forget about it +-- elseif mathsize == 0 then +-- lastmathids[1] = lastfontid +-- else +-- lastmathids[mathsize] = lastfontid +-- end +-- -- +-- stoptiming(fonts) +-- end + scanners.definefont_two = function() local global = scanboolean() -- \ifx\fontclass\empty\s!false\else\s!true\fi @@ -1072,7 +1320,7 @@ do -- else too many locals local scaledfontmode = scaninteger() -- \scaledfontmode if trace_defining then - report_defining("start stage two: %s (size %s)",str,size) + report_defining("start stage two: %s, size %s, features %a & %a",str,size,classfeatures,fontfeatures) end -- name is now resolved and size is scaled cf sa/mo local lookup, name, sub, method, detail = getspecification(str or "") @@ -1167,25 +1415,8 @@ do -- else too many locals local tfmdata = definers.read(specification,size) -- id not yet known (size in spec?) -- local lastfontid = 0 - if not tfmdata then - report_defining("unable to define %a as %a",name,nice_cs(cs)) - lastfontid = -1 - texsetcount("scaledfontsize",0) - -- ctx_letvaluerelax(cs) -- otherwise the current definition takes the previous one - elseif type(tfmdata) == "number" then - if trace_defining then - report_defining("reusing %s, id %a, target %a, features %a / %a, fallbacks %a / %a, goodies %a / %a, designsize %a / %a", - name,tfmdata,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,classgoodies,goodies,classdesignsize,fontdesignsize) - end - csnames[tfmdata] = specification.cs - texdefinefont(global,cs,tfmdata) - -- resolved (when designsize is used): - local size = fontdata[tfmdata].parameters.size or 0 - -- ctx_setsomefontsize(size .. "sp") - setmacro("somefontsize",size.."sp") - texsetcount("scaledfontsize",size) - lastfontid = tfmdata - else + local tfmtype = type(tfmdata) + if tfmtype == "table" then -- setting the extra characters will move elsewhere local characters = tfmdata.characters local parameters = tfmdata.parameters @@ -1196,23 +1427,83 @@ do -- else too many locals -- characters[0x2008] = { width = characters[0x002E] and characters[0x002E].width or parameters.space } -- period -- constructors.checkvirtualids(tfmdata) -- experiment, will become obsolete when slots can selfreference - local id = definefont(tfmdata) - csnames[id] = specification.cs - tfmdata.properties.id = id - definers.register(tfmdata,id) -- to be sure, normally already done - texdefinefont(global,cs,id) - constructors.cleanuptable(tfmdata) - constructors.finalize(tfmdata) + local fallbacks = specification.fallbacks + if fallbacks and fallbacks ~= "" and tfmdata.properties.hasmath then + -- We need this ugly hack in order to resolve fontnames (at the \TEX end). Originally + -- math was done in Lua after loading (plugged into aftercopying). + -- + -- After tl 2017 I'll also do text falbacks this way (although backups there are done + -- in a completely different way. + mathematics.resolvefallbacks(tfmdata,specification,fallbacks) + context(function() + mathematics.finishfallbacks(tfmdata,specification,fallbacks) + local id = definefont(tfmdata) + csnames[id] = specification.cs + tfmdata.properties.id = id + definers.register(tfmdata,id) -- to be sure, normally already done + texdefinefont(global,cs,id) + constructors.cleanuptable(tfmdata) + constructors.finalize(tfmdata) + if trace_defining then + report_defining("defining %a, id %a, target %a, features %a / %a, fallbacks %a / %a", + name,id,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks) + end + -- resolved (when designsize is used): + local size = tfmdata.parameters.size or 655360 + setmacro("somefontsize",size.."sp") + -- ctx_setsomefontsize(size .. "sp") + texsetcount("scaledfontsize",size) + lastfontid = id + -- + texsetcount("global","lastfontid",lastfontid) + specifiers[lastfontid] = { str, size } + if not mathsize then + -- forget about it + elseif mathsize == 0 then + lastmathids[1] = lastfontid + else + lastmathids[mathsize] = lastfontid + end + stoptiming(fonts) + end) + return + else + local id = definefont(tfmdata) + csnames[id] = specification.cs + tfmdata.properties.id = id + definers.register(tfmdata,id) -- to be sure, normally already done + texdefinefont(global,cs,id) + constructors.cleanuptable(tfmdata) + constructors.finalize(tfmdata) + if trace_defining then + report_defining("defining %a, id %a, target %a, features %a / %a, fallbacks %a / %a", + name,id,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks) + end + -- resolved (when designsize is used): + local size = tfmdata.parameters.size or 655360 + setmacro("somefontsize",size.."sp") + -- ctx_setsomefontsize(size .. "sp") + texsetcount("scaledfontsize",size) + lastfontid = id + end + elseif tfmtype == "number" then if trace_defining then - report_defining("defining %a, id %a, target %a, features %a / %a, fallbacks %a / %a", - name,id,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks) + report_defining("reusing %s, id %a, target %a, features %a / %a, fallbacks %a / %a, goodies %a / %a, designsize %a / %a", + name,tfmdata,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,classgoodies,goodies,classdesignsize,fontdesignsize) end + csnames[tfmdata] = specification.cs + texdefinefont(global,cs,tfmdata) -- resolved (when designsize is used): - local size = tfmdata.parameters.size or 655360 - setmacro("somefontsize",size.."sp") + local size = fontdata[tfmdata].parameters.size or 0 -- ctx_setsomefontsize(size .. "sp") + setmacro("somefontsize",size.."sp") texsetcount("scaledfontsize",size) - lastfontid = id + lastfontid = tfmdata + else + report_defining("unable to define %a as %a",name,nice_cs(cs)) + lastfontid = -1 + texsetcount("scaledfontsize",0) + -- ctx_letvaluerelax(cs) -- otherwise the current definition takes the previous one end if trace_defining then report_defining("memory usage after: %s",statistics.memused()) @@ -1220,6 +1511,7 @@ do -- else too many locals end -- texsetcount("global","lastfontid",lastfontid) + specifiers[lastfontid] = { str, size } if not mathsize then -- forget about it elseif mathsize == 0 then @@ -1231,6 +1523,26 @@ do -- else too many locals stoptiming(fonts) end + function scanners.specifiedfontspec() + local f = specifiers[scaninteger()] + if f then + context(f[1]) + end + end + function scanners.specifiedfontsize() + local f = specifiers[scaninteger()] + if f then + context(f[2]) + end + end + function scanners.specifiedfont() + local f = specifiers[scaninteger()] + local s = scannumber() + if f and s then + context("%s at %0.2p",f[1],s * f[2]) -- we round to 2 decimals (as at the tex end) + end + end + -- function definers.define(specification) @@ -1383,7 +1695,7 @@ function constructors.calculatescale(tfmdata,scaledpoints,relativeid,specificati local scaledpoints, delta = calculatescale(tfmdata,scaledpoints) -- if enable_auto_r_scale and relativeid then -- for the moment this is rather context specific (we need to hash rscale then) -- local relativedata = fontdata[relativeid] - -- local rfmdata = relativedata and relativedata.unscaled and relativedata.unscaled + -- local rfmdata = relativedata and relativedata.unscaled and relativedata.unscaled -- just use metadata instead -- local id_x_height = rfmdata and rfmdata.parameters and rfmdata.parameters.x_height -- local tf_x_height = tfmdata and tfmdata.parameters and tfmdata.parameters.x_height -- if id_x_height and tf_x_height then @@ -1397,14 +1709,19 @@ end local designsizes = constructors.designsizes +-- called quite often when in mp labels +-- otf.normalizedaxis + function constructors.hashinstance(specification,force) - local hash, size, fallbacks = specification.hash, specification.size, specification.fallbacks + local hash = specification.hash + local size = specification.size + local fallbacks = specification.fallbacks if force or not hash then hash = constructors.hashfeatures(specification) specification.hash = hash end if size < 1000 and designsizes[hash] then - size = math.round(constructors.scaled(size,designsizes[hash])) + size = round(constructors.scaled(size,designsizes[hash])) specification.size = size end if fallbacks then @@ -1437,7 +1754,7 @@ function definers.resolve(specification) -- overload function in font-con.lua else specification.forced = specification.forced end - -- goodies are a context specific thing and not always defined + -- goodies are a context specific thing and are not always defined -- as feature, so we need to make sure we add them here before -- hashing because otherwise we get funny goodies applied local goodies = specification.goodies @@ -1456,14 +1773,18 @@ function definers.resolve(specification) -- overload function in font-con.lua end end -- so far for goodie hacks - specification.hash = lower(specification.name .. ' @ ' .. hashfeatures(specification)) - if specification.sub and specification.sub ~= "" then - specification.hash = specification.sub .. ' @ ' .. specification.hash + local hash = hashfeatures(specification) + local name = specification.name + local sub = specification.sub + if sub and sub ~= "" then + specification.hash = lower(name .. " @ " .. sub .. ' @ ' .. hash) + else + specification.hash = lower(name .. " @ " .. ' @ ' .. hash) end + -- return specification end - -- soon to be obsolete: local mappings = fonts.mappings @@ -1534,7 +1855,6 @@ implement { local function nametoslot(name) local t = type(name) - local s = nil if t == "string" then local slot = unicodes[true][name] if slot then @@ -1543,12 +1863,82 @@ local function nametoslot(name) if not aglunicodes then aglunicodes = encodings.agl.unicodes end - slot = aglunicodes[name] - if characters[true][slot] then + local char = characters[true] + local slot = aglunicodes[name] + if char[slot] then + return slot + end + -- not in font + elseif t == "number" then + if characters[true][name] then return slot else -- not in font end + end +end + + +local found = { } + +local function descriptiontoslot(name) + local t = type(name) + if t == "string" then + -- slow + local list = sortedkeys(chardata) + local slot = found[name] + local char = characters[true] + if slot then + return char[slot] and slot or nil + end + local NAME = upper(name) + for i=1,#list do + slot = list[i] + local c = chardata[slot] + local d = c.description + if d == NAME then + found[name] = slot + return char[slot] and slot or nil + end + end + for i=1,#list do + slot = list[i] + local c = chardata[slot] + local s = c.synonyms + if s then + for i=1,#s do + local si = s[i] + if si == name then + found[name] = si + return char[slot] and slot or nil + end + end + end + end + for i=1,#list do + slot = list[i] + local c = chardata[slot] + local d = c.description + if d and find(d,NAME) then + found[name] = slot + return char[slot] and slot or nil + end + end + for i=1,#list do + slot = list[i] + local c = chardata[slot] + local s = c.synonyms + if s then + for i=1,#s do + local si = s[i] + if find(s[i],name) then + found[name] = si + return char[slot] and slot or nil + end + end + end + end + -- not in font elseif t == "number" then if characters[true][name] then return slot @@ -1625,6 +2015,16 @@ do -- else too many locals local n = nametoslot(name) return n and utfchar(n) or name end, + -- unicode description (synonym) + u = function(name) + local n = descriptiontoslot(name,false) + return n and utfchar(n) or name + end, + -- all + a = function(name) + local n = nametoslot(name) or descriptiontoslot(name) + return n and utfchar(n) or name + end, -- char c = function(name) return name @@ -1657,21 +2057,22 @@ do -- else too many locals end end - helpers.nametoslot = nametoslot - helpers.indextoslot = indextoslot - helpers.tochar = tochar + helpers.nametoslot = nametoslot + helpers.descriptiontoslot = descriptiontoslot + helpers.indextoslot = indextoslot + helpers.tochar = tochar -- interfaces: implement { name = "fontchar", - actions = { nametoslot, context_char }, + actions = { nametoslot, ctx_char }, arguments = "string", } implement { name = "fontcharbyindex", - actions = { indextoslot, context_char }, + actions = { indextoslot, ctx_char }, arguments = "integer", } @@ -1702,15 +2103,16 @@ function loggers.reportdefinedfonts() properties.fullname or "", properties.sharedwith or "", } - report_status("%s: % t",properties.name,sortedkeys(data)) end formatcolumns(t," ") - report_status() + logs.pushtarget("logfile") + report_newline() report_status("defined fonts:") - report_status() + report_newline() for k=1,tn do report_status(t[k]) end + logs.poptarget() end end @@ -1729,12 +2131,14 @@ function loggers.reportusedfeatures() setup.number = n -- restore it (normally not needed as we're done anyway) end formatcolumns(t," ") - report_status() + logs.pushtarget("logfile") + report_newline() report_status("defined featuresets:") - report_status() + report_newline() for k=1,n do report_status(t[k]) end + logs.poptarget() end end @@ -2023,15 +2427,7 @@ end do - -- local scanners = tokens.scanners - -- local scanstring = scanners.string - -- local scaninteger = scanners.integer - -- local scandimen = scanners.dimen - -- local scanboolean = scanners.boolean - - -- local scanners = interfaces.scanners - - local setmacro = tokens.setters.macro + local setmacro = tokens.setters.macro function constructors.currentfonthasfeature(n) local f = fontdata[currentfont()] @@ -2048,25 +2444,9 @@ do arguments = "string" } - -- local p, f = 1, formatters["%0.1fpt"] -- normally this value is changed only once - -- - -- local stripper = lpeg.patterns.stripzeros - -- - -- function commands.nbfs(amount,precision) - -- if precision ~= p then - -- p = precision - -- f = formatters["%0." .. p .. "fpt"] - -- end - -- context(lpegmatch(stripper,f(amount/65536))) - -- end - local f_strip = formatters["%0.2fpt"] -- normally this value is changed only once local stripper = lpeg.patterns.stripzeros - -- scanners.nbfs = function() - -- context(lpegmatch(stripper,f_strip(scandimen()/65536))) - -- end - implement { name = "nbfs", arguments = "dimen", @@ -2075,18 +2455,6 @@ do end } - -- commands.featureattribute = function(tag) context(contextnumber(tag)) end - -- commands.setfontfeature = function(tag) texsetattribute(0,contextnumber(tag)) end - -- commands.resetfontfeature = function() texsetattribute(0,0) end - -- commands.setfontofid = function(id) context_getvalue(csnames[id]) end - -- commands.definefontfeature = presetcontext - - -- scanners.featureattribute = function() context(contextnumber(scanstring())) end - -- scanners.setfontfeature = function() texsetattribute(0,contextnumber(scanstring())) end - -- scanners.resetfontfeature = function() texsetattribute(0,0) end - -- scanners.setfontofid = function() context_getvalue(csnames[scaninteger()]) end - -- scanners.definefontfeature = function() presetcontext(scanstring(),scanstring(),scanstring()) end - implement { name = "featureattribute", arguments = "string", @@ -2109,7 +2477,7 @@ do name = "setfontofid", arguments = "integer", actions = function(id) - context_getvalue(csnames[id]) + ctx_getvalue(csnames[id]) end } @@ -2119,6 +2487,12 @@ do actions = presetcontext } + implement { + name = "adaptfontfeature", + arguments = { "string", "string" }, + actions = adaptcontext + } + local cache = { } local hows = { @@ -2189,6 +2563,9 @@ do end end + constructors.setfeature = setfeature + constructors.resetfeature = resetfeature + implement { name = "resetfeature", actions = resetfeature } implement { name = "addfeature", actions = setfeature, arguments = { "'+'", "string", "string" } } implement { name = "subtractfeature", actions = setfeature, arguments = { "'-'", "string", "string" } } @@ -2202,8 +2579,8 @@ do } implement { - name = "registerlanguagefeatures", - actions = registerlanguagefeatures, + name = "registerlanguagefeatures", + actions = registerlanguagefeatures, } end @@ -2216,7 +2593,7 @@ do local copy_node = nuts.copy local kern = nuts.pool.register(nuts.pool.kern()) - setattr(kern,attributes.private('fontkern'),1) + setattr(kern,attributes.private('fontkern'),1) -- no gain in setprop as it's shared nodes.injections.installnewkern(function(k) local c = copy_node(kern) @@ -2275,100 +2652,106 @@ end -- make a closure (200 limit): -local trace_analyzing = false trackers.register("otf.analyzing", function(v) trace_analyzing = v end) +do -local analyzers = fonts.analyzers -local methods = analyzers.methods + local trace_analyzing = false trackers.register("otf.analyzing", function(v) trace_analyzing = v end) -local unsetvalue = attributes.unsetvalue + local analyzers = fonts.analyzers + local methods = analyzers.methods -local traverse_id = nuts.traverse_id + local unsetvalue = attributes.unsetvalue -local a_color = attributes.private('color') -local a_colormodel = attributes.private('colormodel') -local a_state = attributes.private('state') -local m_color = attributes.list[a_color] or { } + local traverse_id = nuts.traverse_id -local glyph_code = nodes.nodecodes.glyph + local a_color = attributes.private('color') + local a_colormodel = attributes.private('colormodel') + local a_state = attributes.private('state') + local m_color = attributes.list[a_color] or { } -local states = analyzers.states + local glyph_code = nodes.nodecodes.glyph -local colornames = { - [states.init] = "font:1", - [states.medi] = "font:2", - [states.fina] = "font:3", - [states.isol] = "font:4", - [states.mark] = "font:5", - [states.rest] = "font:6", - [states.rphf] = "font:1", - [states.half] = "font:2", - [states.pref] = "font:3", - [states.blwf] = "font:4", - [states.pstf] = "font:5", -} + local states = analyzers.states + + local colornames = { + [states.init] = "font:1", + [states.medi] = "font:2", + [states.fina] = "font:3", + [states.isol] = "font:4", + [states.mark] = "font:5", + [states.rest] = "font:6", + [states.rphf] = "font:1", + [states.half] = "font:2", + [states.pref] = "font:3", + [states.blwf] = "font:4", + [states.pstf] = "font:5", + } -local function markstates(head) - if head then - head = tonut(head) - local model = getattr(head,a_colormodel) or 1 - for glyph in traverse_id(glyph_code,head) do - local a = getprop(glyph,a_state) - if a then - local name = colornames[a] - if name then - local color = m_color[name] - if color then - setattr(glyph,a_colormodel,model) - setattr(glyph,a_color,color) + local function markstates(head) + if head then + head = tonut(head) + local model = getattr(head,a_colormodel) or 1 + for glyph in traverse_id(glyph_code,head) do + local a = getprop(glyph,a_state) + if a then + local name = colornames[a] + if name then + local color = m_color[name] + if color then + setattr(glyph,a_colormodel,model) + setattr(glyph,a_color,color) + end end end end end end -end -local function analyzeprocessor(head,font,attr) - local tfmdata = fontdata[font] - local script, language = otf.scriptandlanguage(tfmdata,attr) - local action = methods[script] - if not action then - return head, false - end - if type(action) == "function" then - local head, done = action(head,font,attr) - if done and trace_analyzing then - markstates(head) + local function analyzeprocessor(head,font,attr) + local tfmdata = fontdata[font] + local script, language = otf.scriptandlanguage(tfmdata,attr) + local action = methods[script] + if not action then + return head, false end - return head, done - end - action = action[language] - if action then - local head, done = action(head,font,attr) - if done and trace_analyzing then - markstates(head) + if type(action) == "function" then + local head, done = action(head,font,attr) + if done and trace_analyzing then + markstates(head) + end + return head, done + end + action = action[language] + if action then + local head, done = action(head,font,attr) + if done and trace_analyzing then + markstates(head) + end + return head, done + else + return head, false end - return head, done - else - return head, false end -end -registerotffeature { -- adapts - name = "analyze", - processors = { - node = analyzeprocessor, + registerotffeature { -- adapts + name = "analyze", + processors = { + node = analyzeprocessor, + } } -} -function methods.nocolor(head,font,attr) - for n in traverse_id(glyph_code,head) do - if not font or getfont(n) == font then - setattr(n,a_color,unsetvalue) + + function methods.nocolor(head,font,attr) + for n in traverse_id(glyph_code,head) do + if not font or getfont(n) == font then + setattr(n,a_color,unsetvalue) + end end + return head, true end - return head, true + end + local function purefontname(name) if type(name) == "number" then name = getfontname(name) @@ -2385,6 +2768,7 @@ implement { } local list = storage.shared.bodyfontsizes or { } + storage.shared.bodyfontsizes = list implement { @@ -2421,7 +2805,7 @@ implement { implement { name = "cleanfontname", - actions = { names.cleanname, context }, + actions = { cleanname, context }, arguments = "string" } @@ -2496,3 +2880,197 @@ implement { actions = { names.exists, commands.doifelse }, arguments = "string" } + +-- we use 0xFE000+ and 0xFF000+ in math and for runtime (text) extensions we +-- use 0xFD000+ + +constructors.privateslots = constructors.privateslots or { } + +storage.register("fonts/constructors/privateslots", constructors.privateslots, "fonts.constructors.privateslots") + +do + + local privateslots = constructors.privateslots + local lastprivateslot = 0xFD000 + + constructors.privateslots = setmetatableindex(privateslots,function(t,k) + local v = lastprivateslot + lastprivateslot = lastprivateslot + 1 + t[k] = v + return v + end) + + implement { + name = "getprivateglyphslot", + actions = function(name) context(privateslots[name]) end, + arguments = "string", + } + +end + +-- an extra helper + +function helpers.getcoloredglyphs(tfmdata) + if type(tfmdata) == "number" then + tfmdata = fontdata[tfmdata] + end + if not tfmdata then + tfmdata = fontdata[true] + end + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + local collected = { } + for unicode, character in next, characters do + local description = descriptions[unicode] + if description and (description.colors or character.svg) then + collected[#collected+1] = unicode + end + end + table.sort(collected) + return collected +end + +-- for the font manual + +statistics.register("used fonts",function() + if trace_usage then + local filename = file.nameonly(environment.jobname) .. "-fonts-usage.lua" + if next(fontdata) then + local files = { } + local list = { } + for id, tfmdata in sortedhash(fontdata) do + local filename = tfmdata.properties.filename + if filename then + local filedata = files[filename] + if filedata then + filedata.instances = filedata.instances + 1 + else + local rawdata = tfmdata.shared and tfmdata.shared.rawdata + local metadata = rawdata and rawdata.metadata + files[filename] = { + instances = 1, + filename = filename, + version = metadata and metadata.version, + size = rawdata and rawdata.size, + } + end + else + -- what to do + end + end + for k, v in sortedhash(files) do + list[#list+1] = v + end + table.save(filename,list) + else + os.remove(filename) + end + end +end) + +-- new + +do + + local settings_to_array = utilities.parsers.settings_to_array + -- local namedcolorattributes = attributes.colors.namedcolorattributes + -- local colorvalues = attributes.colors.values + + -- implement { + -- name = "definefontcolorpalette", + -- arguments = { "string", "string" }, + -- actions = function(name,set) + -- set = settings_to_array(set) + -- for i=1,#set do + -- local name = set[i] + -- local space, color = namedcolorattributes(name) + -- local values = colorvalues[color] + -- if values then + -- set[i] = { r = values[3], g = values[4], b = values[5] } + -- else + -- set[i] = { r = 0, g = 0, b = 0 } + -- end + -- end + -- otf.registerpalette(name,set) + -- end + -- } + + implement { + name = "definefontcolorpalette", + arguments = { "string", "string" }, + actions = function(name,set) + otf.registerpalette(name,settings_to_array(set)) + end + } + +end + +do + + local pattern = C((1-S("* "))^1) -- strips all after * or ' at' + + implement { + name = "truefontname", + arguments = "string", + actions = function(s) + -- context(match(s,"[^* ]+") or s) + context(lpegmatch(pattern,s) or s) + end + } + +end + +do + + local function getinstancespec(id) + local data = fontdata[id or true] + local shared = data.shared + local resources = shared and shared.rawdata.resources + if resources then + local instancespec = data.properties.instance + if instancespec then + local variabledata = resources.variabledata + if variabledata then + local instances = variabledata.instances + if instances then + for i=1,#instances do + local instance = instances[i] + if cleanname(instance.subfamily)== instancespec then + local values = table.copy(instance.values) + local axis = variabledata.axis + for i=1,#values do + for j=1,#axis do + if values[i].axis == axis[j].tag then + values[i].name = axis[j].name + break + end + end + end + return values + end + end + end + end + end + end + end + + helpers.getinstancespec = getinstancespec + + implement { + name = "currentfontinstancespec", + actions = function() + local t = getinstancespec() -- current font + if t then + for i=1,#t do + if i > 1 then + context.space() + end + local ti = t[i] + context("%s=%s",ti.name,ti.value) + end + end + end + } + +end diff --git a/tex/context/base/mkiv/font-def.lua b/tex/context/base/mkiv/font-def.lua index add42ee38..c8394badf 100644 --- a/tex/context/base/mkiv/font-def.lua +++ b/tex/context/base/mkiv/font-def.lua @@ -8,10 +8,12 @@ if not modules then modules = { } end modules ['font-def'] = { -- We can overload some of the definers.functions so we don't local them. -local format, gmatch, match, find, lower, gsub = string.format, string.gmatch, string.match, string.find, string.lower, string.gsub +local lower, gsub = string.lower, string.gsub local tostring, next = tostring, next local lpegmatch = lpeg.match -local suffixonly, removesuffix = file.suffix, file.removesuffix +local suffixonly, removesuffix, basename = file.suffix, file.removesuffix, file.basename +local formatters = string.formatters +local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys local allocate = utilities.storage.allocate @@ -183,11 +185,30 @@ end function resolvers.name(specification) local resolve = fonts.names.resolve if resolve then - local resolved, sub, subindex = resolve(specification.name,specification.sub,specification) -- we pass specification for overloaded versions + local resolved, sub, subindex, instance = resolve(specification.name,specification.sub,specification) -- we pass specification for overloaded versions if resolved then specification.resolved = resolved specification.sub = sub specification.subindex = subindex + -- new, needed for experiments + if instance then + specification.instance = instance + local features = specification.features + if not features then + features = { } + specification.features = features + end + local normal = features.normal + if not normal then + normal = { } + features.normal = normal + end + normal.instance = instance + if not callbacks.supported.glyph_stream_provider then + normal.variableshapes = true -- for the moment + end + end + -- local suffix = lower(suffixonly(resolved)) if fonts.formats[suffix] then specification.forced = suffix @@ -264,7 +285,7 @@ function definers.applypostprocessors(tfmdata) if type(extrahash) == "string" and extrahash ~= "" then -- e.g. a reencoding needs this extrahash = gsub(lower(extrahash),"[^a-z]","-") - properties.fullname = format("%s-%s",properties.fullname,extrahash) + properties.fullname = formatters["%s-%s"](properties.fullname,extrahash) end end end @@ -293,8 +314,68 @@ local function checkembedding(tfmdata) tfmdata.embedding = embedding end +local function checkfeatures(tfmdata) + local resources = tfmdata.resources + local shared = tfmdata.shared + if resources and shared then + local features = resources.features + local usedfeatures = shared.features + if features and usedfeatures then + local usedlanguage = usedfeatures.language or "dflt" + local usedscript = usedfeatures.script or "dflt" + local function check(what) + if what then + local foundlanguages = { } + for feature, scripts in next, what do + if usedscript == "auto" or scripts["*"] then + -- ok + elseif not scripts[usedscript] then + -- report_defining("font %!font:name!, feature %a, no script %a", + -- tfmdata,feature,usedscript) + else + for script, languages in next, scripts do + if languages["*"] then + -- ok + elseif not languages[usedlanguage] then + report_defining("font %!font:name!, feature %a, script %a, no language %a", + tfmdata,feature,script,usedlanguage) + end + end + end + for script, languages in next, scripts do + for language in next, languages do + foundlanguages[language] = true + end + end + end + if false then + foundlanguages["*"] = nil + foundlanguages = sortedkeys(foundlanguages) + for feature, scripts in sortedhash(what) do + for script, languages in next, scripts do + if not languages["*"] then + for i=1,#foundlanguages do + local language = foundlanguages[i] + if not languages[language] then + report_defining("font %!font:name!, feature %a, script %a, no language %a", + tfmdata,feature,script,language) + end + end + end + end + end + end + end + end + check(features.gsub) + check(features.gpos) + end + end +end + function definers.loadfont(specification) local hash = constructors.hashinstance(specification) + -- todo: also hash by instance / factors local tfmdata = loadedfonts[hash] -- hashes by size ! if not tfmdata then local forced = specification.forced or "" @@ -326,6 +407,7 @@ function definers.loadfont(specification) checkembedding(tfmdata) -- todo: general postprocessor loadedfonts[hash] = tfmdata designsizes[specification.hash] = tfmdata.parameters.designsize + checkfeatures(tfmdata) end end if not tfmdata then @@ -437,7 +519,7 @@ function definers.read(specification,size,id) -- id can be optional, name can al local parameters = tfmdata.parameters or { } report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a", properties.format or "unknown", id, properties.name, parameters.size, properties.encodingbytes, - properties.encodingname, properties.fullname, file.basename(properties.filename)) + properties.encodingname, properties.fullname, basename(properties.filename)) end statistics.stoptiming(fonts) return tfmdata diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua index 330a9400c..b46e1b82c 100644 --- a/tex/context/base/mkiv/font-dsp.lua +++ b/tex/context/base/mkiv/font-dsp.lua @@ -48,15 +48,28 @@ if not modules then modules = { } end modules ['font-dsp'] = { -- of node lists is not noticeable faster for latin texts, but for arabic we gain some 10% -- (and could probably gain a bit more). +-- All this packing in the otf format is somewhat obsessive as nowadays 4K resolution +-- multi-gig videos pass through our networks and storage and memory is abundant. + local next, type = next, type local bittest = bit32.btest +local band = bit32.band +local extract = bit32.extract +local bor = bit32.bor +local lshift = bit32.lshift local rshift = bit32.rshift -local concat = table.concat +local gsub = string.gsub local lower = string.lower local sub = string.sub local strip = string.strip local tohash = table.tohash +local concat = table.concat +local copy = table.copy local reversed = table.reversed +local sort = table.sort +local insert = table.insert +local round = math.round +local lpegmatch = lpeg.match local setmetatableindex = table.setmetatableindex local formatters = string.formatters @@ -69,18 +82,32 @@ local readers = fonts.handlers.otf.readers local streamreader = readers.streamreader local setposition = streamreader.setposition -local skipbytes = streamreader.skip -local skipshort = streamreader.skipshort +local getposition = streamreader.getposition local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer +local readinteger = streamreader.readinteger1 local readshort = streamreader.readinteger2 -- 16-bit signed integer -local readfword = readshort local readstring = streamreader.readstring local readtag = streamreader.readtag +local readbytes = streamreader.readbytes +local readfixed = streamreader.readfixed4 +local read2dot14 = streamreader.read2dot14 +local skipshort = streamreader.skipshort +local skipbytes = streamreader.skip +local readfword = readshort +local readbytetable = streamreader.readbytetable +local readbyte = streamreader.readbyte local gsubhandlers = { } local gposhandlers = { } +readers.gsubhandlers = gsubhandlers +readers.gposhandlers = gposhandlers + +local helpers = readers.helpers +local gotodatatable = helpers.gotodatatable +local setvariabledata = helpers.setvariabledata + local lookupidoffset = -1 -- will become 1 when we migrate (only -1 for comparign with old) local classes = { @@ -119,6 +146,90 @@ local chaindirections = { reversechainedcontextsingle = -1, } +local function setmetrics(data,where,tag,d) + local w = data[where] + if w then + local v = w[tag] + if v then + -- it looks like some fonts set the value and not the delta + -- report("adding %s to %s.%s value %s",d,where,tag,v) + w[tag] = v + d + end + end +end + +local variabletags = { + hasc = function(data,d) setmetrics(data,"windowsmetrics","typoascender",d) end, + hdsc = function(data,d) setmetrics(data,"windowsmetrics","typodescender",d) end, + hlgp = function(data,d) setmetrics(data,"windowsmetrics","typolinegap",d) end, + hcla = function(data,d) setmetrics(data,"windowsmetrics","winascent",d) end, + hcld = function(data,d) setmetrics(data,"windowsmetrics","windescent",d) end, + vasc = function(data,d) setmetrics(data,"vhea not done","ascent",d) end, + vdsc = function(data,d) setmetrics(data,"vhea not done","descent",d) end, + vlgp = function(data,d) setmetrics(data,"vhea not done","linegap",d) end, + xhgt = function(data,d) setmetrics(data,"windowsmetrics","xheight",d) end, + cpht = function(data,d) setmetrics(data,"windowsmetrics","capheight",d) end, + sbxs = function(data,d) setmetrics(data,"windowsmetrics","subscriptxsize",d) end, + sbys = function(data,d) setmetrics(data,"windowsmetrics","subscriptysize",d) end, + sbxo = function(data,d) setmetrics(data,"windowsmetrics","subscriptxoffset",d) end, + sbyo = function(data,d) setmetrics(data,"windowsmetrics","subscriptyoffset",d) end, + spxs = function(data,d) setmetrics(data,"windowsmetrics","superscriptxsize",d) end, + spys = function(data,d) setmetrics(data,"windowsmetrics","superscriptysize",d) end, + spxo = function(data,d) setmetrics(data,"windowsmetrics","superscriptxoffset",d) end, + spyo = function(data,d) setmetrics(data,"windowsmetrics","superscriptyoffset",d) end, + strs = function(data,d) setmetrics(data,"windowsmetrics","strikeoutsize",d) end, + stro = function(data,d) setmetrics(data,"windowsmetrics","strikeoutpos",d) end, + unds = function(data,d) setmetrics(data,"postscript","underlineposition",d) end, + undo = function(data,d) setmetrics(data,"postscript","underlinethickness",d) end, +} + +local read_cardinal = { + streamreader.readcardinal1, + streamreader.readcardinal2, + streamreader.readcardinal3, + streamreader.readcardinal4, +} + +local read_integer = { + streamreader.readinteger1, + streamreader.readinteger2, + streamreader.readinteger3, + streamreader.readinteger4, +} + +-- using helpers doesn't make much sense, subtle differences +-- +-- local function readushortarray(f,n) +-- local t = { } +-- for i=1,n do +-- t[i] = readushort(f) +-- end +-- return t +-- end +-- +-- local function readulongarray(f,n) +-- local t = { } +-- for i=1,n do +-- t[i] = readulong(f) +-- end +-- return t +-- end +-- +-- local function readushortarray(f,target,first,size) +-- if not size then +-- for i=1,size do +-- target[i] = readushort(f) +-- end +-- else +-- for i=1,size do +-- target[first+i] = readushort(f) +-- end +-- end +-- return target +-- end +-- +-- so we get some half helper - half non helper mix then + -- Traditionally we use these unique names (so that we can flatten the lookup list -- (we create subsets runtime) but I will adapt the old code to newer names. @@ -181,6 +292,269 @@ local lookupflags = setmetatableindex(function(t,k) return v end) +-- Variation stores: it's not entirely clear if the regions are a shared +-- resource (it looks like they are). Anyway, we play safe and use a +-- share. + +-- values can be anything the min/max permits so we can either think of +-- real values of a fraction along the axis (probably easier) + +-- wght:400,wdth:100,ital:1 + +-- local names = table.setmetatableindex ( { +-- weight = "wght", +-- width = "wdth", +-- italic = "ital", +-- }, "self") + +-- todo: spaces in name but not before : + +local pattern = lpeg.Cf ( + lpeg.Ct("") * + lpeg.Cg ( + --(lpeg.R("az")^1/names) * lpeg.S(" :") * + lpeg.C((lpeg.R("az","09")+lpeg.P(" "))^1) * lpeg.S(" :=") * + (lpeg.patterns.number/tonumber) * lpeg.S(" ,")^0 + )^1, rawset +) + +local hash = table.setmetatableindex(function(t,k) + local v = lpegmatch(pattern,k) + local t = { } + for k, v in sortedhash(v) do + t[#t+1] = k .. "=" .. v + end + v = concat(t,",") + t[k] = v + return v +end) + +helpers.normalizedaxishash = hash + +local cleanname = fonts.names and fonts.names.cleanname or function(name) + return name and (gsub(lower(name),"[^%a%d]","")) or nil +end + +helpers.cleanname = cleanname + +function helpers.normalizedaxis(str) + return hash[str] or str +end + +local function axistofactors(str) + return lpegmatch(pattern,str) +end + +-- contradicting spec ... (signs) so i'll check it and fix it once we have +-- proper fonts + +local function getaxisscale(segments,minimum,default,maximum,user) + -- + -- returns the right values cf example in standard + -- + if not minimum or not default or not maximum then + return false + end + if user < minimum then + user = minimum + elseif user > maximum then + user = maximum + end + if user < default then + default = - (default - user) / (default - minimum) + elseif user > default then + default = (user - default) / (maximum - default) + else + default = 0 + end + if not segments then + return default + end + local e + for i=1,#segments do + local s = segments[i] + if type(s) ~= "number" then + report("using default axis scale") + return default + elseif s[1] >= default then + if s[2] == default then + return default + else + e = i + break + end + end + end + if e then + local b = segments[e-1] + local e = segments[e] + return b[2] + (e[2] - b[2]) * (default - b[1]) / (e[1] - b[1]) + else + return false + end +end + +local function getfactors(data,instancespec) + if instancespec == true then + -- take default + elseif type(instancespec) ~= "string" or instancespec == "" then + return + end + local variabledata = data.variabledata + if not variabledata then + return + end + local instances = variabledata.instances + local axis = variabledata.axis + local segments = variabledata.segments + if instances and axis then + local values + if instancespec == true then + -- first instance: + -- values = instances[1].values + -- axis defaults: + values = { } + for i=1,#axis do + values[i] = { + -- axis = axis[i].tag, + value = axis[i].default, + } + end + + else + for i=1,#instances do + local instance = instances[i] + if cleanname(instance.subfamily) == instancespec then + values = instance.values + break + end + end + end + if values then + local factors = { } + for i=1,#axis do + local a = axis[i] + factors[i] = getaxisscale(segments,a.minimum,a.default,a.maximum,values[i].value) + end + return factors + end + local values = axistofactors(hash[instancespec] or instancespec) + if values then + local factors = { } + for i=1,#axis do + local a = axis[i] + local d = a.default + factors[i] = getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d) + end + return factors + end + end +end + +local function getscales(regions,factors) + local scales = { } + for i=1,#regions do + local region = regions[i] + local s = 1 + for j=1,#region do + local axis = region[j] + local f = factors[j] + local start = axis.start + local peak = axis.peak + local stop = axis.stop + -- get rid of these tests, false flag + if start > peak or peak > stop then + -- * 1 + elseif start < 0 and stop > 0 and peak ~= 0 then + -- * 1 + elseif peak == 0 then + -- * 1 + elseif f < start or f > stop then + -- * 0 + s = 0 + break + elseif f < peak then + -- s = - s * (f - start) / (peak - start) + s = s * (f - start) / (peak - start) + elseif f > peak then + s = s * (stop - f) / (stop - peak) + else + -- * 1 + end + end + scales[i] = s + end + return scales +end + +helpers.getaxisscale = getaxisscale +helpers.getfactors = getfactors +helpers.getscales = getscales +helpers.axistofactors = axistofactors + +local function readvariationdata(f,storeoffset,factors) -- store + local position = getposition(f) + setposition(f,storeoffset) + -- header + local format = readushort(f) + local regionoffset = storeoffset + readulong(f) + local nofdeltadata = readushort(f) + local deltadata = { } + for i=1,nofdeltadata do + deltadata[i] = readulong(f) + end + -- regions + setposition(f,regionoffset) + local nofaxis = readushort(f) + local nofregions = readushort(f) + local regions = { } + for i=1,nofregions do -- 0 + local t = { } + for i=1,nofaxis do + t[i] = { -- maybe no keys, just 1..3 + start = read2dot14(f), + peak = read2dot14(f), + stop = read2dot14(f), + } + end + regions[i] = t + end + -- deltas + if factors then + for i=1,nofdeltadata do + setposition(f,storeoffset+deltadata[i]) + local nofdeltasets = readushort(f) + local nofshorts = readushort(f) + local nofregions = readushort(f) + local usedregions = { } + local deltas = { } + for i=1,nofregions do + usedregions[i] = regions[readushort(f)+1] + end + -- we could test before and save a for + for i=1,nofdeltasets do + local t = { } -- newtable + for i=1,nofshorts do + t[i] = readshort(f) + end + for i=nofshorts+1,nofregions do + t[i] = readinteger(f) + end + deltas[i] = t + end + deltadata[i] = { + regions = usedregions, + deltas = deltas, + scales = factors and getscales(usedregions,factors) or nil, + } + end + end + setposition(f,position) + return regions, deltadata +end + +helpers.readvariationdata = readvariationdata + -- Beware: only use the simple variant if we don't set keys/values (otherwise too many entries). We -- could also have a variant that applies a function but there is no real benefit in this. @@ -224,10 +598,15 @@ local function readcoverage(f,offset,simple) return coverage end -local function readclassdef(f,offset) +local function readclassdef(f,offset,preset) setposition(f,offset) local classdefformat = readushort(f) local classdef = { } + if type(preset) == "number" then + for k=0,preset-1 do + classdef[k] = 1 + end + end if classdefformat == 1 then local index = readushort(f) local nofclassdef = readushort(f) @@ -249,6 +628,13 @@ local function readclassdef(f,offset) else report("unknown classdef format %a ",classdefformat) end + if type(preset) == "table" then + for k in next, preset do + if not classdef[k] then + classdef[k] = 1 + end + end + end return classdef end @@ -269,36 +655,168 @@ end -- extra readers -local function readposition(f,format) +local skips = { [0] = + 0, -- ---- + 1, -- ---x + 1, -- --y- + 2, -- --yx + 1, -- -h-- + 2, -- -h-x + 2, -- -hy- + 3, -- -hyx + 2, -- v--x + 2, -- v-y- + 3, -- v-yx + 2, -- vh-- + 3, -- vh-x + 3, -- vhy- + 4, -- vhyx +} + +-- We can assume that 0 is nothing and in fact we can start at 1 as +-- usual in Lua to make sure of that. + +local function readvariation(f,offset) + local p = getposition(f) + setposition(f,offset) + local outer = readushort(f) + local inner = readushort(f) + local format = readushort(f) + setposition(f,p) + if format == 0x8000 then + return outer, inner + end +end + +local function readposition(f,format,mainoffset,getdelta) if format == 0 then - return nil + return end - -- maybe fast test on 0x0001 + 0x0002 + 0x0004 + 0x0008 (profile first) - local x = bittest(format,0x0001) and readshort(f) or 0 -- placement - local y = bittest(format,0x0002) and readshort(f) or 0 -- placement - local h = bittest(format,0x0004) and readshort(f) or 0 -- advance - local v = bittest(format,0x0008) and readshort(f) or 0 -- advance - if x == 0 and y == 0 and h == 0 and v == 0 then - return nil + -- a few happen often + if format == 0x04 then + local h = readshort(f) + if h == 0 then + return + else + return { 0, 0, h, 0 } + end + end + if format == 0x05 then + local x = readshort(f) + local h = readshort(f) + if x == 0 and h == 0 then + return + else + return { x, 0, h, 0 } + end + end + if format == 0x44 then + local h = readshort(f) + if getdelta then + local d = readshort(f) -- short or ushort + if d > 0 then + local outer, inner = readvariation(f,mainoffset+d) + if outer then + h = h + getdelta(outer,inner) + end + end + else + skipshort(f,1) + end + if h == 0 then + return + else + return { 0, 0, h, 0 } + end + end + -- + -- todo: + -- + -- if format == 0x55 then + -- local x = readshort(f) + -- local h = readshort(f) + -- .... + -- end + -- + local x = bittest(format,0x01) and readshort(f) or 0 -- x placement + local y = bittest(format,0x02) and readshort(f) or 0 -- y placement + local h = bittest(format,0x04) and readshort(f) or 0 -- h advance + local v = bittest(format,0x08) and readshort(f) or 0 -- v advance + if format >= 0x10 then + local X = bittest(format,0x10) and skipshort(f) or 0 + local Y = bittest(format,0x20) and skipshort(f) or 0 + local H = bittest(format,0x40) and skipshort(f) or 0 + local V = bittest(format,0x80) and skipshort(f) or 0 + local s = skips[extract(format,4,4)] + if s > 0 then + skipshort(f,s) + end + if getdelta then + if X > 0 then + local outer, inner = readvariation(f,mainoffset+X) + if outer then + x = x + getdelta(outer,inner) + end + end + if Y > 0 then + local outer, inner = readvariation(f,mainoffset+Y) + if outer then + y = y + getdelta(outer,inner) + end + end + if H > 0 then + local outer, inner = readvariation(f,mainoffset+H) + if outer then + h = h + getdelta(outer,inner) + end + end + if V > 0 then + local outer, inner = readvariation(f,mainoffset+V) + if outer then + v = v + getdelta(outer,inner) + end + end + end + return { x, y, h, v } + elseif x == 0 and y == 0 and h == 0 and v == 0 then + return else return { x, y, h, v } end end -local function readanchor(f,offset) +local function readanchor(f,offset,getdelta) -- maybe also ignore 0's as in pos if not offset or offset == 0 then return nil -- false end setposition(f,offset) - local format = readshort(f) - if format == 0 then - report("invalid anchor format %i @ position %i",format,offset) - return false - elseif format > 3 then - report("unsupported anchor format %i @ position %i",format,offset) - return false + -- no need to skip as we position each + local format = readshort(f) -- 1: x y 2: x y index 3 x y X Y + local x = readshort(f) + local y = readshort(f) + if format == 3 then + if getdelta then + local X = readshort(f) + local Y = readshort(f) + if X > 0 then + local outer, inner = readvariation(f,offset+X) + if outer then + x = x + getdelta(outer,inner) + end + end + if Y > 0 then + local outer, inner = readvariation(f,offset+Y) + if outer then + y = y + getdelta(outer,inner) + end + end + else + skipshort(f,2) + end + return { x, y } -- , { xindex, yindex } + else + return { x, y } end - return { readshort(f), readshort(f) } end -- common handlers: inlining can be faster but we cache anyway @@ -365,6 +883,58 @@ end -- We generalize the chained lookups so that we can do with only one handler -- when processing them. +-- pruned + +local function readlookuparray(f,noflookups,nofcurrent) + local lookups = { } + if noflookups > 0 then + local length = 0 + for i=1,noflookups do + local index = readushort(f) + 1 + if index > length then + length = index + end + local lookup = readushort(f) + 1 + local list = lookups[index] + if list then + list[#list+1] = lookup + else + lookups[index] = { lookup } + end + end + for index=1,length do + if not lookups[index] then + lookups[index] = false + end + end + -- if length > nofcurrent then + -- report("more lookups than currently matched characters") + -- end + end + return lookups +end + +-- not pruned +-- +-- local function readlookuparray(f,noflookups,nofcurrent) +-- local lookups = { } +-- for i=1,nofcurrent do +-- lookups[i] = false +-- end +-- for i=1,noflookups do +-- local index = readushort(f) + 1 +-- if index > nofcurrent then +-- report("more lookups than currently matched characters") +-- for i=nofcurrent+1,index-1 do +-- lookups[i] = false +-- end +-- nofcurrent = index +-- end +-- lookups[index] = readushort(f) + 1 +-- end +-- return lookups +-- end + local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) local tableoffset = lookupoffset + offset setposition(f,tableoffset) @@ -389,10 +959,7 @@ local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,n for i=2,nofcurrent do current[i] = { readushort(f) } end - local lookups = { } - for i=1,noflookups do - lookups[readushort(f)+1] = readushort(f) + 1 - end + local lookups = readlookuparray(f,noflookups,nofcurrent) rules[#rules+1] = { current = current, lookups = lookups @@ -416,7 +983,7 @@ local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,n local rules = { } if subclasssets then coverage = readcoverage(f,tableoffset + coverage) - currentclassdef = readclassdef(f,tableoffset + currentclassdef) + currentclassdef = readclassdef(f,tableoffset + currentclassdef,coverage) local currentclasses = classtocoverage(currentclassdef,fontdata.glyphs) for class=1,#subclasssets do local offset = subclasssets[class] @@ -435,10 +1002,7 @@ local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,n for i=2,nofcurrent do current[i] = currentclasses[readushort(f) + 1] end - local lookups = { } - for i=1,noflookups do - lookups[readushort(f)+1] = readushort(f) + 1 - end + local lookups = readlookuparray(f,noflookups,nofcurrent) rules[#rules+1] = { current = current, lookups = lookups @@ -462,10 +1026,7 @@ local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,n elseif subtype == 3 then local current = readarray(f) local noflookups = readushort(f) - local lookups = { } - for i=1,noflookups do - lookups[readushort(f)+1] = readushort(f) + 1 - end + local lookups = readlookuparray(f,noflookups,#current) current = readcoveragearray(f,tableoffset,current,true) return { format = "coverage", @@ -525,10 +1086,7 @@ local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nof end end local noflookups = readushort(f) - local lookups = { } - for i=1,noflookups do - lookups[readushort(f)+1] = readushort(f) + 1 - end + local lookups = readlookuparray(f,noflookups,nofcurrent) rules[#rules+1] = { before = before, current = current, @@ -554,9 +1112,9 @@ local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nof local rules = { } if subclasssets then local coverage = readcoverage(f,tableoffset + coverage) - local beforeclassdef = readclassdef(f,tableoffset + beforeclassdef) - local currentclassdef = readclassdef(f,tableoffset + currentclassdef) - local afterclassdef = readclassdef(f,tableoffset + afterclassdef) + local beforeclassdef = readclassdef(f,tableoffset + beforeclassdef,nofglyphs) + local currentclassdef = readclassdef(f,tableoffset + currentclassdef,coverage) + local afterclassdef = readclassdef(f,tableoffset + afterclassdef,nofglyphs) local beforeclasses = classtocoverage(beforeclassdef,fontdata.glyphs) local currentclasses = classtocoverage(currentclassdef,fontdata.glyphs) local afterclasses = classtocoverage(afterclassdef,fontdata.glyphs) @@ -596,10 +1154,7 @@ local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nof end -- no sequence index here (so why in context as it saves nothing) local noflookups = readushort(f) - local lookups = { } - for i=1,noflookups do - lookups[readushort(f)+1] = readushort(f) + 1 - end + local lookups = readlookuparray(f,noflookups,nofcurrent) rules[#rules+1] = { before = before, current = current, @@ -627,10 +1182,7 @@ local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nof local current = readarray(f) local after = readarray(f) local noflookups = readushort(f) - local lookups = { } - for i=1,noflookups do - lookups[readushort(f)+1] = readushort(f) + 1 - end + local lookups = readlookuparray(f,noflookups,#current) before = readcoveragearray(f,tableoffset,before,true) current = readcoveragearray(f,tableoffset,current,true) after = readcoveragearray(f,tableoffset,after,true) @@ -716,6 +1268,8 @@ function gsubhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofg end end +-- we see coverage format 0x300 in some old ms fonts + local function sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) local tableoffset = lookupoffset + offset setposition(f,tableoffset) @@ -854,20 +1408,21 @@ end -- gpos handlers -local function readpairsets(f,tableoffset,sets,format1,format2) +local function readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) local done = { } for i=1,#sets do local offset = sets[i] local reused = done[offset] if not reused then - setposition(f,tableoffset + offset) + offset = tableoffset + offset + setposition(f,offset) local n = readushort(f) reused = { } for i=1,n do reused[i] = { readushort(f), -- second glyph id - readposition(f,format1), - readposition(f,format2) + readposition(f,format1,offset,getdelta), + readposition(f,format2,offset,getdelta), } end done[offset] = reused @@ -877,14 +1432,14 @@ local function readpairsets(f,tableoffset,sets,format1,format2) return sets end -local function readpairclasssets(f,nofclasses1,nofclasses2,format1,format2) +local function readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,mainoffset,getdelta) local classlist1 = { } for i=1,nofclasses1 do local classlist2 = { } classlist1[i] = classlist2 for j=1,nofclasses2 do - local one = readposition(f,format1) - local two = readposition(f,format2) + local one = readposition(f,format1,mainoffset,getdelta) + local two = readposition(f,format2,mainoffset,getdelta) if one or two then classlist2[j] = { one, two } else @@ -900,26 +1455,27 @@ end function gposhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) local tableoffset = lookupoffset + offset setposition(f,tableoffset) - local subtype = readushort(f) + local subtype = readushort(f) + local getdelta = fontdata.temporary.getdelta if subtype == 1 then local coverage = readushort(f) local format = readushort(f) - local value = readposition(f,format) + local value = readposition(f,format,tableoffset,getdelta) local coverage = readcoverage(f,tableoffset+coverage) for index, newindex in next, coverage do coverage[index] = value end return { format = "pair", - coverage = coverage + coverage = coverage, } elseif subtype == 2 then local coverage = readushort(f) local format = readushort(f) - local values = { } local nofvalues = readushort(f) + local values = { } for i=1,nofvalues do - values[i] = readposition(f,format) + values[i] = readposition(f,format,tableoffset,getdelta) end local coverage = readcoverage(f,tableoffset+coverage) for index, newindex in next, coverage do @@ -927,7 +1483,7 @@ function gposhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofg end return { format = "pair", - coverage = coverage + coverage = coverage, } else report("unsupported subtype %a in %a positioning",subtype,"single") @@ -944,13 +1500,14 @@ end function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) local tableoffset = lookupoffset + offset setposition(f,tableoffset) - local subtype = readushort(f) + local subtype = readushort(f) + local getdelta = fontdata.temporary.getdelta if subtype == 1 then local coverage = readushort(f) local format1 = readushort(f) local format2 = readushort(f) local sets = readarray(f) - sets = readpairsets(f,tableoffset,sets,format1,format2) + sets = readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) coverage = readcoverage(f,tableoffset + coverage) for index, newindex in next, coverage do local set = sets[newindex+1] @@ -972,7 +1529,7 @@ function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofgly end return { format = "pair", - coverage = coverage + coverage = coverage, } elseif subtype == 2 then local coverage = readushort(f) @@ -982,10 +1539,10 @@ function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofgly local classdef2 = readushort(f) local nofclasses1 = readushort(f) -- incl class 0 local nofclasses2 = readushort(f) -- incl class 0 - local classlist = readpairclasssets(f,nofclasses1,nofclasses2,format1,format2) + local classlist = readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,tableoffset,getdelta) coverage = readcoverage(f,tableoffset+coverage) - classdef1 = readclassdef(f,tableoffset+classdef1) - classdef2 = readclassdef(f,tableoffset+classdef2) + classdef1 = readclassdef(f,tableoffset+classdef1,coverage) + classdef2 = readclassdef(f,tableoffset+classdef2,nofglyphs) local usedcoverage = { } for g1, c1 in next, classdef1 do if coverage[g1] then @@ -1010,7 +1567,7 @@ function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofgly end return { format = "pair", - coverage = usedcoverage + coverage = usedcoverage, } elseif subtype == 3 then report("yet unsupported subtype %a in %a positioning",subtype,"pair") @@ -1022,7 +1579,8 @@ end function gposhandlers.cursive(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) local tableoffset = lookupoffset + offset setposition(f,tableoffset) - local subtype = readushort(f) + local subtype = readushort(f) + local getdelta = fontdata.temporary.getdelta if subtype == 1 then local coverage = tableoffset + readushort(f) local nofrecords = readushort(f) @@ -1038,17 +1596,18 @@ function gposhandlers.cursive(f,fontdata,lookupid,lookupoffset,offset,glyphs,nof coverage = readcoverage(f,coverage) for i=1,nofrecords do local r = records[i] + -- slot 1 will become hash after loading (must be unique per lookup when packed) records[i] = { - 1, -- will become hash after loading (must be unique per lookup when packed) - readanchor(f,r.entry) or nil, - readanchor(f,r.exit ) or nil, + 1, + readanchor(f,r.entry,getdelta) or nil, + readanchor(f,r.exit, getdelta) or nil, } end for index, newindex in next, coverage do coverage[index] = records[newindex+1] end return { - coverage = coverage + coverage = coverage, } else report("unsupported subtype %a in %a positioning",subtype,"cursive") @@ -1058,7 +1617,8 @@ end local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,ligature) local tableoffset = lookupoffset + offset setposition(f,tableoffset) - local subtype = readushort(f) + local subtype = readushort(f) + local getdelta = fontdata.temporary.getdelta if subtype == 1 then -- we are one based, not zero local markcoverage = tableoffset + readushort(f) @@ -1077,17 +1637,12 @@ local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyp local lastanchor = fontdata.lastanchor or 0 local usedanchors = { } -- --- local placeholder = (fontdata.markcount or 0) + 1 --- fontdata.markcount = placeholder --- placeholder = "m" .. placeholder - -- for i=1,nofmarkclasses do local class = readushort(f) + 1 local offset = readushort(f) if offset == 0 then markclasses[i] = false else --- markclasses[i] = { placeholder, class, markoffset + offset } markclasses[i] = { class, markoffset + offset } end usedanchors[class] = true @@ -1095,8 +1650,7 @@ local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyp for i=1,nofmarkclasses do local mc = markclasses[i] if mc then --- mc[3] = readanchor(f,mc[3]) - mc[2] = readanchor(f,mc[2]) + mc[2] = readanchor(f,mc[2],getdelta) end end -- @@ -1150,7 +1704,7 @@ local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyp local classes = components[c] if classes then for i=1,nofclasses do - local anchor = readanchor(f,classes[i]) + local anchor = readanchor(f,classes[i],getdelta) local bclass = baseclasses[i] local bentry = bclass[b] if bentry then @@ -1160,7 +1714,6 @@ local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyp end end end --- components[i] = classes end end end @@ -1193,7 +1746,7 @@ local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyp local r = baserecords[i] local b = basecoverage[i] for j=1,nofclasses do - baseclasses[j][b] = readanchor(f,r[j]) + baseclasses[j][b] = readanchor(f,r[j],getdelta) end end for index, newindex in next, markcoverage do @@ -1242,20 +1795,54 @@ do local plugins = { } - function plugins.size(f,fontdata,tableoffset,parameters) - if not fontdata.designsize then - setposition(f,tableoffset+parameters) - local designsize = readushort(f) - if designsize > 0 then - fontdata.designsize = designsize - skipshort(f,2) - fontdata.minsize = readushort(f) - fontdata.maxsize = readushort(f) + function plugins.size(f,fontdata,tableoffset,feature) + if fontdata.designsize then + -- yes, there are fonts with multiple size entries ... it probably relates + -- to the other two fields (menu entries in some language) + else + local function check(offset) + setposition(f,offset) + local designsize = readushort(f) + if designsize > 0 then -- we could also have a threshold + local fontstyleid = readushort(f) + local guimenuid = readushort(f) + local minsize = readushort(f) + local maxsize = readushort(f) + if minsize == 0 and maxsize == 0 and fontstyleid == 0 and guimenuid == 0 then + minsize = designsize + maxsize = designsize + end + if designsize >= minsize and designsize <= maxsize then + return minsize, maxsize, designsize + end + end + end + local minsize, maxsize, designsize = check(tableoffset+feature.offset+feature.parameters) + if not designsize then + -- some old adobe fonts have: tableoffset+feature.parameters and we could + -- use some heuristic but why bother ... this extra check will be removed + -- some day and/or when we run into an issue + minsize, maxsize, designsize = check(tableoffset+feature.parameters) + if designsize then + report("bad size feature in %a, falling back to wrong offset",fontdata.filename or "?") + else + report("bad size feature in %a,",fontdata.filename or "?") + end + end + if designsize then + fontdata.minsize = minsize + fontdata.maxsize = maxsize + fontdata.designsize = designsize end end end - -- feature order needs checking ... as we loop over a hash + -- function plugins.rvrn(f,fontdata,tableoffset,feature) + -- -- todo, at least a message + -- end + + -- feature order needs checking ... as we loop over a hash ... however, in the file + -- they are sorted so order is not that relevant local function reorderfeatures(fontdata,scripts,features) local scriptlangs = { } @@ -1397,7 +1984,7 @@ do feature.parameters = parameters local plugin = plugins[feature.tag] if plugin then - plugin(f,fontdata,offset,parameters) + plugin(f,fontdata,featureoffset,feature) end end end @@ -1412,8 +1999,8 @@ do lookups[i] = readushort(f) end for lookupid=1,noflookups do - local index = lookups[lookupid] - setposition(f,lookupoffset+index) + local offset = lookups[lookupid] + setposition(f,lookupoffset+offset) local subtables = { } local typebits = readushort(f) local flagbits = readushort(f) @@ -1421,8 +2008,7 @@ do local lookupflags = lookupflags[flagbits] local nofsubtables = readushort(f) for j=1,nofsubtables do - local offset = readushort(f) - subtables[j] = offset + index -- we can probably put lookupoffset here + subtables[j] = offset + readushort(f) -- we can probably put lookupoffset here end -- which one wins? local markclass = bittest(flagbits,0x0010) -- usemarkfilteringset @@ -1447,23 +2033,9 @@ do return lookups end - local function readscriptoffsets(f,fontdata,tableoffset) - if not tableoffset then - return - end - setposition(f,tableoffset) - local version = readulong(f) - if version ~= 0x00010000 then - report("table version %a of %a is not supported (yet), maybe font %s is bad",version,what,fontdata.filename) - return - end - -- - return tableoffset + readushort(f), tableoffset + readushort(f), tableoffset + readushort(f) - end - local f_lookupname = formatters["%s_%s_%s"] - local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what) + local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) local sequences = fontdata.sequences or { } local sublookuplist = fontdata.sublookups or { } @@ -1599,6 +2171,14 @@ do local reported = { } + local function report_issue(i,what,sequence,kind) + local name = sequence.name + if not reported[name] then + report("rule %i in %s lookup %a has %s lookups",i,what,name,kind) + reported[name] = true + end + end + for i=lastsequence+1,nofsequences do local sequence = sequences[i] local steps = sequence.steps @@ -1610,46 +2190,72 @@ do local rule = rules[i] local rlookups = rule.lookups if not rlookups then - local name = sequence.name - if not reported[name] then - report("rule %i in %s lookup %a has %s lookups",i,what,name,"no") - reported[name] = true - end + report_issue(i,what,sequence,"no") elseif not next(rlookups) then - local name = sequence.name - if not reported[name] then - -- can be ok as it aborts a chain sequence - report("rule %i in %s lookup %a has %s lookups",i,what,name,"empty") - reported[name] = true - end + -- can be ok as it aborts a chain sequence + report_issue(i,what,sequence,"empty") rule.lookups = nil else - for index, lookupid in sortedhash(rlookups) do -- nicer - local h = sublookuphash[lookupid] - if not h then - -- here we have a lookup that is used independent as well - -- as in another one - nofsublookups = nofsublookups + 1 - -- report("registering %i as sublookup %i",lookupid,nofsublookups) - local d = lookups[lookupid].done - h = { - index = nofsublookups, -- handy for tracing - name = f_lookupname(lookupprefix,"d",lookupid+lookupidoffset), - derived = true, -- handy for tracing - steps = d.steps, - nofsteps = d.nofsteps, - type = d.lookuptype, - markclass = d.markclass or nil, - flags = d.flags, - -- chain = d.chain, - } - sublookuplist[nofsublookups] = h - sublookuphash[lookupid] = nofsublookups - sublookupcheck[lookupid] = 1 + -- we can have holes in rlookups flagged false and we can have multiple lookups + -- applied (first time seen in seguemj) + local length = #rlookups + for index=1,length do + local lookuplist = rlookups[index] + if lookuplist then + local length = #lookuplist + local found = { } + local noffound = 0 + for index=1,length do + local lookupid = lookuplist[index] + if lookupid then + local h = sublookuphash[lookupid] + if not h then + -- here we have a lookup that is used independent as well + -- as in another one + local lookup = lookups[lookupid] + if lookup then + local d = lookup.done + if d then + nofsublookups = nofsublookups + 1 + -- report("registering %i as sublookup %i",lookupid,nofsublookups) + h = { + index = nofsublookups, -- handy for tracing + name = f_lookupname(lookupprefix,"d",lookupid+lookupidoffset), + derived = true, -- handy for tracing + steps = d.steps, + nofsteps = d.nofsteps, + type = d.lookuptype or "gsub_single", -- todo: check type + markclass = d.markclass or nil, + flags = d.flags, + -- chain = d.chain, + } + sublookuplist[nofsublookups] = copy(h) -- we repack later + sublookuphash[lookupid] = nofsublookups + sublookupcheck[lookupid] = 1 + h = nofsublookups + else + report_issue(i,what,sequence,"missing") + rule.lookups = nil + break + end + else + report_issue(i,what,sequence,"bad") + rule.lookups = nil + break + end + else + sublookupcheck[lookupid] = sublookupcheck[lookupid] + 1 + end + if h then + noffound = noffound + 1 + found[noffound] = h + end + end + end + rlookups[index] = noffound > 0 and found or false else - sublookupcheck[lookupid] = sublookupcheck[lookupid] + 1 + rlookups[index] = false end - rlookups[index] = h end end end @@ -1663,45 +2269,124 @@ do if n == 0 and t ~= "extension" then local d = l.done report("%s lookup %s of type %a is not used",what,d and d.name or l.name,t) - -- inspect(l) end end end - local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo) - local datatable = fontdata.tables[what] - if not datatable then - return - end - local tableoffset = datatable.offset - if not tableoffset then - return + local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) + setposition(f,variationsoffset) + local version = readulong(f) + local nofrecords = readulong(f) + local records = { } + for i=1,nofrecords do + records[i] = { + conditions = readulong(f), + substitutions = readulong(f), + } end - local scriptoffset, featureoffset, lookupoffset = readscriptoffsets(f,fontdata,tableoffset) - if not scriptoffset then - return + for i=1,nofrecords do + local record = records[i] + local offset = record.conditions + if offset == 0 then + record.condition = nil + record.matchtype = "always" + else + setposition(f,variationsoffset+offset) + local nofconditions = readushort(f) + local conditions = { } + for i=1,nofconditions do + conditions[i] = variationsoffset+offset+readulong(f) + end + record.conditions = conditions + record.matchtype = "condition" + end end - -- - local scripts = readscriplan(f,fontdata,scriptoffset) - local features = readfeatures(f,fontdata,featureoffset) - -- - local scriptlangs, featurehash, featureorder = reorderfeatures(fontdata,scripts,features) - -- - if fontdata.features then - fontdata.features[what] = scriptlangs - else - fontdata.features = { [what] = scriptlangs } + for i=1,nofrecords do + local record = records[i] + if record.matchtype == "condition" then + local conditions = record.conditions + for i=1,#conditions do + setposition(f,conditions[i]) + conditions[i] = { + format = readushort(f), + axis = readushort(f), + minvalue = read2dot14(f), + maxvalue = read2dot14(f), + } + end + end end - -- - if not lookupstoo then - return + + for i=1,nofrecords do + local record = records[i] + local offset = record.substitutions + if offset == 0 then + record.substitutions = { } + else + setposition(f,variationsoffset + offset) + local version = readulong(f) + local nofsubstitutions = readushort(f) + local substitutions = { } + for i=1,nofsubstitutions do + substitutions[readushort(f)] = readulong(f) + end + for index, alternates in sortedhash(substitutions) do + if index == 0 then + record.substitutions = false + else + local tableoffset = variationsoffset + offset + alternates + setposition(f,tableoffset) + local parameters = readulong(f) -- feature parameters + local noflookups = readushort(f) + local lookups = { } + for i=1,noflookups do + lookups[i] = readushort(f) -- not sure what to do with these + end + -- todo : resolve to proper lookups + record.substitutions = lookups + end + end + end end - -- - local lookups = readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) - -- - if lookups then - resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what) + setvariabledata(fontdata,"features",records) + end + + local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo) + local tableoffset = gotodatatable(f,fontdata,what,true) + if tableoffset then + local version = readulong(f) + local scriptoffset = tableoffset + readushort(f) + local featureoffset = tableoffset + readushort(f) + local lookupoffset = tableoffset + readushort(f) + local variationsoffset = version > 0x00010000 and (tableoffset + readulong(f)) or 0 + if not scriptoffset then + return + end + local scripts = readscriplan(f,fontdata,scriptoffset) + local features = readfeatures(f,fontdata,featureoffset) + -- + local scriptlangs, featurehash, featureorder = reorderfeatures(fontdata,scripts,features) + -- + if fontdata.features then + fontdata.features[what] = scriptlangs + else + fontdata.features = { [what] = scriptlangs } + end + -- + if not lookupstoo then + return + end + -- + local lookups = readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) + -- + if lookups then + resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) + end + -- + if variationsoffset > 0 then + loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) + end end end @@ -1721,61 +2406,65 @@ do report("ignoring global kern table using gpos kern feature") return end - report("adding global kern table as gpos feature %a",name) setposition(f,datatable.offset) local version = readushort(f) local noftables = readushort(f) - local kerns = setmetatableindex("table") - for i=1,noftables do - local version = readushort(f) - local length = readushort(f) - local coverage = readushort(f) - -- bit 8-15 of coverage: format 0 or 2 - local format = bit32.rshift(coverage,8) -- is this ok? - if format == 0 then - local nofpairs = readushort(f) - local searchrange = readushort(f) - local entryselector = readushort(f) - local rangeshift = readushort(f) - for i=1,nofpairs do - kerns[readushort(f)][readushort(f)] = readfword(f) + if noftables > 1 then + report("adding global kern table as gpos feature %a",name) + local kerns = setmetatableindex("table") + for i=1,noftables do + local version = readushort(f) + local length = readushort(f) + local coverage = readushort(f) + -- bit 8-15 of coverage: format 0 or 2 + local format = bit32.rshift(coverage,8) -- is this ok + if format == 0 then + local nofpairs = readushort(f) + local searchrange = readushort(f) + local entryselector = readushort(f) + local rangeshift = readushort(f) + for i=1,nofpairs do + kerns[readushort(f)][readushort(f)] = readfword(f) + end + elseif format == 2 then + -- apple specific so let's ignore it + else + -- not supported by ms end - elseif format == 2 then - -- apple specific so let's ignore it + end + local feature = { dflt = { dflt = true } } + if not features then + fontdata.features = { gpos = { [name] = feature } } + elseif not gposfeatures then + fontdata.features.gpos = { [name] = feature } else - -- not supported by ms + gposfeatures[name] = feature end - end - local feature = { dflt = { dflt = true } } - if not features then - fontdata.features = { gpos = { [name] = feature } } - elseif not gposfeatures then - fontdata.features.gpos = { [name] = feature } - else - gposfeatures[name] = feature - end - local sequences = fontdata.sequences - if not sequences then - sequences = { } - fontdata.sequences = sequences - end - local nofsequences = #sequences + 1 - sequences[nofsequences] = { - index = nofsequences, - name = name, - steps = { - { - coverage = kerns, - format = "kern", + local sequences = fontdata.sequences + if not sequences then + sequences = { } + fontdata.sequences = sequences + end + local nofsequences = #sequences + 1 + sequences[nofsequences] = { + index = nofsequences, + name = name, + steps = { + { + coverage = kerns, + format = "kern", + }, }, - }, - nofsteps = 1, - type = "gpos_pair", - -- type = "gpos_single", -- maybe better - flags = { false, false, false, false }, - order = { name }, - features = { [name] = feature }, - } + nofsteps = 1, + type = "gpos_pair", + -- type = "gpos_single", -- maybe better + flags = { false, false, false, false }, + order = { name }, + features = { [name] = feature }, + } + else + report("ignoring empty kern table of feature %a",name) + end end function readers.gsub(f,fontdata,specification) @@ -1796,92 +2485,126 @@ do end function readers.gdef(f,fontdata,specification) - if specification.glyphs then - local datatable = fontdata.tables.gdef - if datatable then - local tableoffset = datatable.offset - setposition(f,tableoffset) - local version = readulong(f) - local classoffset = tableoffset + readushort(f) - local attachmentoffset = tableoffset + readushort(f) -- used for bitmaps - local ligaturecarets = tableoffset + readushort(f) -- used in editors (maybe nice for tracing) - local markclassoffset = tableoffset + readushort(f) - local marksetsoffset = version == 0x00010002 and (tableoffset + readushort(f)) - local glyphs = fontdata.glyphs - local marks = { } - local markclasses = setmetatableindex("table") - local marksets = setmetatableindex("table") - fontdata.marks = marks - fontdata.markclasses = markclasses - fontdata.marksets = marksets - -- class definitions - setposition(f,classoffset) - local classformat = readushort(f) - if classformat == 1 then - local firstindex = readushort(f) - local lastindex = firstindex + readushort(f) - 1 - for index=firstindex,lastindex do - local class = classes[readushort(f)] - if class == "mark" then - marks[index] = true - end - glyphs[index].class = class + if not specification.glyphs then + return + end + local datatable = fontdata.tables.gdef + if datatable then + local tableoffset = datatable.offset + setposition(f,tableoffset) + local version = readulong(f) + local classoffset = tableoffset + readushort(f) + local attachmentoffset = tableoffset + readushort(f) -- used for bitmaps + local ligaturecarets = tableoffset + readushort(f) -- used in editors (maybe nice for tracing) + local markclassoffset = tableoffset + readushort(f) + local marksetsoffset = version >= 0x00010002 and (tableoffset + readushort(f)) + local varsetsoffset = version >= 0x00010003 and (tableoffset + readulong(f)) + local glyphs = fontdata.glyphs + local marks = { } + local markclasses = setmetatableindex("table") + local marksets = setmetatableindex("table") + fontdata.marks = marks + fontdata.markclasses = markclasses + fontdata.marksets = marksets + -- class definitions + setposition(f,classoffset) + local classformat = readushort(f) + if classformat == 1 then + local firstindex = readushort(f) + local lastindex = firstindex + readushort(f) - 1 + for index=firstindex,lastindex do + local class = classes[readushort(f)] + if class == "mark" then + marks[index] = true end - elseif classformat == 2 then - local nofranges = readushort(f) - for i=1,nofranges do - local firstindex = readushort(f) - local lastindex = readushort(f) - local class = classes[readushort(f)] - if class then - for index=firstindex,lastindex do - glyphs[index].class = class - if class == "mark" then - marks[index] = true - end + glyphs[index].class = class + end + elseif classformat == 2 then + local nofranges = readushort(f) + for i=1,nofranges do + local firstindex = readushort(f) + local lastindex = readushort(f) + local class = classes[readushort(f)] + if class then + for index=firstindex,lastindex do + glyphs[index].class = class + if class == "mark" then + marks[index] = true end end end end - -- mark classes - setposition(f,markclassoffset) - local classformat = readushort(f) - if classformat == 1 then + end + -- mark classes + setposition(f,markclassoffset) + local classformat = readushort(f) + if classformat == 1 then + local firstindex = readushort(f) + local lastindex = firstindex + readushort(f) - 1 + for index=firstindex,lastindex do + markclasses[readushort(f)][index] = true + end + elseif classformat == 2 then + local nofranges = readushort(f) + for i=1,nofranges do local firstindex = readushort(f) - local lastindex = firstindex + readushort(f) - 1 + local lastindex = readushort(f) + local class = markclasses[readushort(f)] for index=firstindex,lastindex do - markclasses[readushort(f)][index] = true + class[index] = true end - elseif classformat == 2 then - local nofranges = readushort(f) - for i=1,nofranges do - local firstindex = readushort(f) - local lastindex = readushort(f) - local class = markclasses[readushort(f)] - for index=firstindex,lastindex do - class[index] = true + end + end + -- mark sets : todo: just make the same as class sets above + if marksetsoffset and marksetsoffset > tableoffset then -- zero offset means no table + setposition(f,marksetsoffset) + local format = readushort(f) + if format == 1 then + local nofsets = readushort(f) + local sets = { } + for i=1,nofsets do + sets[i] = readulong(f) + end + for i=1,nofsets do + local offset = sets[i] + if offset ~= 0 then + marksets[i] = readcoverage(f,marksetsoffset+offset) end end end - -- mark sets : todo: just make the same as class sets above - if marksetsoffset then - setposition(f,marksetsoffset) - local format = readushort(f) - if format == 1 then - local nofsets = readushort(f) - local sets = { } - for i=1,nofsets do - sets[i] = readulong(f) - end - -- somehow this fails on e.g. notosansethiopic-bold.ttf - for i=1,nofsets do - local offset = sets[i] - if offset ~= 0 then - marksets[i] = readcoverage(f,marksetsoffset+offset) + end + + local factors = specification.factors + + if (specification.variable or factors) and varsetsoffset and varsetsoffset > tableoffset then + + local regions, deltas = readvariationdata(f,varsetsoffset,factors) + + -- setvariabledata(fontdata,"gregions",regions) + + if factors then + fontdata.temporary.getdelta = function(outer,inner) + local delta = deltas[outer+1] + if delta then + local d = delta.deltas[inner+1] + if d then + local scales = delta.scales + local dd = 0 + for i=1,#scales do + local di = d[i] + if di then + dd = dd + scales[i] * di + else + break + end + end + return round(dd) end end + return 0 end end + end end end @@ -2015,16 +2738,15 @@ local function readmathglyphinfo(f,fontdata,offset) local function get(offset) setposition(f,kernoffset+offset) local n = readushort(f) - if n > 0 then + if n == 0 then + local k = readmathvalue(f) + if k == 0 then + -- no need for it (happens sometimes) + else + return { { kern = k } } + end + else local l = { } - -- for i=1,n do - -- l[i] = { readushort(f), 0 } -- height, kern - -- skipshort(f) - -- end - -- for i=1,n do - -- l[i][2] = readushort(f) - -- skipshort(f) - -- end for i=1,n do l[i] = { height = readmathvalue(f) } end @@ -2059,10 +2781,10 @@ local function readmathglyphinfo(f,fontdata,offset) if next(kernset) then local glyph = glyphs[coverage[i]] local math = glyph.math - if not math then - glyph.math = { kerns = kernset } - else + if math then math.kerns = kernset + else + glyph.math = { kerns = kernset } end end end @@ -2171,30 +2893,721 @@ local function readmathvariants(f,fontdata,offset) end function readers.math(f,fontdata,specification) - if specification.glyphs then - local datatable = fontdata.tables.math - if datatable then - local tableoffset = datatable.offset - setposition(f,tableoffset) - local version = readulong(f) - if version ~= 0x00010000 then - report("table version %a of %a is not supported (yet), maybe font %s is bad",version,what,fontdata.filename) - return + local tableoffset = gotodatatable(f,fontdata,"math",specification.glyphs) + if tableoffset then + local version = readulong(f) + -- if version ~= 0x00010000 then + -- report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"math",fontdata.filename) + -- return + -- end + local constants = readushort(f) + local glyphinfo = readushort(f) + local variants = readushort(f) + if constants == 0 then + report("the math table of %a has no constants",fontdata.filename) + else + readmathconstants(f,fontdata,tableoffset+constants) + end + if glyphinfo ~= 0 then + readmathglyphinfo(f,fontdata,tableoffset+glyphinfo) + end + if variants ~= 0 then + readmathvariants(f,fontdata,tableoffset+variants) + end + end +end + +function readers.colr(f,fontdata,specification) + local tableoffset = gotodatatable(f,fontdata,"colr",specification.glyphs) + if tableoffset then + local version = readushort(f) + if version ~= 0 then + report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"colr",fontdata.filename) + return + end + if not fontdata.tables.cpal then + report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal") + fontdata.colorpalettes = { } + end + local glyphs = fontdata.glyphs + local nofglyphs = readushort(f) + local baseoffset = readulong(f) + local layeroffset = readulong(f) + local noflayers = readushort(f) + local layerrecords = { } + local maxclass = 0 + -- The special value 0xFFFF is foreground (but we index from 1). It + -- more looks like indices into a palette so 'class' is a better name + -- than 'palette'. + setposition(f,tableoffset + layeroffset) + for i=1,noflayers do + local slot = readushort(f) + local class = readushort(f) + if class < 0xFFFF then + class = class + 1 + if class > maxclass then + maxclass = class + end end - local constants = readushort(f) - local glyphinfo = readushort(f) - local variants = readushort(f) - if constants == 0 then - report("the math table of %a has no constants",fontdata.filename) - else - readmathconstants(f,fontdata,tableoffset+constants) + layerrecords[i] = { + slot = slot, + class = class, + } + end + fontdata.maxcolorclass = maxclass + setposition(f,tableoffset + baseoffset) + for i=0,nofglyphs-1 do + local glyphindex = readushort(f) + local firstlayer = readushort(f) + local noflayers = readushort(f) + local t = { } + for i=1,noflayers do + t[i] = layerrecords[firstlayer+i] end - if glyphinfo ~= 0 then - readmathglyphinfo(f,fontdata,tableoffset+glyphinfo) + glyphs[glyphindex].colors = t + end + end + fontdata.hascolor = true +end + +function readers.cpal(f,fontdata,specification) + local tableoffset = gotodatatable(f,fontdata,"cpal",specification.glyphs) + if tableoffset then + local version = readushort(f) + -- if version > 1 then + -- report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"cpal",fontdata.filename) + -- return + -- end + local nofpaletteentries = readushort(f) + local nofpalettes = readushort(f) + local nofcolorrecords = readushort(f) + local firstcoloroffset = readulong(f) + local colorrecords = { } + local palettes = { } + for i=1,nofpalettes do + palettes[i] = readushort(f) + end + if version == 1 then + -- used for guis + local palettettypesoffset = readulong(f) + local palettelabelsoffset = readulong(f) + local paletteentryoffset = readulong(f) + end + setposition(f,tableoffset+firstcoloroffset) + for i=1,nofcolorrecords do + local b, g, r, a = readbytes(f,4) + colorrecords[i] = { + r, g, b, a ~= 255 and a or nil, + } + end + for i=1,nofpalettes do + local p = { } + local o = palettes[i] + for j=1,nofpaletteentries do + p[j] = colorrecords[o+j] end - if variants ~= 0 then - readmathvariants(f,fontdata,tableoffset+variants) + palettes[i] = p + end + fontdata.colorpalettes = palettes + end +end + +function readers.svg(f,fontdata,specification) + local tableoffset = gotodatatable(f,fontdata,"svg",specification.glyphs) + if tableoffset then + local version = readushort(f) + -- if version ~= 0 then + -- report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"svg",fontdata.filename) + -- return + -- end + local glyphs = fontdata.glyphs + local indexoffset = tableoffset + readulong(f) + local reserved = readulong(f) + setposition(f,indexoffset) + local nofentries = readushort(f) + local entries = { } + for i=1,nofentries do + entries[i] = { + first = readushort(f), + last = readushort(f), + offset = indexoffset + readulong(f), + length = readulong(f), + } + end + for i=1,nofentries do + local entry = entries[i] + setposition(f,entry.offset) + entries[i] = { + first = entry.first, + last = entry.last, + data = readstring(f,entry.length) + } + end + fontdata.svgshapes = entries + end + fontdata.hascolor = true +end + +function readers.sbix(f,fontdata,specification) + local tableoffset = gotodatatable(f,fontdata,"sbix",specification.glyphs) + if tableoffset then + local version = readushort(f) + local flags = readushort(f) + local nofstrikes = readulong(f) + local strikes = { } + local nofglyphs = fontdata.nofglyphs + for i=1,nofstrikes do + strikes[i] = readulong(f) + end + -- if true then + local shapes = { } + local done = 0 + for i=1,nofstrikes do + local strikeoffset = strikes[i] + tableoffset + setposition(f,strikeoffset) + strikes[i] = { + ppem = readushort(f), + ppi = readushort(f), + offset = strikeoffset + } + end + -- highest first + sort(strikes,function(a,b) + if b.ppem == a.ppem then + return b.ppi < a.ppi + else + return b.ppem < a.ppem + end + end) + local glyphs = { } + for i=1,nofstrikes do + local strike = strikes[i] + local strikeppem = strike.ppem + local strikeppi = strike.ppi + local strikeoffset = strike.offset + setposition(f,strikeoffset) + for i=0,nofglyphs do + glyphs[i] = readulong(f) + end + local glyphoffset = glyphs[0] + for i=0,nofglyphs-1 do + local nextoffset = glyphs[i+1] + if not shapes[i] then + local datasize = nextoffset - glyphoffset + if datasize > 0 then + setposition(f,strikeoffset + glyphoffset) + shapes[i] = { + x = readshort(f), + y = readshort(f), + tag = readtag(f), -- maybe for tracing + data = readstring(f,datasize-8), + ppem = strikeppem, -- not used, for tracing + ppi = strikeppi, -- not used, for tracing + } + done = done + 1 + if done == nofglyphs then + break + end + end + end + glyphoffset = nextoffset + end + end + fontdata.sbixshapes = shapes + -- else + -- for i=1,nofstrikes do + -- local strikeoffset = strikes[i] + tableoffset + -- setposition(f,strikeoffset) + -- local glyphs = { } + -- strikes[i] = { + -- ppem = readushort(f), + -- ppi = readushort(f), + -- glyphs = glyphs, + -- } + -- for i=0,nofglyphs do + -- glyphs[i] = readulong(f) + -- end + -- local glyphoffset = glyphs[0] + -- for i=0,nofglyphs-1 do + -- local nextoffset = glyphs[i+1] + -- local datasize = nextoffset - glyphoffset + -- if datasize > 0 then + -- setposition(f,strikeoffset + glyphoffset) + -- glyphs[i] = { + -- x = readshort(f), + -- y = readshort(f), + -- tag = readtag(f), + -- data = readstring(f,datasize-8) + -- } + -- glyphoffset = nextoffset + -- end + -- end + -- end + -- fontdata.sbixshapes = strikes + -- end + end +end + +-- function readers.cblc(f,fontdata,specification) +-- local tableoffset = gotodatatable(f,fontdata,"cblc",specification.glyphs) +-- if tableoffset then +-- end +-- end +-- +-- function readers.cbdt(f,fontdata,specification) +-- local tableoffset = gotodatatable(f,fontdata,"ctdt",specification.glyphs) +-- if tableoffset then +-- +-- local function getmetrics(f) +-- return { +-- ascender = readinteger(f), +-- descender = readinteger(f), +-- widthmax = readcardinal(f), +-- caretslopedumerator = readinteger(f), +-- caretslopedenominator = readinteger(f), +-- caretoffset = readinteger(f), +-- minorigin = readinteger(f), +-- minadvance = readinteger(f), +-- maxbefore = readinteger(f), +-- minafter = readinteger(f), +-- pad1 = readinteger(f), +-- pad2 = readinteger(f), +-- } +-- end +-- +-- local majorversion = readushort(f) +-- local minorversion = readushort(f) +-- local nofsizetables = readulong(f) +-- local sizetable = { } +-- for i=1,nofsizetables do +-- sizetable[i] = { +-- subtables = readulong(f), +-- indexsize = readulong(f), +-- nofsubtables = readulong(f), +-- colorref = readulong(f), +-- hormetrics = getmetrics(f), +-- vermetrics = getmetrics(f), +-- firstindex = readushort(f), +-- lastindex = readushort(f), +-- ppemx = readbyte(f), +-- ppemy = readbyte(f), +-- bitdepth = readbyte(f), +-- flags = readbyte(f), +-- } +-- end +-- +-- sort(sizetable,function(a,b) +-- if b.ppemx == a.ppemx then +-- return b.bitdepth < a.bitdepth +-- else +-- return b.ppemx < a.ppemx +-- end +-- end) +-- +-- local shapes = { } +-- +-- for i=1,nofsizetables do +-- local s = sizetables[i] +-- for j=firstindex,lastindex do +-- if not shapes[j] then +-- shapes[j] = { +-- i +-- } +-- end +-- end +-- end +-- +-- inspect(shapes) +-- +-- end +-- end + +-- function readers.ebdt(f,fontdata,specification) +-- if specification.glyphs then +-- end +-- end + +-- function readers.ebsc(f,fontdata,specification) +-- if specification.glyphs then +-- end +-- end + +-- function readers.eblc(f,fontdata,specification) +-- if specification.glyphs then +-- end +-- end + +-- + AVAR : optional +-- + CFF2 : otf outlines +-- - CVAR : ttf hinting, not needed +-- + FVAR : the variations +-- + GVAR : ttf outline changes +-- + HVAR : horizontal changes +-- + MVAR : metric changes +-- + STAT : relations within fonts +-- * VVAR : vertical changes +-- +-- * BASE : extra baseline adjustments +-- - GASP : not needed +-- + GDEF : not needed (carets) +-- + GPOS : adapted device tables (needed?) +-- + GSUB : new table +-- + NAME : 25 added + +function readers.stat(f,fontdata,specification) + local tableoffset = gotodatatable(f,fontdata,"stat",true) -- specification.variable + if tableoffset then + local extras = fontdata.extras + local version = readulong(f) -- 0x00010000 + local axissize = readushort(f) + local nofaxis = readushort(f) + local axisoffset = readulong(f) + local nofvalues = readushort(f) + local valuesoffset = readulong(f) + local fallbackname = extras[readushort(f)] -- beta fonts mess up + local axis = { } + local values = { } + setposition(f,tableoffset+axisoffset) + for i=1,nofaxis do + axis[i] = { + tag = readtag(f), + name = lower(extras[readushort(f)]), + ordering = readushort(f), -- maybe gaps + variants = { } + } + end + -- flags: + -- + -- 0x0001 : OlderSiblingFontAttribute + -- 0x0002 : ElidableAxisValueName + -- 0xFFFC : reservedFlags + -- + setposition(f,tableoffset+valuesoffset) + for i=1,nofvalues do + values[i] = readushort(f) + end + for i=1,nofvalues do + setposition(f,tableoffset + valuesoffset + values[i]) + local format = readushort(f) + local index = readushort(f) + 1 + local flags = readushort(f) + local name = lower(extras[readushort(f)]) + local value = readfixed(f) + local variant + if format == 1 then + variant = { + flags = flags, + name = name, + value = value, + } + elseif format == 2 then + variant = { + flags = flags, + name = name, + value = value, + minimum = readfixed(f), + maximum = readfixed(f), + } + elseif format == 3 then + variant = { + flags = flags, + name = name, + value = value, + link = readfixed(f), + } + end + insert(axis[index].variants,variant) + end + sort(axis,function(a,b) + return a.ordering < b.ordering + end) + for i=1,#axis do + local a = axis[i] + sort(a.variants,function(a,b) + return a.name < b.name + end) + a.ordering = nil + end + setvariabledata(fontdata,"designaxis",axis) + setvariabledata(fontdata,"fallbackname",fallbackname) + end +end + +-- The avar table is optional and used in combination with fvar. Given the +-- detailed explanation about bad values we expect the worst and do some +-- checking. + +function readers.avar(f,fontdata,specification) + local tableoffset = gotodatatable(f,fontdata,"avar",true) -- specification.variable + if tableoffset then + + local function collect() + local nofvalues = readushort(f) + local values = { } + local lastfrom = false + local lastto = false + for i=1,nofvalues do + local f, t = read2dot14(f), read2dot14(f) + if lastfrom and f <= lastfrom then + -- ignore + elseif lastto and t >= lastto then + -- ignore + else + values[#values+1] = { f, t } + lastfrom, lastto = f, t + end + end + nofvalues = #values + if nofvalues > 2 then + local some = values[1] + if some[1] == -1 and some[2] == -1 then + some = values[nofvalues] + if some[1] == 1 and some[2] == 1 then + for i=2,nofvalues-1 do + some = values[i] + if some[1] == 0 and some[2] == 0 then + return values + end + end + end + end + end + return false + end + + local majorversion = readushort(f) -- 1 + local minorversion = readushort(f) -- 0 + local reserved = readushort(f) + local nofaxis = readushort(f) + local segments = { } + for i=1,nofaxis do + segments[i] = collect() + end + setvariabledata(fontdata,"segments",segments) + end +end + +function readers.fvar(f,fontdata,specification) + local tableoffset = gotodatatable(f,fontdata,"fvar",true) -- specification.variable or specification.instancenames + if tableoffset then + local version = readulong(f) -- 1.0 + local offsettoaxis = tableoffset + readushort(f) + local reserved = skipshort(f) + -- pair 1 + local nofaxis = readushort(f) + local sizeofaxis = readushort(f) + -- pair 2 + local nofinstances = readushort(f) + local sizeofinstances = readushort(f) + -- + local extras = fontdata.extras + local axis = { } + local instances = { } + -- + setposition(f,offsettoaxis) + -- + for i=1,nofaxis do + axis[i] = { + tag = readtag(f), -- ital opsz slnt wdth wght + minimum = readfixed(f), + default = readfixed(f), + maximum = readfixed(f), + flags = readushort(f), + name = lower(extras[readushort(f)] or "bad name"), + } + local n = sizeofaxis - 20 + if n > 0 then + skipbytes(f,n) + elseif n < 0 then + -- error + end + end + -- + local nofbytes = 2 + 2 + 2 + nofaxis * 4 + local readpsname = nofbytes <= sizeofinstances + local skippable = sizeofinstances - nofbytes + for i=1,nofinstances do + local subfamid = readushort(f) + local flags = readushort(f) -- 0, not used yet + local values = { } + for i=1,nofaxis do + values[i] = { + axis = axis[i].tag, + value = readfixed(f), + } + end + local psnameid = readpsname and readushort(f) or 0xFFFF + if subfamid == 2 or subfamid == 17 then + -- okay + elseif subfamid == 0xFFFF then + subfamid = nil + elseif subfamid <= 256 or subfamid >= 32768 then + subfamid = nil -- actually an error + end + if psnameid == 6 then + -- okay + elseif psnameid == 0xFFFF then + psnameid = nil + elseif psnameid <= 256 or psnameid >= 32768 then + psnameid = nil -- actually an error + end + instances[i] = { + -- flags = flags, + subfamily = extras[subfamid], + psname = psnameid and extras[psnameid] or nil, + values = values, + } + if skippable > 0 then + skipbytes(f,skippable) + end + end + setvariabledata(fontdata,"axis",axis) + setvariabledata(fontdata,"instances",instances) + end +end + +function readers.hvar(f,fontdata,specification) + local factors = specification.factors + if not factors then + return + end + local tableoffset = gotodatatable(f,fontdata,"hvar",specification.variable) + if not tableoffset then + return + end + + local version = readulong(f) -- 1.0 + local variationoffset = tableoffset + readulong(f) -- the store + local advanceoffset = tableoffset + readulong(f) + local lsboffset = tableoffset + readulong(f) + local rsboffset = tableoffset + readulong(f) + + local regions = { } + local variations = { } + local innerindex = { } -- size is mapcount + local outerindex = { } -- size is mapcount + + if variationoffset > 0 then + regions, deltas = readvariationdata(f,variationoffset,factors) + end + + if not regions then + -- for now .. what to do ? + return + end + + if advanceoffset > 0 then + -- + -- innerIndexBitCountMask = 0x000F + -- mapEntrySizeMask = 0x0030 + -- reservedFlags = 0xFFC0 + -- + -- outerIndex = entry >> ((entryFormat & innerIndexBitCountMask) + 1) + -- innerIndex = entry & ((1 << ((entryFormat & innerIndexBitCountMask) + 1)) - 1) + -- + setposition(f,advanceoffset) + local format = readushort(f) -- todo: check + local mapcount = readushort(f) + local entrysize = rshift(band(format,0x0030),4) + 1 + local nofinnerbits = band(format,0x000F) + 1 -- n of inner bits + local innermask = lshift(1,nofinnerbits) - 1 + local readcardinal = read_cardinal[entrysize] -- 1 upto 4 bytes + for i=0,mapcount-1 do + local mapdata = readcardinal(f) + outerindex[i] = rshift(mapdata,nofinnerbits) + innerindex[i] = band(mapdata,innermask) + end + -- use last entry when no match i + setvariabledata(fontdata,"hvarwidths",true) + local glyphs = fontdata.glyphs + for i=0,fontdata.nofglyphs-1 do + local glyph = glyphs[i] + local width = glyph.width + if width then + local outer = outerindex[i] or 0 + local inner = innerindex[i] or i + if outer and inner then -- not needed + local delta = deltas[outer+1] + if delta then + local d = delta.deltas[inner+1] + if d then + local scales = delta.scales + local deltaw = 0 + for i=1,#scales do + local di = d[i] + if di then + deltaw = deltaw + scales[i] * di + else + break -- can't happen + end + end +-- report("index: %i, outer: %i, inner: %i, deltas: %|t, scales: %|t, width: %i, delta %i", +-- i,outer,inner,d,scales,width,round(deltaw)) + glyph.width = width + round(deltaw) + end + end + end + end + end + + end + + -- if lsboffset > 0 then + -- -- we don't use left side bearings + -- end + + -- if rsboffset > 0 then + -- -- we don't use right side bearings + -- end + + -- setvariabledata(fontdata,"hregions",regions) + +end + +function readers.vvar(f,fontdata,specification) + if not specification.variable then + return + end +end + +function readers.mvar(f,fontdata,specification) + local tableoffset = gotodatatable(f,fontdata,"mvar",specification.variable) + if tableoffset then + local version = readulong(f) -- 1.0 + local reserved = skipshort(f,1) + local recordsize = readushort(f) + local nofrecords = readushort(f) + local offsettostore = tableoffset + readushort(f) + local dimensions = { } + local factors = specification.factors + if factors then + local regions, deltas = readvariationdata(f,offsettostore,factors) + for i=1,nofrecords do + local tag = readtag(f) + local var = variabletags[tag] + if var then + local outer = readushort(f) + local inner = readushort(f) + local delta = deltas[outer+1] + if delta then + local d = delta.deltas[inner+1] + if d then + local scales = delta.scales + local dd = 0 + for i=1,#scales do + dd = dd + scales[i] * d[i] + end + var(fontdata,round(dd)) + end + end + else + skipshort(f,2) + end + if recordsize > 8 then -- 4 + 2 + 2 + skipbytes(recordsize-8) + end end end + -- setvariabledata(fontdata,"mregions",regions) end end diff --git a/tex/context/base/mkiv/font-enc.lua b/tex/context/base/mkiv/font-enc.lua index 2e8b722de..1470f3b8d 100644 --- a/tex/context/base/mkiv/font-enc.lua +++ b/tex/context/base/mkiv/font-enc.lua @@ -20,7 +20,7 @@ them in tables. But we may do so some day, for consistency.</p> local report_encoding = logs.reporter("fonts","encoding") -local encodings = { } +local encodings = fonts.encodings or { } fonts.encodings = encodings encodings.version = 1.03 @@ -78,22 +78,32 @@ function encodings.load(filename) if foundname and foundname ~= "" then local ok, encoding, size = resolvers.loadbinfile(foundname) if ok and encoding then - encoding = gsub(encoding,"%%(.-)\n","") - local tag, vec = match(encoding,"/(%w+)%s*%[(.*)%]%s*def") - local i = 0 - for ch in gmatch(vec,"/([%a%d%.]+)") do - if ch ~= ".notdef" then - vector[i] = ch - if not hash[ch] then - hash[ch] = i - else - -- duplicate, play safe for tex ligs and take first - end - if enccodes[ch] then - unicodes[enccodes[ch]] = i + encoding = gsub(encoding,"%%(.-)[\n\r]+","") + if encoding then + local unicoding = fonts.encodings.agl.unicodes + local tag, vec = match(encoding,"[/]*(%w+)%s*%[(.*)%]%s*def") + if vec then + local i = 0 + for ch in gmatch(vec,"/([%a%d%.]+)") do + if ch ~= ".notdef" then + vector[i] = ch + if not hash[ch] then + hash[ch] = i + else + -- duplicate, play safe for tex ligs and take first + end + local u = unicoding[ch] or enccodes[ch] -- enccodes have also context names + if u then + unicodes[u] = i + end + end + i = i + 1 end + else + report_encoding("reading vector in encoding file %a fails",filename) end - i = i + 1 + else + report_encoding("reading encoding file %a fails",filename) end end end diff --git a/tex/context/base/mkiv/font-enh.lua b/tex/context/base/mkiv/font-enh.lua index f3209f5ee..b1fcd9be8 100644 --- a/tex/context/base/mkiv/font-enh.lua +++ b/tex/context/base/mkiv/font-enh.lua @@ -18,13 +18,12 @@ local report_unicoding = logs.reporter("fonts","unicoding") local fonts = fonts local constructors = fonts.constructors -local tfmfeatures = constructors.newfeatures("tfm") -local registertfmfeature = tfmfeatures.register +----- tfmfeatures = constructors.features.tfm +local afmfeatures = constructors.features.afm +local otffeatures = constructors.features.otf -local afmfeatures = fonts.constructors.newfeatures("afm") +----- registertfmfeature = tfmfeatures.register local registerafmfeature = afmfeatures.register - -local otffeatures = fonts.constructors.newfeatures("otf") local registerotffeature = otffeatures.register -- -- these will become goodies (when needed at all) @@ -119,19 +118,16 @@ local registerotffeature = otffeatures.register local function initializeunicoding(tfmdata) local goodies = tfmdata.goodies local newcoding = nil - -- local tounicode = false for i=1,#goodies do local remapping = goodies[i].remapping if remapping and remapping.unicodes then newcoding = remapping.unicodes -- names to unicodes - -- tounicode = remapping.tounicode -- not used end end if newcoding then local characters = tfmdata.characters local descriptions = tfmdata.descriptions local oldcoding = tfmdata.resources.unicodes - -- local tounicodes = tfmdata.resources.tounicode -- index to unicode local originals = { } for name, newcode in next, newcoding do local oldcode = oldcoding[name] @@ -143,25 +139,21 @@ local function initializeunicoding(tfmdata) end if oldcode then local original = originals[oldcode] + local character, description if original then - characters [newcode] = original.character - descriptions[newcode] = original.description + character = original.character + description = original.description else - characters [newcode] = characters [oldcode] - descriptions[newcode] = descriptions[oldcode] + character = characters [oldcode] + description = descriptions[oldcode] end + characters [newcode] = character + descriptions[newcode] = description + character .unicode = newcode + description.unicode = newcode else oldcoding[name] = newcode end - -- if tounicode then - -- local description = descriptions[newcode] - -- if description then - -- local index = description.index - -- if not tounicodes[index] then - -- tounicodes[index] = tosixteen(newcode) -- shared (we could have a metatable) - -- end - -- end - -- end if trace_unicoding then if oldcode then report_unicoding("aliasing glyph %a from %U to %U",name,oldcode,newcode) diff --git a/tex/context/base/mkiv/font-ext.lua b/tex/context/base/mkiv/font-ext.lua index 98ad9e09e..6edfe7025 100644 --- a/tex/context/base/mkiv/font-ext.lua +++ b/tex/context/base/mkiv/font-ext.lua @@ -6,8 +6,10 @@ if not modules then modules = { } end modules ['font-ext'] = { license = "see context related readme files" } -local next, type, byte = next, type, string.byte -local utfbyte = utf.byte +local next, type, tonumber = next, type, tonumber +local formatters = string.formatters +local byte = string.byte +local utfchar = utf.char local context = context local fonts = fonts @@ -18,7 +20,6 @@ local trace_expansion = false trackers.register("fonts.expansion", function local report_expansions = logs.reporter("fonts","expansions") local report_protrusions = logs.reporter("fonts","protrusions") -local report_opbd = logs.reporter("fonts","otf opbd") --[[ldx-- <p>When we implement functions that deal with features, most of them @@ -34,10 +35,13 @@ local registerotffeature = handlers.otf.features.register local registerafmfeature = handlers.afm.features.register local fontdata = hashes.identifiers +local fontproperties = hashes.properties local allocate = utilities.storage.allocate local settings_to_array = utilities.parsers.settings_to_array local getparameters = utilities.parsers.getparameters +local gettexdimen = tex.getdimen +local family_font = node.family_font local setmetatableindex = table.setmetatableindex @@ -77,6 +81,8 @@ expansions.classes = classes expansions.vectors = vectors -- beware, pdftex itself uses percentages * 10 +-- +-- todo: get rid of byte() here classes.preset = { stretch = 2, shrink = 2, step = .5, factor = 1 } @@ -286,12 +292,11 @@ vectors['quality'] = table.merged( vectors['alpha'] ) --- As this is experimental code, users should not depend on it. The --- implications are still discussed on the ConTeXt Dev List and we're --- not sure yet what exactly the spec is (the next code is tested with --- a gyre font patched by / fea file made by Khaled Hosny). The double --- trick should not be needed it proper hanging punctuation is used in --- which case values < 1 can be used. +-- As this is experimental code, users should not depend on it. The implications are still +-- discussed on the ConTeXt Dev List and we're not sure yet what exactly the spec is (the +-- next code is tested with a gyre font patched by / fea file made by Khaled Hosny). The +-- double trick should not be needed it proper hanging punctuation is used in which case +-- values < 1 can be used. -- -- preferred (in context, usine vectors): -- @@ -339,17 +344,23 @@ local function map_opbd_onto_protrusion(tfmdata,value,opbd) if validlookups then for i=1,#lookuplist do local lookup = lookuplist[i] - local data = lookuphash[lookup] - if data then + local steps = lookup.steps + if steps then if trace_protrusion then - report_protrusions("setting left using lfbd lookup %a",lookuptags[lookup]) + report_protrusions("setting left using lfbd") end - for k, v in next, data do - -- local p = - v[3] / descriptions[k].width-- or 1 ~= 0 too but the same - local p = - (v[1] / 1000) * factor * left - characters[k].left_protruding = p - if trace_protrusion then - report_protrusions("lfbd -> %s -> %C -> %0.03f (% t)",lookuptags[lookup],k,p,v) + for i=1,#steps do + local step = steps[i] + local coverage = step.coverage + if coverage then + for k, v in next, coverage do + -- local p = - v[3] / descriptions[k].width-- or 1 ~= 0 too but the same + local p = - (v[1] / 1000) * factor * left + characters[k].left_protruding = p + if trace_protrusion then + report_protrusions("lfbd -> %C -> %p",k,p) + end + end end end done = true @@ -362,17 +373,23 @@ local function map_opbd_onto_protrusion(tfmdata,value,opbd) if validlookups then for i=1,#lookuplist do local lookup = lookuplist[i] - local data = lookuphash[lookup] - if data then + local steps = lookup.steps + if steps then if trace_protrusion then - report_protrusions("setting right using rtbd lookup %a",lookuptags[lookup]) + report_protrusions("setting right using rtbd") end - for k, v in next, data do - -- local p = v[3] / descriptions[k].width -- or 3 - local p = (v[1] / 1000) * factor * right - characters[k].right_protruding = p - if trace_protrusion then - report_protrusions("rtbd -> %s -> %C -> %0.03f (% t)",lookuptags[lookup],k,p,v) + for i=1,#steps do + local step = steps[i] + local coverage = step.coverage + if coverage then + for k, v in next, coverage do + -- local p = v[3] / descriptions[k].width -- or 3 + local p = (v[1] / 1000) * factor * right + characters[k].right_protruding = p + if trace_protrusion then + report_protrusions("rtbd -> %C -> %p",k,p) + end + end end end end @@ -391,10 +408,9 @@ local function map_opbd_onto_protrusion(tfmdata,value,opbd) end end --- The opbd test is just there because it was discussed on the --- context development list. However, the mentioned fxlbi.otf font --- only has some kerns for digits. So, consider this feature not --- supported till we have a proper test font. +-- The opbd test is just there because it was discussed on the context development list. However, +-- the mentioned fxlbi.otf font only has some kerns for digits. So, consider this feature not supported +-- till we have a proper test font. local function initializeprotrusion(tfmdata,value) if value then @@ -550,10 +566,10 @@ local textitalics_specification = { registerotffeature(textitalics_specification) registerafmfeature(textitalics_specification) -local function initializemathitalics(tfmdata,value) -- yes no delay - tfmdata.properties.mathitalics = toboolean(value) -end - +-- local function initializemathitalics(tfmdata,value) -- yes no delay +-- tfmdata.properties.mathitalics = toboolean(value) +-- end +-- -- local mathitalics_specification = { -- name = "mathitalics", -- description = "use alternative math italic correction", @@ -627,12 +643,20 @@ local function manipulatedimensions(tfmdata,key,value) if type(value) == "string" and value ~= "" then local characters = tfmdata.characters local parameters = tfmdata.parameters - local emwidth = parameters.quad - local exheight = parameters.xheight - local spec = settings_to_array(value) - local width = (spec[1] or 0) * emwidth - local height = (spec[2] or 0) * exheight - local depth = (spec[3] or 0) * exheight + local emwidth = parameters.quad + local exheight = parameters.xheight + local width = 0 + local height = 0 + local depth = 0 + if value == "strut" then + height = gettexdimen("strutht") + depth = gettexdimen("strutdp") + else + local spec = settings_to_array(value) + width = (spec[1] or 0) * emwidth + height = (spec[2] or 0) * exheight + depth = (spec[3] or 0) * exheight + end if width > 0 then local resources = tfmdata.resources local additions = { } @@ -689,7 +713,7 @@ local function manipulatedimensions(tfmdata,key,value) elseif height > 0 and depth > 0 then for unicode, old_c in next, characters do old_c.height = height - old_c.depth = depth + old_c.depth = depth end elseif height > 0 then for unicode, old_c in next, characters do @@ -823,6 +847,8 @@ registerotffeature { -- -- local v_local = interfaces and interfaces.variables and interfaces.variables["local"] or "local" -- +-- local utfbyte = utf.byte +-- -- local function initialize(tfmdata,key,value) -- local characters = tfmdata.characters -- local parameters = tfmdata.parameters @@ -966,74 +992,307 @@ registerafmfeature(dimensions_specification) -- a handy helper (might change or be moved to another namespace) -local nodepool = nodes.pool +local nodepool = nodes.pool +local new_glyph = nodepool.glyph -local new_special = nodepool.special -local new_glyph = nodepool.glyph -local new_rule = nodepool.rule -local hpack_node = node.hpack +local helpers = fonts.helpers +local currentfont = font.current -local helpers = fonts.helpers -local currentfont = font.current +local currentprivate = 0xE000 +local maximumprivate = 0xEFFF -function helpers.addprivate(tfmdata,name,characterdata) - local properties = tfmdata.properties - local privates = properties.privates - local lastprivate = properties.lastprivate - if lastprivate then - lastprivate = lastprivate + 1 +-- if we run out of space we can think of another range but by sharing we can +-- use these privates for mechanisms like alignments-on-character and such + +local sharedprivates = setmetatableindex(function(t,k) + v = currentprivate + if currentprivate < maximumprivate then + currentprivate = currentprivate + 1 else - lastprivate = 0xE000 + -- reuse last slot, todo: warning end + t[k] = v + return v +end) + +function helpers.addprivate(tfmdata,name,characterdata) + local properties = tfmdata.properties + local characters = tfmdata.characters + local privates = properties.privates if not privates then privates = { } properties.privates = privates end - if name then - privates[name] = lastprivate + if not name then + name = formatters["anonymous_private_0x%05X"](currentprivate) end - properties.lastprivate = lastprivate - tfmdata.characters[lastprivate] = characterdata - if properties.finalized then - properties.lateprivates = true + local usedprivate = sharedprivates[name] + privates[name] = usedprivate + characters[usedprivate] = characterdata + return usedprivate +end + +local function getprivateslot(id,name) + if not name then + name = id + id = currentfont() end - return lastprivate + local properties = fontproperties[id] + local privates = properties and properties.privates + return privates and privates[name] end local function getprivatenode(tfmdata,name) + if type(tfmdata) == "number" then + tfmdata = fontdata[tfmdata] + end local properties = tfmdata.properties - local privates = properties and properties.privates - if privates then - local p = privates[name] - if p then - local char = tfmdata.characters[p] - local commands = char.commands - if commands then - local fake = hpack_node(new_special(commands[1][2])) - fake.width = char.width - fake.height = char.height - fake.depth = char.depth - return fake - else - -- todo: set current attribibutes - return new_glyph(properties.id,p) - end + local font = properties.id + local slot = getprivateslot(font,name) + if slot then + -- todo: set current attribibutes + local char = tfmdata.characters[slot] + local tonode = char.tonode + if tonode then + return tonode(font,char) + else + return new_glyph(font,slot) end end end -helpers.getprivatenode = getprivatenode +local function getprivatecharornode(tfmdata,name) + if type(tfmdata) == "number" then + tfmdata = fontdata[tfmdata] + end + local properties = tfmdata.properties + local font = properties.id + local slot = getprivateslot(font,name) + if slot then + -- todo: set current attribibutes + local char = tfmdata.characters[slot] + local tonode = char.tonode + if tonode then + return "node", tonode(tfmdata,char) + else + return "char", slot + end + end +end + +helpers.getprivateslot = getprivateslot +helpers.getprivatenode = getprivatenode +helpers.getprivatecharornode = getprivatecharornode + +function helpers.getprivates(tfmdata) + if type(tfmdata) == "number" then + tfmdata = fontdata[tfmdata] + end + local properties = tfmdata.properties + return properties and properties.privates +end function helpers.hasprivate(tfmdata,name) + if type(tfmdata) == "number" then + tfmdata = fontdata[tfmdata] + end local properties = tfmdata.properties local privates = properties and properties.privates return privates and privates[name] or false end +-- relatively new: + +do + + local extraprivates = { } + + function fonts.helpers.addextraprivate(name,f) + extraprivates[#extraprivates+1] = { name, f } + end + + local function addextraprivates(tfmdata) + for i=1,#extraprivates do + local e = extraprivates[i] + local c = e[2](tfmdata) + if c then + fonts.helpers.addprivate(tfmdata, e[1], c) + end + end + end + + fonts.constructors.newfeatures.otf.register { + name = "extraprivates", + description = "extra privates", + default = true, + manipulators = { + base = addextraprivates, + node = addextraprivates, + } + } + +end + implement { name = "getprivatechar", arguments = "string", actions = function(name) - context(getprivatenode(fontdata[currentfont()],name)) + local p = getprivateslot(name) + if p then + context(utfchar(p)) + end + end +} + +implement { + name = "getprivatemathchar", + arguments = "string", + actions = function(name) + local p = getprivateslot(family_font(0),name) + if p then + context(utfchar(p)) + end + end +} + +implement { + name = "getprivateslot", + arguments = "string", + actions = function(name) + local p = getprivateslot(name) + if p then + context(p) + end end } + +-- requested for latex but not supported unless really needed in context: +-- +-- registerotffeature { +-- name = "ignoremathconstants", +-- description = "ignore math constants table", +-- initializers = { +-- base = function(tfmdata,value) +-- if value then +-- tfmdata.mathparameters = nil +-- end +-- end +-- } +-- } + +-- tfmdata.properties.mathnolimitsmode = tonumber(value) or 0 + +do + + local splitter = lpeg.splitat(",",tonumber) + local lpegmatch = lpeg.match + + local function initialize(tfmdata,value) + local mathparameters = tfmdata.mathparameters + if mathparameters then + local sup, sub + if type(value) == "string" then + sup, sub = lpegmatch(splitter,value) + if not sup then + sub, sup = 0, 0 + elseif not sub then + sub, sup = sup, 0 + end + elseif type(value) == "number" then + sup, sub = 0, value + end + mathparameters.NoLimitSupFactor = sup + mathparameters.NoLimitSubFactor = sub + end + end + + registerotffeature { + name = "mathnolimitsmode", + description = "influence nolimits placement", + initializers = { + base = initialize, + node = initialize, + } + } + +end + +do + + local function initialize(tfmdata,value) + local properties = tfmdata.properties + if properties then + properties.identity = value == "vertical" and "vertical" or "horizontal" + end + end + + registerotffeature { + name = "identity", + description = "set font identity", + initializers = { + base = initialize, + node = initialize, + } + } + + local function initialize(tfmdata,value) + local properties = tfmdata.properties + if properties then + properties.writingmode = value == "vertical" and "vertical" or "horizontal" + end + end + + registerotffeature { + name = "writingmode", + description = "set font direction", + initializers = { + base = initialize, + node = initialize, + } + } + +end + +do -- another hack for a crappy font + + local function additalictowidth(tfmdata,key,value) + local characters = tfmdata.characters + local resources = tfmdata.resources + local additions = { } + local private = resources.private + for unicode, old_c in next, characters do + -- maybe check for math + local oldwidth = old_c.width + local olditalic = old_c.italic + if olditalic and olditalic ~= 0 then + private = private + 1 + local new_c = { + width = oldwidth + olditalic, + height = old_c.height, + depth = old_c.depth, + commands = { + { "slot", 1, private }, + { "right", olditalic }, + }, + } + setmetatableindex(new_c,old_c) + characters[unicode] = new_c + additions[private] = old_c + end + end + for k, v in next, additions do + characters[k] = v + end + resources.private = private + end + + registerotffeature { + name = "italicwidths", + description = "add italic to width", + manipulators = { + base = additalictowidth, + -- node = additalictowidth, -- only makes sense for math + } + } + +end diff --git a/tex/context/base/mkiv/font-fea.mkvi b/tex/context/base/mkiv/font-fea.mkvi index dade70494..840b64e9c 100644 --- a/tex/context/base/mkiv/font-fea.mkvi +++ b/tex/context/base/mkiv/font-fea.mkvi @@ -125,6 +125,12 @@ \def\font_basics_define_font_feature[#featureset][#parent][#settings]% {\clf_definefontfeature{#featureset}{#parent}{#settings}} +\unexpanded\def\adaptfontfeature + {\dodoubleargument\font_basics_adapt_font_feature} + +\def\font_basics_adapt_font_feature[#pattern][#settings]% + {\clf_adaptfontfeature{#pattern}{#settings}} + \unexpanded\def\fontfeatureslist {\dodoubleargument\font_basics_features_list} @@ -284,6 +290,38 @@ \letvalue{\??featureyes\s!unknown}\empty \letvalue{\??featurenop\s!unknown}\empty +% experimental bonus: + +% \unexpanded\def\addfflanguage +% {\ifnum\c_font_feature_state=\plusone +% \ifx\currentlanguage\currentfeature\else +% \font_feature_add_language_indeed +% \fi +% \else +% \font_feature_add_language_indeed +% \fi} +% +% \unexpanded\def\font_feature_add_language_indeed +% {\clf_addfeature{\m_font_feature_list}{\currentlanguage}% +% \edef\m_font_feature_list{\m_font_feature_list+\currentlanguage}% also + at the lua end +% \c_font_feature_state\plusone +% \let\currentfeature\currentlanguage} +% +% some 3% slower: + +% \unexpanded\def\addfflanguage +% {\let\m_font_feature_asked\currentlanguage +% \font_feature_add} + +\let\m_font_feature_language\currentlanguage + +\unexpanded\def\addfflanguage + {\ifx\currentlanguage\m_font_feature_language\else + \let\m_font_feature_language\currentlanguage + \let\m_font_feature_asked \currentlanguage + \font_feature_add + \fi} + % just for old times sake: \unexpanded\def\featureattribute#feature% @@ -353,4 +391,22 @@ 0% \endgroup} +% not nice but maybe handy + +% \starttyping +% \blockligatures[fi,ff] \blockligatures[fl] +% +% \definefontfeature[default:b][default][blockligatures=yes] +% +% \setupbodyfont[pagella] \showfontkerns +% +% \definedfont[Serif*default:b] +% +% \startTEXpage[offset=1em] +% fi ff fl +% \stopTEXpage +% \stoptyping + +\unexpanded\def\blockligatures[#1]{\clf_blockligatures{#1}} + \protect \endinput diff --git a/tex/context/base/mkiv/font-fil.mkvi b/tex/context/base/mkiv/font-fil.mkvi index 0bfc07b6c..ba9d5e2c6 100644 --- a/tex/context/base/mkiv/font-fil.mkvi +++ b/tex/context/base/mkiv/font-fil.mkvi @@ -234,6 +234,24 @@ #name% \fi\fi\fi} +% ok when the last lookup is not stripped .. we ned to be able to define synonyms for symbols +% +% \def\truefontname#name% +% %{\normalexpanded{\noexpand\font_helpers_true_fontname{\clf_truefontname{#name}}}} +% {\expandafter\expandafter\expandafter\font_helpers_true_fontname\expandafter\expandafter\expandafter{\clf_truefontname{#name}}} +% +% \def\font_helpers_true_fontname#name% +% {\ifcsname\??fontfile\fontclass#name\endcsname +% \expandafter\font_helpers_true_fontname\expandafter{\lastnamedcs}% +% \else\ifcsname\??fontfile\defaultfontclass#name\endcsname +% \expandafter\font_helpers_true_fontname\expandafter{\lastnamedcs}% +% \else\ifcsname\??fontfile#name\endcsname +% \expandafter\font_helpers_true_fontname\expandafter{\lastnamedcs}% +% \else +% % \clf_truefontname{#name}% +% #name% so the last one can have features ! +% \fi\fi\fi} + \def\expandfontsynonym#command#name% one level expansion {\ifcsname\??fontfile\fontclass#name\endcsname %\expandafter\normaldef\expandafter#command\expandafter{\csname\??fontfile\fontclass#name\endcsname}% @@ -451,4 +469,8 @@ \setxvalue{\??fontclass\fontclass#style\s!designsize}{#designsize}% \setxvalue{\??fontclass\fontclass#style\s!direction }{#direction}} +% bonus + +\let\currentfontinstancespec\clf_currentfontinstancespec % expandable + \protect \endinput diff --git a/tex/context/base/mkiv/font-gbn.lua b/tex/context/base/mkiv/font-gbn.lua index a02406b75..1f8df642c 100644 --- a/tex/context/base/mkiv/font-gbn.lua +++ b/tex/context/base/mkiv/font-gbn.lua @@ -19,8 +19,7 @@ local nodes = nodes local nuts = nodes.nuts -- context abstraction of direct nodes local traverse_id = nuts.traverse_id -local remove_node = nuts.remove -local free_node = nuts.free +local flush_node = nuts.flush_node local glyph_code = nodes.nodecodes.glyph local disc_code = nodes.nodecodes.disc @@ -160,7 +159,7 @@ function nodes.handlers.nodepass(head) end end end - free_node(r) + flush_node(r) end end for d in traverse_id(disc_code,nuthead) do diff --git a/tex/context/base/mkiv/font-hsh.lua b/tex/context/base/mkiv/font-hsh.lua index efd042fe1..12f7bdfc2 100644 --- a/tex/context/base/mkiv/font-hsh.lua +++ b/tex/context/base/mkiv/font-hsh.lua @@ -31,6 +31,7 @@ local xheights = hashes.xheights or allocate() local csnames = hashes.csnames or allocate() -- namedata local features = hashes.features or allocate() local marks = hashes.marks or allocate() +local classes = hashes.classes or allocate() local italics = hashes.italics or allocate() local lastmathids = hashes.lastmathids or allocate() local dynamics = hashes.dynamics or allocate() @@ -51,6 +52,7 @@ hashes.xheights = xheights hashes.exheights = xheights hashes.csnames = csnames hashes.features = features hashes.marks = marks +hashes.classes = classes hashes.italics = italics hashes.lastmathids = lastmathids hashes.dynamics = dynamics @@ -212,12 +214,23 @@ setmetatableindex(marks, function(t,k) return marks[currentfont()] else local resources = identifiers[k].resources or { } - local marks = resources.marks or { } + local marks = resources.marks or { } t[k] = marks return marks end end) +setmetatableindex(classes, function(t,k) + if k == true then + return classes[currentfont()] + else + local resources = identifiers[k].resources or { } + local classes = resources.classes or { } + t[k] = classes + return classes + end +end) + setmetatableindex(quads, function(t,k) if k == true then return quads[currentfont()] diff --git a/tex/context/base/mkiv/font-ini.lua b/tex/context/base/mkiv/font-ini.lua index c547f89ac..abc319484 100644 --- a/tex/context/base/mkiv/font-ini.lua +++ b/tex/context/base/mkiv/font-ini.lua @@ -12,8 +12,6 @@ if not modules then modules = { } end modules ['font-ini'] = { local allocate = utilities.storage.allocate -local report_defining = logs.reporter("fonts","defining") - fonts = fonts or { } local fonts = fonts diff --git a/tex/context/base/mkiv/font-ini.mkvi b/tex/context/base/mkiv/font-ini.mkvi index 7e5851b26..2697dff2e 100644 --- a/tex/context/base/mkiv/font-ini.mkvi +++ b/tex/context/base/mkiv/font-ini.mkvi @@ -647,25 +647,70 @@ \def\font_basics_check_math_bodyfont#style#alternative#size% {} +% \def\font_basics_check_text_bodyfont#style#alternative#size% size can be empty (checking needed as \bf is already defined) +% {\setugvalue{#style#size}{\font_helpers_set_current_font_style_size{#style}{#size}}% \rma +% \setugvalue{#alternative#size}{\font_helpers_set_current_font_alternative_size{#alternative}{#size}}% \sla +% \setugvalue{#style#alternative#size}{\font_helpers_set_current_font_style_alternative_size{#style}{#alternative}{#size}}% \rmsla +% \ifcsname\s!normal#style\endcsname % text/math check +% \expandafter\let\csname#style\expandafter\endcsname\csname\s!normal#style\endcsname +% \else +% \setugvalue{#style}{\font_helpers_set_current_font_style{#style}}% \rm +% \fi +% \ifcsname\s!normal#alternative\endcsname % text/math check +% \expandafter\let\csname#alternative\expandafter\endcsname\csname\s!normal#alternative\endcsname +% \else +% \setugvalue{#alternative}{\font_helpers_set_current_font_alternative{#alternative}}% \sl +% \fi +% \setugvalue{#style\s!x}{\font_helpers_set_current_font_x_style_alternative{#style}}% \rmx +% \setugvalue{#style\s!xx}{\font_helpers_set_current_font_xx_style_alternative{#style}}% \rmxx +% \setugvalue{#alternative\s!x}{\font_helpers_set_current_font_x_alternative{#alternative}}% \slx +% \setugvalue{#alternative\s!xx}{\font_helpers_set_current_font_xx_alternative{#alternative}}% \slxx +% \setugvalue{#style#alternative}{\font_helpers_set_current_font_style_alternative{#style}{#alternative}}}% \rmsl + +% \def\font_basics_check_text_bodyfont#style#alternative#size% size can be empty (checking needed as \bf is already defined) +% {\ifcsname#style#size\endcsname\else +% \setugvalue{#style#size}{\font_helpers_set_current_font_style_size{#style}{#size}}% \rma +% \fi +% \ifcsname#alternative#size\endcsname\else +% \setugvalue{#alternative#size}{\font_helpers_set_current_font_alternative_size{#alternative}{#size}}% \sla +% \fi +% \ifcsname#style#alternative#size\endcsname\else +% \setugvalue{#style#alternative#size}{\font_helpers_set_current_font_style_alternative_size{#style}{#alternative}{#size}}% \rmsla +% \fi +% \ifcsname#style\endcsname\else +% \setugvalue{#style}{\font_helpers_set_current_font_style{#style}}% \rm +% \fi +% \ifcsname#alternative\endcsname\else +% \setugvalue{#alternative}{\font_helpers_set_current_font_alternative{#alternative}}% \sl +% \fi +% \ifcsname#style\s!x\endcsname\else +% \setugvalue{#style\s!x }{\font_helpers_set_current_font_x_style_alternative{#style}}% \rmx +% \setugvalue{#style\s!xx}{\font_helpers_set_current_font_xx_style_alternative{#style}}% \rmxx +% \fi +% \ifcsname#alternative\s!x\endcsname\else +% \setugvalue{#alternative\s!x }{\font_helpers_set_current_font_x_alternative{#alternative}}% \slx +% \setugvalue{#alternative\s!xx}{\font_helpers_set_current_font_xx_alternative{#alternative}}% \slxx +% \fi +% \ifcsname#style#alternative\endcsname\else +% \setugvalue{#style#alternative}{\font_helpers_set_current_font_style_alternative{#style}{#alternative}}% \rmsl +% \fi} + +\def\font_basics_check_text_bodyfont_step#whatever#body% size can be empty (checking needed as \bf is already defined) + {\ifcsname#whatever\endcsname\else + \setugvalue{#whatever}{#body}% + \fi} + \def\font_basics_check_text_bodyfont#style#alternative#size% size can be empty (checking needed as \bf is already defined) - {\setugvalue{#style#size}{\font_helpers_set_current_font_style_size{#style}{#size}}% \rma - \setugvalue{#alternative#size}{\font_helpers_set_current_font_alternative_size{#alternative}{#size}}% \sla - \setugvalue{#style#alternative#size}{\font_helpers_set_current_font_style_alternative_size{#style}{#alternative}{#size}}% \rmsla - \ifcsname\s!normal#style\endcsname % text/math check - \expandafter\let\csname#style\expandafter\endcsname\csname\s!normal#style\endcsname - \else - \setugvalue{#style}{\font_helpers_set_current_font_style{#style}}% \rm - \fi - \ifcsname\s!normal#alternative\endcsname % text/math check - \expandafter\let\csname#alternative\expandafter\endcsname\csname\s!normal#alternative\endcsname - \else - \setugvalue{#alternative}{\font_helpers_set_current_font_alternative{#alternative}}% \sl - \fi - \setugvalue{#style\s!x}{\font_helpers_set_current_font_x_style_alternative{#style}}% \rmx - \setugvalue{#style\s!xx}{\font_helpers_set_current_font_xx_style_alternative{#style}}% \rmxx - \setugvalue{#alternative\s!x}{\font_helpers_set_current_font_x_alternative{#alternative}}% \slx - \setugvalue{#alternative\s!xx}{\font_helpers_set_current_font_xx_alternative{#alternative}}% \slxx - \setugvalue{#style#alternative}{\font_helpers_set_current_font_style_alternative{#style}{#alternative}}}% \rmsl + {\font_basics_check_text_bodyfont_step{#style#size}{\font_helpers_set_current_font_style_size{#style}{#size}}% \rma + \font_basics_check_text_bodyfont_step{#alternative#size}{\font_helpers_set_current_font_alternative_size{#alternative}{#size}}% \sla + \font_basics_check_text_bodyfont_step{#style#alternative#size}{\font_helpers_set_current_font_style_alternative_size{#style}{#alternative}{#size}}% \rmsla + \font_basics_check_text_bodyfont_step{#style}{\font_helpers_set_current_font_style{#style}}% \rm + \font_basics_check_text_bodyfont_step{#alternative}{\font_helpers_set_current_font_alternative{#alternative}}% \sl + \font_basics_check_text_bodyfont_step{#style\s!x }{\font_helpers_set_current_font_x_style_alternative{#style}}% \rmx + \font_basics_check_text_bodyfont_step{#style\s!xx}{\font_helpers_set_current_font_xx_style_alternative{#style}}% \rmxx + \font_basics_check_text_bodyfont_step{#alternative\s!x }{\font_helpers_set_current_font_x_alternative{#alternative}}% \slx + \font_basics_check_text_bodyfont_step{#alternative\s!xx}{\font_helpers_set_current_font_xx_alternative{#alternative}}% \slxx + \font_basics_check_text_bodyfont_step{#style#alternative}{\font_helpers_set_current_font_style_alternative{#style}{#alternative}}}% \rmsl %D Scaling macros: %D @@ -879,6 +924,40 @@ \let\fontfile\s!unknown +%D Relatively new: + +\installcorenamespace{fonts} +\installcorenamespace{fontslanguage} + +\installsetuponlycommandhandler \??fonts {fonts} + +\newconstant\c_fonts_auto_language + +\letvalue{\??fontslanguage\v!auto}\plusone % experimental +%letvalue{\??fontslanguage\v!yes }\plustwo % less efficient, for experiments + +\appendtoks + \c_fonts_auto_language + \ifcsname\??fontslanguage\fontsparameter\c!language\endcsname + \lastnamedcs + \else + \zerocount + \fi +\to \everysetupfonts + +\appendtoks + \ifcase\c_fonts_auto_language + % nothing + \or + \addfflanguage + % \or + % font + \fi +\to \everylanguage + +% \setupfonts +% [\c!language=\v!auto] + %D \macros %D {everyfont,everyfontswitch} @@ -887,6 +966,16 @@ \def\setfontcharacteristics{\the\everyfont} +% \appendtoks +% \ifcase\c_fonts_auto_language +% % nothing +% \or +% % auto +% \or +% \addfflanguage +% \fi +% \to \everyfont + %D \macros %D {definefont} %D @@ -2038,32 +2127,24 @@ \font_helpers_set_current_xsize_alternative{#xsize}{#alternative}% \fi} -\def\font_helpers_set_current_font_x_alternative#alternative% - {\font_helpers_set_current_font_xxx_alternative{#alternative}{4}\scriptstyle - \currentxfontsize\plusone - \let\tx\txx} - -\def\font_helpers_set_current_font_xx_alternative#alternative% - {\font_helpers_set_current_font_xxx_alternative{#alternative}{5}\scriptscriptstyle - \currentxfontsize\plustwo - \let\tx\empty - \let\txx\empty} - \def\font_helpers_reset_x_fontsize {\ifcase\currentxfontsize\else \currentxfontsize\zerocount - \let\tx\normaltx + % also \sx and \sxx ? + \let\tx \normaltx \let\txx\normaltxx \fi} -\def\font_helpers_check_nested_x_fontsize % option +% \def\font_helpers_check_nested_x_fontsize % option % {\ifcase\currentxfontsize\else\ifx\fontsize\empty\else % \currentxfontsize\zerocount % \let\fontsize\empty % \let\tx\normaltx % \let\txx\normaltxx % \fi\fi} - {} +% {} + +\let\font_helpers_check_nested_x_fontsize\relax \def\font_helpers_set_current_font_x_alternative#alternative% {\font_helpers_check_nested_x_fontsize @@ -2110,30 +2191,136 @@ % \unexpanded\def\tx {\font_helpers_set_current_font_x_alternative \fontalternative} % \unexpanded\def\txx{\font_helpers_set_current_font_xx_alternative\fontalternative} +% \unexpanded\def\tx +% {\ifmmode +% \scriptstyle +% \else +% \let\fontface\!!plusfour +% \let\fontalternative\fontalternative +% \font_helpers_synchronize_font +% \fi +% \currentxfontsize\plusone +% \let\tx\txx} +% +% \unexpanded\def\txx +% {\ifmmode +% \scriptscriptstyle +% \else +% \let\fontface\!!plusfive +% \let\fontalternative\fontalternative +% \font_helpers_synchronize_font +% \fi +% \currentxfontsize\plustwo} + +\installcorenamespace{fontscalex} +\installcorenamespace{fontscalexx} + +\newconditional\c_font_inherit_scale + +\def\font_scale_inherit#1% + {\begingroup + \scratchcounterone\fontid\font\relax + \currentxfontsize\plusone + \normalexpanded{\definedfont[\clf_specifiedfont\scratchcounterone\font_currentfontscale\relax]}% + \scratchcountertwo\fontid\font\relax + \currentxfontsize\plustwo + \normalexpanded{\definedfont[\clf_specifiedfont\scratchcounterone\font_currentfontscale\relax]}% + \scratchcounterthree\fontid\font\relax + % parent -> x -> xx + % parent -> xx + \global\expandafter\chardef\csname\??fontscalex \number\scratchcounterone\endcsname\scratchcountertwo + \global\expandafter\chardef\csname\??fontscalexx\number\scratchcounterone\endcsname\scratchcounterthree + \global\expandafter\chardef\csname\??fontscalex \number\scratchcountertwo\endcsname\scratchcounterthree + \global\expandafter\chardef\csname\??fontscalexx\number\scratchcountertwo\endcsname\scratchcounterthree + \endgroup + \setfontid\csname#1\number\fontid\font\endcsname} + +\def\font_scale_inherit_x + {\ifcsname\??fontscalex\number\fontid\font\endcsname + \setfontid\lastnamedcs + \else + \font_scale_inherit\??fontscalex + \fi + \ifskipfontcharacteristics + \setfontcharacteristics + \the\everyfontswitch + \fi} + +\def\font_scale_inherit_xx + {\ifcsname\??fontscalexx\number\fontid\font\endcsname + \setfontid\lastnamedcs + \else + \font_scale_inherit\??fontscalexx + \fi + \ifskipfontcharacteristics + \setfontcharacteristics + \the\everyfontswitch + \fi} + +\def\font_scale_defined_x + {\let\fontface\!!plusfour + \let\fontalternative\fontalternative + \font_helpers_synchronize_font} + +\def\font_scale_defined_xx + {\let\fontface\!!plusfive + \let\fontalternative\fontalternative + \font_helpers_synchronize_font} + \unexpanded\def\tx - {\ifmmode + {\currentxfontsize\plusone + \ifmmode \scriptstyle + \else\ifconditional\c_font_inherit_scale + \font_scale_inherit_x \else - \let\fontface\!!plusfour - \let\fontalternative\fontalternative - \font_helpers_synchronize_font - \fi - \currentxfontsize\plusone + \font_scale_defined_x + \fi\fi \let\tx\txx} \unexpanded\def\txx - {\ifmmode + {\currentxfontsize\plustwo + \ifmmode + \scriptscriptstyle + \else\ifconditional\c_font_inherit_scale + \font_scale_inherit_xx + \else + \font_scale_defined_xx + \fi\fi + \let\tx \empty + \let\txx\empty} + +\unexpanded\def\sx + {\currentxfontsize\plusone + \ifmmode + \scriptstyle + \else + \font_scale_inherit_x + \fi + \let\tx\txx + \let\sx\sxx} + +\unexpanded\def\sxx + {\currentxfontsize\plustwo + \ifmmode \scriptscriptstyle \else - \let\fontface\!!plusfive - \let\fontalternative\fontalternative - \font_helpers_synchronize_font + \font_scale_inherit_xx \fi - \currentxfontsize\plustwo} + \let\tx \empty + \let\txx\empty + \let\sx \empty + \let\sxx\empty} + +\unexpanded\def\useinheritxsizes{\settrue \c_font_inherit_scale} % not yet public, playground for WS and me +\unexpanded\def\usedefinedxsizes{\setfalse\c_font_inherit_scale} % not yet public, playground for WS and me \let\normaltx \tx \let\normaltxx\txx +\let\normalsx \sx +\let\normalsxx\sxx + %D When asking for a complete font switch, for instance from 10 %D to 12~points, the next macro does the job. First we %D normalize the size, next we define the current range of @@ -2269,7 +2456,6 @@ \unexpanded\def\switchtobodyfont[#specification]% could become an ifx {\doifsomething{#specification}{\font_basics_switchtobodyfont{#specification}}} - \unexpanded\def\usebodyfontparameter#1% {\edef\m_font_bodyfont_asked{#1\c!bodyfont}% \ifx\m_font_bodyfont_asked\empty\else @@ -2332,7 +2518,6 @@ %D Handy for manuals: - %D The \type {\tochar} commmand takes a specification: %D %D \starttabulate[|l|l|l|] @@ -2343,6 +2528,8 @@ %D \NC i \NC decimal index \NC i:456 \NC \NR %D \NC n \NC name \NC n:eight \NC \NR %D \NC c \NC name \NC c:x \NC \NR +%D \NC u \NC unicode descriptions \NC u:dog \NC \NR +%D \NC a \NC all (also descriptions) \NC a:rewind \NC \NR %D \stoptabulate %D %D This is an expandable command! @@ -2526,6 +2713,32 @@ \def\saveddefinedfontid {\number\fontid\font} \def\saveddefinedfontname{\fontname\font} +%D Handy for defining additional glyphs: + +\let\getprivateglyphslot\clf_getprivateglyphslot % kind of private macro + +\let\getprivatechar \clf_getprivatechar % gives back a utf ! +\let\getprivatemathchar \clf_getprivatemathchar % gives back a utf ! +\let\getprivateslot \clf_getprivateslot % companion to fonts.helpers.addprivate + +% \unexpanded\def\getprivatemathchar#1% +% {\begingroup\the\textfont\zerocount\getprivatechar{#1}\endgroup} + +\def\privatechar % the text variant gets expanded to utf + {\ifmmode + \expandafter\getprivatemathchar + \else + \expandafter\getprivatechar + \fi} + +% new + +\unexpanded\def\definefontcolorpalette + {\dodoubleargument\font_define_color_palette} + +\def\font_define_color_palette[#1][#2]% + {\clf_definefontcolorpalette{#1}{#2}} + % yes or no: % \let\font_basics_check_text_bodyfont_slow\font_basics_check_text_bodyfont diff --git a/tex/context/base/mkiv/font-inj.lua b/tex/context/base/mkiv/font-inj.lua index 89370210d..ccc41d3f3 100644 --- a/tex/context/base/mkiv/font-inj.lua +++ b/tex/context/base/mkiv/font-inj.lua @@ -22,7 +22,6 @@ if not modules then modules = { } end modules ['font-inj'] = { if not nodes.properties then return end local next, rawget = next, rawget -local utfchar = utf.char local fastcopy = table.fastcopy local trace_injections = false trackers.register("fonts.injections", function(v) trace_injections = v end) @@ -262,7 +261,7 @@ function injections.setpair(current,factor,rlmode,r2lflag,spec,injection) -- r2l local i = rawget(p,injection) if i then if leftkern ~= 0 then - i.leftkern = (i.leftkern or 0) + leftkern + i.leftkern = (i.leftkern or 0) + leftkern end if rightkern ~= 0 then i.rightkern = (i.rightkern or 0) + rightkern @@ -548,7 +547,7 @@ local function collect_glyphs(head,offsets) identify(n,"preinjections") end end - end + end local d = getfield(n,"post") if d then for n in traverse_id(glyph_code,d) do @@ -556,7 +555,7 @@ local function collect_glyphs(head,offsets) identify(n,"postinjections") end end - end + end local d = getfield(n,"replace") if d then for n in traverse_id(glyph_code,d) do @@ -564,9 +563,9 @@ local function collect_glyphs(head,offsets) identify(n,"replaceinjections") end end - end + end end - n = getnext(n) + n = getnext(n) end return glyphs, glyphi, nofglyphs, marks, marki, nofmarks @@ -601,11 +600,11 @@ local function inject_marks(marks,marki,nofmarks) -- kern(x) glyph(p) kern(w-x) mark(n) -- ox = px - getfield(p,"width") + pn.markx - pp.leftkern -- - -- According to Kai we don't need to handle leftkern here but I'm + -- According to Kai we don't need to handle leftkern here but I'm -- pretty sure I've run into a case where it was needed so maybe - -- some day we need something more clever here. + -- some day we need something more clever here. -- - if false then + if false then -- a mark with kerning local leftkern = pp.leftkern if leftkern then @@ -636,17 +635,16 @@ local function inject_marks(marks,marki,nofmarks) pn.rightkern = -wn/2 -- wx[n] = { 0, -wn/2, 0, -wn } end - -- so far end setfield(n,"xoffset",ox) -- local py = getfield(p,"yoffset") --- local oy = 0 --- if marks[p] then --- oy = py + pn.marky --- else --- oy = getfield(n,"yoffset") + py + pn.marky --- end + -- local oy = 0 + -- if marks[p] then + -- oy = py + pn.marky + -- else + -- oy = getfield(n,"yoffset") + py + pn.marky + -- end local oy = getfield(n,"yoffset") + py + pn.marky setfield(n,"yoffset",oy) else @@ -754,54 +752,54 @@ local function inject_kerns(head,glist,ilist,length) -- not complete ! compare w local n = glist[i] local pn = rawget(properties,n) if pn then - local dp = nil - local dr = nil + local dp = nil + local dr = nil local ni = ilist[i] local p = nil - if ni == "injections" then - p = getprev(n) - if p then - local id = getid(p) - if id == disc_code then - dp = getfield(p,"post") - dr = getfield(p,"replace") - end - end - end - if dp then - local i = rawget(pn,"postinjections") - if i then - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - local t = find_tail(dp) - insert_node_after(dp,t,newkern(leftkern)) + if ni == "injections" then + p = getprev(n) + if p then + local id = getid(p) + if id == disc_code then + dp = getfield(p,"post") + dr = getfield(p,"replace") + end + end + end + if dp then + local i = rawget(pn,"postinjections") + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + local t = find_tail(dp) + insert_node_after(dp,t,newkern(leftkern)) setfield(p,"post",dp) -- currently we need to force a tail refresh - end - end - end - if dr then - local i = rawget(pn,"replaceinjections") - if i then - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - local t = find_tail(dr) - insert_node_after(dr,t,newkern(leftkern)) + end + end + end + if dr then + local i = rawget(pn,"replaceinjections") + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + local t = find_tail(dr) + insert_node_after(dr,t,newkern(leftkern)) setfield(p,"replace",dr) -- currently we need to force a tail refresh - end - end - else - local i = rawget(pn,ni) - if i then - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - insert_node_before(head,n,newkern(leftkern)) -- type 0/2 - end - local rightkern = i.rightkern - if rightkern and rightkern ~= 0 then - insert_node_after(head,n,newkern(rightkern)) -- type 0/2 - end - end - end + end + end + else + local i = rawget(pn,ni) + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + insert_node_before(head,n,newkern(leftkern)) -- type 0/2 + end + local rightkern = i.rightkern + if rightkern and rightkern ~= 0 then + insert_node_after(head,n,newkern(rightkern)) -- type 0/2 + end + end + end end end end @@ -823,7 +821,7 @@ local function inject_everything(head,where) end if nofmarks > 0 then inject_kerns(head,marks,marki,nofmarks) - end + end if keepregisteredcounts then keepregisteredcounts = false else diff --git a/tex/context/base/mkiv/font-lib.mkvi b/tex/context/base/mkiv/font-lib.mkvi index fd6f70d69..d9cae503b 100644 --- a/tex/context/base/mkiv/font-lib.mkvi +++ b/tex/context/base/mkiv/font-lib.mkvi @@ -18,6 +18,7 @@ \registerctxluafile{font-ini}{1.001} \registerctxluafile{font-log}{1.001} \registerctxluafile{font-con}{1.001} +\registerctxluafile{font-cft}{1.001} \registerctxluafile{font-enc}{1.001} \registerctxluafile{font-agl}{1.001} % if needed we can comment this and delay loading \registerctxluafile{font-cid}{1.001} % cid maps @@ -26,13 +27,14 @@ % the otf font loader: \registerctxluafile{font-otr}{1.001} % opentype fontloader +\registerctxluafile{font-web}{1.001} % opentype fontloader \registerctxluafile{font-cff}{1.001} % quadratic outlines \registerctxluafile{font-ttf}{1.001} % cubic outlines %registerctxluafile{font-tmp}{1.001} % temporary placeholder \registerctxluafile{font-dsp}{1.001} % ... for this one \registerctxluafile{font-off}{1.001} % the old loader -\registerctxluafile{font-tfm}{1.001} +% \registerctxluafile{font-tfm}{1.001} \registerctxluafile{font-hsh}{1.001} % hashes used by context \registerctxluafile{font-nod}{1.001} @@ -50,6 +52,7 @@ \registerctxluafile{font-otc}{1.001} \registerctxluafile{font-oth}{1.001} \registerctxluafile{font-osd}{1.001} +\registerctxluafile{font-ocl}{1.001} % we use otf code for type one @@ -58,11 +61,19 @@ %registerctxluafile{font-afm}{1.001} \registerctxluafile{font-afk}{1.001} +% tfm + +\registerctxluafile{font-tfm}{1.001} + % name database \registerctxluafile{font-syn}{1.001} \registerctxluafile{font-trt}{1.001} +% shapes + +\registerctxluafile{font-shp}{1.001} + % so far \registerctxluafile{font-pat}{1.001} % patchers @@ -76,7 +87,10 @@ \registerctxluafile{font-vf} {1.001} \registerctxluafile{font-enh}{1.001} -\registerctxluafile{font-gds}{1.001} +\registerctxluafile{good-ini}{1.001} +\registerctxluafile{good-gen}{1.001} +\registerctxluafile{good-ctx}{1.001} +\registerctxluafile{good-mth}{1.001} \registerctxluafile{font-def}{1.001} \registerctxluafile{font-ctx}{1.001} % after def as it overloads @@ -86,6 +100,8 @@ \registerctxluafile{font-aux}{1.001} +\registerctxluafile{font-lig}{1.001} % only for experiments so try to avoid it + %D Some low level helpers %D %D \starttyping diff --git a/tex/context/base/mkiv/font-lig.lua b/tex/context/base/mkiv/font-lig.lua new file mode 100644 index 000000000..bb9ee0096 --- /dev/null +++ b/tex/context/base/mkiv/font-lig.lua @@ -0,0 +1,48 @@ +if not modules then modules = { } end modules ['font-lig'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +-- This module is not loaded but generated a file for plain TeX as a substitute +-- for collapsing the input: "luatex-fonts-lig.lua" with "collapse=yes". + +local standalone = not characters + +if standalone then + require("char-utf") +end + +local data = { } + +for first, seconds in next, characters.graphemes do + for second, combined in next, seconds do + data[combined] = { first, second } + end +end + +-- data['c'] = { 'a', 'b' } +-- data['d'] = { 'c', 'c' } + +local feature = { + name = "collapse", + type = "ligature", + prepend = true, + dataset = { + { data = data }, + { data = data }, + } +} + +if standalone then + local filename = "luatex-fonts-lig.lua" + local filedata = "-- this file is generated by context\n\n" + .. "fonts.handlers.otf.addfeature " + .. table.serialize(feature,false) + logs.report("fonts","pseudo ligature file %a saved",filename) + io.savedata(filename,filedata) +else + fonts.handlers.otf.addfeature(feature) +end diff --git a/tex/context/base/mkiv/font-map.lua b/tex/context/base/mkiv/font-map.lua index 838c74173..cf369708c 100644 --- a/tex/context/base/mkiv/font-map.lua +++ b/tex/context/base/mkiv/font-map.lua @@ -10,16 +10,18 @@ local tonumber, next, type = tonumber, next, type local match, format, find, concat, gsub, lower = string.match, string.format, string.find, table.concat, string.gsub, string.lower local P, R, S, C, Ct, Cc, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.match -local utfbyte = utf.byte local floor = math.floor local formatters = string.formatters +local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys -local trace_loading = false trackers.register("fonts.loading", function(v) trace_loading = v end) -local trace_mapping = false trackers.register("fonts.mapping", function(v) trace_unimapping = v end) +local trace_loading = false trackers.register("fonts.loading", function(v) trace_loading = v end) +local trace_mapping = false trackers.register("fonts.mapping", function(v) trace_mapping = v end) local report_fonts = logs.reporter("fonts","loading") -- not otf only -local force_ligatures = false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures = v end) +-- force_ligatures is true per 2017-04-20 so that these emoji's with bad names work too + +local force_ligatures = true directives.register("fonts.mapping.forceligatures",function(v) force_ligatures = v end) local fonts = fonts or { } local mappings = fonts.mappings or { } @@ -140,7 +142,7 @@ local f_double = formatters["%04X%04X"] -- end -- end -local function tounicode16(unicode,name) +local function tounicode16(unicode) if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then return f_single(unicode) else @@ -149,7 +151,7 @@ local function tounicode16(unicode,name) end end -local function tounicode16sequence(unicodes,name) +local function tounicode16sequence(unicodes) local t = { } for l=1,#unicodes do local u = unicodes[l] @@ -186,6 +188,32 @@ local function tounicode(unicode,name) end end +-- no real gain on runs +-- +-- local hash = setmetatableindex(function(t,u) +-- local v +-- if u < 0xD7FF or (u > 0xDFFF and u <= 0xFFFF) then +-- v = f_single(u) +-- else +-- u = u - 0x10000 +-- v = f_double(floor(u/1024)+0xD800,u%1024+0xDC00) +-- end +-- t[u] = v +-- return v +-- end) +-- +-- local function tounicode(unicode,name) +-- if type(unicode) == "table" then +-- local t = { } +-- for l=1,#unicode do +-- t[l] = hash[u] +-- end +-- return concat(t) +-- else +-- return hash[unicode] +-- end +-- end + local function fromunicode16(str) if #str == 4 then return tonumber(str,16) @@ -216,6 +244,8 @@ mappings.tounicode16 = tounicode16 mappings.tounicode16sequence = tounicode16sequence mappings.fromunicode16 = fromunicode16 +-- mozilla emoji has bad lig names: name = gsub(name,"(u[a-f0-9_]+)%-([a-f0-9_]+)","%1_%2") + local ligseparator = P("_") local varseparator = P(".") local namesplitter = Ct(C((1 - ligseparator - varseparator)^1) * (ligseparator * C((1 - ligseparator - varseparator)^1))^0) @@ -237,39 +267,50 @@ local namesplitter = Ct(C((1 - ligseparator - varseparator)^1) * (ligseparator * -- to be completed .. for fonts that use unicodes for ligatures which -- is a actually a bad thing and should be avoided in the first place -local overloads = allocate { - IJ = { name = "I_J", unicode = { 0x49, 0x4A }, mess = 0x0132 }, - ij = { name = "i_j", unicode = { 0x69, 0x6A }, mess = 0x0133 }, - ff = { name = "f_f", unicode = { 0x66, 0x66 }, mess = 0xFB00 }, - fi = { name = "f_i", unicode = { 0x66, 0x69 }, mess = 0xFB01 }, - fl = { name = "f_l", unicode = { 0x66, 0x6C }, mess = 0xFB02 }, - ffi = { name = "f_f_i", unicode = { 0x66, 0x66, 0x69 }, mess = 0xFB03 }, - ffl = { name = "f_f_l", unicode = { 0x66, 0x66, 0x6C }, mess = 0xFB04 }, - fj = { name = "f_j", unicode = { 0x66, 0x6A } }, - fk = { name = "f_k", unicode = { 0x66, 0x6B } }, -} - -for k, v in next, overloads do - local name = v.name - local mess = v.mess - if name then - overloads[name] = v - end - if mess then - overloads[mess] = v +do + + local overloads = allocate { + IJ = { name = "I_J", unicode = { 0x49, 0x4A }, mess = 0x0132 }, + ij = { name = "i_j", unicode = { 0x69, 0x6A }, mess = 0x0133 }, + ff = { name = "f_f", unicode = { 0x66, 0x66 }, mess = 0xFB00 }, + fi = { name = "f_i", unicode = { 0x66, 0x69 }, mess = 0xFB01 }, + fl = { name = "f_l", unicode = { 0x66, 0x6C }, mess = 0xFB02 }, + ffi = { name = "f_f_i", unicode = { 0x66, 0x66, 0x69 }, mess = 0xFB03 }, + ffl = { name = "f_f_l", unicode = { 0x66, 0x66, 0x6C }, mess = 0xFB04 }, + fj = { name = "f_j", unicode = { 0x66, 0x6A } }, + fk = { name = "f_k", unicode = { 0x66, 0x6B } }, + } + + local o = { } + + for k, v in next, overloads do + local name = v.name + local mess = v.mess + if name then + o[name] = v + end + if mess then + o[mess] = v + end + o[k] = v end -end -mappings.overloads = overloads + mappings.overloads = o + +end function mappings.addtounicode(data,filename,checklookups) local resources = data.resources local unicodes = resources.unicodes if not unicodes then + if trace_mapping then + report_fonts("no unicode list, quitting tounicode for %a",filename) + end return end local properties = data.properties local descriptions = data.descriptions + local overloads = mappings.overloads -- we need to move this code unicodes['space'] = unicodes['space'] or 32 unicodes['hyphen'] = unicodes['hyphen'] or 45 @@ -288,17 +329,25 @@ function mappings.addtounicode(data,filename,checklookups) local usedmap = cidinfo and fonts.cid.getmap(cidinfo) local uparser = makenameparser() -- hm, every time? if usedmap then - oparser = usedmap and makenameparser(cidinfo.ordering) - cidnames = usedmap.names - cidcodes = usedmap.unicodes + oparser = usedmap and makenameparser(cidinfo.ordering) + cidnames = usedmap.names + cidcodes = usedmap.unicodes end - local ns = 0 - local nl = 0 + local ns = 0 + local nl = 0 + -- + -- in order to avoid differences between runs due to hash randomization we + -- run over a sorted list -- - for du, glyph in next, descriptions do - local name = glyph.name + local dlist = sortedkeys(descriptions) + -- + -- for du, glyph in next, descriptions do + for i=1,#dlist do + local du = dlist[i] + local glyph = descriptions[du] + local name = glyph.name if name then - local overload = overloads[name] + local overload = overloads[name] or overloads[du] if overload then -- get rid of weird ligatures -- glyph.name = overload.name @@ -434,52 +483,71 @@ function mappings.addtounicode(data,filename,checklookups) end end end + else + local overload = overloads[du] + if overload then + glyph.unicode = overload.unicode + end end end if type(checklookups) == "function" then checklookups(data,missing,nofmissing) end - -- todo: go lowercase - - local collected = false local unicoded = 0 - for unicode, glyph in next, descriptions do - if glyph.class == "ligature" and (force_ligatures or not glyph.unicode) then - if not collected then - collected = fonts.handlers.otf.readers.getcomponents(data) - if not collected then - break - end + local collected = fonts.handlers.otf.readers.getcomponents(data) -- neglectable overhead + + local function resolve(glyph,u) + local n = #u + for i=1,n do + if u[i] > private then + n = 0 + break + end + end + if n > 0 then + if n > 1 then + glyph.unicode = u + else + glyph.unicode = u[1] end - local u = collected[unicode] -- always tables + unicoded = unicoded + 1 + end + end + + if not collected then + -- move on + elseif force_ligatures then + for i=1,#dlist do + local du = dlist[i] + local u = collected[du] -- always tables if u then - local n = #u - for i=1,n do - if u[i] > private then - n = 0 - break - end - end - if n > 0 then - if n > 1 then - glyph.unicode = u - else - glyph.unicode = u[1] - end - unicoded = unicoded + 1 + resolve(descriptions[du],u) + end + end + else + for i=1,#dlist do + local du = dlist[i] + local glyph = descriptions[du] + if glyph.class == "ligature" and not glyph.unicode then + local u = collected[du] -- always tables + if u then + resolve(glyph,u) end end end end + if trace_mapping and unicoded > 0 then report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded) end - if trace_mapping then - for unic, glyph in table.sortedhash(descriptions) do - local name = glyph.name - local index = glyph.index + -- for unic, glyph in sortedhash(descriptions) do + for i=1,#dlist do + local du = dlist[i] + local glyph = descriptions[du] + local name = glyph.name or "-" + local index = glyph.index or 0 local unicode = glyph.unicode if unicode then if type(unicode) == "table" then @@ -487,12 +555,12 @@ function mappings.addtounicode(data,filename,checklookups) for i=1,#unicode do unicodes[i] = formatters("%U",unicode[i]) end - report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,unic,unicodes) + report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes) else - report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,unic,unicode) + report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode) end else - report_fonts("internal slot %U, name %a, unicode %U",index,name,unic) + report_fonts("internal slot %U, name %a, unicode %U",index,name,du) end end end diff --git a/tex/context/base/mkiv/font-mat.mkvi b/tex/context/base/mkiv/font-mat.mkvi index 2e7c2080d..cbc78aca8 100644 --- a/tex/context/base/mkiv/font-mat.mkvi +++ b/tex/context/base/mkiv/font-mat.mkvi @@ -127,14 +127,16 @@ \settrue \c_font_auto_size \fi\fi} +\let\mathsizesuffix\empty + \def\font_helpers_set_math_family_indeed#mrtag#family% \fontface etc are also used later on {\let\savedfontbody\fontbody \let\fontfamily#family% % the order is important as we depend on known id's when completing fonts - \let\fontface\!!plusthree\font_helpers_set_math_family_a\scriptscriptfont#mrtag\font - \let\fontface\!!plustwo \font_helpers_set_math_family_a\scriptfont #mrtag\font - \let\fontface\!!plusone \font_helpers_set_math_family_a\textfont #mrtag\font - \let\fontface\!!zerocount + \let\mathsizesuffix\mathscriptscriptsuffix\let\fontface\!!plusthree\font_helpers_set_math_family_a\scriptscriptfont#mrtag\font + \let\mathsizesuffix\mathscriptsuffix \let\fontface\!!plustwo \font_helpers_set_math_family_a\scriptfont #mrtag\font + \let\mathsizesuffix\mathtextsuffix \let\fontface\!!plusone \font_helpers_set_math_family_a\textfont #mrtag\font + \let\mathsizesuffix\empty \let\fontface\!!zerocount \let\fontbody\savedfontbody \setfalse\c_font_auto_size} @@ -159,10 +161,10 @@ \let\defaultfontclass\fontclass % else truefontname falls back on the wrong one \let\savedfontbody\fontbody \let\fontfamily#familytag% - \let\fontface\!!plusthree\font_helpers_set_math_family_bold_a\scriptscriptfont#mbfam#mrfam% - \let\fontface\!!plustwo \font_helpers_set_math_family_bold_a\scriptfont #mbfam#mrfam% - \let\fontface\!!plusone \font_helpers_set_math_family_bold_a\textfont #mbfam#mrfam% - \let\fontface\!!zerocount + \let\mathsizesuffix\mathscriptscriptsuffix\let\fontface\!!plusthree\font_helpers_set_math_family_bold_a\scriptscriptfont#mbfam#mrfam% + \let\mathsizesuffix\mathscriptsuffix \let\fontface\!!plustwo \font_helpers_set_math_family_bold_a\scriptfont #mbfam#mrfam% + \let\mathsizesuffix\mathtextsuffix \let\fontface\!!plusone \font_helpers_set_math_family_bold_a\textfont #mbfam#mrfam% + \let\mathsizesuffix\empty \let\fontface\!!zerocount \let\fontbody\savedfontbody \let\defaultfontclass\savedfontclass \setfalse\c_font_auto_size} diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua index d359e2132..6d5c9fbf2 100644 --- a/tex/context/base/mkiv/font-mis.lua +++ b/tex/context/base/mkiv/font-mis.lua @@ -21,7 +21,7 @@ local readers = otf.readers if readers then - otf.version = otf.version or 3.020 + otf.version = otf.version or 3.029 otf.cache = otf.cache or containers.define("fonts", "otl", otf.version, true) function fonts.helpers.getfeatures(name,save) diff --git a/tex/context/base/mkiv/font-mps.lua b/tex/context/base/mkiv/font-mps.lua index 7b7c859df..69b2af68c 100644 --- a/tex/context/base/mkiv/font-mps.lua +++ b/tex/context/base/mkiv/font-mps.lua @@ -21,11 +21,9 @@ fonts = fonts or { } local metapost = fonts.metapost or { } fonts.metapost = metapost -local trace_skips = false trackers.register("metapost.outlines.skips",function(v) trace_skips = v end) - -local f_moveto = formatters["(%.4F,%.4F)"] -local f_lineto = formatters["--(%.4F,%.4F)"] -local f_curveto = formatters["..controls(%.4F,%.4F)and(%.4F,%.4F)..(%.4F,%.4F)"] +local f_moveto = formatters["(%F,%F)"] +local f_lineto = formatters["--(%F,%F)"] +local f_curveto = formatters["..controls(%F,%F)and(%F,%F)..(%F,%F)"] local s_cycle = "--cycle" local f_nofill = formatters["nofill %s;"] @@ -34,8 +32,8 @@ local f_dofill = formatters["fill %s;"] local f_draw_trace = formatters["drawpathonly %s;"] local f_draw = formatters["draw %s;"] -local f_boundingbox = formatters["((%.4F,%.4F)--(%.4F,%.4F)--(%.4F,%.4F)--(%.4F,%.4F)--cycle)"] -local f_vertical = formatters["((%.4F,%.4F)--(%.4F,%.4F))"] +local f_boundingbox = formatters["((%F,%F)--(%F,%F)--(%F,%F)--(%F,%F)--cycle)"] +local f_vertical = formatters["((%F,%F)--(%F,%F))"] function metapost.boundingbox(d,factor) local bounds = d.boundingbox @@ -238,39 +236,52 @@ function metapost.maxbounds(data,index,factor) ) end ------ formatters = string.formatters ------ concat = table.concat - -local nodecodes = nodes.nodecodes -- no nuts yet - -local glyph_code = nodecodes.glyph -local disc_code = nodecodes.disc -local kern_code = nodecodes.kern -local glue_code = nodecodes.glue -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local rule_code = nodecodes.rule -local penalty_code = nodecodes.penalty - -local find_tail = nodes.tail - ------ metapost = fonts.glyphs.metapost - -local characters = fonts.hashes.characters -local quaddata = fonts.hashes.emwidths -local shapes = fonts.hashes.shapes -local topaths = metapost.paths - -local f_code = formatters["mfun_do_outline_text_flush(%q,%i,%.4F,%.4F)(%,t);"] -local s_nothing = "(origin scaled 10)" -local f_trace_rule = formatters["draw rule(%6F,%6F,%6F) shifted (%6F,%6F) withcolor .5white;"] -local f_strut = formatters["strut(%6F,%6F);"] -local f_hrule = formatters["draw rule(%6F,%6F,%6F);"] -local f_vrule = formatters["draw rule(%6F,%6F,%6F) shifted (%6F,%6F);"] -local f_bounds = formatters["checkbounds(%6F,%6F,%6F,%6F);"] - -local sc = 10 -local fc = number.dimenfactors.bp * sc / 10 +-- This is a nice example of tex, metapost and lua working in tandem. Each kicks in at the +-- right time. It's probably why I like watching https://www.youtube.com/watch?v=c5FqpddnJmc +-- so much: precisely (and perfectly) timed too. + +local nodecodes = nodes.nodecodes -- no nuts yet + +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc +local kern_code = nodecodes.kern +local glue_code = nodecodes.glue +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local rule_code = nodecodes.rule + +local normal_rule = nodes.rulecodes.normal + +local nuts = nodes.nuts +local getnext = nuts.getnext +local getid = nuts.getid +local getlist = nuts.getlist +local getchar = nuts.getchar +local getfont = nuts.getfont +local getsubtype = nuts.getsubtype +local getfield = nuts.getfield +local getbox = nuts.getbox +local getwhd = nuts.getwhd +local getkern = nuts.getkern +local getshift = nuts.getshift +local getwidth = nuts.getwidth +local getheight = nuts.getheight +local getdepth = nuts.getdepth + +local effective_glue = nuts.effective_glue + +local characters = fonts.hashes.characters +local parameters = fonts.hashes.parameters +local shapes = fonts.hashes.shapes +local topaths = metapost.paths + +local f_code = formatters["mfun_do_outline_text_flush(%q,%i,%F,%F)(%,t);"] +local f_rule = formatters["mfun_do_outline_rule_flush(%q,%F,%F,%F,%F);"] +local f_bounds = formatters["checkbounds(%F,%F,%F,%F);"] +local s_nothing = "(origin scaled 10)" + +local sc = 10 +local fc = number.dimenfactors.bp * sc / 10 -- todo: make the next more efficient: @@ -284,8 +295,8 @@ function metapost.output(kind,font,char,advance,shift,ex) if glyphs then local glyf = glyphs[index] if glyf then - local units = shapedata.units or 1000 - local yfactor = sc/units + local units = 1000 -- factor already takes shapedata.units into account + local yfactor = (sc/units) * parameters[font].factor / 655.36 local xfactor = yfactor local shift = shift or 0 local advance = advance or 0 @@ -296,8 +307,12 @@ function metapost.output(kind,font,char,advance,shift,ex) xfactor = xfactor * wfactor end local paths = topaths(glyf,xfactor,yfactor) - local code = f_code(kind,#paths,advance,shift,paths) - return code, character.width * fc * wfactor + if paths then + local code = f_code(kind,#paths,advance,shift,paths) + return code, character.width * fc * wfactor + else + return "", 0 + end end end end @@ -317,131 +332,111 @@ function fonts.metapost.boxtomp(n,kind) local llx, lly, urx, ury = 0, 0, 0, 0 - local boxtomp + local horizontal, vertical - local function horizontal(current,shift,glue_sign,glue_set,glue_order,ht,dp) - shift = shift or 0 + horizontal = function(parent,current,xoffset,yoffset) + local dx = 0 while current do - local id = current.id + local id = getid(current) if id == glyph_code then - local code, width = metapost.output(kind,current.font,current.char,advance,-shift*fc,current.expansion_factor) + local code, width = metapost.output(kind,getfont(current),getchar(current),xoffset+dx,yoffset,getfield(current,"expansion_factor")) result[#result+1] = code - advance = advance + width + dx = dx + width elseif id == disc_code then - local replace = current.replace + local replace = getfield(current,"replace") if replace then - horizontal(replace,shift,glue_sign,glue_set,glue_order,ht,dp) + dx = dx + horizontal(parent,replace,xoffset+dx,yoffset) end elseif id == kern_code then - local kern = current.kern * fc - if trace_skips then - result[#result+1] = f_trace_rule(kern,0.8*ht*fc,0.8*dp*fc,advance,-shift*fc) - end - advance = advance + kern + dx = dx + getkern(current) * fc elseif id == glue_code then - local width = current.width - if glue_sign == 1 then - if current.stretch_order == glue_order then - width = (width + current.stretch * glue_set) * fc - else - width = width * fc - end - elseif glue_sign == 2 then - if current.shrink_order == glue_order then - width = (width - current.shrink * glue_set) * fc - else - width = width * fc - end - else - width = width * fc - end - if trace_skips then - result[#result+1] = f_trace_rule(width,0.1*ht*fc,0.1*dp*fc,advance,-shift*fc) - end - advance = advance + width + dx = dx + effective_glue(current,parent) * fc elseif id == hlist_code then - local a = advance - boxtomp(current,shift+current.shift,current.glue_sign,current.glue_set,current.glue_order) - advance = a + current.width * fc + local list = getlist(current) + if list then + horizontal(current,list,xoffset+dx,yoffset-getshift(current)*fc) + end + dx = dx + getwidth(current) * fc elseif id == vlist_code then - boxtomp(current) -- ,distance + shift,current.glue_set*current.glue_sign) - advance = advance + current.width * fc + local list = getlist(current) + if list then + vertical(current,list,xoffset+dx,yoffset-getshift(current)*fc) + end + dx = dx + getwidth(current) * fc elseif id == rule_code then - local wd = current.width - local ht = current.height - local dp = current.depth - if not (ht == signal or dp == signal or wd == signal) then - ht = ht - shift - dp = dp - shift - if wd == 0 then - result[#result+1] = f_strut(ht*fc,-dp*fc) - else - result[#result+1] = f_hrule(wd*fc,ht*fc,-dp*fc) + local wd, ht, dp = getwhd(current) + if wd ~= 0 then + wd = wd * fc + if ht == signal then + ht = getheight(parent) end - end - if wd ~= signal then - advance = advance + wd * fc + if dp == signal then + dp = getdepth(parent) + end + local hd = (ht + dp) * fc + if hd ~= 0 and getsubtype(current) == normal_rule then + result[#result+1] = f_rule(kind,xoffset+dx+wd/2,yoffset+hd/2,wd,hd) + end + dx = dx + wd end end - current = current.next + current = getnext(current) end + return dx end - local function vertical(current,shift) - shift = shift or 0 - current = find_tail(current) -- otherwise bad bbox + vertical = function(parent,current,xoffset,yoffset) + local dy = getheight(parent) * fc while current do - local id = current.id + local id = getid(current) if id == hlist_code then - distance = distance - current.depth - boxtomp(current,distance + shift,current.glue_set*current.glue_sign) - distance = distance - current.height + local _, ht, dp = getwhd(current) + dy = dy - ht * fc + local list = getlist(current) + if list then + horizontal(current,list,xoffset+getshift(current)*fc,yoffset+dy) + end + dy = dy - dp * fc elseif id == vlist_code then - print("vertical >>>") - vertical(current.list,0) + local wd, ht, dp = getwhd(current) + dy = dy - ht * fc + local list = getlist(current) + if list then + vertical(current,list,xoffset+getshift(current)*fc,yoffset+dy) + end + dy = dy - dp * fc elseif id == kern_code then - distance = distance - current.kern - advance = 0 + dy = dy - getkern(current) * fc elseif id == glue_code then - distance = distance - current.width - advance = 0 + dy = dy - effective_glue(current,parent) * fc elseif id == rule_code then - local wd = current.width - local ht = current.height - local dp = current.depth - if not (ht == signal or dp == signal or wd == signal) then - distance = distance - dp - if wd == 0 then - result[#result+1] = f_strut(ht*fc,-dp*fc) + local wd, ht, dp = getwhd(current) + local hd = (ht + dp) * fc + if hd ~= 0 then + if wd == signal then + wd = getwidth(parent) * fc else - result[#result+1] = f_vrule(wd*fc,ht*fc,-dp*fc,0,distance+shift) + wd = wd * fc end - distance = distance - ht + dy = dy - ht * fc + if wd ~= 0 and getsubtype(current) == 0 then + result[#result+1] = f_rule(kind,xoffset+wd/2,yoffset+dy+hd/2,wd,hd) + end + dy = dy - dp * fc end end - current = current.prev + current = getnext(current) end + return dy end - boxtomp = function(list,shift) - local current = list.list - if current then - if list.id == hlist_code then - horizontal(current,shift,list.glue_sign,list.glue_set,list.glue_order,list.height,list.depth) - else - vertical(current,shift) - end - end + local box = getbox(n) + local list = box and getlist(box) + if list then + (getid(box) == hlist_code and horizontal or vertical)(box,list,0,0) end - local box = tex.box[n] - - boxtomp(box,box.shift,box.glue_sign,box.glue_set,box.glue_order) - - local wd = box.width - local ht = box.height - local dp = box.depth - local sh = box.shift + local wd, ht, dp = getwhd(box) result[#result+1] = f_bounds(0,-dp*fc,wd*fc,ht*fc) diff --git a/tex/context/base/mkiv/font-nod.lua b/tex/context/base/mkiv/font-nod.lua index 7f30b6d5c..9166970b8 100644 --- a/tex/context/base/mkiv/font-nod.lua +++ b/tex/context/base/mkiv/font-nod.lua @@ -16,8 +16,6 @@ local utfchar = utf.char local concat, fastcopy = table.concat, table.fastcopy local match, rep = string.match, string.rep -local report_nodes = logs.reporter("fonts","tracing") - fonts = fonts or { } nodes = nodes or { } @@ -49,7 +47,6 @@ local vlist_code = nodecodes.vlist local disc_code = nodecodes.disc local glue_code = nodecodes.glue local kern_code = nodecodes.kern -local rule_code = nodecodes.rule local dir_code = nodecodes.dir local localpar_code = nodecodes.localpar @@ -66,7 +63,11 @@ local getsubtype = nuts.getsubtype local getchar = nuts.getchar local getlist = nuts.getlist local getdisc = nuts.getdisc +local getcomponents = nuts.getcomponents local isglyph = nuts.isglyph +local getkern = nuts.getkern +local getdir = nuts.getdir +local getwidth = nuts.getwidth local setfield = nuts.setfield local setbox = nuts.setbox @@ -75,7 +76,7 @@ local setsubtype = nuts.setsubtype local copy_node_list = nuts.copy_list local hpack_node_list = nuts.hpack -local free_node_list = nuts.flush_list +local flush_node_list = nuts.flush_list local traverse_nodes = nuts.traverse local traverse_id = nuts.traverse_id local protect_glyphs = nuts.protect_glyphs @@ -100,7 +101,6 @@ local properties = nodes.properties.data -- direct.set_properties_mode(true,true) -- default local function freeze(h,where) - -- report_nodes("freezing %s",where) for n in traverse_nodes(tonut(h)) do -- todo: disc but not traced anyway local p = properties[n] if p then @@ -274,7 +274,7 @@ function step_tracers.reset() for i=1,#collection do local c = collection[i] if c then - free_node_list(c) + flush_node_list(c) end end collection, messages = { }, { } @@ -392,7 +392,7 @@ function step_tracers.codes(i,command,space) if id == glyph_code then showchar(c) elseif id == dir_code or id == localpar_code then - context("[%s]",getfield(c,"dir")) + context("[%s]",getdir(c)) elseif id == disc_code then local pre, post, replace = getdisc(c) if pre or post or replace then @@ -439,7 +439,10 @@ function step_tracers.check(head) local n = copy_node_list(h) freeze(n,"check") injections.keepcounts(n) -- one-time - injections.handler(n,"trace") + local l = injections.handler(n,"trace") + if l then -- hm, can be false + n = tonut(l) + end protect_glyphs(n) collection[1] = n end @@ -453,7 +456,10 @@ function step_tracers.register(head) local n = copy_node_list(h) freeze(n,"register") injections.keepcounts(n) -- one-time - injections.handler(n,"trace") + local l = injections.handler(n,"trace") + if l then -- hm, can be false + n = tonut(l) + end protect_glyphs(n) collection[nc] = n end @@ -473,16 +479,16 @@ end -- -local threshold = 65536 +local threshold = 65536 -- 1pt -local function toutf(list,result,nofresult,stopcriterium) +local function toutf(list,result,nofresult,stopcriterium,nostrip) if list then for n in traverse_nodes(tonut(list)) do local c, id = isglyph(n) if c then - local components = getfield(n,"components") + local components = getcomponents(n) if components then - result, nofresult = toutf(components,result,nofresult) + result, nofresult = toutf(components,result,nofresult,false,true) elseif c > 0 then local fc = fontcharacters[getfont(n)] if fc then @@ -514,20 +520,20 @@ local function toutf(list,result,nofresult,stopcriterium) result[nofresult] = f_badcode(c) end elseif id == disc_code then - result, nofresult = toutf(getfield(n,"replace"),result,nofresult) -- needed? + result, nofresult = toutf(getfield(n,"replace"),result,nofresult,false,true) -- needed? elseif id == hlist_code or id == vlist_code then -- if nofresult > 0 and result[nofresult] ~= " " then -- nofresult = nofresult + 1 -- result[nofresult] = " " -- end - result, nofresult = toutf(getlist(n),result,nofresult) + result, nofresult = toutf(getlist(n),result,nofresult,false,true) elseif id == glue_code then - if nofresult > 0 and result[nofresult] ~= " " then + if nofresult > 0 and result[nofresult] ~= " " and getwidth(n) > threshold then nofresult = nofresult + 1 result[nofresult] = " " end - elseif id == kern_code and getfield(n,"kern") > threshold then - if nofresult > 0 and result[nofresult] ~= " " then + elseif id == kern_code then + if nofresult > 0 and result[nofresult] ~= " " and getkern(n) > threshold then nofresult = nofresult + 1 result[nofresult] = " " end @@ -537,7 +543,7 @@ local function toutf(list,result,nofresult,stopcriterium) end end end - if nofresult > 0 and result[nofresult] == " " then + if not nostrip and nofresult > 0 and result[nofresult] == " " then result[nofresult] = nil nofresult = nofresult - 1 end diff --git a/tex/context/base/mkiv/font-ocl.lua b/tex/context/base/mkiv/font-ocl.lua new file mode 100644 index 000000000..c166f5ce4 --- /dev/null +++ b/tex/context/base/mkiv/font-ocl.lua @@ -0,0 +1,586 @@ +if not modules then modules = { } end modules ['font-ocl'] = { + version = 1.001, + comment = "companion to font-otf.lua (context)", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo : user list of colors + +local tostring, next, format = tostring, next, string.format +local round, max = math.round, math.round +local sortedkeys, sortedhash = table.sortedkeys, table.sortedhash +local setmetatableindex = table.setmetatableindex + +local formatters = string.formatters +local tounicode = fonts.mappings.tounicode + +local otf = fonts.handlers.otf + +local f_color = formatters["pdf:direct:%f %f %f rg"] +local f_gray = formatters["pdf:direct:%f g"] + +if context then + + local startactualtext = nil + local stopactualtext = nil + + function otf.getactualtext(s) + if not startactualtext then + startactualtext = backends.codeinjections.startunicodetoactualtextdirect + stopactualtext = backends.codeinjections.stopunicodetoactualtextdirect + end + return startactualtext(s), stopactualtext() + end + +else + + local tounicode = fonts.mappings.tounicode16 + + function otf.getactualtext(s) + return + "/Span << /ActualText <feff" .. n .. "> >> BDC", + "EMC" + end + +end + +local sharedpalettes = { } + +local hash = setmetatableindex(function(t,k) + local v = { "special", k } + t[k] = v + return v +end) + +if context then + + local colors = attributes.list[attributes.private('color')] or { } + local transparencies = attributes.list[attributes.private('transparency')] or { } + + function otf.registerpalette(name,values) + sharedpalettes[name] = values + for i=1,#values do + local v = values[i] + local c = nil + local t = nil + if type(v) == "table" then + c = colors.register(name,"rgb", + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + ) + else + c = colors[v] + t = transparencies[v] + end + if c and t then + values[i] = hash["pdf:direct:" .. lpdf.color(1,c) .. " " .. lpdf.transparency(t)] + elseif c then + values[i] = hash["pdf:direct:" .. lpdf.color(1,c)] + elseif t then + values[i] = hash["pdf:direct:" .. lpdf.color(1,t)] + end + end + end + +else -- for generic + + function otf.registerpalette(name,values) + sharedpalettes[name] = values + for i=1,#values do + local v = values[i] + values[i] = hash[f_color( + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + )] + end + end + +end + +-- We need to force page first because otherwise the q's get outside +-- the font switch and as a consequence the next character has no font +-- set (well, it has: the preceding one). As a consequence these fonts +-- are somewhat inefficient as each glyph gets the font set. It's a +-- side effect of the fact that a font is handled when a character gets +-- flushed. + +local function convert(t,k) + local v = { } + for i=1,#k do + local p = k[i] + local r, g, b = p[1], p[2], p[3] + if r == g and g == b then + v[i] = hash[f_gray(r/255)] + else + v[i] = hash[f_color(r/255,g/255,b/255)] + end + end + t[k] = v + return v +end + +local function initializecolr(tfmdata,kind,value) -- hm, always value + if value then + local resources = tfmdata.resources + local palettes = resources.colorpalettes + if palettes then + -- + local converted = resources.converted + if not converted then + converted = setmetatableindex(convert) + resources.converted = converted + end + local colorvalues = sharedpalettes[value] or converted[palettes[tonumber(value) or 1] or palettes[1]] or { } + local classes = #colorvalues + if classes == 0 then + return + end + -- + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + local properties = tfmdata.properties + -- + properties.virtualized = true + tfmdata.fonts = { + { id = 0 } + } + local widths = setmetatableindex(function(t,k) + local v = { "right", -k } + t[k] = v + return v + end) + -- + local getactualtext = otf.getactualtext + local default = colorvalues[#colorvalues] + local b, e = getactualtext(tounicode(0xFFFD)) + local start = { "special", "pdf:page:q" } + local stop = { "special", "pdf:raw:Q" } + local actualb = { "special", "pdf:page:" .. b } -- saves tables + local actuale = { "special", "pdf:page:" .. e } -- saves tables + -- + local cache = setmetatableindex(function(t,k) + local v = { "char", k } + t[k] = v + return v + end) + -- + for unicode, character in next, characters do + local description = descriptions[unicode] + if description then + local colorlist = description.colors + if colorlist then + local u = description.unicode or characters[unicode].unicode + local w = character.width or 0 + local s = #colorlist + local goback = w ~= 0 and widths[w] or nil -- needs checking: are widths the same + local t = { + start, + not u and actualb or { "special", "pdf:raw:" .. getactualtext(tounicode(u)) } + } + local n = 2 + local l = nil + for i=1,s do + local entry = colorlist[i] + local v = colorvalues[entry.class] or default + if v and l ~= v then + n = n + 1 t[n] = v + l = v + end + n = n + 1 t[n] = cache[entry.slot] + if s > 1 and i < s and goback then + n = n + 1 t[n] = goback + end + end + n = n + 1 t[n] = actuale + n = n + 1 t[n] = stop + character.commands = t + end + end + end + end + end +end + +fonts.handlers.otf.features.register { + name = "colr", + description = "color glyphs", + manipulators = { + base = initializecolr, + node = initializecolr, + } +} + +do + + -- local f_setstream = formatters[ [[io.savedata("svg-glyph-%05i",%q)]] ] + -- local f_getstream = formatters[ [[svg-glyph-%05i]] ] + + -- function otfsvg.storepdfdata(pdf) + -- nofstreams = nofstreams + 1 + -- storepdfdata = function(pdf) + -- nofstreams = nofstreams + 1 + -- return f_setstream(nofstreams,pdf), f_getstream(nofstreams) + -- end + -- end + + local nofstreams = 0 + local f_name = formatters[ [[pdf-glyph-%05i]] ] + local f_used = context and formatters[ [[original:///%s]] ] or formatters[ [[%s]] ] + local hashed = { } + local cache = { } + + function otf.storepdfdata(pdf) + local done = hashed[pdf] + if not done then + nofstreams = nofstreams + 1 + local o, n = epdf.openMemStream(pdf,#pdf,f_name(nofstreams)) + cache[n] = o -- we need to keep in mem + done = f_used(n) + hashed[pdf] = done + end + return nil, done, nil + end + + -- maybe more efficient but much slower (and we hash already) + -- + -- if context then + -- + -- local storepdfdata = otf.storepdfdata + -- local initialized = false + -- + -- function otf.storepdfdata(pdf) + -- if not initialized then + -- if resolvers.setmemstream then + -- local f_setstream = formatters[ [[resolvers.setmemstream("pdf-glyph-%05i",%q,true)]] ] + -- local f_getstream = formatters[ [[memstream:///pdf-glyph-%05i]] ] + -- local f_nilstream = formatters[ [[resolvers.resetmemstream("pdf-glyph-%05i",true)]] ] + -- storepdfdata = function(pdf) + -- local done = hashed[pdf] + -- local set = nil + -- local reset = nil + -- if not done then + -- nofstreams = nofstreams + 1 + -- set = f_setstream(nofstreams,pdf) + -- done = f_getstream(nofstreams) + -- reset = f_nilstream(nofstreams) + -- hashed[pdf] = done + -- end + -- return set, done, reset + -- end + -- otf.storepdfdata = storepdfdata + -- end + -- initialized = true + -- end + -- return storepdfdata(pdf) + -- end + -- + -- end + +end + +local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = sbix|svg + if not tfmdata or not pdfshapes or not kind then + return + end + -- + local characters = tfmdata.characters + local properties = tfmdata.properties + local parameters = tfmdata.parameters + local hfactor = parameters.hfactor + -- + properties.virtualized = true + -- + tfmdata.fonts = { + { id = 0 } + } + -- + local getactualtext = otf.getactualtext + local storepdfdata = otf.storepdfdata + -- + -- local nop = { "nop" } + -- + for unicode, character in sortedhash(characters) do -- sort is nicer for svg + local index = character.index + if index then + local pdf = pdfshapes[index] + local typ = type(pdf) + local data = nil + local dx = nil + local dy = nil + if typ == "table" then + data = pdf.data + dx = pdf.dx or 0 + dy = pdf.dy or 0 + elseif typ == "string" then + data = pdf + dx = 0 + dy = 0 + end + if data then + local setcode, name, nilcode = storepdfdata(data) + if name then + local bt, et = getactualtext(unicode) + local wd = character.width or 0 + local ht = character.height or 0 + local dp = character.depth or 0 + character.commands = { + { "special", "pdf:direct:" .. bt }, + { "down", dp + dy * hfactor }, + { "right", dx * hfactor }, + -- setcode and { "lua", setcode } or nop, + { "image", { filename = name, width = wd, height = ht, depth = dp } }, + -- nilcode and { "lua", nilcode } or nop, + { "special", "pdf:direct:" .. et }, + } + character[kind] = true + end + end + end + end +end + +local otfsvg = otf.svg or { } +otf.svg = otfsvg +otf.svgenabled = true + +do + + local report_svg = logs.reporter("fonts","svg conversion") + + local loaddata = io.loaddata + local savedata = io.savedata + local remove = os.remove + + if context and xml.convert then + + local xmlconvert = xml.convert + local xmlfirst = xml.first + + function otfsvg.filterglyph(entry,index) + local svg = xmlconvert(entry.data) + local root = svg and xmlfirst(svg,"/svg[@id='glyph"..index.."']") + local data = root and tostring(root) + -- report_svg("data for glyph %04X: %s",index,data) + return data + end + + else + + function otfsvg.filterglyph(entry,index) -- can be overloaded + return entry.data + end + + end + + local runner = sandbox and sandbox.registerrunner { + name = "otfsvg", + program = "inkscape", + method = "pipeto", + template = "--shell > temp-otf-svg-shape.log", + reporter = report_svg, + } + + if not runner then + -- + -- poor mans variant for generic: + -- + runner = function() + return io.open("inkscape --shell > temp-otf-svg-shape.log","w") + end + end + + function otfsvg.topdf(svgshapes) + local pdfshapes = { } + local inkscape = runner() + if inkscape then + local nofshapes = #svgshapes + local f_svgfile = formatters["temp-otf-svg-shape-%i.svg"] + local f_pdffile = formatters["temp-otf-svg-shape-%i.pdf"] + local f_convert = formatters["%s --export-pdf=%s\n"] + local filterglyph = otfsvg.filterglyph + local nofdone = 0 + report_svg("processing %i svg containers",nofshapes) + statistics.starttiming() + for i=1,nofshapes do + local entry = svgshapes[i] + for index=entry.first,entry.last do + local data = filterglyph(entry,index) + if data and data ~= "" then + local svgfile = f_svgfile(index) + local pdffile = f_pdffile(index) + savedata(svgfile,data) + inkscape:write(f_convert(svgfile,pdffile)) + pdfshapes[index] = true + nofdone = nofdone + 1 + if nofdone % 100 == 0 then + report_svg("%i shapes processed",nofdone) + end + end + end + end + inkscape:write("quit\n") + inkscape:close() + report_svg("processing %i pdf results",nofshapes) + for index in next, pdfshapes do + local svgfile = f_svgfile(index) + local pdffile = f_pdffile(index) + pdfshapes[index] = loaddata(pdffile) + remove(svgfile) + remove(pdffile) + end + statistics.stoptiming() + if statistics.elapsedseconds then + report_svg("svg conversion time %s",statistics.elapsedseconds() or "-") + end + end + return pdfshapes + end + +end + +local function initializesvg(tfmdata,kind,value) -- hm, always value + if value and otf.svgenabled then + local svg = tfmdata.properties.svg + local hash = svg and svg.hash + local timestamp = svg and svg.timestamp + if not hash then + return + end + local pdffile = containers.read(otf.pdfcache,hash) + local pdfshapes = pdffile and pdffile.pdfshapes + if not pdfshapes or pdffile.timestamp ~= timestamp then + local svgfile = containers.read(otf.svgcache,hash) + local svgshapes = svgfile and svgfile.svgshapes + pdfshapes = svgshapes and otfsvg.topdf(svgshapes) or { } + containers.write(otf.pdfcache, hash, { + pdfshapes = pdfshapes, + timestamp = timestamp, + }) + end + pdftovirtual(tfmdata,pdfshapes,"svg") + end +end + +fonts.handlers.otf.features.register { + name = "svg", + description = "svg glyphs", + manipulators = { + base = initializesvg, + node = initializesvg, + } +} + +-- This can be done differently e.g. with ffi and gm and we can share code anway. Using +-- batchmode in gm is not faster and as it accumulates we would need to flush all +-- individual shapes. + +local otfsbix = otf.sbix or { } +otf.sbix = otfsbix +otf.sbixenabled = true + +do + + -- for now png but also other bitmap formats + + local report_sbix = logs.reporter("fonts","sbix conversion") + + local loaddata = io.loaddata + local savedata = io.savedata + local remove = os.remove + + local runner = sandbox and sandbox.registerrunner { + name = "otfsbix", + program = "gm", + template = "convert -quality 100 temp-otf-sbix-shape.sbix temp-otf-sbix-shape.pdf > temp-otf-svg-shape.log", + -- reporter = report_sbix, + } + + if not runner then + -- + -- poor mans variant for generic: + -- + runner = function() + return os.execute("gm convert -quality 100 temp-otf-sbix-shape.sbix temp-otf-sbix-shape.pdf > temp-otf-svg-shape.log") + end + end + + -- Alternatively we can create a single pdf file with -adjoin and then pick up pages from + -- that file but creating thousands of small files is no fun either. + + function otfsbix.topdf(sbixshapes) + local pdfshapes = { } + local sbixfile = "temp-otf-sbix-shape.sbix" + local pdffile = "temp-otf-sbix-shape.pdf" + local nofdone = 0 + local indices = sortedkeys(sbixshapes) -- can be sparse + local nofindices = #indices + report_sbix("processing %i sbix containers",nofindices) + statistics.starttiming() + for i=1,nofindices do + local index = indices[i] + local entry = sbixshapes[index] + local data = entry.data + local x = entry.x + local y = entry.y + savedata(sbixfile,data) + runner() + pdfshapes[index] = { + x = x ~= 0 and x or nil, + y = y ~= 0 and y or nil, + data = loaddata(pdffile), + } + nofdone = nofdone + 1 + if nofdone % 100 == 0 then + report_sbix("%i shapes processed",nofdone) + end + end + report_sbix("processing %i pdf results",nofindices) + remove(sbixfile) + remove(pdffile) + statistics.stoptiming() + if statistics.elapsedseconds then + report_sbix("sbix conversion time %s",statistics.elapsedseconds() or "-") + end + return pdfshapes + -- end + end + +end + +local function initializesbix(tfmdata,kind,value) -- hm, always value + if value and otf.sbixenabled then + local sbix = tfmdata.properties.sbix + local hash = sbix and sbix.hash + local timestamp = sbix and sbix.timestamp + if not hash then + return + end + local pdffile = containers.read(otf.pdfcache,hash) + local pdfshapes = pdffile and pdffile.pdfshapes + if not pdfshapes or pdffile.timestamp ~= timestamp then + local sbixfile = containers.read(otf.sbixcache,hash) + local sbixshapes = sbixfile and sbixfile.sbixshapes + pdfshapes = sbixshapes and otfsbix.topdf(sbixshapes) or { } + containers.write(otf.pdfcache, hash, { + pdfshapes = pdfshapes, + timestamp = timestamp, + }) + end + -- + pdftovirtual(tfmdata,pdfshapes,"sbix") + end +end + +fonts.handlers.otf.features.register { + name = "sbix", + description = "sbix glyphs", + manipulators = { + base = initializesbix, + node = initializesbix, + } +} + diff --git a/tex/context/base/mkiv/font-odv.lua b/tex/context/base/mkiv/font-odv.lua index 6b9a5a9e4..345b17a52 100644 --- a/tex/context/base/mkiv/font-odv.lua +++ b/tex/context/base/mkiv/font-odv.lua @@ -105,7 +105,7 @@ local glyph_code = nodecodes.glyph local handlers = otf.handlers local methods = fonts.analyzers.methods -local otffeatures = fonts.constructors.newfeatures("otf") +local otffeatures = fonts.constructors.features.otf local registerotffeature = otffeatures.register local nuts = nodes.nuts @@ -126,9 +126,9 @@ local setprop = nuts.setprop local insert_node_after = nuts.insert_after local copy_node = nuts.copy -local free_node = nuts.free local remove_node = nuts.remove local flush_list = nuts.flush_list +local flush_node = nuts.flush_node local copyinjection = nodes.injections.copy -- KE: is this necessary? HH: probably not as positioning comes later and we rawget/set @@ -693,7 +693,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) if current == stop then stop = getprev(stop) head = remove_node(head,current) - free_node(current) + flush_node(current) return head, stop, nbspaces else nbspaces = nbspaces + 1 @@ -714,9 +714,9 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) local tmp = next and getnext(next) or nil -- needs checking local changestop = next == stop local tempcurrent = copy_node(next) - copyinjection(tempcurrent,next) + copyinjection(tempcurrent,next) local nextcurrent = copy_node(current) - copyinjection(nextcurrent,current) -- KE: necessary? HH: probably not as positioning comes later and we rawget/set + copyinjection(nextcurrent,current) -- KE: necessary? HH: probably not as positioning comes later and we rawget/set setnext(tempcurrent,nextcurrent) setprev(nextcurrent,tempcurrent) setprop(tempcurrent,a_state,s_blwf) @@ -725,7 +725,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) if getchar(next) == getchar(tempcurrent) then flush_list(tempcurrent) local n = copy_node(current) - copyinjection(n,current) -- KE: necessary? HH: probably not as positioning comes later and we rawget/set + copyinjection(n,current) -- KE: necessary? HH: probably not as positioning comes later and we rawget/set setchar(current,dotted_circle) head = insert_node_after(head, current, n) else @@ -735,7 +735,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) if tmp then setprev(tmp,current) end - free_node(freenode) + flush_node(freenode) flush_list(tempcurrent) if changestop then stop = current @@ -1018,7 +1018,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) if getchar(base) == c_nbsp then nbspaces = nbspaces - 1 head = remove_node(head,base) - free_node(base) + flush_node(base) end return head, stop, nbspaces @@ -1269,7 +1269,7 @@ function handlers.devanagari_remove_joiners(head,start,kind,lookupname,replaceme setnext(prev,stop) end if head == start then - head = stop + head = stop end flush_list(start) return head, stop, true @@ -1548,7 +1548,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa if current == stop then stop = getprev(stop) head = remove_node(head,current) - free_node(current) + flush_node(current) return head, stop, nbspaces else nbspaces = nbspaces + 1 @@ -1578,7 +1578,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa if halant[getchar(current)] then setnext(getnext(current),tmp) local nc = copy_node(current) - copyinjection(nc,current) + copyinjection(nc,current) setchar(current,dotted_circle) head = insert_node_after(head,current,nc) else @@ -1642,17 +1642,17 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa local last = getnext(stop) while current ~= last do local char, target, cn = locl[current] or getchar(current), nil, getnext(current) --- not so efficient (needed for malayalam) -local tpm = twopart_mark[char] -if tpm then - local extra = copy_node(current) - copyinjection(extra,current) - char = tpm[1] - setchar(current,char) - setchar(extra,tpm[2]) - head = insert_node_after(head,current,extra) -end --- + -- not so efficient (needed for malayalam) + local tpm = twopart_mark[char] + if tpm then + local extra = copy_node(current) + copyinjection(extra,current) + char = tpm[1] + setchar(current,char) + setchar(extra,tpm[2]) + head = insert_node_after(head,current,extra) + end + -- if not moved[current] and dependent_vowel[char] then if pre_mark[char] then -- Before first half form in the syllable moved[current] = true @@ -1767,7 +1767,7 @@ end if getchar(base) == c_nbsp then nbspaces = nbspaces - 1 head = remove_node(head, base) - free_node(base) + flush_node(base) end return head, stop, nbspaces @@ -2081,7 +2081,7 @@ end local function inject_syntax_error(head,current,mark) local signal = copy_node(current) - copyinjection(signal,current) + copyinjection(signal,current) if mark == pre_mark then setchar(signal,dotted_circle) else @@ -2127,8 +2127,8 @@ function methods.deva(head,font,attr) end if standalone then -- stand alone cluster (at the start of the word only): #[Ra+H]+NBSP+[N]+[<[<ZWJ|ZWNJ>]+H+C>]+[{M}+[N]+[H]]+[SM]+[(VD)] - local syllableend = analyze_next_chars_one(c,font,2) - current = getnext(syllableend) + local syllableend = analyze_next_chars_one(c,font,2) + current = getnext(syllableend) if syllablestart ~= syllableend then head, current, nbspaces = deva_reorder(head,syllablestart,syllableend,font,attr,nbspaces) current = getnext(current) diff --git a/tex/context/base/mkiv/font-off.lua b/tex/context/base/mkiv/font-off.lua index 82426552e..b8fadb634 100644 --- a/tex/context/base/mkiv/font-off.lua +++ b/tex/context/base/mkiv/font-off.lua @@ -11,11 +11,11 @@ local round = math.round local setmetatableindex = table.setmetatableindex local fontloader = fontloader -local font_to_table = fontloader.to_table +----- font_to_table = fontloader.to_table local open_font = fontloader.open -local get_font_info = fontloader.info +----- get_font_info = fontloader.info local close_font = fontloader.close -local font_fields = fontloader.fields +----- font_fields = fontloader.fields -- table={ -- ["familyname"]="TeXGyrePagella", diff --git a/tex/context/base/mkiv/font-one.lua b/tex/context/base/mkiv/font-one.lua index a9f78f4fb..d9b9c65df 100644 --- a/tex/context/base/mkiv/font-one.lua +++ b/tex/context/base/mkiv/font-one.lua @@ -29,42 +29,45 @@ local bxor, rshift = bit32.bxor, bit32.rshift local P, S, R, Cmt, C, Ct, Cs, Carg = lpeg.P, lpeg.S, lpeg.R, lpeg.Cmt, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg local lpegmatch, patterns = lpeg.match, lpeg.patterns -local trace_features = false trackers.register("afm.features", function(v) trace_features = v end) -local trace_indexing = false trackers.register("afm.indexing", function(v) trace_indexing = v end) -local trace_loading = false trackers.register("afm.loading", function(v) trace_loading = v end) -local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) +local trace_features = false trackers.register("afm.features", function(v) trace_features = v end) +local trace_indexing = false trackers.register("afm.indexing", function(v) trace_indexing = v end) +local trace_loading = false trackers.register("afm.loading", function(v) trace_loading = v end) +local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) -local report_afm = logs.reporter("fonts","afm loading") +local report_afm = logs.reporter("fonts","afm loading") -local setmetatableindex = table.setmetatableindex -local derivetable = table.derive +local setmetatableindex = table.setmetatableindex +local derivetable = table.derive -local findbinfile = resolvers.findbinfile +local findbinfile = resolvers.findbinfile -local definers = fonts.definers -local readers = fonts.readers -local constructors = fonts.constructors +local definers = fonts.definers +local readers = fonts.readers +local constructors = fonts.constructors -local afm = constructors.newhandler("afm") -local pfb = constructors.newhandler("pfb") -local otf = fonts.handlers.otf +local afm = constructors.handlers.afm +local pfb = constructors.handlers.pfb +local otf = fonts.handlers.otf -local otfreaders = otf.readers -local otfenhancers = otf.enhancers +local otfreaders = otf.readers +local otfenhancers = otf.enhancers -local afmfeatures = constructors.newfeatures("afm") -local registerafmfeature = afmfeatures.register +local afmfeatures = constructors.features.afm +local registerafmfeature = afmfeatures.register -afm.version = 1.512 -- incrementing this number one up will force a re-cache -afm.cache = containers.define("fonts", "afm", afm.version, true) -afm.autoprefixed = true -- this will become false some day (catches texnansi-blabla.*) +local afmenhancers = constructors.enhancers.afm +local registerafmenhancer = afmenhancers.register -afm.helpdata = { } -- set later on so no local for this -afm.syncspace = true -- when true, nicer stretch values +afm.version = 1.512 -- incrementing this number one up will force a re-cache +afm.cache = containers.define("fonts", "one", afm.version, true) +afm.autoprefixed = true -- this will become false some day (catches texnansi-blabla.*) -local overloads = fonts.mappings.overloads +afm.helpdata = { } -- set later on so no local for this +afm.syncspace = true -- when true, nicer stretch values -local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes +local overloads = fonts.mappings.overloads + +local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes --[[ldx-- <p>We cache files. Caching is taken care of in the loader. We cheat a bit by adding @@ -76,35 +79,6 @@ fashion and later we transform it to sequences. Then we apply some methods also used in opentype fonts (like <t>tlig</t>).</p> --ldx]]-- -local enhancers = { - -- It's cleaner to implement them after we've seen what we are - -- dealing with. -} - -local steps = { - "unify names", - "add ligatures", - "add extra kerns", - "normalize features", - "fix names", --- "add tounicode data", -} - -local function applyenhancers(data,filename) - for i=1,#steps do - local step = steps[i] - local enhancer = enhancers[step] - if enhancer then - if trace_loading then - report_afm("applying enhancer %a",step) - end - enhancer(data,filename) - else - report_afm("invalid enhancer %a",step) - end - end -end - function afm.load(filename) filename = resolvers.findfile(filename,'afm') or "" if filename ~= "" and not fonts.names.ignoredfile(filename) then @@ -128,7 +102,7 @@ function afm.load(filename) report_afm("reading %a",filename) data = afm.readers.loadfont(filename,pfbname) if data then - applyenhancers(data,filename) + afmenhancers.apply(data,filename) -- otfreaders.addunicodetable(data) -- only when not done yet fonts.mappings.addtounicode(data,filename) -- otfreaders.extend(data) @@ -161,7 +135,7 @@ end local uparser = fonts.mappings.makenameparser() -- each time -enhancers["unify names"] = function(data, filename) +local function enhance_unify_names(data, filename) local unicodevector = fonts.encodings.agl.unicodes -- loaded runtime in context local unicodes = { } local names = { } @@ -217,7 +191,7 @@ end local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } } local noflags = { false, false, false, false } -enhancers["normalize features"] = function(data) +local function enhance_normalize_features(data) local ligatures = setmetatableindex("table") local kerns = setmetatableindex("table") local extrakerns = setmetatableindex("table") @@ -318,7 +292,7 @@ enhancers["normalize features"] = function(data) data.resources.sequences = sequences end -enhancers["fix names"] = function(data) +local function enhance_fix_names(data) for k, v in next, data.descriptions do local n = v.name local r = overloads[n] @@ -365,14 +339,10 @@ local addthem = function(rawdata,ligatures) end end -enhancers["add ligatures"] = function(rawdata) +local function enhance_add_ligatures(rawdata) addthem(rawdata,afm.helpdata.ligatures) end --- enhancers["add tex ligatures"] = function(rawdata) --- addthem(rawdata,afm.helpdata.texligatures) --- end - --[[ldx-- <p>We keep the extra kerns in separate kerning tables so that we can use them selectively.</p> @@ -385,7 +355,7 @@ them selectively.</p> -- we don't use the character database. (Ok, we can have a context specific -- variant). -enhancers["add extra kerns"] = function(rawdata) -- using shcodes is not robust here +local function enhance_add_extra_kerns(rawdata) -- using shcodes is not robust here local descriptions = rawdata.descriptions local resources = rawdata.resources local unicodes = resources.unicodes @@ -752,18 +722,12 @@ end <p>We have the usual two modes and related features initializers and processors.</p> --ldx]]-- -local function setmode(tfmdata,value) - if value then - tfmdata.properties.mode = lower(value) - end -end - registerafmfeature { name = "mode", description = "mode", initializers = { - base = setmode, - node = setmode, + base = otf.modeinitializer, + node = otf.modeinitializer, } } @@ -782,8 +746,6 @@ registerafmfeature { -- readers -local check_tfm = readers.check_tfm - fonts.formats.afm = "type1" fonts.formats.pfb = "type1" @@ -820,7 +782,8 @@ function readers.afm(specification,method) tfmdata = check_afm(specification,specification.name .. "." .. forced) end if not tfmdata then - method = method or definers.method or "afm or tfm" + local check_tfm = readers.check_tfm + method = (check_tfm and (method or definers.method or "afm or tfm")) or "afm" if method == "tfm" then tfmdata = check_tfm(specification,specification.name) elseif method == "afm" then @@ -855,3 +818,12 @@ function readers.pfb(specification,method) -- only called when forced swap("specification") return readers.afm(specification,method) end + +-- now we register them + +registerafmenhancer("unify names", enhance_unify_names) +registerafmenhancer("add ligatures", enhance_add_ligatures) +registerafmenhancer("add extra kerns", enhance_add_extra_kerns) +registerafmenhancer("normalize features", enhance_normalize_features) +registerafmenhancer("check extra features", otfenhancers.enhance) +registerafmenhancer("fix names", enhance_fix_names) diff --git a/tex/context/base/mkiv/font-onr.lua b/tex/context/base/mkiv/font-onr.lua index a4969ad73..85d3604b7 100644 --- a/tex/context/base/mkiv/font-onr.lua +++ b/tex/context/base/mkiv/font-onr.lua @@ -21,23 +21,21 @@ add features.</p> local fonts, logs, trackers, resolvers = fonts, logs, trackers, resolvers -local next, type, tonumber, rawget = next, type, tonumber, rawget +local next, type, tonumber, rawget, rawset = next, type, tonumber, rawget, rawset local match, lower, gsub, strip, find = string.match, string.lower, string.gsub, string.strip, string.find local char, byte, sub = string.char, string.byte, string.sub local abs = math.abs local bxor, rshift = bit32.bxor, bit32.rshift -local P, S, R, Cmt, C, Ct, Cs, Carg = lpeg.P, lpeg.S, lpeg.R, lpeg.Cmt, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg +local P, S, R, Cmt, C, Ct, Cs, Carg, Cf, Cg = lpeg.P, lpeg.S, lpeg.R, lpeg.Cmt, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg, lpeg.Cf, lpeg.Cg local lpegmatch, patterns = lpeg.match, lpeg.patterns local trace_indexing = false trackers.register("afm.indexing", function(v) trace_indexing = v end) local trace_loading = false trackers.register("afm.loading", function(v) trace_loading = v end) local report_afm = logs.reporter("fonts","afm loading") -local report_afm = logs.reporter("fonts","pfb loading") +local report_pfb = logs.reporter("fonts","pfb loading") -fonts = fonts or { } -local handlers = fonts.handlers or { } -fonts.handlers = handlers +local handlers = fonts.handlers local afm = handlers.afm or { } handlers.afm = afm local readers = afm.readers or { } @@ -52,42 +50,10 @@ and <l n='otf'/> reader.</p> and new vectors (we actually had one bad vector with the old loader).</p> --ldx]]-- -local get_indexes +local get_indexes, get_shapes do - local n, m - - local progress = function(str,position,name,size) - local forward = position + tonumber(size) + 3 + 2 - n = n + 1 - if n >= m then - return #str, name - elseif forward < #str then - return forward, name - else - return #str, name - end - end - - local initialize = function(str,position,size) - n = 0 - m = tonumber(size) - return position + 1 - end - - local charstrings = P("/CharStrings") - local name = P("/") * C((R("az")+R("AZ")+R("09")+S("-_."))^1) - local size = C(R("09")^1) - local spaces = P(" ")^1 - - local p_filternames = Ct ( - (1-charstrings)^0 * charstrings * spaces * Cmt(size,initialize) - * (Cmt(name * P(" ")^1 * C(R("09")^1), progress) + P(1))^1 - ) - - -- if one of first 4 not 0-9A-F then binary else hex - local decrypt do @@ -101,23 +67,107 @@ do return char(plain) end - decrypt = function(binary) - r, c1, c2, n = 55665, 52845, 22719, 4 + decrypt = function(binary,initial,seed) + r, c1, c2, n = initial, 52845, 22719, seed binary = gsub(binary,".",step) return sub(binary,n+1) end -- local pattern = Cs((P(1) / step)^1) -- - -- decrypt = function(binary) - -- r, c1, c2, n = 55665, 52845, 22719, 4 + -- decrypt = function(binary,initial,seed) + -- r, c1, c2, n = initial, 52845, 22719, seed -- binary = lpegmatch(pattern,binary) -- return sub(binary,n+1) -- end end - local function loadpfbvector(filename) + local charstrings = P("/CharStrings") + local subroutines = P("/Subrs") + local encoding = P("/Encoding") + local dup = P("dup") + local put = P("put") + local array = P("array") + local name = P("/") * C((R("az")+R("AZ")+R("09")+S("-_."))^1) + local digits = R("09")^1 + local cardinal = digits / tonumber + local spaces = P(" ")^1 + local spacing = patterns.whitespace^0 + + local routines, vector, chars, n, m + + local initialize = function(str,position,size) + n = 0 + m = size -- % tonumber(size) + return position + 1 + end + + local setroutine = function(str,position,index,size) + local forward = position + tonumber(size) + local stream = decrypt(sub(str,position+1,forward),4330,4) + routines[index] = { byte(stream,1,#stream) } + return forward + end + + local setvector = function(str,position,name,size) + local forward = position + tonumber(size) + if n >= m then + return #str + elseif forward < #str then + vector[n] = name + n = n + 1 -- we compensate for notdef at the cff loader end + return forward + else + return #str + end + end + + local setshapes = function(str,position,name,size) + local forward = position + tonumber(size) + local stream = sub(str,position+1,forward) + if n > m then + return #str + elseif forward < #str then + vector[n] = name + n = n + 1 + chars [n] = decrypt(stream,4330,4) + return forward + else + return #str + end + end + + local p_rd = spacing * (P("RD") + P("-|")) + local p_np = spacing * (P("NP") + P( "|")) + local p_nd = spacing * (P("ND") + P( "|")) + + local p_filterroutines = -- dup <i> <n> RD or -| <n encrypted bytes> NP or | + (1-subroutines)^0 * subroutines * spaces * Cmt(cardinal,initialize) + * (Cmt(cardinal * spaces * cardinal * p_rd, setroutine) * p_np + P(1))^1 + + local p_filtershapes = -- /foo <n> RD <n encrypted bytes> ND + (1-charstrings)^0 * charstrings * spaces * Cmt(cardinal,initialize) + * (Cmt(name * spaces * cardinal * p_rd, setshapes) * p_nd + P(1))^1 + + local p_filternames = Ct ( + (1-charstrings)^0 * charstrings * spaces * Cmt(cardinal,initialize) + * (Cmt(name * spaces * cardinal, setvector) + P(1))^1 + ) + + -- /Encoding 256 array + -- 0 1 255 {1 index exch /.notdef put} for + -- dup 0 /Foo put + + local p_filterencoding = + (1-encoding)^0 * encoding * spaces * digits * spaces * array * (1-dup)^0 + * Cf( + Ct("") * Cg(spacing * dup * spaces * cardinal * spaces * name * spaces * put)^1 + ,rawset) + + -- if one of first 4 not 0-9A-F then binary else hex + + local function loadpfbvector(filename,shapestoo) -- for the moment limited to encoding only local data = io.loaddata(resolvers.findfile(filename)) @@ -139,24 +189,43 @@ do return end - binary = decrypt(binary,4) - - local vector = lpegmatch(p_filternames,binary) - - if vector[1] == ".notdef" then - -- tricky - vector[0] = table.remove(vector,1) + binary = decrypt(binary,55665,4) + + local names = { } + local encoding = lpegmatch(p_filterencoding,ascii) + local glyphs = { } + + routines, vector, chars = { }, { }, { } + + if shapestoo then + lpegmatch(p_filterroutines,binary) + lpegmatch(p_filtershapes,binary) + local data = { + dictionaries = { + { + charstrings = chars, + charset = vector, + subroutines = routines, + } + }, + } + fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,true) + else + lpegmatch(p_filternames,binary) end - if not vector then - report_pfb("no vector in %a",filename) - return - end + names = vector + + routines, vector, chars = nil, nil, nil - return vector + return names, encoding, glyphs end + local pfb = handlers.pfb or { } + handlers.pfb = pfb + pfb.loadvector = loadpfbvector + get_indexes = function(data,pfbname) local vector = loadpfbvector(pfbname) if vector then @@ -177,6 +246,11 @@ do end end + get_shapes = function(pfbname) + local vector, encoding, glyphs = loadpfbvector(pfbname,true) + return glyphs + end + end --[[ldx-- @@ -389,20 +463,40 @@ function readers.loadfont(afmname,pfbname) local data = read(resolvers.findfile(afmname),fullparser) if data then if not pfbname or pfbname == "" then - pfbname = file.replacesuffix(file.nameonly(afmname),"pfb") - pfbname = resolvers.findfile(pfbname) + pfbname = resolvers.findfile(file.replacesuffix(file.nameonly(afmname),"pfb")) end if pfbname and pfbname ~= "" then data.resources.filename = resolvers.unresolve(pfbname) get_indexes(data,pfbname) - elseif trace_loading then + return data + else -- if trace_loading then report_afm("no pfb file for %a",afmname) - -- data.resources.filename = "unset" -- better than loading the afm file + -- better than loading the afm file: data.resources.filename = rawname + -- but that will still crash the backend so we just return nothing now end - return data end end +-- for now, todo: n and check with otf (no afm needed here) + +function readers.loadshapes(filename) + local fullname = resolvers.findfile(filename) or "" + if fullname == "" then + return { + filename = "not found: " .. filename, + glyphs = { } + } + else + return { + filename = fullname, + format = "opentype", + glyphs = get_shapes(fullname) or { }, + units = 1000, + } + end +end + + function readers.getinfo(filename) local data = read(resolvers.findfile(filename),infoparser) if data then diff --git a/tex/context/base/mkiv/font-osd.lua b/tex/context/base/mkiv/font-osd.lua index 6ff2e38b6..ca20f6782 100644 --- a/tex/context/base/mkiv/font-osd.lua +++ b/tex/context/base/mkiv/font-osd.lua @@ -79,13 +79,10 @@ fonts.analyzers.methods = fonts.analyzers.methods or { node = { otf = { } } } local otf = fonts.handlers.otf -local nodecodes = nodes.nodecodes -local glyph_code = nodecodes.glyph - local handlers = otf.handlers local methods = fonts.analyzers.methods -local otffeatures = fonts.constructors.newfeatures("otf") +local otffeatures = fonts.constructors.features.otf local registerotffeature = otffeatures.register local nuts = nodes.nuts @@ -110,9 +107,9 @@ local ischar = nuts.is_char local insert_node_after = nuts.insert_after local copy_node = nuts.copy -local free_node = nuts.free local remove_node = nuts.remove local flush_list = nuts.flush_list +local flush_node = nuts.flush_node local copyinjection = nodes.injections.copy -- KE: is this necessary? HH: probably not as positioning comes later and we rawget/set @@ -616,13 +613,12 @@ local function initializedevanagi(tfmdata) local steps = sequence.steps local nofsteps = sequence.nofsteps local features = sequence.features - if features["rphf"] then - -- deva + local has_rphf = features.rphf + local has_blwf = features.blwf + if has_rphf and has_rphf.deva then devanagari.reph = true - elseif features["blwf"] then - -- deva + elseif has_blwf and has_blwf.deva then devanagari.vattu = true - -- dev2 for i=1,nofsteps do local step = steps[i] local coverage = step.coverage @@ -635,59 +631,71 @@ local function initializedevanagi(tfmdata) end end end - if valid[kind] then - for i=1,nofsteps do - local step = steps[i] - local coverage = step.coverage - if coverage then - local reph = false - if step.osdstep then - -- rphf acts on consonant + halant - for k, v in next, ra do - local r = coverage[k] - if r then - local h = false - for k, v in next, halant do - local h = r[k] - if h then - reph = h.ligature or false - break + for kind, spec in next, features do -- beware, this is + if spec.dev2 and valid[kind] then + for i=1,nofsteps do + local step = steps[i] + local coverage = step.coverage + if coverage then + local reph = false + if kind == "rphf" then + -- + -- KE: I don't understand the rationale behind osdstep. The original if + -- statement checked whether coverage is contextual chaining. + -- + -- HH: The osdstep signals that we deal with our own feature here, not + -- one in the font itself so it was just a safeguard against us overloading + -- something driven by the font. + -- + -- if step.osdstep then -- selective + if true then -- always + -- rphf acts on consonant + halant + for k, v in next, ra do + local r = coverage[k] + if r then + local h = false + for k, v in next, halant do + local h = r[k] + if h then + reph = h.ligature or false + break + end + end + if reph then + break + end end end - if reph then - break - end + else + -- rphf might be result of other handler/chainproc end end - else - -- rphf might be result of other handler/chainproc + seqsubset[#seqsubset+1] = { kind, coverage, reph } end - seqsubset[#seqsubset+1] = { kind, coverage, reph } end end - end - if kind == "pref" then - local sequence = dataset[3] -- was [5] - local steps = sequence.steps - local nofsteps = sequence.nofsteps - for i=1,nofsteps do - local step = steps[i] - local coverage = step.coverage - if coverage then - for k, v in next, halant do - local h = coverage[k] - if h then - local found = false - for k, v in next, h do - found = v and v.ligature + if kind == "pref" then + local steps = sequence.steps + local nofsteps = sequence.nofsteps + for i=1,nofsteps do + local step = steps[i] + local coverage = step.coverage + if coverage then + for k, v in next, halant do + local h = coverage[k] + if h then + local found = false + for k, v in next, h do + found = v and v.ligature + if found then + pre_base_reordering_consonants[k] = found + break + end + end if found then - pre_base_reordering_consonants[k] = found break end end - if found then - break - end end end end @@ -795,7 +803,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) if current == stop then stop = getprev(stop) head = remove_node(head,current) - free_node(current) + flush_node(current) return head, stop, nbspaces else nbspaces = nbspaces + 1 @@ -833,7 +841,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) setchar(current,getchar(tempcurrent)) -- we assumes that the result of blwf consists of one node local freenode = getnext(current) setlink(current,tmp) - free_node(freenode) + flush_node(freenode) flush_list(tempcurrent) if changestop then stop = current @@ -1096,7 +1104,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) if getchar(base) == c_nbsp then nbspaces = nbspaces - 1 head = remove_node(head,base) - free_node(base) + flush_node(base) end return head, stop, nbspaces @@ -1132,9 +1140,12 @@ function handlers.devanagari_reorder_matras(head,start) -- no leak head = remove_node(head,start) setlink(start,next) setlink(current,start) + -- setlink(current,start,next) -- maybe start = startnext break end + else + break end current = next end @@ -1174,12 +1185,12 @@ function handlers.devanagari_reorder_reph(head,start) local startfont = getfont(start) local startattr = getprop(start,a_syllabe) while current do - local char = ischar(current,font) + local char = ischar(current,startfont) if char and getprop(current,a_syllabe) == startattr then -- step 2 if halant[char] and not getprop(current,a_state) then local next = getnext(current) if next then - local nextchar = ischar(next,font) + local nextchar = ischar(next,startfont) if nextchar and zw_char[nextchar] and getprop(next,a_syllabe) == startattr then current = next next = getnext(current) @@ -1189,6 +1200,7 @@ function handlers.devanagari_reorder_reph(head,start) head = remove_node(head,start) setlink(start,next) setlink(current,start) + -- setlink(current,start,next) -- maybe start = startnext startattr = getprop(start,a_syllabe) break @@ -1201,14 +1213,14 @@ function handlers.devanagari_reorder_reph(head,start) if not startnext then current = getnext(start) while current do - local char = ischar(current,font) + local char = ischar(current,startfont) if char and getprop(current,a_syllabe) == startattr then -- step 4 if getprop(current,a_state) == s_pstf then -- post-base startnext = getnext(start) head = remove_node(head,start) - local prev = getprev(current) - setlink(prev,start) + setlink(getprev(current),start) setlink(start,current) + -- setlink(getprev(current),start,current) -- maybe start = startnext startattr = getprop(start,a_syllabe) break @@ -1226,7 +1238,7 @@ function handlers.devanagari_reorder_reph(head,start) current = getnext(start) local c = nil while current do - local char = ischar(current,font) + local char = ischar(current,startfont) if char and getprop(current,a_syllabe) == startattr then -- step 5 if not c and mark_above_below_post[char] and reorder_class[char] ~= "after subscript" then c = current @@ -1240,9 +1252,9 @@ function handlers.devanagari_reorder_reph(head,start) if c then startnext = getnext(start) head = remove_node(head,start) - local prev = getprev(c) - setlink(prev,start) + setlink(getprev(c),start) setlink(start,c) + -- setlink(getprev(c),start,c) -- maybe -- end start = startnext startattr = getprop(start,a_syllabe) @@ -1253,7 +1265,7 @@ function handlers.devanagari_reorder_reph(head,start) current = start local next = getnext(current) while next do - local nextchar = ischar(next,font) + local nextchar = ischar(next,startfont) if nextchar and getprop(next,a_syllabe) == startattr then --step 6 current = next next = getnext(current) @@ -1264,9 +1276,9 @@ function handlers.devanagari_reorder_reph(head,start) if start ~= current then startnext = getnext(start) head = remove_node(head,start) - local next = getnext(current) - setlink(start,next) - setlink(current,"next",start) + setlink(start,getnext(current)) + setlink(current,start) + -- setlink(current,start,getnext(current)) -- maybe start = startnext end end @@ -1293,12 +1305,12 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start) local startattr = getprop(start,a_syllabe) -- can be fast for loop + caching state while current do - local char = ischar(current,font) + local char = ischar(current,startfont) if char and getprop(current,a_syllabe) == startattr then local next = getnext(current) if halant[char] and not getprop(current,a_state) then if next then - local nextchar = ischar(next,font) + local nextchar = ischar(next,startfont) if nextchar and getprop(next,a_syllabe) == startattr then if nextchar == c_zwnj or nextchar == c_zwj then current = next @@ -1310,6 +1322,7 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start) removenode(start,start) setlink(start,next) setlink(current,start) + -- setlink(current,start,next) -- maybe start = startnext break end @@ -1322,14 +1335,14 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start) current = getnext(start) startattr = getprop(start,a_syllabe) while current do - local char = ischar(current,font) + local char = ischar(current,startfont) if char and getprop(current,a_syllabe) == startattr then if not consonant[char] and getprop(current,a_state) then -- main startnext = getnext(start) removenode(start,start) - local prev = getprev(current) - setlink(start,prev) + setlink(getprev(current),start) setlink(start,current) + -- setlink(getprev(current),start,current) -- maybe start = startnext break end @@ -1429,21 +1442,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa local kind = subset[1] local lookupcache = subset[2] if kind == "rphf" then - for k, v in next, ra do - local r = lookupcache[k] - if r then - for k, v in next, halant do - local h = r[k] - if h then - reph = h.ligature or false - break - end - end - if reph then - break - end - end - end + reph = subset[3] local current = start local last = getnext(stop) while current ~= last do @@ -1476,7 +1475,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa if current ~= stop then local c = locl[current] or getchar(current) local found = lookupcache[c] - if found then + if found then -- pre-base: pref Halant + Consonant local next = getnext(current) local n = locl[next] or getchar(next) if found[n] then @@ -1574,7 +1573,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa if current == stop then stop = getprev(stop) head = remove_node(head,current) - free_node(current) + flush_node(current) return head, stop, nbspaces else nbspaces = nbspaces + 1 @@ -1694,9 +1693,9 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa end start = current end - local prev = getprev(halfpos) - setlink(prev,current) + setlink(getprev(halfpos),current) setlink(current,halfpos) + -- setlink(getprev(halfpos),current,halfpos) -- maybe halfpos = current elseif above_mark[char] then -- After main consonant target = basepos @@ -1721,13 +1720,13 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa local prev = getprev(current) if prev ~= target then local next = getnext(current) - setlink(next,prev) + setlink(prev,next) if current == stop then stop = prev end - local next = getnext(target) - setlink(current,next) + setlink(current,getnext(target)) setlink(target,current) + -- setlink(target,current,getnext(target)) -- maybe end end end @@ -1754,8 +1753,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa if stop == next then stop = current end - local prev = getprev(c) - setlink(next,prev) + setlink(getprev(c),next) local nextnext = getnext(next) setnext(current,nextnext) local nextnextnext = getnext(nextnext) @@ -1769,9 +1767,12 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa end if getchar(base) == c_nbsp then + if base == stop then + stop = getprev(stop) + end nbspaces = nbspaces - 1 head = remove_node(head, base) - free_node(base) + flush_node(base) end return head, stop, nbspaces @@ -1818,7 +1819,7 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe elseif (vv == c_zwnj or vv == c_zwj) and halant[vvv] then local nnnn = getnext(nnn) if nnnn then - local vvvv = ischar(nnnn) + local vvvv = ischar(nnnn,font) if vvvv and consonant[vvvv] then c = nnnn end @@ -1841,7 +1842,7 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe local nn = getnext(n) if nn then local vv = ischar(nn,font) - if vv and zw_char[vv] then + if vv and zw_char[v] then n = nn v = vv nn = getnext(nn) diff --git a/tex/context/base/mkiv/font-ota.lua b/tex/context/base/mkiv/font-ota.lua index 6a3804a74..232c2586a 100644 --- a/tex/context/base/mkiv/font-ota.lua +++ b/tex/context/base/mkiv/font-ota.lua @@ -32,7 +32,6 @@ local a_state = attributes.private('state') local nuts = nodes.nuts local tonut = nuts.tonut -local getfield = nuts.getfield local getnext = nuts.getnext local getprev = nuts.getprev local getprev = nuts.getprev @@ -44,7 +43,6 @@ local getchar = nuts.getchar local ischar = nuts.is_char local traverse_id = nuts.traverse_id -local traverse_node_list = nuts.traverse local end_of_math = nuts.end_of_math local nodecodes = nodes.nodecodes @@ -56,7 +54,7 @@ local fontdata = fonts.hashes.identifiers local categories = characters and characters.categories or { } -- sorry, only in context local chardata = characters and characters.data -local otffeatures = fonts.constructors.newfeatures("otf") +local otffeatures = fonts.constructors.features.otf local registerotffeature = otffeatures.register --[[ldx-- @@ -263,36 +261,44 @@ local classifiers = characters.classifiers if not classifiers then - local first_arabic, last_arabic = characters.blockrange("arabic") - local first_syriac, last_syriac = characters.blockrange("syriac") - local first_mandiac, last_mandiac = characters.blockrange("mandiac") - local first_nko, last_nko = characters.blockrange("nko") + local f_arabic, l_arabic = characters.blockrange("arabic") + local f_syriac, l_syriac = characters.blockrange("syriac") + local f_mandiac, l_mandiac = characters.blockrange("mandiac") + local f_nko, l_nko = characters.blockrange("nko") + local f_ext_a, l_ext_a = characters.blockrange("arabicextendeda") classifiers = table.setmetatableindex(function(t,k) - local c = chardata[k] - local v = false - if c then - local arabic = c.arabic - if arabic then - v = mappers[arabic] - if not v then - log.report("analyze","error in mapping arabic %C",k) - -- error - v = false - end - elseif k >= first_arabic and k <= last_arabic or k >= first_syriac and k <= last_syriac or - k >= first_mandiac and k <= last_mandiac or k >= first_nko and k <= last_nko then - if categories[k] == "mn" then - v = s_mark - else - v = s_rest + if type(k) == "number" then + local c = chardata[k] + local v = false + if c then + local arabic = c.arabic + if arabic then + v = mappers[arabic] + if not v then + log.report("analyze","error in mapping arabic %C",k) + -- error + v = false + end + elseif (k >= f_arabic and k <= l_arabic) or + (k >= f_syriac and k <= l_syriac) or + (k >= f_mandiac and k <= l_mandiac) or + (k >= f_nko and k <= l_nko) or + (k >= f_ext_a and k <= l_ext_a) then + if categories[k] == "mn" then + v = s_mark + else + v = s_rest + end end end + t[k] = v + return v end - t[k] = v - return v end) + characters.classifiers = classifiers + end function methods.arab(head,font,attr) diff --git a/tex/context/base/mkiv/font-otb.lua b/tex/context/base/mkiv/font-otb.lua index c9f5d4aca..a31079225 100644 --- a/tex/context/base/mkiv/font-otb.lua +++ b/tex/context/base/mkiv/font-otb.lua @@ -8,8 +8,6 @@ if not modules then modules = { } end modules ['font-otb'] = { local concat = table.concat local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip local type, next, tonumber, tostring, rawget = type, next, tonumber, tostring, rawget -local lpegmatch = lpeg.match -local utfchar = utf.char local trace_baseinit = false trackers.register("otf.baseinit", function(v) trace_baseinit = v end) local trace_singles = false trackers.register("otf.singles", function(v) trace_singles = v end) diff --git a/tex/context/base/mkiv/font-otc.lua b/tex/context/base/mkiv/font-otc.lua index a91dac5cf..5d879ec1d 100644 --- a/tex/context/base/mkiv/font-otc.lua +++ b/tex/context/base/mkiv/font-otc.lua @@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['font-otc'] = { local format, insert, sortedkeys, tohash = string.format, table.insert, table.sortedkeys, table.tohash local type, next = type, next local lpegmatch = lpeg.match -local utfbyte, utflen = utf.byte, utf.len +local utfbyte, utflen, utfsplit = utf.byte, utf.len, utf.split -- we assume that the other otf stuff is loaded already @@ -44,6 +44,24 @@ local types = { chainposition = "gpos_contextchain", } +local names = { + gsub_single = "gsub", + gsub_multiple = "gsub", + gsub_alternate = "gsub", + gsub_ligature = "gsub", + gsub_context = "gsub", + gsub_contextchain = "gsub", + gsub_reversecontextchain = "gsub", + gpos_single = "gpos", + gpos_pair = "gpos", + gpos_cursive = "gpos", + gpos_mark2base = "gpos", + gpos_mark2ligature = "gpos", + gpos_mark2mark = "gpos", + gpos_context = "gpos", + gpos_contextchain = "gpos", +} + setmetatableindex(types, function(t,k) t[k] = k return k end) -- "key" local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } } @@ -51,18 +69,89 @@ local noflags = { false, false, false, false } -- beware: shared, maybe we should copy the sequence +local function getrange(sequences,category) + local count = #sequences + local first = nil + local last = nil + for i=1,count do + local t = sequences[i].type + if t and names[t] == category then + if not first then + first = i + end + last = i + end + end + return first or 1, last or count +end + +local function validspecification(specification,name) + local dataset = specification.dataset + if dataset then + -- okay + elseif specification[1] then + dataset = specification + specification = { dataset = dataset } + else + dataset = { { data = specification.data } } + specification.data = nil + specification.dataset = dataset + end + local first = dataset[1] + if first then + first = first.data + end + if not first then + report_otf("invalid feature specification, no dataset") + return + end + if type(name) ~= "string" then + name = specification.name or first.name + end + if type(name) ~= "string" then + report_otf("invalid feature specification, no name") + return + end + local n = #dataset + if n > 0 then + for i=1,n do + setmetatableindex(dataset[i],specification) + end + return specification, name + end +end + local function addfeature(data,feature,specifications) -- todo: add some validator / check code so that we're more tolerant to -- user errors + if not specifications then + report_otf("missing specification") + return + end + local descriptions = data.descriptions local resources = data.resources local features = resources.features local sequences = resources.sequences + if not features or not sequences then + report_otf("missing specification") return end + + local alreadydone = resources.alreadydone + if not alreadydone then + alreadydone = { } + resources.alreadydone = alreadydone + end + if alreadydone[specifications] then + return + else + alreadydone[specifications] = true + end + -- feature has to be unique but the name entry wins eventually local fontfeatures = resources.features or everywhere @@ -72,9 +161,10 @@ local function addfeature(data,feature,specifications) local skip = 0 local aglunicodes = false - if not specifications[1] then - -- so we accept a one entry specification - specifications = { specifications } + local specifications = validspecification(specifications,feature) + if not specifications then + -- report_otf("invalid specification") + return end local function tounicode(code) @@ -105,13 +195,15 @@ local function addfeature(data,feature,specifications) local stepkey = coverup.stepkey local register = coverup.register - local function prepare_substitution(list,featuretype) + local function prepare_substitution(list,featuretype,nocheck) local coverage = { } local cover = coveractions[featuretype] for code, replacement in next, list do local unicode = tounicode(code) local description = descriptions[unicode] - if description then + if not nocheck and not description then + skip = skip + 1 + else if type(replacement) == "table" then replacement = replacement[1] end @@ -122,26 +214,24 @@ local function addfeature(data,feature,specifications) else skip = skip + 1 end - else - skip = skip + 1 end end return coverage end - local function prepare_alternate(list,featuretype) + local function prepare_alternate(list,featuretype,nocheck) local coverage = { } local cover = coveractions[featuretype] for code, replacement in next, list do local unicode = tounicode(code) local description = descriptions[unicode] - if not description then + if not nocheck and not description then skip = skip + 1 elseif type(replacement) == "table" then local r = { } for i=1,#replacement do local u = tounicode(replacement[i]) - r[i] = descriptions[u] and u or unicode + r[i] = (nocheck or descriptions[u]) and u or unicode end cover(coverage,unicode,r) done = done + 1 @@ -158,19 +248,19 @@ local function addfeature(data,feature,specifications) return coverage end - local function prepare_multiple(list,featuretype) + local function prepare_multiple(list,featuretype,nocheck) local coverage = { } local cover = coveractions[featuretype] for code, replacement in next, list do local unicode = tounicode(code) local description = descriptions[unicode] - if not description then + if not nocheck and not description then skip = skip + 1 elseif type(replacement) == "table" then local r, n = { }, 0 for i=1,#replacement do local u = tounicode(replacement[i]) - if descriptions[u] then + if nocheck or descriptions[u] then n = n + 1 r[n] = u end @@ -194,13 +284,15 @@ local function addfeature(data,feature,specifications) return coverage end - local function prepare_ligature(list,featuretype) + local function prepare_ligature(list,featuretype,nocheck) local coverage = { } local cover = coveractions[featuretype] for code, ligature in next, list do local unicode = tounicode(code) local description = descriptions[unicode] - if description then + if not nocheck and not description then + skip = skip + 1 + else if type(ligature) == "string" then ligature = { lpegmatch(splitter,ligature) } end @@ -208,7 +300,7 @@ local function addfeature(data,feature,specifications) for i=1,#ligature do local l = ligature[i] local u = tounicode(l) - if descriptions[u] then + if nocheck or descriptions[u] then ligature[i] = u else present = false @@ -221,16 +313,23 @@ local function addfeature(data,feature,specifications) else skip = skip + 1 end - else - skip = skip + 1 end end return coverage end + local function resetspacekerns() + -- a bit of a hack, this nil setting but it forces a + -- rehash of the resources needed .. the feature itself + -- should be a kern (at least for now) + data.properties.hasspacekerns = true + data.resources .spacekerns = nil + end + local function prepare_kern(list,featuretype) local coverage = { } local cover = coveractions[featuretype] + local isspace = false for code, replacement in next, list do local unicode = tounicode(code) local description = descriptions[unicode] @@ -240,11 +339,17 @@ local function addfeature(data,feature,specifications) local u = tounicode(k) if u then r[u] = v + if u == 32 then + isspace = true + end end end if next(r) then cover(coverage,unicode,r) done = done + 1 + if unicode == 32 then + isspace = true + end else skip = skip + 1 end @@ -252,6 +357,9 @@ local function addfeature(data,feature,specifications) skip = skip + 1 end end + if isspace then + resetspacekerns() + end return coverage end @@ -268,11 +376,17 @@ local function addfeature(data,feature,specifications) local u = tounicode(k) if u then r[u] = v + if u == 32 then + isspace = true + end end end if next(r) then cover(coverage,unicode,r) done = done + 1 + if unicode == 32 then + isspace = true + end else skip = skip + 1 end @@ -280,6 +394,9 @@ local function addfeature(data,feature,specifications) skip = skip + 1 end end + if isspace then + resetspacekerns() + end else report_otf("unknown cover type %a",featuretype) end @@ -326,14 +443,27 @@ local function addfeature(data,feature,specifications) local subtype = nil if lookups and sublookups then for k, v in next, lookups do - local lookup = sublookups[v] - if lookup then - lookups[k] = lookup - if not subtype then - subtype = lookup.type + local t = type(v) + if t == "table" then + -- already ok + for i=1,#v do + local vi = v[i] + if type(vi) ~= "table" then + v[i] = { vi } + end + end + elseif t == "number" then + local lookup = sublookups[v] + if lookup then + lookups[k] = { lookup } + if not subtype then + subtype = lookup.type + end + else + lookups[k] = false -- new end else - -- already expanded + lookups[k] = false -- new end end end @@ -376,11 +506,83 @@ local function addfeature(data,feature,specifications) return coverage end - for s=1,#specifications do - local specification = specifications[s] - local valid = specification.valid - local feature = specification.name or feature - if not valid or valid(data,specification,feature) then + local dataset = specifications.dataset + + local function report(name,category,position,first,last,sequences) + report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]", + name,category,position,first,last,1,#sequences) + end + + local function inject(specification,sequences,sequence,first,last,category,name) + local position = specification.position or false + if not position then + position = specification.prepend + if position == true then + if trace_loading then + report(name,category,first,first,last,sequences) + end + insert(sequences,first,sequence) + return + end + end + if not position then + position = specification.append + if position == true then + if trace_loading then + report(name,category,last+1,first,last,sequences) + end + insert(sequences,last+1,sequence) + return + end + end + local kind = type(position) + if kind == "string" then + local index = false + for i=first,last do + local s = sequences[i] + local f = s.features + if f then + for k in next, f do + if k == position then + index = i + break + end + end + if index then + break + end + end + end + if index then + position = index + else + position = last + 1 + end + elseif kind == "number" then + if position < 0 then + position = last - position + 1 + end + if position > last then + position = last + 1 + elseif position < first then + position = first + end + else + position = last + 1 + end + if trace_loading then + report(name,category,position,first,last,sequences) + end + insert(sequences,position,sequence) + end + + for s=1,#dataset do + local specification = dataset[s] + local valid = specification.valid -- nowhere used + local feature = specification.name or feature + if not feature or feature == "" then + report_otf("no valid name given for extra feature") + elseif not valid or valid(data,specification,feature) then -- anum uses this local initialize = specification.initialize if initialize then -- when false is returned we initialize only once @@ -390,6 +592,8 @@ local function addfeature(data,feature,specifications) local askedsteps = specification.steps or specification.subtables or { specification.data } or { } local featuretype = normalized[specification.type or "substitution"] or "substitution" local featureflags = specification.flags or noflags + local nocheck = specification.nocheck + local futuresteps = specification.futuresteps local featureorder = specification.order or { feature } local featurechain = (featuretype == "chainsubstitution" or featuretype == "chainposition") and 1 or 0 local nofsteps = 0 @@ -410,13 +614,13 @@ local function addfeature(data,feature,specifications) local coverage = nil local format = nil if featuretype == "substitution" then - coverage = prepare_substitution(list,featuretype) + coverage = prepare_substitution(list,featuretype,nocheck) elseif featuretype == "ligature" then - coverage = prepare_ligature(list,featuretype) + coverage = prepare_ligature(list,featuretype,nocheck) elseif featuretype == "alternate" then - coverage = prepare_alternate(list,featuretype) + coverage = prepare_alternate(list,featuretype,nocheck) elseif featuretype == "multiple" then - coverage = prepare_multiple(list,featuretype) + coverage = prepare_multiple(list,featuretype,nocheck) elseif featuretype == "kern" then format = "kern" coverage = prepare_kern(list,featuretype) @@ -432,6 +636,7 @@ local function addfeature(data,feature,specifications) s[i] = { [stepkey] = steps, nofsteps = nofsteps, + flags = featureflags, type = types[featuretype], } end @@ -443,16 +648,16 @@ local function addfeature(data,feature,specifications) local format = nil if featuretype == "substitution" then category = "gsub" - coverage = prepare_substitution(list,featuretype) + coverage = prepare_substitution(list,featuretype,nocheck) elseif featuretype == "ligature" then category = "gsub" - coverage = prepare_ligature(list,featuretype) + coverage = prepare_ligature(list,featuretype,nocheck) elseif featuretype == "alternate" then category = "gsub" - coverage = prepare_alternate(list,featuretype) + coverage = prepare_alternate(list,featuretype,nocheck) elseif featuretype == "multiple" then category = "gsub" - coverage = prepare_multiple(list,featuretype) + coverage = prepare_multiple(list,featuretype,nocheck) elseif featuretype == "kern" then category = "gpos" format = "kern" @@ -486,6 +691,7 @@ local function addfeature(data,feature,specifications) if featureflags[1] then featureflags[1] = "mark" end if featureflags[2] then featureflags[2] = "ligature" end if featureflags[3] then featureflags[3] = "base" end + local steptype = types[featuretype] local sequence = { chain = featurechain, features = { [feature] = askedfeatures }, @@ -494,14 +700,11 @@ local function addfeature(data,feature,specifications) order = featureorder, [stepkey] = steps, nofsteps = nofsteps, - type = types[featuretype], + type = steptype, } - -- todo : before|after|index - if specification.prepend then - insert(sequences,1,sequence) - else - insert(sequences,sequence) - end + -- position | prepend | append + local first, last = getrange(sequences,category) + inject(specification,sequences,sequence,first,last,category,feature) -- register in metadata (merge as there can be a few) local features = fontfeatures[category] if not features then @@ -540,18 +743,28 @@ local knownfeatures = { } function otf.addfeature(name,specification) if type(name) == "table" then specification = name - name = specification.name end - if type(name) == "string" then + if type(specification) ~= "table" then + report_otf("invalid feature specification, no valid table") + return + end + specification, name = validspecification(specification,name) + if name and specification then local slot = knownfeatures[name] - if slot then - -- we overload one - else + if not slot then + -- we have a new one + slot = #extrafeatures + 1 + knownfeatures[name] = slot + elseif specification.overload == false then + -- we add an extre one slot = #extrafeatures + 1 knownfeatures[name] = slot + else + -- we overload a previous one end specification.name = name -- to be sure extrafeatures[slot] = specification + -- report_otf("adding feature %a @ %i",name,slot) end end @@ -566,7 +779,7 @@ local function enhance(data,filename,raw) end end --- otf.enhancers.enhance = enhance +otf.enhancers.enhance = enhance otf.enhancers.register("check extra features",enhance) @@ -626,39 +839,39 @@ registerotffeature { description = 'tex replacements', } --- tcom - -if characters.combined then - - local tcom = { } - - local function initialize() - characters.initialize() - for first, seconds in next, characters.combined do - for second, combination in next, seconds do - tcom[combination] = { first, second } - end - end - -- return false - end +-- -- tcom (obsolete, was already not set for a while) - local tcom_specification = { - type = "ligature", - features = everywhere, - data = tcom, - order = { "tcom" }, - flags = noflags, - initialize = initialize, - } - - otf.addfeature("tcom",tcom_specification) - - registerotffeature { - name = 'tcom', - description = 'tex combinations', - } - -end +-- if characters.combined then +-- +-- local tcom = { } +-- +-- local function initialize() +-- characters.initialize() +-- for first, seconds in next, characters.combined do +-- for second, combination in next, seconds do +-- tcom[combination] = { first, second } +-- end +-- end +-- -- return false +-- end +-- +-- local tcom_specification = { +-- type = "ligature", +-- features = everywhere, +-- data = tcom, +-- order = { "tcom" }, +-- flags = noflags, +-- initialize = initialize, +-- } +-- +-- otf.addfeature("tcom",tcom_specification) +-- +-- registerotffeature { +-- name = 'tcom', +-- description = 'tex combinations', +-- } +-- +-- end -- anum @@ -785,3 +998,96 @@ registerotffeature { -- a = { b = -500 }, -- } -- } + +-- This is a quick and dirty hack. + +local lookups = { } +local protect = { } +local revert = { } +local zwj = { 0x200C } + +otf.addfeature { + name = "blockligatures", + type = "chainsubstitution", + nocheck = true, -- because there is no 0x200C in the font + prepend = true, -- make sure we do it early + future = true, -- avoid nilling due to no steps yet + lookups = { + { + type = "multiple", + data = lookups, + }, + }, + data = { + rules = protect, + } +} + +otf.addfeature { + name = "blockligatures", + type = "chainsubstitution", + nocheck = true, -- because there is no 0x200C in the font + append = true, -- this is done late + overload = false, -- we don't want to overload the previous definition + lookups = { + { + type = "ligature", + data = lookups, + }, + }, + data = { + rules = revert, + } +} + +registerotffeature { + name = 'blockligatures', + description = 'block certain ligatures', +} + +local settings_to_array = utilities.parsers and utilities.parsers.settings_to_array + or function(s) return string.split(s,",") end -- for generic + +local function blockligatures(str) + + local t = settings_to_array(str) + + for i=1,#t do + local ti = utfsplit(t[i]) + if #ti > 1 then + local one = ti[1] + local two = ti[2] + lookups[one] = { one, 0x200C } + local one = { one } + local two = { two } + local new = #protect + 1 + protect[new] = { + current = { one, two }, + lookups = { 1 }, -- not shared ! + } + revert[new] = { + current = { one, zwj }, + after = { two }, + lookups = { 1 }, -- not shared ! + } + end + end + +end + +-- blockligatures("\0\0") + +otf.helpers.blockligatures = blockligatures + +-- blockligatures("fi,ff") +-- blockligatures("fl") + +if context then + + interfaces.implement { + name = "blockligatures", + arguments = "string", + actions = blockligatures, + } + +end diff --git a/tex/context/base/mkiv/font-otd.lua b/tex/context/base/mkiv/font-otd.lua index 2257caa8c..64cb1bcb4 100644 --- a/tex/context/base/mkiv/font-otd.lua +++ b/tex/context/base/mkiv/font-otd.lua @@ -36,9 +36,6 @@ local contextmerged = specifiers.contextmerged local setmetatableindex = table.setmetatableindex -local otffeatures = fonts.constructors.newfeatures("otf") -local registerotffeature = otffeatures.register - local a_to_script = { } local a_to_language = { } @@ -135,6 +132,10 @@ local wildcard = "*" -- needs checking: some added features can pass twice +local P, C, Cc, lpegmatch = lpeg.P, lpeg.C, lpeg.Cc, lpeg.match + +local pattern = P("always") * (P(-1) * Cc(true) + P(":") * C((1-P(-1))^1)) + local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr,dynamic,ra,autoscript,autolanguage) local features = sequence.features if features then @@ -151,21 +152,34 @@ local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr e_e = s_enabled and s_enabled[kind] -- the value (font) end if e_e then - local scripts = features[kind] -- - local languages = scripts[script] or scripts[wildcard] - if not languages and autoscript then - langages = defaultscript(featuretype,autoscript,scripts) - end - if languages then - -- we need detailed control over default becase we want to trace - -- only first attribute match check, so we assume simple fina's - local valid = false - if languages[language] then - valid = e_e - elseif languages[wildcard] then - valid = e_e - elseif autolanguage and defaultlanguage(featuretype,autolanguage,languages) then - valid = e_e + local valid = type(e_e) == "string" and lpegmatch(pattern,e_e) + if valid then + -- we have hit always + local attribute = autofeatures[kind] or false + if trace_applied then + report_process( + "font %s, dynamic %a (%a), feature %a, script %a, language %a, lookup %a, value %a", + font,attr or 0,dynamic,kind,"*","*",sequence.name,valid) + end + ra[#ra+1] = { valid, attribute, sequence, kind } + else + -- we already checked for e_e + local scripts = features[kind] -- + local languages = scripts[script] or scripts[wildcard] + if not languages and autoscript then + langages = defaultscript(featuretype,autoscript,scripts) + end + if languages then + -- we need detailed control over default becase we want to trace + -- only first attribute match check, so we assume simple fina's + -- local valid = false + if languages[language] then + valid = e_e + elseif languages[wildcard] then + valid = e_e + elseif autolanguage and defaultlanguage(featuretype,autolanguage,languages) then + valid = e_e + end end if valid then local attribute = autofeatures[kind] or false @@ -244,6 +258,7 @@ function otf.dataset(tfmdata,font,attr) -- attr only when explicit (as in specia local autoscript = (s_enabled and s_enabled.autoscript ) or (a_enabled and a_enabled.autoscript ) local autolanguage = (s_enabled and s_enabled.autolanguage) or (a_enabled and a_enabled.autolanguage) for s=1,#sequences do + -- just return nil or ra step initialize(sequences[s],script,language,s_enabled,a_enabled,font,attr,dynamic,ra,autoscript,autolanguage) end end diff --git a/tex/context/base/mkiv/font-otf.lua b/tex/context/base/mkiv/font-otf.lua index a1730aced..1db80272e 100644 --- a/tex/context/base/mkiv/font-otf.lua +++ b/tex/context/base/mkiv/font-otf.lua @@ -20,91 +20,87 @@ if not modules then modules = { } end modules ['font-otf'] = { -- more checking against low level calls of functions -local utfbyte = utf.byte local gmatch, gsub, find, match, lower, strip = string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip local type, next, tonumber, tostring = type, next, tonumber, tostring local abs = math.abs local reversed, concat, insert, remove, sortedkeys = table.reversed, table.concat, table.insert, table.remove, table.sortedkeys -local ioflush = io.flush local fastcopy, tohash, derivetable, copy = table.fastcopy, table.tohash, table.derive, table.copy local formatters = string.formatters local P, R, S, C, Ct, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Ct, lpeg.match -local setmetatableindex = table.setmetatableindex -local allocate = utilities.storage.allocate -local registertracker = trackers.register -local registerdirective = directives.register -local starttiming = statistics.starttiming -local stoptiming = statistics.stoptiming -local elapsedtime = statistics.elapsedtime -local findbinfile = resolvers.findbinfile +local setmetatableindex = table.setmetatableindex +local allocate = utilities.storage.allocate +local registertracker = trackers.register +local registerdirective = directives.register +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming +local elapsedtime = statistics.elapsedtime +local findbinfile = resolvers.findbinfile -local trace_private = false registertracker("otf.private", function(v) trace_private = v end) -local trace_subfonts = false registertracker("otf.subfonts", function(v) trace_subfonts = v end) -local trace_loading = false registertracker("otf.loading", function(v) trace_loading = v end) -local trace_features = false registertracker("otf.features", function(v) trace_features = v end) -local trace_dynamics = false registertracker("otf.dynamics", function(v) trace_dynamics = v end) -local trace_sequences = false registertracker("otf.sequences", function(v) trace_sequences = v end) -local trace_markwidth = false registertracker("otf.markwidth", function(v) trace_markwidth = v end) -local trace_defining = false registertracker("fonts.defining", function(v) trace_defining = v end) +local trace_private = false registertracker("otf.private", function(v) trace_private = v end) +local trace_subfonts = false registertracker("otf.subfonts", function(v) trace_subfonts = v end) +local trace_loading = false registertracker("otf.loading", function(v) trace_loading = v end) +local trace_features = false registertracker("otf.features", function(v) trace_features = v end) +local trace_dynamics = false registertracker("otf.dynamics", function(v) trace_dynamics = v end) +local trace_sequences = false registertracker("otf.sequences", function(v) trace_sequences = v end) +local trace_markwidth = false registertracker("otf.markwidth", function(v) trace_markwidth = v end) +local trace_defining = false registertracker("fonts.defining", function(v) trace_defining = v end) -local compact_lookups = true registertracker("otf.compactlookups", function(v) compact_lookups = v end) -local purge_names = true registertracker("otf.purgenames", function(v) purge_names = v end) +local compact_lookups = true registertracker("otf.compactlookups", function(v) compact_lookups = v end) +local purge_names = true registertracker("otf.purgenames", function(v) purge_names = v end) -local report_otf = logs.reporter("fonts","otf loading") +local report_otf = logs.reporter("fonts","otf loading") -local fonts = fonts -local otf = fonts.handlers.otf +local fonts = fonts +local otf = fonts.handlers.otf -otf.glists = { "gsub", "gpos" } +otf.glists = { "gsub", "gpos" } -otf.version = 2.825 -- beware: also sync font-mis.lua and in mtx-fonts -otf.cache = containers.define("fonts", "otf", otf.version, true) +otf.version = 2.826 -- beware: also sync font-mis.lua and in mtx-fonts +otf.cache = containers.define("fonts", "otf", otf.version, true) -local hashes = fonts.hashes -local definers = fonts.definers -local readers = fonts.readers -local constructors = fonts.constructors +local hashes = fonts.hashes +local definers = fonts.definers +local readers = fonts.readers +local constructors = fonts.constructors -local fontdata = hashes and hashes.identifiers -local chardata = characters and characters.data -- not used +local fontdata = hashes and hashes.identifiers +local chardata = characters and characters.data -- not used -local otffeatures = constructors.newfeatures("otf") -local registerotffeature = otffeatures.register +local otffeatures = constructors.features.otf +local registerotffeature = otffeatures.register -local enhancers = allocate() -otf.enhancers = enhancers -local patches = { } -enhancers.patches = patches +local otfenhancers = constructors.enhancers.otf +local registerotfenhancer = otfenhancers.register -local forceload = false -local cleanup = 0 -- mk: 0=885M 1=765M 2=735M (regular run 730M) -local packdata = true -local syncspace = true -local forcenotdef = false -local includesubfonts = false -local overloadkerns = false -- experiment +local forceload = false +local cleanup = 0 -- mk: 0=885M 1=765M 2=735M (regular run 730M) +local packdata = true +local syncspace = true +local forcenotdef = false +local includesubfonts = false +local overloadkerns = false -- experiment -local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes +local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes -local wildcard = "*" -local default = "dflt" +local wildcard = "*" +local default = "dflt" -local fontloader = fontloader -local open_font = fontloader.open -local close_font = fontloader.close -local font_fields = fontloader.fields -local apply_featurefile = fontloader.apply_featurefile +local fontloader = fontloader +local open_font = fontloader.open +local close_font = fontloader.close +local font_fields = fontloader.fields +local apply_featurefile = fontloader.apply_featurefile -local mainfields = nil -local glyphfields = nil -- not used yet +local mainfields = nil +local glyphfields = nil -- not used yet -local formats = fonts.formats +local formats = fonts.formats -formats.otf = "opentype" -formats.ttf = "truetype" -formats.ttc = "truetype" -formats.dfont = "truetype" +formats.otf = "opentype" +formats.ttf = "truetype" +formats.ttc = "truetype" +formats.dfont = "truetype" registerdirective("fonts.otf.loader.cleanup", function(v) cleanup = tonumber(v) or (v and 1) or 0 end) registerdirective("fonts.otf.loader.force", function(v) forceload = v end) @@ -263,127 +259,50 @@ local valid_fields = table.tohash { -- "truetype", -- maybe as check } -local ordered_enhancers = { - "prepare tables", - - "prepare glyphs", - "prepare lookups", - - "analyze glyphs", - "analyze math", - - -- "prepare tounicode", - - "reorganize lookups", - "reorganize mark classes", - "reorganize anchor classes", - - "reorganize glyph kerns", - "reorganize glyph lookups", - "reorganize glyph anchors", - - "merge kern classes", - - "reorganize features", - "reorganize subtables", - - "check glyphs", - "check metadata", - - "prepare tounicode", - - "check encoding", -- moved - "add duplicates", - - "expand lookups", -- a temp hack awaiting the lua loader - - "check extra features", -- after metadata and duplicates - - "cleanup tables", - - "compact lookups", - "purge names", -} - ---[[ldx-- -<p>Here we go.</p> ---ldx]]-- - -local actions = allocate() -local before = allocate() -local after = allocate() - -patches.before = before -patches.after = after - -local function enhance(name,data,filename,raw) - local enhancer = actions[name] - if enhancer then - if trace_loading then - report_otf("apply enhancement %a to file %a",name,filename) - ioflush() - end - enhancer(data,filename,raw) - else - -- no message as we can have private ones - end -end - -function enhancers.apply(data,filename,raw) - local basename = file.basename(lower(filename)) - if trace_loading then - report_otf("%s enhancing file %a","start",filename) - end - ioflush() -- we want instant messages - for e=1,#ordered_enhancers do - local enhancer = ordered_enhancers[e] - local b = before[enhancer] - if b then - for pattern, action in next, b do - if find(basename,pattern) then - action(data,filename,raw) - end +local function adddimensions(data,filename) + -- todo: forget about the width if it's the defaultwidth (saves mem) + -- we could also build the marks hash here (instead of storing it) + if data then + local descriptions = data.descriptions + local resources = data.resources + local defaultwidth = resources.defaultwidth or 0 + local defaultheight = resources.defaultheight or 0 + local defaultdepth = resources.defaultdepth or 0 + local basename = trace_markwidth and file.basename(filename) + for _, d in next, descriptions do + local bb, wd = d.boundingbox, d.width + if not wd then + -- or bb? + d.width = defaultwidth + elseif trace_markwidth and wd ~= 0 and d.class == "mark" then + report_otf("mark %a with width %b found in %a",d.name or "<noname>",wd,basename) + -- d.width = -wd end - end - enhance(enhancer,data,filename,raw) - local a = after[enhancer] - if a then - for pattern, action in next, a do - if find(basename,pattern) then - action(data,filename,raw) - end + if bb then + local ht = bb[4] + local dp = -bb[2] + -- if alldimensions then + -- if ht ~= 0 then + -- d.height = ht + -- end + -- if dp ~= 0 then + -- d.depth = dp + -- end + -- else + if ht == 0 or ht < 0 then + -- not set + else + d.height = ht + end + if dp == 0 or dp < 0 then + -- not set + else + d.depth = dp + end + -- end end end - ioflush() -- we want instant messages end - if trace_loading then - report_otf("%s enhancing file %a","stop",filename) - end - ioflush() -- we want instant messages -end - --- patches.register("before","migrate metadata","cambria",function() end) - -function patches.register(what,where,pattern,action) - local pw = patches[what] - if pw then - local ww = pw[where] - if ww then - ww[pattern] = action - else - pw[where] = { [pattern] = action} - end - end -end - -function patches.report(fmt,...) - if trace_loading then - report_otf("patching: %s",formatters[fmt](...)) - end -end - -function enhancers.register(what,action) -- only already registered can be overloaded - actions[what] = action end function otf.load(filename,sub,featurefile) -- second argument (format) is gone ! @@ -525,14 +444,14 @@ function otf.load(filename,sub,featurefile) -- second argument (format) is gone }, } report_otf("file size: %s", size) - enhancers.apply(data,filename,fontdata) + otfenhancers.apply(data,filename,fontdata) local packtime = { } if packdata then if cleanup > 0 then collectgarbage("collect") end starttiming(packtime) - enhance("pack",data,filename,nil) + otf.packdata(data,filename,nil) -- implemented elsewhere stoptiming(packtime) end report_otf("saving %a in cache",filename) @@ -541,7 +460,7 @@ function otf.load(filename,sub,featurefile) -- second argument (format) is gone collectgarbage("collect") end stoptiming("fontloader") - if elapsedtime then -- not in generic + if elapsedtime then report_otf("loading, optimizing, packing and caching time %s, pack time %s", elapsedtime("fontloader"),packdata and elapsedtime(packtime) or 0) end @@ -563,7 +482,7 @@ function otf.load(filename,sub,featurefile) -- second argument (format) is gone if trace_defining then report_otf("loading from cache using hash %a",hash) end - enhance("unpack",data,filename,nil,false) + otf.unpackdata(data,filename,nil,false) -- implemented elsewhere -- local resources = data.resources local lookuptags = resources.lookuptags @@ -600,7 +519,7 @@ function otf.load(filename,sub,featurefile) -- second argument (format) is gone if applyruntimefixes then applyruntimefixes(filename,data) end - enhance("add dimensions",data,filename,nil,false) + adddimensions(data,filename,nil,false) if trace_sequences then showfeatureorder(data,filename) end @@ -624,56 +543,10 @@ local mt = { end } -actions["prepare tables"] = function(data,filename,raw) +local function enhance_prepare_tables(data,filename,raw) data.properties.hasitalics = false end -actions["add dimensions"] = function(data,filename) - -- todo: forget about the width if it's the defaultwidth (saves mem) - -- we could also build the marks hash here (instead of storing it) - if data then - local descriptions = data.descriptions - local resources = data.resources - local defaultwidth = resources.defaultwidth or 0 - local defaultheight = resources.defaultheight or 0 - local defaultdepth = resources.defaultdepth or 0 - local basename = trace_markwidth and file.basename(filename) - for _, d in next, descriptions do - local bb, wd = d.boundingbox, d.width - if not wd then - -- or bb? - d.width = defaultwidth - elseif trace_markwidth and wd ~= 0 and d.class == "mark" then - report_otf("mark %a with width %b found in %a",d.name or "<noname>",wd,basename) - -- d.width = -wd - end - if bb then - local ht = bb[4] - local dp = -bb[2] - -- if alldimensions then - -- if ht ~= 0 then - -- d.height = ht - -- end - -- if dp ~= 0 then - -- d.depth = dp - -- end - -- else - if ht == 0 or ht < 0 then - -- not set - else - d.height = ht - end - if dp == 0 or dp < 0 then - -- not set - else - d.depth = dp - end - -- end - end - end - end -end - local function somecopy(old) -- fast one if old then local new = { } @@ -708,7 +581,7 @@ end -- not setting hasitalics and class (when nil) during table construction can save some mem -actions["prepare glyphs"] = function(data,filename,raw) +local function enhance_prepare_glyphs(data,filename,raw) local rawglyphs = raw.glyphs local rawsubfonts = raw.subfonts local rawcidinfo = raw.cidinfo @@ -986,7 +859,7 @@ end -- -- PsuedoEncodeUnencoded(EncMap *map,struct ttfinfo *info) -actions["check encoding"] = function(data,filename,raw) +local function enhance_check_encoding(data,filename,raw) local descriptions = data.descriptions local resources = data.resources local properties = data.properties @@ -1065,7 +938,7 @@ end -- do an indirect lookup uni_to_uni . but then we need that in -- all lookups -actions["add duplicates"] = function(data,filename,raw) +local function enhance_add_duplicates(data,filename,raw) local descriptions = data.descriptions local resources = data.resources local properties = data.properties @@ -1118,7 +991,7 @@ end -- class : nil base mark ligature component (maybe we don't need it in description) -- boundingbox: split into ht/dp takes more memory (larger tables and less sharing) -actions["analyze glyphs"] = function(data,filename,raw) -- maybe integrate this in the previous +local function enhance_analyze_glyphs(data,filename,raw) -- maybe integrate this in the previous local descriptions = data.descriptions local resources = data.resources local metadata = data.metadata @@ -1177,7 +1050,7 @@ actions["analyze glyphs"] = function(data,filename,raw) -- maybe integrate this end end -actions["reorganize mark classes"] = function(data,filename,raw) +local function enhance_reorganize_mark_classes(data,filename,raw) local mark_classes = raw.mark_classes if mark_classes then local resources = data.resources @@ -1194,7 +1067,7 @@ actions["reorganize mark classes"] = function(data,filename,raw) end end -actions["reorganize features"] = function(data,filename,raw) -- combine with other +local function enhance_reorganize_features(data,filename,raw) -- combine with other local features = { } data.resources.features = features for k=1,#otf.glists do @@ -1232,7 +1105,7 @@ actions["reorganize features"] = function(data,filename,raw) -- combine with oth end end -actions["reorganize anchor classes"] = function(data,filename,raw) +local function enhance_reorganize_anchor_classes(data,filename,raw) local resources = data.resources local anchor_to_lookup = { } local lookup_to_anchor = { } @@ -1280,7 +1153,7 @@ end -- local private = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF -- -- -- local ns, nl = 0, 0 - +-- -- local guess = { } -- -- helper -- local function check(gname,code,unicode) @@ -1401,7 +1274,7 @@ end -- end -- end -actions["prepare tounicode"] = function(data,filename,raw) +local function enhance_prepare_tounicode(data,filename,raw) fonts.mappings.addtounicode(data,filename) end @@ -1429,7 +1302,7 @@ local g_directions = { -- return true -- end -actions["reorganize subtables"] = function(data,filename,raw) +local function enhance_reorganize_subtables(data,filename,raw) local resources = data.resources local sequences = { } local lookups = { } @@ -1523,7 +1396,7 @@ actions["reorganize subtables"] = function(data,filename,raw) end end -actions["prepare lookups"] = function(data,filename,raw) +local function enhance_prepare_lookups(data,filename,raw) local lookups = raw.lookups if lookups then data.lookups = lookups @@ -1633,7 +1506,7 @@ local function r_uncover(splitter,cache,cover,replacements) end end -actions["reorganize lookups"] = function(data,filename,raw) -- we could check for "" and n == 0 +local function enhance_reorganize_lookups(data,filename,raw) -- we could check for "" and n == 0 -- we prefer the before lookups in a normal order if data.lookups then local helpers = data.helpers @@ -1799,7 +1672,7 @@ actions["reorganize lookups"] = function(data,filename,raw) -- we could check fo end end -actions["expand lookups"] = function(data,filename,raw) -- we could check for "" and n == 0 +local function enhance_expand_lookups(data,filename,raw) -- we could check for "" and n == 0 if data.lookups then local cache = data.helpers.matchcache if cache then @@ -1890,7 +1763,7 @@ local function check_variants(unicode,the_variants,splitter,unicodes) return variants, parts, italic end -actions["analyze math"] = function(data,filename,raw) +local function enhance_analyze_math(data,filename,raw) if raw.math then data.metadata.math = raw.math local unicodes = data.resources.unicodes @@ -1908,18 +1781,16 @@ actions["analyze math"] = function(data,filename,raw) math.accent = accent end if mathkerns then - for k, v in next, mathkerns do - if not next(v) then - mathkerns[k] = nil - else - for k, v in next, v do - if v == 0 then - k[v] = nil -- height / kern can be zero - end - end - end - end - math.kerns = mathkerns + local topright = mathkerns.top_right + local topleft = mathkerns.top_left + local bottomright = mathkerns.bottom_right + local bottomleft = mathkerns.bottom_left + math.kerns = { + topright = topright and next(topright) and topright or nil, + topleft = topleft and next(topleft) and topleft or nil, + bottomright = bottomright and next(bottomright) and bottomright or nil, + bottomleft = bottomleft and next(bottomleft) and bottomleft or nil, + } end if hvariants then math.hvariants, math.hparts, math.hitalic = check_variants(unicode,hvariants,splitter,unicodes) @@ -1936,7 +1807,7 @@ actions["analyze math"] = function(data,filename,raw) end end -actions["reorganize glyph kerns"] = function(data,filename,raw) +local function enhance_reorganize_glyph_kerns(data,filename,raw) local descriptions = data.descriptions local resources = data.resources local unicodes = resources.unicodes @@ -1979,7 +1850,7 @@ actions["reorganize glyph kerns"] = function(data,filename,raw) end end -actions["merge kern classes"] = function(data,filename,raw) +local function enhance_merge_kern_classes(data,filename,raw) local gposlist = raw.gpos if gposlist then local descriptions = data.descriptions @@ -2101,7 +1972,7 @@ actions["merge kern classes"] = function(data,filename,raw) end end -actions["check glyphs"] = function(data,filename,raw) +local function enhance_check_glyphs(data,filename,raw) for unicode, description in next, data.descriptions do description.glyph = nil end @@ -2115,7 +1986,7 @@ local function valid_ps_name(str) return str and str ~= "" and #str < 64 and lpegmatch(valid,str) and true or false end -actions["check metadata"] = function(data,filename,raw) +local function enhance_check_metadata(data,filename,raw) local metadata = data.metadata for _, k in next, mainfields do if valid_fields[k] then @@ -2204,7 +2075,7 @@ actions["check metadata"] = function(data,filename,raw) end end -actions["cleanup tables"] = function(data,filename,raw) +local function enhance_cleanup_tables(data,filename,raw) local duplicates = data.resources.duplicates if duplicates then for k, v in next, duplicates do @@ -2231,7 +2102,7 @@ end -- mlookups only with pairs and ligatures -actions["reorganize glyph lookups"] = function(data,filename,raw) +local function enhance_reorganize_glyph_lookups(data,filename,raw) local resources = data.resources local unicodes = resources.unicodes local descriptions = data.descriptions @@ -2317,7 +2188,7 @@ end local zero = { 0, 0 } -actions["reorganize glyph anchors"] = function(data,filename,raw) +local function enhance_reorganize_glyph_anchors(data,filename,raw) local descriptions = data.descriptions for unicode, description in next, descriptions do local anchors = description.glyph.anchors @@ -2368,7 +2239,7 @@ local bogusname = (P("uni") + P("u")) * R("AF","09")^4 + (P("index") + P("glyph") + S("Ii") * P("dentity") * P(".")^0) * R("09")^1 local uselessname = (1-bogusname)^0 * bogusname -actions["purge names"] = function(data,filename,raw) -- not used yet +local function enhance_purge_names(data,filename,raw) -- not used yet if purge_names then local n = 0 for u, d in next, data.descriptions do @@ -2384,7 +2255,7 @@ actions["purge names"] = function(data,filename,raw) -- not used yet end end -actions["compact lookups"] = function(data,filename,raw) +local function enhance_compact_lookups(data,filename,raw) if not compact_lookups then report_otf("not compacting") return @@ -2700,7 +2571,7 @@ local function copytotfm(data,cache_id) spaceunits, spacer = charwidth, "charwidth" end end - spaceunits = tonumber(spaceunits) or 500 -- brrr + spaceunits = tonumber(spaceunits) or units/2 -- parameters.slant = 0 parameters.space = spaceunits -- 3.333 (cmr10) @@ -3056,3 +2927,42 @@ function otf.getkern(tfmdata,left,right,kind) end return 0 end + + +registerotfenhancer("prepare tables", enhance_prepare_tables) + +registerotfenhancer("prepare glyphs", enhance_prepare_glyphs) +registerotfenhancer("prepare lookups", enhance_prepare_lookups) + +registerotfenhancer("analyze glyphs", enhance_analyze_glyphs) +registerotfenhancer("analyze math", enhance_analyze_math) + +registerotfenhancer("reorganize lookups", enhance_reorganize_lookups) +registerotfenhancer("reorganize mark classes", enhance_reorganize_mark_classes) +registerotfenhancer("reorganize anchor classes", enhance_reorganize_anchor_classes) + +registerotfenhancer("reorganize glyph kerns", enhance_reorganize_glyph_kerns) +registerotfenhancer("reorganize glyph lookups", enhance_reorganize_glyph_lookups) +registerotfenhancer("reorganize glyph anchors", enhance_reorganize_glyph_anchors) + +registerotfenhancer("merge kern classes", enhance_merge_kern_classes) + +registerotfenhancer("reorganize features", enhance_reorganize_features) +registerotfenhancer("reorganize subtables", enhance_reorganize_subtables) + +registerotfenhancer("check glyphs", enhance_check_glyphs) +registerotfenhancer("check metadata", enhance_check_metadata) + +registerotfenhancer("prepare tounicode", enhance_prepare_tounicode) + +registerotfenhancer("check encoding", enhance_check_encoding) +registerotfenhancer("add duplicates", enhance_add_duplicates) + +registerotfenhancer("expand lookups", enhance_expand_lookups) + +registerotfenhancer("check extra features", function() end) --placeholder, will be overloaded + +registerotfenhancer("cleanup tables", enhance_cleanup_tables) + +registerotfenhancer("compact lookups", enhance_compact_lookups) +registerotfenhancer("purge names", enhance_purge_names) diff --git a/tex/context/base/mkiv/font-oti.lua b/tex/context/base/mkiv/font-oti.lua index bacd001a5..4c6053be0 100644 --- a/tex/context/base/mkiv/font-oti.lua +++ b/tex/context/base/mkiv/font-oti.lua @@ -11,8 +11,8 @@ local lower = string.lower local fonts = fonts local constructors = fonts.constructors -local otf = constructors.newhandler("otf") -local otffeatures = constructors.newfeatures("otf") +local otf = constructors.handlers.otf +local otffeatures = constructors.features.otf local registerotffeature = otffeatures.register local otftables = otf.tables or { } @@ -34,6 +34,8 @@ local function setmode(tfmdata,value) end end +otf.modeinitializer = setmode + local function setlanguage(tfmdata,value) if value then local cleanvalue = lower(value) @@ -70,6 +72,7 @@ registerotffeature { initializers = { base = setmode, node = setmode, + plug = setmode, } } @@ -79,6 +82,7 @@ registerotffeature { initializers = { base = setlanguage, node = setlanguage, + plug = setlanguage, } } @@ -88,6 +92,7 @@ registerotffeature { initializers = { base = setscript, node = setscript, + plug = setscript, } } @@ -156,3 +161,102 @@ function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages) end end +-- the following might become available generic in due time but for now +-- this is some context playground (development code) + +-- if not context then +-- return +-- end + +-- local helpers = otf.readers.helpers +-- local axistofactors = helpers.axistofactors +-- local normalizedaxis = helpers.normalizedaxis +-- local getaxisscale = helpers.getaxisscale +-- local cleanname = containers.cleanname + +-- local function validvariable(tfmdata) +-- if tfmdata.properties.factors then +-- return +-- end +-- local resources = tfmdata.resources +-- local variabledata = resources and resources.variabledata +-- if not variabledata then +-- return +-- end +-- local instances = variabledata.instances +-- local axis = variabledata.axis +-- local segments = variabledata.segments +-- if instances and axis then +-- return instances, axis, segments +-- end +-- end + +-- local function initializeinstance(tfmdata,value) +-- if type(value) == "string" then +-- local instances, axis, segments = validvariable(tfmdata) +-- if instances then +-- local values +-- for i=1,#instances do +-- local instance = instances[i] +-- if cleanname(instance.subfamily) == value then +-- values = instance.values +-- break +-- end +-- end +-- if values then +-- local factors = { } +-- for i=1,#axis do +-- local a = axis[i] +-- factors[i] = getaxisscale(segments,a.minimum,a.default,a.maximum,values[i].value) +-- end +-- tfmdata.properties.instance = { +-- hash = instance, +-- factors = factors, +-- } +-- end +-- else +-- report("incomplete variable data") +-- end +-- end +-- end + +-- local function initializeaxis(tfmdata,value) +-- if type(value) == "string" then +-- local instances, axis, segments = validvariable(tfmdata) +-- if instances then +-- local values = axistofactors(value) +-- if values then +-- local factors = { } +-- for i=1,#axis do +-- local a = axis[i] +-- local d = a.default +-- factors[i] = getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d) +-- end +-- tfmdata.properties.instance = { +-- hash = cleanname(value), +-- factors = factors, +-- } +-- end +-- else +-- report("incomplete variable data") +-- end +-- end +-- end + +-- registerotffeature { +-- name = "instance", +-- description = "variation instance", +-- initializers = { +-- node = initializeinstance, +-- base = initializeinstance, +-- } +-- } + +-- registerotffeature { +-- name = "axis", +-- description = "variation axis", +-- initializers = { +-- node = initializeaxis, +-- base = initializeaxis, +-- } +-- } diff --git a/tex/context/base/mkiv/font-otj.lua b/tex/context/base/mkiv/font-otj.lua index b65a9db66..634f8a83c 100644 --- a/tex/context/base/mkiv/font-otj.lua +++ b/tex/context/base/mkiv/font-otj.lua @@ -16,18 +16,16 @@ if not modules then modules = { } end modules ['font-otj'] = { -- cleaner to have an identification pass here. Also, I need to keep tracing in mind so -- being too clever here is dangerous. --- The subtype test is not needed as there will be no (new) properties set, given that we --- reset the properties. - -- As we have a rawget on properties we don't need one on injections. --- The use_advance code is just a test and is meant for testing and manuals. There is no +-- The use_advance code was just a test and is meant for testing and manuals. There is no -- performance (or whatever) gain and using kerns is somewhat cleaner (at least for now). +-- Maybe: subtype fontkern when pure kerns. + if not nodes.properties then return end -local next, rawget = next, rawget -local utfchar = utf.char +local next, rawget, tonumber = next, rawget, tonumber local fastcopy = table.fastcopy local registertracker = trackers.register @@ -35,11 +33,7 @@ local registertracker = trackers.register local trace_injections = false registertracker("fonts.injections", function(v) trace_injections = v end) local trace_marks = false registertracker("fonts.injections.marks", function(v) trace_marks = v end) local trace_cursive = false registertracker("fonts.injections.cursive", function(v) trace_cursive = v end) -local trace_spaces = false registertracker("otf.spaces", function(v) trace_spaces = v end) - --- use_advance is just an experiment: it makes copying glyphs (instead of new_glyph) dangerous - -local use_advance = false directives.register("fonts.injections.advance", function(v) use_advance = v end) +local trace_spaces = false registertracker("fonts.injections.spaces", function(v) trace_spaces = v end) local report_injections = logs.reporter("fonts","injections") local report_spaces = logs.reporter("fonts","spaces") @@ -79,20 +73,23 @@ local getnext = nuts.getnext local getprev = nuts.getprev local getid = nuts.getid local getfont = nuts.getfont -local getsubtype = nuts.getsubtype local getchar = nuts.getchar +local getoffsets = nuts.getoffsets local getboth = nuts.getboth - -local ischar = nuts.is_char - local getdisc = nuts.getdisc local setdisc = nuts.setdisc +local setoffsets = nuts.setoffsets +local ischar = nuts.is_char +local getkern = nuts.getkern +local setkern = nuts.setkern +local setlink = nuts.setlink +local setwidth = nuts.setwidth +local getwidth = nuts.getwidth local traverse_id = nuts.traverse_id local traverse_char = nuts.traverse_char local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after -local find_tail = nuts.tail local properties = nodes.properties.data @@ -137,7 +134,7 @@ end -- if tp then -- tp.injections = si -- else --- propertydata[target] = { +-- properties[target] = { -- injections = si, -- } -- end @@ -169,7 +166,7 @@ function injections.copy(target,source) if tp then tp.injections = si else - propertydata[target] = { + properties[target] = { injections = si, } end @@ -377,7 +374,8 @@ function injections.setkern(current,factor,rlmode,x,injection) end end -function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) -- ba=baseanchor, ma=markanchor +function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark) -- ba=baseanchor, ma=markanchor + local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2]) nofregisteredmarks = nofregisteredmarks + 1 if rlmode >= 0 then @@ -398,6 +396,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) -- ba=b i.markbase = nofregisteredmarks i.markbasenode = base i.markmark = mkmk + i.checkmark = checkmark end else p.injections = { @@ -407,6 +406,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) -- ba=b markbase = nofregisteredmarks, markbasenode = base, markmark = mkmk, + checkmark = checkmark, } end else @@ -418,6 +418,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) -- ba=b markbase = nofregisteredmarks, markbasenode = base, markmark = mkmk, + checkmark = checkmark, }, } end @@ -523,11 +524,12 @@ local function show_result(head) while current do local id = getid(current) if id == glyph_code then - report_injections("char: %C, width %p, xoffset %p, yoffset %p", - getchar(current),getfield(current,"width"),getfield(current,"xoffset"),getfield(current,"yoffset")) + local w = getwidth(current) + local x, y = getoffsets(current) + report_injections("char: %C, width %p, xoffset %p, yoffset %p",getchar(current),w,x,y) skipping = false elseif id == kern_code then - report_injections("kern: %p",getfield(current,"kern")) + report_injections("kern: %p",getkern(current)) skipping = false elseif not skipping then report_injections() @@ -562,76 +564,65 @@ local function inject_kerns_only(head,where) local posttail = nil -- saves a lookup local replacetail = nil -- saves a lookup while current do - local id = getid(current) local next = getnext(current) - if id == glyph_code then - if getsubtype(current) < 256 then - local p = rawget(properties,current) - if p then - -- local i = rawget(p,"injections") - local i = p.injections - if i then - -- left|glyph|right - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - if use_advance then - setfield(current,"xoffset",leftkern) - setfield(current,"xadvance",leftkern) - else - insert_node_before(head,current,newkern(leftkern)) + local char, id = ischar(current) + if char then + local p = rawget(properties,current) + if p then + -- local i = rawget(p,"injections") + local i = p.injections + if i then + -- left|glyph|right + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + head = insert_node_before(head,current,newkern(leftkern)) + end + end + if prevdisc then + local done = false + if post then + -- local i = rawget(p,"postinjections") + local i = p.postinjections + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + setlink(posttail,newkern(leftkern)) + done = true end end end - if prevdisc then - local done = false - if post then - -- local i = rawget(p,"postinjections") - local i = p.postinjections - if i then - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - if use_advance then - setfield(post,"xadvance",leftkern) - else - insert_node_after(post,posttail,newkern(leftkern)) - done = true - end - end + if replace then + -- local i = rawget(p,"replaceinjections") + local i = p.replaceinjections + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + setlink(replacetail,newkern(leftkern)) + done = true end end - if replace then - -- local i = rawget(p,"replaceinjections") - local i = p.replaceinjections - if i then - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - if use_advance then - setfield(replace,"xadvance",leftkern) - else - insert_node_after(replace,replacetail,newkern(leftkern)) - done = true - end - end - end - else - -- local i = rawget(p,"emptyinjections") - local i = p.emptyinjections - if i then - -- glyph|disc|glyph (special case) - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - setfield(prev,"replace",newkern(leftkern)) -- maybe also leftkern - end + else + -- local i = rawget(p,"emptyinjections") + local i = p.emptyinjections + if i then + -- glyph|disc|glyph (special case) + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + setfield(prev,"replace",newkern(leftkern)) -- maybe also leftkern end end - if done then - setdisc(prevdisc,pre,post,replace) - end + end + if done then + setdisc(prevdisc,pre,post,replace) end end end prevdisc = nil prevglyph = current + elseif char == false then + -- other font + prevdisc = nil + prevglyph = current elseif id == disc_code then pre, post, replace, pretail, posttail, replacetail = getdisc(current,true) local done = false @@ -645,13 +636,8 @@ local function inject_kerns_only(head,where) if i then local leftkern = i.leftkern if leftkern and leftkern ~= 0 then - if use_advance then - setfield(pre,"xoffset",leftkern) - setfield(pre,"xadvance",leftkern) - else - pre = insert_node_before(pre,n,newkern(leftkern)) - done = true - end + pre = insert_node_before(pre,n,newkern(leftkern)) + done = true end end end @@ -667,13 +653,8 @@ local function inject_kerns_only(head,where) if i then local leftkern = i.leftkern if leftkern and leftkern ~= 0 then - if use_advance then - setfield(post,"xoffset",leftkern) - setfield(post,"xadvance",leftkern) - else - post = insert_node_before(post,n,newkern(leftkern)) - done = true - end + post = insert_node_before(post,n,newkern(leftkern)) + done = true end end end @@ -689,13 +670,8 @@ local function inject_kerns_only(head,where) if i then local leftkern = i.leftkern if leftkern and leftkern ~= 0 then - if use_advance then - setfield(replace,"xoffset",leftkern) - setfield(replace,"xadvance",leftkern) - else - replace = insert_node_before(replace,n,newkern(leftkern)) - done = true - end + replace = insert_node_before(replace,n,newkern(leftkern)) + done = true end end end @@ -739,87 +715,88 @@ local function inject_pairs_only(head,where) local posttail = nil -- saves a lookup local replacetail = nil -- saves a lookup while current do - local id = getid(current) local next = getnext(current) - if id == glyph_code then - if getsubtype(current) < 256 then - local p = rawget(properties,current) - if p then - -- local i = rawget(p,"injections") - local i = p.injections + local char, id = ischar(current) + if char then + local p = rawget(properties,current) + if p then + -- local i = rawget(p,"injections") + local i = p.injections + if i then + -- left|glyph|right + local yoffset = i.yoffset + if yoffset and yoffset ~= 0 then + setoffsets(current,false,yoffset) + end + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + head = insert_node_before(head,current,newkern(leftkern)) + end + local rightkern = i.rightkern + if rightkern and rightkern ~= 0 then + insert_node_after(head,current,newkern(rightkern)) + end + else + -- local i = rawget(p,"emptyinjections") + local i = p.emptyinjections if i then - -- left|glyph|right - local yoffset = i.yoffset - if yoffset and yoffset ~= 0 then - setfield(current,"yoffset",yoffset) - end - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - insert_node_before(head,current,newkern(leftkern)) - end + -- glyph|disc|glyph (special case) +-- is this okay? local rightkern = i.rightkern if rightkern and rightkern ~= 0 then - insert_node_after(head,current,newkern(rightkern)) - end - else - -- local i = rawget(p,"emptyinjections") - local i = p.emptyinjections - if i then - -- glyph|disc|glyph (special case) --- is this okay? - local rightkern = i.rightkern - if rightkern and rightkern ~= 0 then - if next and getid(next) == disc_code then - if replace then - -- error, we expect an empty one - else - setfield(next,"replace",newkern(rightkern)) -- maybe also leftkern - end + if next and getid(next) == disc_code then + if replace then + -- error, we expect an empty one + else + setfield(next,"replace",newkern(rightkern)) -- maybe also leftkern end end end end - if prevdisc then - local done = false - if post then - -- local i = rawget(p,"postinjections") - local i = p.postinjections - if i then - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - insert_node_after(post,posttail,newkern(leftkern)) - done = true - end + end + if prevdisc then + local done = false + if post then + -- local i = rawget(p,"postinjections") + local i = p.postinjections + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + setlink(posttail,newkern(leftkern)) + done = true end end - if replace then - -- local i = rawget(p,"replaceinjections") - local i = p.replaceinjections - if i then - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - insert_node_after(replace,replacetail,newkern(leftkern)) - done = true - end - end - else - local i = p.emptyinjections - if i then --- new .. okay? - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - setfield(prev,"replace",newkern(leftkern)) -- maybe also leftkern - end + end + if replace then + -- local i = rawget(p,"replaceinjections") + local i = p.replaceinjections + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + setlink(replacetail,newkern(leftkern)) + done = true end end - if done then - setdisc(prevdisc,pre,post,replace) + else + local i = p.emptyinjections + if i then + -- new .. okay? + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + setfield(prev,"replace",newkern(leftkern)) -- maybe also leftkern + end end end + if done then + setdisc(prevdisc,pre,post,replace) + end end end prevdisc = nil prevglyph = current + elseif char == false then + prevdisc = nil + prevglyph = current elseif id == disc_code then pre, post, replace, pretail, posttail, replacetail = getdisc(current,true) local done = false @@ -833,7 +810,7 @@ local function inject_pairs_only(head,where) if i then local yoffset = i.yoffset if yoffset and yoffset ~= 0 then - setfield(n,"yoffset",yoffset) + setoffsets(n,false,yoffset) end local leftkern = i.leftkern if leftkern and leftkern ~= 0 then @@ -859,7 +836,7 @@ local function inject_pairs_only(head,where) if i then local yoffset = i.yoffset if yoffset and yoffset ~= 0 then - setfield(n,"yoffset",yoffset) + setoffsets(n,false,yoffset) end local leftkern = i.leftkern if leftkern and leftkern ~= 0 then @@ -885,7 +862,7 @@ local function inject_pairs_only(head,where) if i then local yoffset = i.yoffset if yoffset and yoffset ~= 0 then - setfield(n,"yoffset",yoffset) + setoffsets(n,false,yoffset) end local leftkern = i.leftkern if leftkern and leftkern ~= 0 then @@ -954,30 +931,9 @@ local function inject_pairs_only(head,where) return tonode(head), true end --- local function showoffset(n,flag) --- local ox = getfield(n,"xoffset") --- local oy = getfield(n,"yoffset") --- if flag then --- if ox == 0 then --- setcolor(n,oy == 0 and "darkgray" or "darkgreen") --- else --- setcolor(n,oy == 0 and "darkblue" or "darkred") --- end --- else --- if ox == 0 then --- setcolor(n,oy == 0 and "gray" or "green") --- else --- setcolor(n,oy == 0 and "blue" or "red") --- end --- end --- end - local function showoffset(n,flag) - local o = getfield(n,"xoffset") - if o == 0 then - o = getfield(n,"yoffset") - end - if o ~= 0 then + local x, y = getoffsets(n) + if x ~= 0 or y ~= 0 then setcolor(n,flag and "darkred" or "darkgreen") else resetcolor(n) @@ -1017,7 +973,8 @@ local function inject_everything(head,where) -- move out -- local function processmark(p,n,pn) -- p = basenode - local px = getfield(p,"xoffset") + local px, py = getoffsets(p) + local nx, ny = getoffsets(n) local ox = 0 local rightkern = nil local pp = rawget(properties,p) @@ -1035,7 +992,7 @@ local function inject_everything(head,where) -- report_injections("r2l case 1: %p",ox) else -- kern(x) glyph(p) kern(w-x) mark(n) - -- ox = px - getfield(p,"width") + pn.markx - pp.leftkern + -- ox = px - getwidth(p) + pn.markx - pp.leftkern -- -- According to Kai we don't need to handle leftkern here but I'm -- pretty sure I've run into a case where it was needed so maybe @@ -1050,7 +1007,7 @@ local function inject_everything(head,where) ox = px - pn.markx end else - ox = px - pn.markx + ox = px - pn.markx - rightkern -- seguiemj needs the rightkern end end else @@ -1058,178 +1015,191 @@ local function inject_everything(head,where) -- ox = px - pn.markx -- -- report_injections("r2l case 3: %p",ox) -- else - -- -- ox = px - getfield(p,"width") + pn.markx + -- -- ox = px - getwidth(p) + pn.markx ox = px - pn.markx -- report_injections("l2r case 3: %p",ox) -- end - local wn = getfield(n,"width") -- in arial marks have widths - if wn ~= 0 then - -- bad: we should center - pn.leftkern = -wn/2 - pn.rightkern = -wn/2 + if pn.checkmark then + local wn = getwidth(n) -- in arial marks have widths + if wn and wn ~= 0 then + wn = wn/2 + if trace_injections then + report_injections("correcting non zero width mark %C",getchar(n)) + end + -- -- bad: we should center + -- pn.leftkern = -wn + -- pn.rightkern = -wn + -- -- we're too late anyway as kerns are already injected so + -- -- we do it the ugly way (no checking if the previous is + -- -- already a kern) .. maybe we should fix the font instead + -- hm, no head ? + insert_node_before(n,n,newkern(-wn)) + insert_node_after(n,n,newkern(-wn)) + end end end - local oy = getfield(n,"yoffset") + getfield(p,"yoffset") + pn.marky - setfield(n,"xoffset",ox) - setfield(n,"yoffset",oy) + local oy = ny + py + pn.marky + setoffsets(n,ox,oy) if trace_marks then showoffset(n,true) end end -- todo: marks in disc while current do - local id = getid(current) local next = getnext(current) - if id == glyph_code then - if getsubtype(current) < 256 then - local p = rawget(properties,current) - if p then - -- local i = rawget(p,"injections") - local i = p.injections - if i then - local pm = i.markbasenode - if pm then - nofmarks = nofmarks + 1 - marks[nofmarks] = current - else - if hascursives then - local cursivex = i.cursivex - if cursivex then - if cursiveanchor then - if cursivex ~= 0 then - i.leftkern = (i.leftkern or 0) + cursivex - end - if maxc == 0 then - minc = 1 - maxc = 1 - glyphs[1] = cursiveanchor - else - maxc = maxc + 1 - glyphs[maxc] = cursiveanchor - end - properties[cursiveanchor].cursivedy = i.cursivey -- cursiveprops - last = current + local char, id = ischar(current) + if char then + local p = rawget(properties,current) + if p then + -- local i = rawget(p,"injections") + local i = p.injections + if i then + local pm = i.markbasenode + if pm then + nofmarks = nofmarks + 1 + marks[nofmarks] = current + else + local yoffset = i.yoffset + if yoffset and yoffset ~= 0 then + setoffsets(current,false,yoffset) + end + if hascursives then + local cursivex = i.cursivex + if cursivex then + if cursiveanchor then + if cursivex ~= 0 then + i.leftkern = (i.leftkern or 0) + cursivex + end + if maxc == 0 then + minc = 1 + maxc = 1 + glyphs[1] = cursiveanchor else - maxc = 0 + maxc = maxc + 1 + glyphs[maxc] = cursiveanchor end - elseif maxc > 0 then - local ny = getfield(current,"yoffset") + properties[cursiveanchor].cursivedy = i.cursivey -- cursiveprops + last = current + else + maxc = 0 + end + elseif maxc > 0 then + local nx, ny = getoffsets(current) + for i=maxc,minc,-1 do + local ti = glyphs[i] + ny = ny + properties[ti].cursivedy + setoffsets(ti,false,ny) -- why not add ? + if trace_cursive then + showoffset(ti) + end + end + maxc = 0 + cursiveanchor = nil + end + if i.cursiveanchor then + cursiveanchor = current -- no need for both now + else + if maxc > 0 then + local nx, ny = getoffsets(current) for i=maxc,minc,-1 do local ti = glyphs[i] ny = ny + properties[ti].cursivedy - setfield(ti,"yoffset",ny) -- why not add ? + setoffsets(ti,false,ny) -- why not add ? if trace_cursive then showoffset(ti) end end maxc = 0 - cursiveanchor = nil end - if i.cursiveanchor then - cursiveanchor = current -- no need for both now - else - if maxc > 0 then - local ny = getfield(current,"yoffset") - for i=maxc,minc,-1 do - local ti = glyphs[i] - ny = ny + properties[ti].cursivedy - setfield(ti,"yoffset",ny) -- why not add ? - if trace_cursive then - showoffset(ti) - end - end - maxc = 0 - end - cursiveanchor = nil - end - end - -- left|glyph|right - local yoffset = i.yoffset - if yoffset and yoffset ~= 0 then - setfield(current,"yoffset",yoffset) - end - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - insert_node_before(head,current,newkern(leftkern)) - end - local rightkern = i.rightkern - if rightkern and rightkern ~= 0 then - insert_node_after(head,current,newkern(rightkern)) + cursiveanchor = nil end end - else - -- local i = rawget(p,"emptyinjections") - local i = p.emptyinjections - if i then - -- glyph|disc|glyph (special case) --- okay? - local rightkern = i.rightkern - if rightkern and rightkern ~= 0 then - if next and getid(next) == disc_code then - if replace then - -- error, we expect an empty one - else - setfield(next,"replace",newkern(rightkern)) -- maybe also leftkern - end + -- left|glyph|right + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + head = insert_node_before(head,current,newkern(leftkern)) + end + local rightkern = i.rightkern + if rightkern and rightkern ~= 0 then + insert_node_after(head,current,newkern(rightkern)) + end + end + else + -- local i = rawget(p,"emptyinjections") + local i = p.emptyinjections + if i then + -- glyph|disc|glyph (special case) + -- okay? + local rightkern = i.rightkern + if rightkern and rightkern ~= 0 then + if next and getid(next) == disc_code then + if replace then + -- error, we expect an empty one + else + setfield(next,"replace",newkern(rightkern)) -- maybe also leftkern end end end end - if prevdisc then - if p then - local done = false - if post then - -- local i = rawget(p,"postinjections") - local i = p.postinjections - if i then - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - insert_node_after(post,posttail,newkern(leftkern)) - done = true - end + end + if prevdisc then + if p then + local done = false + if post then + -- local i = rawget(p,"postinjections") + local i = p.postinjections + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + setlink(posttail,newkern(leftkern)) + done = true end end - if replace then - -- local i = rawget(p,"replaceinjections") - local i = p.replaceinjections - if i then - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - insert_node_after(replace,replacetail,newkern(leftkern)) - done = true - end - end - else - -- local i = rawget(p,"emptyinjections") - local i = p.emptyinjections - if i then - local leftkern = i.leftkern - if leftkern and leftkern ~= 0 then - setfield(prev,"replace",newkern(leftkern)) -- maybe also leftkern - end + end + if replace then + -- local i = rawget(p,"replaceinjections") + local i = p.replaceinjections + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + setlink(replacetail,newkern(leftkern)) + done = true end end - if done then - setdisc(prevdisc,pre,post,replace) + else + -- local i = rawget(p,"emptyinjections") + local i = p.emptyinjections + if i then + local leftkern = i.leftkern + if leftkern and leftkern ~= 0 then + setfield(prev,"replace",newkern(leftkern)) -- maybe also leftkern + end end end - end - else - -- cursive - if hascursives and maxc > 0 then - local ny = getfield(current,"yoffset") - for i=maxc,minc,-1 do - local ti = glyphs[i] - ny = ny + properties[ti].cursivedy - setfield(ti,"yoffset",getfield(ti,"yoffset") + ny) -- can be mark + if done then + setdisc(prevdisc,pre,post,replace) end - maxc = 0 - cursiveanchor = nil end end + else + -- cursive + if hascursives and maxc > 0 then + local nx, ny = getoffsets(current) + for i=maxc,minc,-1 do + local ti = glyphs[i] + ny = ny + properties[ti].cursivedy + local xi, yi = getoffsets(ti) + setoffsets(ti,xi,yi + ny) -- can be mark, we could use properties + end + maxc = 0 + cursiveanchor = nil + end end prevdisc = nil prevglyph = current + elseif char == false then + prevdisc = nil + prevglyph = current elseif id == disc_code then pre, post, replace, pretail, posttail, replacetail = getdisc(current,true) local done = false @@ -1243,7 +1213,7 @@ local function inject_everything(head,where) if i then local yoffset = i.yoffset if yoffset and yoffset ~= 0 then - setfield(n,"yoffset",yoffset) + setoffsets(n,false,yoffset) end local leftkern = i.leftkern if leftkern and leftkern ~= 0 then @@ -1258,7 +1228,7 @@ local function inject_everything(head,where) if hasmarks then local pm = i.markbasenode if pm then - processmark(pm,current,i) + processmark(pm,n,i) end end end @@ -1275,7 +1245,7 @@ local function inject_everything(head,where) if i then local yoffset = i.yoffset if yoffset and yoffset ~= 0 then - setfield(n,"yoffset",yoffset) + setoffsets(n,false,yoffset) end local leftkern = i.leftkern if leftkern and leftkern ~= 0 then @@ -1290,7 +1260,7 @@ local function inject_everything(head,where) if hasmarks then local pm = i.markbasenode if pm then - processmark(pm,current,i) + processmark(pm,n,i) end end end @@ -1307,7 +1277,7 @@ local function inject_everything(head,where) if i then local yoffset = i.yoffset if yoffset and yoffset ~= 0 then - setfield(n,"yoffset",yoffset) + setoffsets(n,false,yoffset) end local leftkern = i.leftkern if leftkern and leftkern ~= 0 then @@ -1322,7 +1292,7 @@ local function inject_everything(head,where) if hasmarks then local pm = i.markbasenode if pm then - processmark(pm,current,i) + processmark(pm,n,i) end end end @@ -1375,11 +1345,11 @@ local function inject_everything(head,where) end -- cursive if hascursives and maxc > 0 then - local ny = getfield(last,"yoffset") + local nx, ny = getoffsets(last) for i=maxc,minc,-1 do local ti = glyphs[i] ny = ny + properties[ti].cursivedy - setfield(ti,"yoffset",ny) -- why not add ? + setoffsets(ti,false,ny) -- why not add ? if trace_cursive then showoffset(ti) end @@ -1422,6 +1392,48 @@ function nodes.injections.setspacekerns(font,sequence) end end +local getthreshold + +if context then + + local threshold = 1 -- todo: add a few methods for context + local parameters = fonts.hashes.parameters + + directives.register("otf.threshold", function(v) threshold = tonumber(v) or 1 end) + + getthreshold = function(font) + local p = parameters[font] + local f = p.factor + local s = p.spacing + local t = threshold * (s and s.width or p.space or 0) - 2 + return t > 0 and t or 0, f + end + +else + + injections.threshold = 0 + + getthreshold = function(font) + local p = fontdata[font].parameters + local f = p.factor + local s = p.spacing + local t = injections.threshold * (s and s.width or p.space or 0) - 2 + return t > 0 and t or 0, f + end + +end + +injections.getthreshold = getthreshold + +function injections.isspace(n,threshold,id) + if (id or getid(n)) == glue_code then + local w = getwidth(n) + if threshold and w > threshold then -- was >= + return 32 + end + end +end + local function injectspaces(head) if not triggers then @@ -1438,18 +1450,11 @@ local function injectspaces(head) local rightkern = false local function updatefont(font,trig) - -- local resources = resources[font] - -- local spacekerns = resources.spacekerns - -- if spacekerns then - -- leftkerns = spacekerns.left - -- rightkerns = spacekerns.right - -- end leftkerns = trig.left rightkerns = trig.right - local par = fontdata[font].parameters -- fallback for generic - factor = par.factor - threshold = par.spacing.width - 1 -- get rid of rounding errors lastfont = font + threshold, + factor = getthreshold(font) end for n in traverse_id(glue_code,tonut(head)) do @@ -1469,7 +1474,7 @@ local function injectspaces(head) end end if prevchar then - local font = getfont(next) + local font = getfont(prev) local trig = triggers[font] if trig then if lastfont ~= font then @@ -1481,32 +1486,32 @@ local function injectspaces(head) end end if leftkern then - local old = getfield(n,"width") - if old >= threshold then + local old = getwidth(n) + if old > threshold then if rightkern then local new = old + (leftkern + rightkern) * factor if trace_spaces then report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar) end - setfield(n,"width",new) + setwidth(n,new) leftkern = false else local new = old + leftkern * factor if trace_spaces then report_spaces("%C [%p -> %p]",prevchar,old,new) end - setfield(n,"width",new) + setwidth(n,new) end end leftkern = false elseif rightkern then - local old = getfield(n,"width") - if old >= threshold then + local old = getwidth(n) + if old > threshold then local new = old + rightkern * factor if trace_spaces then report_spaces("[%p -> %p] %C",nextchar,old,new) end - setfield(n,"width",new) + setwidth(n,new) end rightkern = false end @@ -1522,11 +1527,21 @@ function injections.handler(head,where) if triggers then head = injectspaces(head) end + -- todo: marks only run too if nofregisteredmarks > 0 or nofregisteredcursives > 0 then + if trace_injections then + report_injections("injection variant %a","everything") + end return inject_everything(head,where) elseif nofregisteredpairs > 0 then + if trace_injections then + report_injections("injection variant %a","pairs") + end return inject_pairs_only(head,where) elseif nofregisteredkerns > 0 then + if trace_injections then + report_injections("injection variant %a","kerns") + end return inject_kerns_only(head,where) else return head, false diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua index 304b6b989..9400096a0 100644 --- a/tex/context/base/mkiv/font-otl.lua +++ b/tex/context/base/mkiv/font-otl.lua @@ -23,183 +23,88 @@ if not modules then modules = { } end modules ['font-otl'] = { -- todo: less tounicodes -local gmatch, find, match, lower, strip = string.gmatch, string.find, string.match, string.lower, string.strip +local lower = string.lower local type, next, tonumber, tostring, unpack = type, next, tonumber, tostring, unpack local abs = math.abs -local ioflush = io.flush local derivetable = table.derive local formatters = string.formatters -local setmetatableindex = table.setmetatableindex -local allocate = utilities.storage.allocate -local registertracker = trackers.register -local registerdirective = directives.register -local starttiming = statistics.starttiming -local stoptiming = statistics.stoptiming -local elapsedtime = statistics.elapsedtime -local findbinfile = resolvers.findbinfile +local setmetatableindex = table.setmetatableindex +local allocate = utilities.storage.allocate +local registertracker = trackers.register +local registerdirective = directives.register +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming +local elapsedtime = statistics.elapsedtime +local findbinfile = resolvers.findbinfile ------ trace_private = false registertracker("otf.private", function(v) trace_private = v end) ------ trace_subfonts = false registertracker("otf.subfonts", function(v) trace_subfonts = v end) -local trace_loading = false registertracker("otf.loading", function(v) trace_loading = v end) -local trace_features = false registertracker("otf.features", function(v) trace_features = v end) ------ trace_dynamics = false registertracker("otf.dynamics", function(v) trace_dynamics = v end) ------ trace_sequences = false registertracker("otf.sequences", function(v) trace_sequences = v end) ------ trace_markwidth = false registertracker("otf.markwidth", function(v) trace_markwidth = v end) -local trace_defining = false registertracker("fonts.defining", function(v) trace_defining = v end) +----- trace_private = false registertracker("otf.private", function(v) trace_private = v end) +----- trace_subfonts = false registertracker("otf.subfonts", function(v) trace_subfonts = v end) +local trace_loading = false registertracker("otf.loading", function(v) trace_loading = v end) +local trace_features = false registertracker("otf.features", function(v) trace_features = v end) +----- trace_dynamics = false registertracker("otf.dynamics", function(v) trace_dynamics = v end) +----- trace_sequences = false registertracker("otf.sequences", function(v) trace_sequences = v end) +----- trace_markwidth = false registertracker("otf.markwidth", function(v) trace_markwidth = v end) +local trace_defining = false registertracker("fonts.defining", function(v) trace_defining = v end) -local report_otf = logs.reporter("fonts","otf loading") +local report_otf = logs.reporter("fonts","otf loading") -local fonts = fonts -local otf = fonts.handlers.otf +local fonts = fonts +local otf = fonts.handlers.otf -otf.version = 3.020 -- beware: also sync font-mis.lua and in mtx-fonts -otf.cache = containers.define("fonts", "otl", otf.version, true) +otf.version = 3.029 -- beware: also sync font-mis.lua and in mtx-fonts +otf.cache = containers.define("fonts", "otl", otf.version, true) +otf.svgcache = containers.define("fonts", "svg", otf.version, true) +otf.sbixcache = containers.define("fonts", "sbix", otf.version, true) +otf.pdfcache = containers.define("fonts", "pdf", otf.version, true) -local otfreaders = otf.readers +otf.svgenabled = false +otf.sbixenabled = false -local hashes = fonts.hashes -local definers = fonts.definers -local readers = fonts.readers -local constructors = fonts.constructors +local otfreaders = otf.readers -local otffeatures = constructors.newfeatures("otf") -local registerotffeature = otffeatures.register +local hashes = fonts.hashes +local definers = fonts.definers +local readers = fonts.readers +local constructors = fonts.constructors -local enhancers = allocate() -otf.enhancers = enhancers -local patches = { } -enhancers.patches = patches +local otffeatures = constructors.features.otf +local registerotffeature = otffeatures.register -local forceload = false -local cleanup = 0 -- mk: 0=885M 1=765M 2=735M (regular run 730M) -local syncspace = true -local forcenotdef = false +local otfenhancers = constructors.enhancers.otf +local registerotfenhancer = otfenhancers.register -local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes +local forceload = false +local cleanup = 0 -- mk: 0=885M 1=765M 2=735M (regular run 730M) +local syncspace = true +local forcenotdef = false -local wildcard = "*" -local default = "dflt" +local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes -local formats = fonts.formats +local wildcard = "*" +local default = "dflt" -formats.otf = "opentype" -formats.ttf = "truetype" -formats.ttc = "truetype" +local formats = fonts.formats + +formats.otf = "opentype" +formats.ttf = "truetype" +formats.ttc = "truetype" registerdirective("fonts.otf.loader.cleanup", function(v) cleanup = tonumber(v) or (v and 1) or 0 end) registerdirective("fonts.otf.loader.force", function(v) forceload = v end) registerdirective("fonts.otf.loader.syncspace", function(v) syncspace = v end) registerdirective("fonts.otf.loader.forcenotdef", function(v) forcenotdef = v end) --- local function load_featurefile(raw,featurefile) --- if featurefile and featurefile ~= "" then --- if trace_loading then --- report_otf("using featurefile %a", featurefile) --- end --- -- TODO: apply_featurefile(raw, featurefile) --- end --- end - --- Enhancers are used to apply fixes and extensions to fonts. For instance, we use them --- to implement tlig and trep features. They are not neccessarily bound to opentype --- fonts but can also apply to type one fonts, given that they obey the structure of an --- opentype font. They are not to be confused with format specific features but maybe --- some are so generic that they might eventually move to this mechanism. - -local ordered_enhancers = { - "check extra features", -} - -local actions = allocate() -local before = allocate() -local after = allocate() - -patches.before = before -patches.after = after - -local function enhance(name,data,filename,raw) - local enhancer = actions[name] - if enhancer then - if trace_loading then - report_otf("apply enhancement %a to file %a",name,filename) - ioflush() - end - enhancer(data,filename,raw) - else - -- no message as we can have private ones - end -end - -function enhancers.apply(data,filename,raw) - local basename = file.basename(lower(filename)) - if trace_loading then - report_otf("%s enhancing file %a","start",filename) - end - ioflush() -- we want instant messages - for e=1,#ordered_enhancers do - local enhancer = ordered_enhancers[e] - local b = before[enhancer] - if b then - for pattern, action in next, b do - if find(basename,pattern) then - action(data,filename,raw) - end - end - end - enhance(enhancer,data,filename,raw) - local a = after[enhancer] - if a then - for pattern, action in next, a do - if find(basename,pattern) then - action(data,filename,raw) - end - end - end - ioflush() -- we want instant messages - end - if trace_loading then - report_otf("%s enhancing file %a","stop",filename) - end - ioflush() -- we want instant messages -end - --- patches.register("before","migrate metadata","cambria",function() end) - -function patches.register(what,where,pattern,action) - local pw = patches[what] - if pw then - local ww = pw[where] - if ww then - ww[pattern] = action - else - pw[where] = { [pattern] = action} - end - end -end - -function patches.report(fmt,...) - if trace_loading then - report_otf("patching: %s",formatters[fmt](...)) - end -end +-- otfenhancers.patch("before","migrate metadata","cambria",function() end) -function enhancers.register(what,action) -- only already registered can be overloaded - actions[what] = action -end +registerotfenhancer("check extra features", function() end) -- placeholder -function otf.load(filename,sub,featurefile) -- second argument (format) is gone ! - -- - local featurefile = nil -- not supported (yet) - -- +function otf.load(filename,sub,instance) local base = file.basename(file.removesuffix(filename)) - local name = file.removesuffix(base) + local name = file.removesuffix(base) -- already no suffix local attr = lfs.attributes(filename) local size = attr and attr.size or 0 local time = attr and attr.modification or 0 - if featurefile then - name = name .. "@" .. file.removesuffix(file.basename(featurefile)) - end -- sub can be number of string if sub == "" then sub = false @@ -208,68 +113,57 @@ function otf.load(filename,sub,featurefile) -- second argument (format) is gone if sub then hash = hash .. "-" .. sub end - hash = containers.cleanname(hash) - local featurefiles - if featurefile then - featurefiles = { } - for s in gmatch(featurefile,"[^,]+") do - local name = resolvers.findfile(file.addsuffix(s,'fea'),'fea') or "" - if name == "" then - report_otf("loading error, no featurefile %a",s) - else - local attr = lfs.attributes(name) - featurefiles[#featurefiles+1] = { - name = name, - size = attr and attr.size or 0, - time = attr and attr.modification or 0, - } - end - end - if #featurefiles == 0 then - featurefiles = nil - end + if instance then + hash = hash .. "-" .. instance end + hash = containers.cleanname(hash) local data = containers.read(otf.cache,hash) local reload = not data or data.size ~= size or data.time ~= time or data.tableversion ~= otfreaders.tableversion if forceload then report_otf("forced reload of %a due to hard coded flag",filename) reload = true end - -- if not reload then - -- local featuredata = data.featuredata - -- if featurefiles then - -- if not featuredata or #featuredata ~= #featurefiles then - -- reload = true - -- else - -- for i=1,#featurefiles do - -- local fi, fd = featurefiles[i], featuredata[i] - -- if fi.name ~= fd.name or fi.size ~= fd.size or fi.time ~= fd.time then - -- reload = true - -- break - -- end - -- end - -- end - -- elseif featuredata then - -- reload = true - -- end - -- if reload then - -- report_otf("loading: forced reload due to changed featurefile specification %a",featurefile) - -- end - -- end if reload then report_otf("loading %a, hash %a",filename,hash) -- starttiming(otfreaders) - data = otfreaders.loadfont(filename,sub or 1) -- we can pass the number instead (if it comes from a name search) - -- - -- if featurefiles then - -- for i=1,#featurefiles do - -- load_featurefile(data,featurefiles[i].name) - -- end - -- end - -- - -- + data = otfreaders.loadfont(filename,sub or 1,instance) -- we can pass the number instead (if it comes from a name search) if data then + -- todo: make this a plugin + local resources = data.resources + local svgshapes = resources.svgshapes + local sbixshapes = resources.sbixshapes + if svgshapes then + resources.svgshapes = nil + if otf.svgenabled then + local timestamp = os.date() + -- work in progress ... a bit boring to do + containers.write(otf.svgcache,hash, { + svgshapes = svgshapes, + timestamp = timestamp, + }) + data.properties.svg = { + hash = hash, + timestamp = timestamp, + } + end + end + if sbixshapes then + resources.sbixshapes = nil + if otf.sbixenabled then + local timestamp = os.date() + -- work in progress ... a bit boring to do + containers.write(otf.sbixcache,hash, { + sbixshapes = sbixshapes, + timestamp = timestamp, + }) + data.properties.sbix = { + hash = hash, + timestamp = timestamp, + } + end + end + -- otfreaders.compact(data) otfreaders.rehash(data,"unicodes") otfreaders.addunicodetable(data) @@ -282,7 +176,7 @@ function otf.load(filename,sub,featurefile) -- second argument (format) is gone collectgarbage("collect") end stoptiming(otfreaders) - if elapsedtime then -- not in generic + if elapsedtime then report_otf("loading, optimizing, packing and caching time %s", elapsedtime(otfreaders)) end if cleanup > 3 then @@ -306,7 +200,7 @@ function otf.load(filename,sub,featurefile) -- second argument (format) is gone otfreaders.expand(data) -- inline tables otfreaders.addunicodetable(data) -- only when not done yet -- - enhancers.apply(data,filename,data) + otfenhancers.apply(data,filename,data) -- -- constructors.addcoreunicodes(data.resources.unicodes) -- still needed ? -- @@ -315,9 +209,23 @@ function otf.load(filename,sub,featurefile) -- second argument (format) is gone end -- data.metadata.math = data.resources.mathconstants + -- + -- delayed tables (experiment) + -- + local classes = data.resources.classes + if not classes then + local descriptions = data.descriptions + classes = setmetatableindex(function(t,k) + local d = descriptions[k] + local v = (d and d.class or "base") or false + t[k] = v + return v + end) + data.resources.classes = classes + end + -- end - return data end @@ -346,7 +254,6 @@ end local function copytotfm(data,cache_id) if data then local metadata = data.metadata - local resources = data.resources local properties = derivetable(data.properties) local descriptions = derivetable(data.descriptions) local goodies = derivetable(data.goodies) @@ -485,14 +392,14 @@ local function copytotfm(data,cache_id) spaceunits, spacer = charwidth, "charwidth" end end - spaceunits = tonumber(spaceunits) or 500 -- brrr + spaceunits = tonumber(spaceunits) or units/2 -- parameters.slant = 0 - parameters.space = spaceunits -- 3.333 (cmr10) + parameters.space = spaceunits -- 3.333 (cmr10) parameters.space_stretch = 1*units/2 -- 500 -- 1.666 (cmr10) - parameters.space_shrink = 1*units/3 -- 333 -- 1.111 (cmr10) - parameters.x_height = 2*units/5 -- 400 - parameters.quad = units -- 1000 + parameters.space_shrink = 1*units/3 -- 333 -- 1.111 (cmr10) + parameters.x_height = 2*units/5 -- 400 + parameters.quad = units -- 1000 if spaceunits < 2*units/5 then -- todo: warning end @@ -553,16 +460,55 @@ local function copytotfm(data,cache_id) end end +-- These woff files are a kind of joke in a tex environment because one can simply convert +-- them to ttf/otf and use them as such (after all, we cache them too). The successor format +-- woff2 is more complex so there we can as well call an external converter which in the end +-- makes this code kind of obsolete before it's even used. Although ... it might become a +-- more general conversion plug in. + +local converters = { + woff = { + cachename = "webfonts", + action = otf.readers.woff2otf, + } +} + +local function checkconversion(specification) + local filename = specification.filename + local converter = converters[lower(file.suffix(filename))] + if converter then + local base = file.basename(filename) + local name = file.removesuffix(base) + local attr = lfs.attributes(filename) + local size = attr and attr.size or 0 + local time = attr and attr.modification or 0 + if size > 0 then + local cleanname = containers.cleanname(name) + local cachename = caches.setfirstwritablefile(cleanname,converter.cachename) + if not io.exists(cachename) or (time ~= lfs.attributes(cachename).modification) then + report_otf("caching font %a in %a",filename,cachename) + converter.action(filename,cachename) -- todo infoonly + lfs.touch(cachename,time,time) + end + specification.filename = cachename + end + end +end + local function otftotfm(specification) local cache_id = specification.hash local tfmdata = containers.read(constructors.cache,cache_id) if not tfmdata then + + checkconversion(specification) -- for the moment here + local name = specification.name local sub = specification.sub local subindex = specification.subindex local filename = specification.filename local features = specification.features.normal - local rawdata = otf.load(filename,sub,features and features.featurefile) + local instance = specification.instance or (features and features.axis) + local rawdata = otf.load(filename,sub,instance) if rawdata and next(rawdata) then local descriptions = rawdata.descriptions rawdata.lookuphash = { } -- to be done @@ -702,7 +648,7 @@ local function getgsub(tfmdata,k,kind,value) local properties = tfmdata.properties local validlookups, lookuplist = otf.collectlookups(rawdata,kind,properties.script,properties.language) if validlookups then - local choice = tonumber(value) or 1 -- no random here (yet) + -- local choice = tonumber(value) or 1 -- no random here (yet) for i=1,#lookuplist do local lookup = lookuplist[i] local steps = lookup.steps @@ -725,7 +671,7 @@ end otf.getgsub = getgsub -- returns value, gsub_kind function otf.getsubstitution(tfmdata,k,kind,value) - local found, kind = getgsub(tfmdata,k,kind) + local found, kind = getgsub(tfmdata,k,kind,value) if not found then -- elseif kind == "gsub_single" then @@ -790,9 +736,14 @@ end readers.opentype = opentypereader -- kind of useless and obsolete -function readers.otf (specification) return opentypereader(specification,"otf") end -function readers.ttf (specification) return opentypereader(specification,"ttf") end -function readers.ttc (specification) return opentypereader(specification,"ttf") end +function readers.otf(specification) return opentypereader(specification,"otf") end +function readers.ttf(specification) return opentypereader(specification,"ttf") end +function readers.ttc(specification) return opentypereader(specification,"ttf") end + +function readers.woff(specification) + checkconversion(specification) + opentypereader(specification,"") +end -- this will be overloaded diff --git a/tex/context/base/mkiv/font-otn.lua b/tex/context/base/mkiv/font-otn.lua index 7e701c4b4..ace7bf12b 100644 --- a/tex/context/base/mkiv/font-otn.lua +++ b/tex/context/base/mkiv/font-otn.lua @@ -192,7 +192,6 @@ local report_subchain = logs.reporter("fonts","otf subchain") local report_chain = logs.reporter("fonts","otf chain") local report_process = logs.reporter("fonts","otf process") local report_prepare = logs.reporter("fonts","otf prepare") -local report_warning = logs.reporter("fonts","otf warning") local report_run = logs.reporter("fonts","otf run") registertracker("otf.verbose_chain", function(v) otf.setcontextchain(v and "verbose") end) @@ -226,15 +225,12 @@ local setsubtype = nuts.setsubtype local getchar = nuts.getchar local setchar = nuts.setchar -local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after -local delete_node = nuts.delete -local remove_node = nuts.remove local copy_node = nuts.copy local copy_node_list = nuts.copy_list local find_node_tail = nuts.tail local flush_node_list = nuts.flush_list -local free_node = nuts.free +local flush_node = nuts.flush_node local end_of_math = nuts.end_of_math local traverse_nodes = nuts.traverse local traverse_id = nuts.traverse_id @@ -251,7 +247,6 @@ local glyphcodes = nodes.glyphcodes local disccodes = nodes.disccodes local glyph_code = nodecodes.glyph -local glue_code = nodecodes.glue local disc_code = nodecodes.disc local math_code = nodecodes.math local dir_code = nodecodes.dir @@ -286,11 +281,13 @@ local cursonce = true local fonthashes = fonts.hashes local fontdata = fonthashes.identifiers -local otffeatures = fonts.constructors.newfeatures("otf") +local otffeatures = fonts.constructors.features.otf local registerotffeature = otffeatures.register local onetimemessage = fonts.loggers.onetimemessage or function() end +local getrandom = utilities and utilities.randomizer and utilities.randomizer.get + otf.defaultnodealternate = "none" -- first last -- we share some vars here, after all, we have no nested lookups and less code @@ -409,7 +406,7 @@ end local function flattendisk(head,disc) local replace = getfield(disc,"replace") setfield(disc,"replace",nil) - free_node(disc) + flush_node(disc) if head == disc then local next = getnext(disc) if replace then @@ -687,7 +684,7 @@ end local function get_alternative_glyph(start,alternatives,value,trace_alternatives) local n = #alternatives if value == "random" then - local r = random(1,n) + local r = getrandom and getrandom("glyph",1,n) or random(1,n) return alternatives[r], trace_alternatives and formatters["value %a, taking %a"](value,r) elseif value == "first" then return alternatives[1], trace_alternatives and formatters["value %a, taking %a"](value,1) @@ -1228,41 +1225,6 @@ example, the following is valid:</p> <line>xxxabcdexxx [single a->A][multiple b->BCD][ligature cde->E] xxxABCDExxx</line> </typing> -<p>Therefore we we don't really do the replacement here already unless we have the -single lookup case. The efficiency of the replacements can be improved by deleting -as less as needed but that would also make the code even more messy.</p> ---ldx]]-- - --- local function delete_till_stop(head,start,stop,ignoremarks) -- keeps start --- local n = 1 --- if start == stop then --- -- done --- elseif ignoremarks then --- repeat -- start x x m x x stop => start m --- local next = getnext(start) --- if not marks[getchar(next)] then --- local components = getnext(next,"components") --- if components then -- probably not needed --- flush_node_list(components) --- end --- head = delete_node(head,next) --- end --- n = n + 1 --- until next == stop --- else -- start x x x stop => start --- repeat --- local next = getnext(start) --- local components = getfield(next,"components") --- if components then -- probably not needed --- flush_node_list(components) --- end --- head = delete_node(head,next) --- n = n + 1 --- until next == stop --- end --- return head, n --- end - --[[ldx-- <p>Here we replace start by a single variant.</p> --ldx]]-- @@ -2850,10 +2812,12 @@ function otf.dataset(tfmdata,font) -- generic variant, overloaded in context } rs[language] = rl local sequences = tfmdata.resources.sequences - for s=1,#sequences do - local v = enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage) - if v then - rl[#rl+1] = v + if sequences then + for s=1,#sequences do + local v = enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage) + if v then + rl[#rl+1] = v + end end end end diff --git a/tex/context/base/mkiv/font-oto.lua b/tex/context/base/mkiv/font-oto.lua index 23beba787..13568799b 100644 --- a/tex/context/base/mkiv/font-oto.lua +++ b/tex/context/base/mkiv/font-oto.lua @@ -14,8 +14,6 @@ local concat, unpack = table.concat, table.unpack local insert, remove = table.insert, table.remove local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip local type, next, tonumber, tostring, rawget = type, next, tonumber, tostring, rawget -local lpegmatch = lpeg.match -local utfchar = utf.char local trace_baseinit = false trackers.register("otf.baseinit", function(v) trace_baseinit = v end) local trace_singles = false trackers.register("otf.singles", function(v) trace_singles = v end) @@ -122,7 +120,7 @@ local function registerbasehash(tfmdata) basehash[hash] = base end properties.basehash = base - properties.fullname = properties.fullname .. "-" .. base + properties.fullname = (properties.fullname or properties.name) .. "-" .. base -- report_prepare("fullname base hash '%a, featureset %a",tfmdata.properties.fullname,hash) applied = { } end @@ -227,6 +225,11 @@ local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplis local trace_alternatives = trace_baseinit and trace_alternatives local trace_ligatures = trace_baseinit and trace_ligatures + if not changed then + changed = { } + tfmdata.changed = changed + end + for i=1,#lookuplist do local sequence = lookuplist[i] local steps = sequence.steps @@ -234,12 +237,12 @@ local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplis if kind == "gsub_single" then for i=1,#steps do for unicode, data in next, steps[i].coverage do - if not changed[unicode] then + -- if not changed[unicode] then -- fails for multiple subs in some math fonts if trace_singles then report_substitution(feature,sequence,descriptions,unicode,data) end changed[unicode] = data - end + -- end end end elseif kind == "gsub_alternate" then @@ -394,7 +397,8 @@ local function featuresinitializer(tfmdata,value) local properties = tfmdata.properties local script = properties.script local language = properties.language - local rawfeatures = rawdata.resources.features + local rawresources = rawdata.resources + local rawfeatures = rawresources and rawresources.features local basesubstitutions = rawfeatures and rawfeatures.gsub local basepositionings = rawfeatures and rawfeatures.gpos -- diff --git a/tex/context/base/mkiv/font-otp.lua b/tex/context/base/mkiv/font-otp.lua index 91bd05b32..c52e574b9 100644 --- a/tex/context/base/mkiv/font-otp.lua +++ b/tex/context/base/mkiv/font-otp.lua @@ -30,9 +30,6 @@ fonts.handlers = handlers local otf = handlers.otf or { } handlers.otf = otf -local enhancers = otf.enhancers or { } -otf.enhancers = enhancers - local glists = otf.glists or { "gsub", "gpos" } otf.glists = glists @@ -146,7 +143,7 @@ end -- and repack in such cases (never needed anyway) .. a tricky aspect is that -- we then need to sort more thanks to random hashing -local function packdata(data) +function otf.packdata(data) if data then -- stripdata(data) @@ -536,7 +533,7 @@ local unpacked_mt = { end } -local function unpackdata(data) +function otf.unpackdata(data) if data then local tables = data.tables @@ -895,15 +892,3 @@ local function unpackdata(data) end end end - -if otf.enhancers.register then - - otf.enhancers.register( "pack", packdata) - otf.enhancers.register("unpack",unpackdata) - --- todo: directive - -end - -otf.enhancers.unpack = unpackdata -- used elsewhere -otf.enhancers.pack = packdata -- used elsewhere diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua index c967e2411..4f93c5579 100644 --- a/tex/context/base/mkiv/font-otr.lua +++ b/tex/context/base/mkiv/font-otr.lua @@ -65,11 +65,9 @@ if not modules then modules = { } end modules ['font-otr'] = { -- require("char-ini") -- end -local next, type, unpack = next, type, unpack -local byte, lower, char, strip, gsub = string.byte, string.lower, string.char, string.strip, string.gsub -local bittest = bit32.btest -local concat, remove, unpack, fastcopy = table.concat, table.remov, table.unpack, table.fastcopy -local floor, abs, sqrt, round = math.floor, math.abs, math.sqrt, math.round +local next, type = next, type +local byte, lower, char, gsub = string.byte, string.lower, string.char, string.gsub +local floor, round = math.floor, math.round local P, R, S, C, Cs, Cc, Ct, Carg, Cmt = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.Carg, lpeg.Cmt local lpegmatch = lpeg.match @@ -77,12 +75,16 @@ local setmetatableindex = table.setmetatableindex local formatters = string.formatters local sortedkeys = table.sortedkeys local sortedhash = table.sortedhash -local stripstring = string.strip +local stripstring = string.nospaces local utf16_to_utf8_be = utf.utf16_to_utf8_be local report = logs.reporter("otf reader") local trace_cmap = false -- only for checking issues +local trace_cmap_detail = false -- only for checking issues + +-- local trace_cmap = true +-- local trace_cmap_detail = true fonts = fonts or { } local handlers = fonts.handlers or { } @@ -92,14 +94,16 @@ handlers.otf = otf local readers = otf.readers or { } otf.readers = readers ------ streamreader = utilities.streams -- faster on big files -local streamreader = utilities.files -- faster on identify +----- streamreader = utilities.streams -- faster on big files (not true any longer) +local streamreader = utilities.files -- faster on identify (also uses less memory) +local streamwriter = utilities.files readers.streamreader = streamreader +readers.streamwriter = streamwriter local openfile = streamreader.open local closefile = streamreader.close -local skipbytes = streamreader.skip +----- skipbytes = streamreader.skip local setposition = streamreader.setposition local skipshort = streamreader.skipshort local readbytes = streamreader.readbytes @@ -107,18 +111,18 @@ local readstring = streamreader.readstring local readbyte = streamreader.readcardinal1 -- 8-bit unsigned integer local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer local readuint = streamreader.readcardinal3 -- 24-bit unsigned integer -local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer -local readchar = streamreader.readinteger1 -- 8-bit signed integer +local readulong = streamreader.readcardinal4 -- 32-bit unsigned integer +----- readchar = streamreader.readinteger1 -- 8-bit signed integer local readshort = streamreader.readinteger2 -- 16-bit signed integer -local readlong = streamreader.readinteger4 -- 24-bit unsigned integer +local readlong = streamreader.readinteger4 -- 32-bit unsigned integer local readfixed = streamreader.readfixed4 +local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed number with the low 14 bits of fraction (2.14) (F2DOT14) local readfword = readshort -- 16-bit signed integer that describes a quantity in FUnits local readufword = readushort -- 16-bit unsigned integer that describes a quantity in FUnits local readoffset = readushort -local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed number with the low 14 bits of fraction (2.14) (F2DOT14) function streamreader.readtag(f) - return lower(strip(readstring(f,4))) + return lower(stripstring(readstring(f,4))) end -- date represented in number of seconds since 12:00 midnight, January 1, 1904. The value is represented as a @@ -129,19 +133,9 @@ local function readlongdatetime(f) return 0x100000000 * d + 0x1000000 * e + 0x10000 * f + 0x100 * g + h end -local tableversion = 0.004 -local privateoffset = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF - -readers.tableversion = tableversion - -local reportedskipped = { } - -local function reportskippedtable(tag) - if not reportedskipped[tag] then - report("loading of table %a skipped (reported once only)",tag) - reportedskipped[tag] = true - end -end +local tableversion = 0.004 +readers.tableversion = tableversion +local privateoffset = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF -- We have quite some data tables. We are somewhat ff compatible with names but as I used -- the information from the microsoft site there can be differences. Eventually I might end @@ -173,6 +167,7 @@ local reservednames = { [0] = "wwssubfamily", "lightbackgroundpalette", "darkbackgroundpalette", + "variationspostscriptnameprefix", } -- more at: https://www.microsoft.com/typography/otspec/name.htm @@ -644,7 +639,7 @@ local weights = { [300] = "light", [400] = "normal", [500] = "medium", - [600] = "semibold", + [600] = "semibold", -- demi demibold [700] = "bold", [800] = "extrabold", [900] = "black", @@ -703,6 +698,44 @@ local panosewidths = { -- We implement a reader per table. +-- helper + +local helpers = { } +readers.helpers = helpers + +local function gotodatatable(f,fontdata,tag,criterium) + if criterium and f then + local datatable = fontdata.tables[tag] + if datatable then + local tableoffset = datatable.offset + setposition(f,tableoffset) + return tableoffset + end + end +end + +local function reportskippedtable(f,fontdata,tag,criterium) + if criterium and f then + local datatable = fontdata.tables[tag] + if datatable then + report("loading of table %a skipped",tag) + end + end +end + +local function setvariabledata(fontdata,tag,data) + local variabledata = fontdata.variabledata + if variabledata then + variabledata[tag] = data + else + fontdata.variabledata = { [tag] = data } + end +end + +helpers.gotodatatable = gotodatatable +helpers.setvariabledata = setvariabledata +helpers.reportskippedtable = reportskippedtable + -- The name table is probably the first one to load. After all this one provides -- useful information about what we deal with. The complication is that we need -- to filter the best one available. @@ -718,14 +751,13 @@ local platformnames = { } function readers.name(f,fontdata,specification) - local datatable = fontdata.tables.name - if datatable then - setposition(f,datatable.offset) + local tableoffset = gotodatatable(f,fontdata,"name",true) + if tableoffset then local format = readushort(f) local nofnames = readushort(f) local offset = readushort(f) -- we can also provide a raw list as extra, todo as option - local start = datatable.offset + offset + local start = tableoffset + offset local namelists = { unicode = { }, windows = { }, @@ -746,19 +778,17 @@ function readers.name(f,fontdata,specification) local encoding = encodings[encoding] local language = languages[language] if encoding and language then - local name = reservednames[readushort(f)] - if name then - namelist[#namelist+1] = { - platform = platform, - encoding = encoding, - language = language, - name = name, - length = readushort(f), - offset = start + readushort(f), - } - else - skipshort(f,2) - end + local index = readushort(f) + local name = reservednames[index] + namelist[#namelist+1] = { + platform = platform, + encoding = encoding, + language = language, + name = name, + index = index, + length = readushort(f), + offset = start + readushort(f), + } else skipshort(f,3) end @@ -782,8 +812,9 @@ function readers.name(f,fontdata,specification) -- -- we need to choose one we like, for instance an unicode one -- - local names = { } - local done = { } + local names = { } + local done = { } + local extras = { } -- -- there is quite some logic in ff ... hard to follow so we start simple -- and extend when we run into it (todo: proper reverse hash) .. we're only @@ -794,7 +825,8 @@ function readers.name(f,fontdata,specification) for i=1,#namelist do local name = namelist[i] local nametag = name.name - if not done[nametag] then + local index = name.index + if not done[nametag or i] then local encoding = name.encoding local language = name.language if (not e or encoding == e) and (not l or language == l) then @@ -807,13 +839,16 @@ function readers.name(f,fontdata,specification) if decoder then content = decoder(content) end - names[nametag] = { - content = content, - platform = platform, - encoding = encoding, - language = language, - } - done[nametag] = true + if nametag then + names[nametag] = { + content = content, + platform = platform, + encoding = encoding, + language = language, + } + end + extras[index] = content + done[nametag or i] = true end end end @@ -826,7 +861,8 @@ function readers.name(f,fontdata,specification) filter("macintosh") filter("unicode") -- - fontdata.names = names + fontdata.names = names + fontdata.extras = extras -- if specification.platformnames then local collected = { } @@ -883,9 +919,8 @@ end -- properties table afterwards. readers["os/2"] = function(f,fontdata) - local datatable = fontdata.tables["os/2"] - if datatable then - setposition(f,datatable.offset) + local tableoffset = gotodatatable(f,fontdata,"os/2",true) + if tableoffset then local version = readushort(f) local windowsmetrics = { version = version, @@ -944,9 +979,8 @@ readers["os/2"] = function(f,fontdata) end readers.head = function(f,fontdata) - local datatable = fontdata.tables.head - if datatable then - setposition(f,datatable.offset) + local tableoffset = gotodatatable(f,fontdata,"head",true) + if tableoffset then local fontheader = { version = readfixed(f), revision = readfixed(f), @@ -974,37 +1008,63 @@ readers.head = function(f,fontdata) end -- This table is a rather simple one. No treatment of values is needed here. Most --- variables are not used but nofhmetrics is quite important. +-- variables are not used but nofmetrics is quite important. readers.hhea = function(f,fontdata,specification) - if specification.details then - local datatable = fontdata.tables.hhea - if datatable then - setposition(f,datatable.offset) - fontdata.horizontalheader = { - version = readfixed(f), - ascender = readfword(f), - descender = readfword(f), - linegap = readfword(f), - maxadvancewidth = readufword(f), - minleftsidebearing = readfword(f), - minrightsidebearing = readfword(f), - maxextent = readfword(f), - caretsloperise = readshort(f), - caretsloperun = readshort(f), - caretoffset = readshort(f), - reserved_1 = readshort(f), - reserved_2 = readshort(f), - reserved_3 = readshort(f), - reserved_4 = readshort(f), - metricdataformat = readshort(f), - nofhmetrics = readushort(f), - } - else - fontdata.horizontalheader = { - nofhmetrics = 0, - } - end + local tableoffset = gotodatatable(f,fontdata,"hhea",specification.details) + if tableoffset then + fontdata.horizontalheader = { + version = readfixed(f), -- two ushorts: major minor + ascender = readfword(f), + descender = readfword(f), + linegap = readfword(f), + maxadvancewidth = readufword(f), + minleftsidebearing = readfword(f), + minrightsidebearing = readfword(f), + maxextent = readfword(f), + caretsloperise = readshort(f), + caretsloperun = readshort(f), + caretoffset = readshort(f), + reserved_1 = readshort(f), + reserved_2 = readshort(f), + reserved_3 = readshort(f), + reserved_4 = readshort(f), + metricdataformat = readshort(f), + nofmetrics = readushort(f), + } + else + fontdata.horizontalheader = { + nofmetrics = 0, + } + end +end + +readers.vhea = function(f,fontdata,specification) + local tableoffset = gotodatatable(f,fontdata,"vhea",specification.details) + if tableoffset then + fontdata.verticalheader = { + version = readfixed(f), + ascender = readfword(f), + descender = readfword(f), + linegap = readfword(f), + maxadvanceheight = readufword(f), + mintopsidebearing = readfword(f), + minbottomsidebearing = readfword(f), + maxextent = readfword(f), + caretsloperise = readshort(f), + caretsloperun = readshort(f), + caretoffset = readshort(f), + reserved_1 = readshort(f), + reserved_2 = readshort(f), + reserved_3 = readshort(f), + reserved_4 = readshort(f), + metricdataformat = readshort(f), + nofmetrics = readushort(f), + } + else + fontdata.verticalheader = { + nofmetrics = 0, + } end end @@ -1014,44 +1074,40 @@ end -- fontdata.maximumprofile can be bad readers.maxp = function(f,fontdata,specification) - if specification.details then - local datatable = fontdata.tables.maxp - if datatable then - setposition(f,datatable.offset) - local version = readfixed(f) - local nofglyphs = readushort(f) - fontdata.nofglyphs = nofglyphs - if version == 0.5 then - fontdata.maximumprofile = { - version = version, - nofglyphs = nofglyphs, - } - return - elseif version == 1.0 then - fontdata.maximumprofile = { - version = version, - nofglyphs = nofglyphs, - points = readushort(f), - contours = readushort(f), - compositepoints = readushort(f), - compositecontours = readushort(f), - zones = readushort(f), - twilightpoints = readushort(f), - storage = readushort(f), - functiondefs = readushort(f), - instructiondefs = readushort(f), - stackelements = readushort(f), - sizeofinstructions = readushort(f), - componentelements = readushort(f), - componentdepth = readushort(f), - } - return - end + local tableoffset = gotodatatable(f,fontdata,"maxp",specification.details) + if tableoffset then + local version = readfixed(f) + local nofglyphs = readushort(f) + fontdata.nofglyphs = nofglyphs + if version == 0.5 then + fontdata.maximumprofile = { + version = version, + nofglyphs = nofglyphs, + } + elseif version == 1.0 then + fontdata.maximumprofile = { + version = version, + nofglyphs = nofglyphs, + points = readushort(f), + contours = readushort(f), + compositepoints = readushort(f), + compositecontours = readushort(f), + zones = readushort(f), + twilightpoints = readushort(f), + storage = readushort(f), + functiondefs = readushort(f), + instructiondefs = readushort(f), + stackelements = readushort(f), + sizeofinstructions = readushort(f), + componentelements = readushort(f), + componentdepth = readushort(f), + } + else + fontdata.maximumprofile = { + version = version, + nofglyphs = 0, + } end - fontdata.maximumprofile = { - version = version, - nofglyphs = 0, - } end end @@ -1059,49 +1115,87 @@ end -- course). readers.hmtx = function(f,fontdata,specification) - if specification.glyphs then - local datatable = fontdata.tables.hmtx - if datatable then - setposition(f,datatable.offset) - local nofmetrics = fontdata.horizontalheader.nofhmetrics - local glyphs = fontdata.glyphs - local nofglyphs = fontdata.nofglyphs - local width = 0 -- advance - local leftsidebearing = 0 - for i=0,nofmetrics-1 do - local glyph = glyphs[i] - width = readshort(f) - leftsidebearing = readshort(f) - if width ~= 0 then - glyph.width = width - end - -- if leftsidebearing ~= 0 then - -- glyph.lsb = leftsidebearing - -- end + local tableoffset = gotodatatable(f,fontdata,"hmtx",specification.glyphs) + if tableoffset then + local horizontalheader = fontdata.horizontalheader + local nofmetrics = horizontalheader.nofmetrics + local glyphs = fontdata.glyphs + local nofglyphs = fontdata.nofglyphs + local width = 0 -- advance + local leftsidebearing = 0 + for i=0,nofmetrics-1 do + local glyph = glyphs[i] + width = readshort(f) + leftsidebearing = readshort(f) + if width ~= 0 then + glyph.width = width end - -- The next can happen in for instance a monospace font or in a cjk font - -- with fixed widths. - for i=nofmetrics,nofglyphs-1 do - local glyph = glyphs[i] - if width ~= 0 then - glyph.width = width - end - -- if leftsidebearing ~= 0 then - -- glyph.lsb = leftsidebearing - -- end +-- for now +-- if leftsidebearing ~= 0 then +-- glyph.lsb = leftsidebearing +-- end + end + -- The next can happen in for instance a monospace font or in a cjk font + -- with fixed widths. + for i=nofmetrics,nofglyphs-1 do + local glyph = glyphs[i] + if width ~= 0 then + glyph.width = width + end + -- if leftsidebearing ~= 0 then + -- glyph.lsb = leftsidebearing + -- end + end + -- hm, there can be a lsb here + end +end + +readers.vmtx = function(f,fontdata,specification) + local tableoffset = gotodatatable(f,fontdata,"vmtx",specification.glyphs) + if tableoffset then + local verticalheader = fontdata.verticalheader + local nofmetrics = verticalheader.nofmetrics + local glyphs = fontdata.glyphs + local nofglyphs = fontdata.nofglyphs + local vheight = 0 + local vdefault = verticalheader.ascender + verticalheader.descender + local topsidebearing = 0 + for i=0,nofmetrics-1 do + local glyph = glyphs[i] + vheight = readshort(f) + topsidebearing = readshort(f) + if vheight ~= 0 and vheight ~= vdefault then + glyph.vheight = vheight end + -- if topsidebearing ~= 0 then + -- glyph.tsb = topsidebearing + -- end + end + -- The next can happen in for instance a monospace font or in a cjk font + -- with fixed heights. + for i=nofmetrics,nofglyphs-1 do + local glyph = glyphs[i] + if vheight ~= 0 and vheight ~= vdefault then + glyph.vheight = vheight + end + -- if topsidebearing ~= 0 then + -- glyph.tsb = topsidebearing + -- end end end end +readers.vorg = function(f,fontdata,specification) + reportskippedtable(f,fontdata,"vorg",specification.glyphs) +end + -- The post table relates to postscript (printing) but has some relevant properties for other -- usage as well. We just use the names from the microsoft specification. The version 2.0 -- description is somewhat fuzzy but it is a hybrid with overloads. readers.post = function(f,fontdata,specification) - local datatable = fontdata.tables.post - if datatable then - setposition(f,datatable.offset) + local tableoffset = gotodatatable(f,fontdata,"post",true) + if tableoffset then local version = readfixed(f) fontdata.postscript = { version = version, @@ -1130,7 +1224,7 @@ readers.post = function(f,fontdata,specification) for i=0,nofglyphs-1 do local nameindex = readushort(f) if nameindex >= 258 then - maxnames = maxnames + 1 + maxnames = maxnames + 1 nameindex = nameindex - 257 indices[nameindex] = i else @@ -1143,7 +1237,7 @@ readers.post = function(f,fontdata,specification) report("quit post name fetching at %a of %a: %s",i,maxnames,"no index") break else - local length = readbyte(f) + local length = readbyte(f) if length > 0 then glyphs[mapping].name = readstring(f,length) else @@ -1163,9 +1257,7 @@ readers.post = function(f,fontdata,specification) end readers.cff = function(f,fontdata,specification) - if specification.glyphs then - reportskippedtable("cff") - end + reportskippedtable(f,fontdata,"cff",specification.glyphs) end -- Not all cmaps make sense .. e.g. dfont is obsolete and probably more are not relevant. Let's see @@ -1187,6 +1279,7 @@ local sequence = { -- variants { 0, 5, 14 }, -- last resort ranges +{ 0, 4, 12 }, { 3, 10, 13 }, } @@ -1205,7 +1298,8 @@ local sequence = { local supported = { } for i=1,#sequence do - local sp, se, sf = unpack(sequence[i]) + local si = sequence[i] + local sp, se, sf = si[1], si[2], si[3] local p = supported[sp] if not p then p = { } @@ -1269,7 +1363,7 @@ formatreaders[4] = function(f,fontdata,offset) elseif offset == 0xFFFF then -- bad encoding elseif offset == 0 then - if trace_cmap then + if trace_cmap_detail then report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar + delta) % 65536) end for unicode=startchar,endchar do @@ -1302,7 +1396,7 @@ formatreaders[4] = function(f,fontdata,offset) end else local shift = (segment-nofsegments+offset/2) - startchar - if trace_cmap then + if trace_cmap_detail then report("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar + delta) % 65536) end for unicode=startchar,endchar do @@ -1352,7 +1446,7 @@ formatreaders[6] = function(f,fontdata,offset) local count = readushort(f) local stop = start+count-1 local nofdone = 0 - if trace_cmap then + if trace_cmap_detail then report("format 6 from %C to %C",2,start,stop) end for unicode=start,stop do @@ -1389,7 +1483,7 @@ formatreaders[12] = function(f,fontdata,offset) local first = readulong(f) local last = readulong(f) local index = readulong(f) - if trace_cmap then + if trace_cmap_detail then report("format 12 from %C to %C starts at index %i",first,last,index) end for unicode=first,last do @@ -1433,7 +1527,7 @@ formatreaders[13] = function(f,fontdata,offset) local last = readulong(f) local index = readulong(f) if first < privateoffset then - if trace_cmap then + if trace_cmap_detail then report("format 13 from %C to %C get index %i",first,last,index) end local glyph = glyphs[index] @@ -1539,76 +1633,82 @@ local function checkcmap(f,fontdata,records,platform,encoding,format) local p = platforms[platform] local e = encodings[p] local n = reader(f,fontdata,data) or 0 - report("cmap checked: platform %i (%s), encoding %i (%s), format %i, new unicodes %i",platform,p,encoding,e and e[encoding] or "?",format,n) + if trace_cmap then + report("cmap checked: platform %i (%s), encoding %i (%s), format %i, new unicodes %i",platform,p,encoding,e and e[encoding] or "?",format,n) + end return n end function readers.cmap(f,fontdata,specification) - if specification.glyphs then - local datatable = fontdata.tables.cmap - if datatable then - local tableoffset = datatable.offset - setposition(f,tableoffset) - local version = readushort(f) - local noftables = readushort(f) - local records = { } - local unicodecid = false - local variantcid = false - local variants = { } - local duplicates = fontdata.duplicates or { } - fontdata.duplicates = duplicates - for i=1,noftables do - local platform = readushort(f) - local encoding = readushort(f) - local offset = readulong(f) - local record = records[platform] - if not record then - records[platform] = { - [encoding] = { - offsets = { offset }, - formats = { }, - } + local tableoffset = gotodatatable(f,fontdata,"cmap",specification.glyphs) + if tableoffset then + local version = readushort(f) + local noftables = readushort(f) + local records = { } + local unicodecid = false + local variantcid = false + local variants = { } + local duplicates = fontdata.duplicates or { } + fontdata.duplicates = duplicates + for i=1,noftables do + local platform = readushort(f) + local encoding = readushort(f) + local offset = readulong(f) + local record = records[platform] + if not record then + records[platform] = { + [encoding] = { + offsets = { offset }, + formats = { }, + } + } + else + local subtables = record[encoding] + if not subtables then + record[encoding] = { + offsets = { offset }, + formats = { }, } else - local subtables = record[encoding] - if not subtables then - record[encoding] = { - offsets = { offset }, - formats = { }, - } - else - local offsets = subtables.offsets - offsets[#offsets+1] = offset - end + local offsets = subtables.offsets + offsets[#offsets+1] = offset end end + end + if trace_cmap then report("found cmaps:") - for platform, record in sortedhash(records) do - local p = platforms[platform] - local e = encodings[p] - local sp = supported[platform] - local ps = p or "?" + end + for platform, record in sortedhash(records) do + local p = platforms[platform] + local e = encodings[p] + local sp = supported[platform] + local ps = p or "?" + if trace_cmap then if sp then report(" platform %i: %s",platform,ps) else report(" platform %i: %s (unsupported)",platform,ps) end - for encoding, subtables in sortedhash(record) do - local se = sp and sp[encoding] - local es = e and e[encoding] or "?" + end + for encoding, subtables in sortedhash(record) do + local se = sp and sp[encoding] + local es = e and e[encoding] or "?" + if trace_cmap then if se then report(" encoding %i: %s",encoding,es) else report(" encoding %i: %s (unsupported)",encoding,es) end - local offsets = subtables.offsets - local formats = subtables.formats - for i=1,#offsets do - local offset = tableoffset + offsets[i] - setposition(f,offset) - formats[readushort(f)] = offset - end - record[encoding] = formats + end + local offsets = subtables.offsets + local formats = subtables.formats + for i=1,#offsets do + local offset = tableoffset + offsets[i] + setposition(f,offset) + formats[readushort(f)] = offset + end + record[encoding] = formats + if trace_cmap then local list = sortedkeys(formats) for i=1,#list do if not (se and se[list[i]]) then @@ -1618,26 +1718,27 @@ function readers.cmap(f,fontdata,specification) report(" formats: % t",list) end end - -- - local ok = false - for i=1,#sequence do - local sp, se, sf = unpack(sequence[i]) - if checkcmap(f,fontdata,records,sp,se,sf) > 0 then - ok = true - end - end - if not ok then - report("no useable unicode cmap found") + end + -- + local ok = false + for i=1,#sequence do + local si = sequence[i] + local sp, se, sf = si[1], si[2], si[3] + if checkcmap(f,fontdata,records,sp,se,sf) > 0 then + ok = true end - -- - fontdata.cidmaps = { - version = version, - noftables = noftables, - records = records, - } - else - fontdata.cidmaps = { } end + if not ok then + report("no useable unicode cmap found") + end + -- + fontdata.cidmaps = { + version = version, + noftables = noftables, + records = records, + } + else + fontdata.cidmaps = { } end end @@ -1646,203 +1747,120 @@ end -- although we not need it in our usage (yet). We can remove the locations table when we're done. function readers.loca(f,fontdata,specification) - if specification.glyphs then - reportskippedtable("loca") - end + reportskippedtable(f,fontdata,"loca",specification.glyphs) end function readers.glyf(f,fontdata,specification) -- part goes to cff module - if specification.glyphs then - reportskippedtable("glyf") - end + reportskippedtable(f,fontdata,"glyf",specification.glyphs) +end + +-- The MicroSoft variant is pretty clean and is supported (implemented elsewhere) +-- just because I wanted to see how such a font looks like. + +function readers.colr(f,fontdata,specification) + reportskippedtable(f,fontdata,"colr",specification.glyphs) +end +function readers.cpal(f,fontdata,specification) + reportskippedtable(f,fontdata,"cpal",specification.glyphs) +end + +-- This one is also supported, if only because I could locate a proper font for +-- testing. + +function readers.svg(f,fontdata,specification) + reportskippedtable(f,fontdata,"svg",specification.glyphs) +end + +-- There is a font from apple to test the next one. Will there be more? Anyhow, +-- it's relatively easy to support, so I did it. + +function readers.sbix(f,fontdata,specification) + reportskippedtable(f,fontdata,"sbix",specification.glyphs) +end + +-- I'm only willing to look into the next variant if I see a decent and complete (!) +-- font and more can show up. It makes no sense to waste time on ideas. Okay, the +-- apple font also has these tables. + +function readers.cbdt(f,fontdata,specification) + reportskippedtable(f,fontdata,"cbdt",specification.glyphs) +end +function readers.cblc(f,fontdata,specification) + reportskippedtable(f,fontdata,"cblc",specification.glyphs) +end +function readers.ebdt(f,fontdata,specification) + reportskippedtable(f,fontdata,"ebdt",specification.glyphs) +end +function readers.ebsc(f,fontdata,specification) + reportskippedtable(f,fontdata,"ebsc",specification.glyphs) +end +function readers.eblc(f,fontdata,specification) + reportskippedtable(f,fontdata,"eblc",specification.glyphs) end -- Here we have a table that we really need for later processing although a more advanced gpos table -- can also be available. Todo: we need a 'fake' lookup for this (analogue to ff). function readers.kern(f,fontdata,specification) - if specification.kerns then - local datatable = fontdata.tables.kern - if datatable then - setposition(f,datatable.offset) - local version = readushort(f) - local noftables = readushort(f) - for i=1,noftables do - local version = readushort(f) - local length = readushort(f) - local coverage = readushort(f) - -- bit 8-15 of coverage: format 0 or 2 - local format = bit32.rshift(coverage,8) -- is this ok? - if format == 0 then - local nofpairs = readushort(f) - local searchrange = readushort(f) - local entryselector = readushort(f) - local rangeshift = readushort(f) - local kerns = { } - local glyphs = fontdata.glyphs - for i=1,nofpairs do - local left = readushort(f) - local right = readushort(f) - local kern = readfword(f) - local glyph = glyphs[left] - local kerns = glyph.kerns - if kerns then - kerns[right] = kern - else - glyph.kerns = { [right] = kern } - end + local tableoffset = gotodatatable(f,fontdata,"kern",specification.kerns) + if tableoffset then + local version = readushort(f) + local noftables = readushort(f) + for i=1,noftables do + local version = readushort(f) + local length = readushort(f) + local coverage = readushort(f) + -- bit 8-15 of coverage: format 0 or 2 + local format = bit32.rshift(coverage,8) -- is this ok? + if format == 0 then + local nofpairs = readushort(f) + local searchrange = readushort(f) + local entryselector = readushort(f) + local rangeshift = readushort(f) + local kerns = { } + local glyphs = fontdata.glyphs + for i=1,nofpairs do + local left = readushort(f) + local right = readushort(f) + local kern = readfword(f) + local glyph = glyphs[left] + local kerns = glyph.kerns + if kerns then + kerns[right] = kern + else + glyph.kerns = { [right] = kern } end - elseif format == 2 then - report("todo: kern classes") - else - report("todo: kerns") end + elseif format == 2 then + report("todo: kern classes") + else + report("todo: kerns") end end end end function readers.gdef(f,fontdata,specification) - if specification.details then - reportskippedtable("gdef") - end + reportskippedtable(f,fontdata,"gdef",specification.details) end function readers.gsub(f,fontdata,specification) - if specification.details then - reportskippedtable("gsub") - end + reportskippedtable(f,fontdata,"gsub",specification.details) end function readers.gpos(f,fontdata,specification) - if specification.details then - reportskippedtable("gpos") - end + reportskippedtable(f,fontdata,"gpos",specification.details) end function readers.math(f,fontdata,specification) - if specification.glyphs then - reportskippedtable("math") - end + reportskippedtable(f,fontdata,"math",specification.details) end --- Goodie. A sequence instead of segments costs a bit more memory, some 300K on a --- dejavu serif and about the same on a pagella regular. - -local function packoutlines(data,makesequence) - local subfonts = data.subfonts - if subfonts then - for i=1,#subfonts do - packoutlines(subfonts[i],makesequence) - end - return - end - local common = data.segments - if common then - return - end - local glyphs = data.glyphs - if not glyphs then - return - end - if makesequence then - for index=1,#glyphs do - local glyph = glyphs[index] - local segments = glyph.segments - if segments then - local sequence = { } - local nofsequence = 0 - for i=1,#segments do - local segment = segments[i] - local nofsegment = #segment - nofsequence = nofsequence + 1 - sequence[nofsequence] = segment[nofsegment] - for i=1,nofsegment-1 do - nofsequence = nofsequence + 1 - sequence[nofsequence] = segment[i] - end - end - glyph.sequence = sequence - glyph.segments = nil - end - end - else - local hash = { } - local common = { } - local reverse = { } - local last = 0 - for index=1,#glyphs do - local segments = glyphs[index].segments - if segments then - for i=1,#segments do - local h = concat(segments[i]," ") - hash[h] = (hash[h] or 0) + 1 - end - end - end - for index=1,#glyphs do - local segments = glyphs[index].segments - if segments then - for i=1,#segments do - local segment = segments[i] - local h = concat(segment," ") - if hash[h] > 1 then -- minimal one shared in order to hash - local idx = reverse[h] - if not idx then - last = last + 1 - reverse[h] = last - common[last] = segment - idx = last - end - segments[i] = idx - end - end - end - end - if last > 0 then - data.segments = common - end - end -end - -local function unpackoutlines(data) - local subfonts = data.subfonts - if subfonts then - for i=1,#subfonts do - unpackoutlines(subfonts[i]) - end - return - end - local common = data.segments - if not common then - return - end - local glyphs = data.glyphs - if not glyphs then - return - end - for index=1,#glyphs do - local segments = glyphs[index].segments - if segments then - for i=1,#segments do - local c = common[segments[i]] - if c then - segments[i] = c - end - end - end - end - data.segments = nil -end - -otf.packoutlines = packoutlines -otf.unpackoutlines = unpackoutlines - -- Now comes the loader. The order of reading these matters as we need to know -- some properties in order to read following tables. When details is true we also -- initialize the glyphs data. -local function getinfo(maindata,sub,platformnames,rawfamilynames) +local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,instancenames) local fontdata = sub and maindata.subfonts and maindata.subfonts[sub] or maindata local names = fontdata.names local info = nil @@ -1852,8 +1870,8 @@ local function getinfo(maindata,sub,platformnames,rawfamilynames) local fontheader = fontdata.fontheader or { } local cffinfo = fontdata.cffinfo or { } local filename = fontdata.filename - local weight = getname(fontdata,"weight") or cffinfo.weight or metrics.weight - local width = getname(fontdata,"width") or cffinfo.width or metrics.width + local weight = getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight) + local width = getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width ) local fontname = getname(fontdata,"postscriptname") local fullname = getname(fontdata,"fullname") local family = getname(fontdata,"family") @@ -1867,6 +1885,25 @@ local function getinfo(maindata,sub,platformnames,rawfamilynames) if not familyname then familyname = family end if not subfamilyname then subfamilyname = subfamily end end + if platformnames then + platformnames = fontdata.platformnames + end + if instancenames then + local variabledata = fontdata.variabledata + if variabledata then + local instances = variabledata and variabledata.instances + if instances then + instancenames = { } + for i=1,#instances do + instancenames[i] = lower(stripstring(instances[i].subfamily)) + end + else + instancenames = nil + end + else + instancenames = nil + end + end info = { -- we inherit some inconsistencies/choices from ff subfontindex = fontdata.subfontindex or sub or 0, -- filename = filename, @@ -1897,8 +1934,32 @@ local function getinfo(maindata,sub,platformnames,rawfamilynames) capheight = metrics.capheight, -- not always present and probably crap ascender = metrics.typoascender, descender = metrics.typodescender, - platformnames = platformnames and fontdata.platformnames or nil, + platformnames = platformnames or nil, + instancenames = instancenames or nil, } + if metricstoo then + local keys = { + "version", + "ascender", "descender", "linegap", + -- "caretoffset", "caretsloperise", "caretsloperun", + "maxadvancewidth", "maxadvanceheight", "maxextent", + -- "metricdataformat", + "minbottomsidebearing", "mintopsidebearing", + } + local h = fontdata.horizontalheader or { } + local v = fontdata.verticalheader or { } + if h then + local th = { } + local tv = { } + for i=1,#keys do + local key = keys[i] + th[key] = h[key] or 0 + tv[key] = v[key] or 0 + end + info.horizontalmetrics = th + info.verticalmetrics = tv + end + end elseif n then info = { filename = fontdata.filename, @@ -1932,6 +1993,7 @@ local function loadtables(f,specification,offset) entryselector = readushort(f), -- not needed rangeshift = readushort(f), -- not needed tables = tables, + foundtables = false, } for i=1,fontdata.noftables do local tag = lower(stripstring(readstring(f,4))) @@ -1947,7 +2009,8 @@ local function loadtables(f,specification,offset) length = length, } end - if tables.cff then + fontdata.foundtables = sortedkeys(tables) + if tables.cff or tables.cff2 then fontdata.format = "opentype" else fontdata.format = "truetype" @@ -1968,14 +2031,35 @@ local function prepareglyps(fontdata) fontdata.mapping = { } end +local function readtable(tag,f,fontdata,specification,...) + local reader = readers[tag] + if reader then + -- local t = os.clock() + reader(f,fontdata,specification,...) + -- report("reading table %a took %0.4f seconds",tag,os.clock()-t) + end +end + +local variablefonts_supported = (context and true) or (logs and logs.application and true) or false + local function readdata(f,offset,specification) + local fontdata = loadtables(f,specification,offset) + if specification.glyphs then prepareglyps(fontdata) end - -- - readers["name"](f,fontdata,specification) - -- + + if not variablefonts_supported then + specification.instance = nil + specification.variable = nil + specification.factors = nil + end + + fontdata.temporary = { } + + readtable("name",f,fontdata,specification) + local askedname = specification.askedname if askedname then local fullname = getname(fontdata,"fullname") or "" @@ -1985,29 +2069,124 @@ local function readdata(f,offset,specification) return -- keep searching end end - -- - -- - readers["os/2"](f,fontdata,specification) - readers["head"](f,fontdata,specification) - readers["maxp"](f,fontdata,specification) - readers["hhea"](f,fontdata,specification) - readers["hmtx"](f,fontdata,specification) - readers["post"](f,fontdata,specification) - readers["cff" ](f,fontdata,specification) - readers["cmap"](f,fontdata,specification) - readers["loca"](f,fontdata,specification) - readers["glyf"](f,fontdata,specification) - readers["kern"](f,fontdata,specification) - readers["gdef"](f,fontdata,specification) - readers["gsub"](f,fontdata,specification) - readers["gpos"](f,fontdata,specification) - readers["math"](f,fontdata,specification) - -- + + readtable("stat",f,fontdata,specification) + readtable("avar",f,fontdata,specification) + readtable("fvar",f,fontdata,specification) + + if variablefonts_supported then + + local variabledata = fontdata.variabledata + + if variabledata then + local instances = variabledata.instances + local axis = variabledata.axis + if axis and (not instances or #instances == 0) then + instances = { } + variabledata.instances = instances + local function add(n,subfamily,value) + local values = { } + for i=1,#axis do + local a = axis[i] + values[i] = { + axis = a.tag, + value = i == n and value or a.default, + } + end + instances[#instances+1] = { + subfamily = subfamily, + values = values, + } + end + for i=1,#axis do + local a = axis[i] + local tag = a.tag + add(i,"default"..tag,a.default) + add(i,"minimum"..tag,a.minimum) + add(i,"maximum"..tag,a.maximum) + end + -- report("%i fake instances added",#instances) + end + end + + if not specification.factors then + local instance = specification.instance + if type(instance) == "string" then + local factors = helpers.getfactors(fontdata,instance) + if factors then + specification.factors = factors + fontdata.factors = factors + fontdata.instance = instance + report("user instance: %s, factors: % t",instance,factors) + else + report("user instance: %s, bad factors",instance) + end + end + end + + if not fontdata.factors then + if fontdata.variabledata then + local factors = helpers.getfactors(fontdata,true) + if factors then + specification.factors = factors + fontdata.factors = factors + report("factors: % t",factors) + else + report("bad factors") + end + else + -- report("unknown instance") + end + end + + end + + readtable("os/2",f,fontdata,specification) + readtable("head",f,fontdata,specification) + readtable("maxp",f,fontdata,specification) + readtable("hhea",f,fontdata,specification) + readtable("vhea",f,fontdata,specification) + readtable("hmtx",f,fontdata,specification) + readtable("vmtx",f,fontdata,specification) + readtable("vorg",f,fontdata,specification) + readtable("post",f,fontdata,specification) + + readtable("mvar",f,fontdata,specification) + readtable("hvar",f,fontdata,specification) + readtable("vvar",f,fontdata,specification) + + readtable("gdef",f,fontdata,specification) + + readtable("cff" ,f,fontdata,specification) + readtable("cff2",f,fontdata,specification) + + readtable("cmap",f,fontdata,specification) + readtable("loca",f,fontdata,specification) -- maybe load it in glyf + readtable("glyf",f,fontdata,specification) -- loads gvar + + readtable("colr",f,fontdata,specification) + readtable("cpal",f,fontdata,specification) + + readtable("svg" ,f,fontdata,specification) + + readtable("sbix",f,fontdata,specification) + + readtable("cbdt",f,fontdata,specification) + readtable("cblc",f,fontdata,specification) + readtable("ebdt",f,fontdata,specification) + readtable("eblc",f,fontdata,specification) + + readtable("kern",f,fontdata,specification) + readtable("gsub",f,fontdata,specification) + readtable("gpos",f,fontdata,specification) + + readtable("math",f,fontdata,specification) + fontdata.locations = nil fontdata.tables = nil fontdata.cidmaps = nil fontdata.dictionaries = nil - -- fontdata.cff = nil + -- fontdata.cff = nil return fontdata end @@ -2082,7 +2261,7 @@ local function loadfontdata(specification) end end -local function loadfont(specification,n) +local function loadfont(specification,n,instance) if type(specification) == "string" then specification = { filename = specification, @@ -2091,11 +2270,13 @@ local function loadfont(specification,n) glyphs = true, shapes = true, kerns = true, + variable = true, globalkerns = true, lookups = true, -- true or number: subfont = n or true, tounicode = false, + instance = instance } end -- if shapes only then @@ -2111,6 +2292,10 @@ local function loadfont(specification,n) if specification.platformnames then specification.platformnames = true -- not really used any more end + if specification.instance or instance then + specification.variable = true + specification.instance = specification.instance or instance + end local function message(str) report("fatal error in file %a: %s\n%s",specification.filename,str,debug.traceback()) end @@ -2122,12 +2307,24 @@ end -- we need even less, but we can have a 'detail' variant -function readers.loadshapes(filename,n) +function readers.loadshapes(filename,n,instance,streams) local fontdata = loadfont { filename = filename, shapes = true, + streams = streams, + variable = true, subfont = n, + instance = instance, } + if fontdata then + -- easier on luajit but still we can hit the 64 K stack constants issue + for k, v in next, fontdata.glyphs do + v.class = nil + v.index = nil + v.math = nil + -- v.name = nil + end + end return fontdata and { -- version = 0.123 -- todo filename = filename, @@ -2142,18 +2339,19 @@ function readers.loadshapes(filename,n) } end -function readers.loadfont(filename,n) +function readers.loadfont(filename,n,instance) local fontdata = loadfont { filename = filename, glyphs = true, shapes = false, lookups = true, + variable = true, -- kerns = true, -- globalkerns = true, -- only for testing, e.g. cambria has different gpos and kern subfont = n, + instance = instance, } if fontdata then - -- return { tableversion = tableversion, creator = "context mkiv", @@ -2163,9 +2361,13 @@ function readers.loadfont(filename,n) descriptions = fontdata.descriptions, format = fontdata.format, goodies = { }, - metadata = getinfo(fontdata,n), -- no platformnames here ! + metadata = getinfo(fontdata,n,false,false,true,true), -- no platformnames here ! properties = { - hasitalics = fontdata.hasitalics or false, + hasitalics = fontdata.hasitalics or false, + maxcolorclass = fontdata.maxcolorclass, + hascolor = fontdata.hascolor or false, + instance = fontdata.instance, + factors = fontdata.factors, }, resources = { -- filename = fontdata.filename, @@ -2182,6 +2384,11 @@ function readers.loadfont(filename,n) version = getname(fontdata,"version"), cidinfo = fontdata.cidinfo, mathconstants = fontdata.mathconstants, + colorpalettes = fontdata.colorpalettes, + svgshapes = fontdata.svgshapes, + sbixshapes = fontdata.sbixshapes, + variabledata = fontdata.variabledata, + foundtables = fontdata.foundtables, }, } end @@ -2193,6 +2400,7 @@ function readers.getinfo(filename,specification) -- string, nil|number|table local subfont = nil local platformnames = false local rawfamilynames = false + local instancenames = true if type(specification) == "table" then subfont = tonumber(specification.subfont) platformnames = specification.platformnames @@ -2204,20 +2412,21 @@ function readers.getinfo(filename,specification) -- string, nil|number|table filename = filename, details = true, platformnames = platformnames, + instancenames = true, -- rawfamilynames = rawfamilynames, } if fontdata then local subfonts = fontdata.subfonts if not subfonts then - return getinfo(fontdata,nil,platformnames,rawfamilynames) + return getinfo(fontdata,nil,platformnames,rawfamilynames,false,instancenames) elseif not subfont then local info = { } for i=1,#subfonts do - info[i] = getinfo(fontdata,i,platformnames,rawfamilynames) + info[i] = getinfo(fontdata,i,platformnames,rawfamilynames,false,instancenames) end return info elseif subfont >= 1 and subfont <= #subfonts then - return getinfo(fontdata,subfont,platformnames,rawfamilynames) + return getinfo(fontdata,subfont,platformnames,rawfamilynames,false,instancenames) else return { filename = filename, @@ -2274,63 +2483,3 @@ function readers.extend(fontdata) end end end - --- for now .. this will move to a context specific file - -if fonts.hashes then - - local identifiers = fonts.hashes.identifiers - local loadshapes = readers.loadshapes - - readers.version = 0.006 - readers.cache = containers.define("fonts", "shapes", readers.version, true) - - -- todo: loaders per format - - local function load(filename,sub) - local base = file.basename(filename) - local name = file.removesuffix(base) - local kind = file.suffix(filename) - local attr = lfs.attributes(filename) - local size = attr and attr.size or 0 - local time = attr and attr.modification or 0 - local sub = tonumber(sub) - if size > 0 and (kind == "otf" or kind == "ttf" or kind == "tcc") then - local hash = containers.cleanname(base) -- including suffix - if sub then - hash = hash .. "-" .. sub - end - data = containers.read(readers.cache,hash) - if not data or data.time ~= time or data.size ~= size then - data = loadshapes(filename,sub) - if data then - data.size = size - data.format = data.format or (kind == "otf" and "opentype") or "truetype" - data.time = time - packoutlines(data) - containers.write(readers.cache,hash,data) - data = containers.read(readers.cache,hash) -- frees old mem - end - end - unpackoutlines(data) - else - data = { - filename = filename, - size = 0, - time = time, - format = "unknown", - units = 1000, - glyphs = { } - } - end - return data - end - - fonts.hashes.shapes = table.setmetatableindex(function(t,k) - local d = identifiers[k] - local v = load(d.properties.filename,d.subindex) - t[k] = v - return v - end) - -end diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index 1af7bacf3..16c2ce735 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -6,73 +6,45 @@ if not modules then modules = { } end modules ['font-ots'] = { -- sequences license = "see context related readme files", } --- to be checked: discrun doesn't seem to do something useful now (except run the --- check again) so if we need it again we'll do a zwnjrun or so - --- components will go away and be replaced by a property table which simplifies --- code (also more efficient) - --- beware, on my development machine we test a slightly a more optimized version - --- assumptions: --- --- cursives don't cross discretionaries --- marks precede bases --- --- pitfalls: --- --- when we append to a dics field we need to set the field in order to update tail --- --- This is a version of font-otn.lua adapted to the new font loader code. It --- is a context version which can contain experimental code, but when we --- have serious patches we will backport to the font-otn files. The plain --- loader that ships with context also uses this now. --- --- todo: looks like we have a leak somewhere (probably in ligatures) --- todo: copy attributes to disc --- todo: get rid of components, better use the tounicode entry if needed (at all) --- --- we do some disc juggling where we need to keep in mind that the --- pre, post and replace fields can have prev pointers to a nesting --- node ... i wonder if that is still needed --- --- not possible: --- --- \discretionary {alpha-} {betagammadelta} --- {\discretionary {alphabeta-} {gammadelta} --- {\discretionary {alphabetagamma-} {delta} --- {alphabetagammadelta}}} - --[[ldx-- <p>This module is a bit more split up that I'd like but since we also want to test with plain <l n='tex'/> it has to be so. This module is part of <l n='context'/> and discussion about improvements and functionality mostly happens on the <l n='context'/> mailing list.</p> -<p>The specification of OpenType is kind of vague. Apart from a lack of a proper -free specifications there's also the problem that Microsoft and Adobe -may have their own interpretation of how and in what order to apply features. -In general the Microsoft website has more detailed specifications and is a -better reference. There is also some information in the FontForge help files.</p> +<p>The specification of OpenType is (or at least a decade ago was) kind of vague. +Apart from a lack of a proper free specifications there's also the problem that +Microsoft and Adobe may have their own interpretation of how and in what order to +apply features. In general the Microsoft website has more detailed specifications +and is a better reference. There is also some information in the FontForge help +files. In the end we rely most on the Microsoft specification.</p> <p>Because there is so much possible, fonts might contain bugs and/or be made to work with certain rederers. These may evolve over time which may have the side -effect that suddenly fonts behave differently.</p> +effect that suddenly fonts behave differently. We don't want to catch all font +issues.</p> -<p>After a lot of experiments (mostly by Taco, me and Idris) we're now at yet another -implementation. Of course all errors are mine and of course the code can be -improved. There are quite some optimizations going on here and processing speed -is currently acceptable. Not all functions are implemented yet, often because I -lack the fonts for testing. Many scripts are not yet supported either, but I will -look into them as soon as <l n='context'/> users ask for it.</p> +<p>After a lot of experiments (mostly by Taco, me and Idris) the first implementation +becaus quite useful. When it did most of what we wanted, a more optimized version +evolved. Of course all errors are mine and of course the code can be improved. There +are quite some optimizations going on here and processing speed is currently quite +acceptable and has been improved over time. Many complex scripts are not yet supported +yet, but I will look into them as soon as <l n='context'/> users ask for it.</p> -<p>The specification leaves room for interpretation. In case of doubt the microsoft +<p>The specification leaves room for interpretation. In case of doubt the Microsoft implementation is the reference as it is the most complete one. As they deal with lots of scripts and fonts, Kai and Ivo did a lot of testing of the generic code and their suggestions help improve the code. I'm aware that not all border cases can be taken care of, unless we accept excessive runtime, and even then the interference with other mechanisms (like hyphenation) are not trivial.</p> +<p>Especially discretionary handling has been improved much by Kai Eigner who uses complex +(latin) fonts. The current implementation is a compromis between his patches and my code +and in the meantime performance is quite ok. We cannot check all border cases without +compromising speed but so far we're okay. Given good test cases we can probably improve +it here and there. Especially chain lookups are non trivial with discretionaries but +things got much better over time thanks to Kai.</p> + <p>Glyphs are indexed not by unicode but in their own way. This is because there is no relationship with unicode at all, apart from the fact that a font might cover certain ranges of characters. One character can have multiple shapes. However, at the @@ -84,35 +56,75 @@ then in the output eventually.</p> that different from the one produced by <l n='fontforge'/> but we uses hashes instead. In <l n='context'/> that table is packed (similar tables are shared) and cached on disk so that successive runs can use the optimized table (after loading the table is -unpacked). The flattening code used later is a prelude to an even more compact table -format (and as such it keeps evolving).</p> - -<p>This module is sparsely documented because it is a moving target. The table format -of the reader changes and we experiment a lot with different methods for supporting -features.</p> +unpacked).</p> -<p>As with the <l n='afm'/> code, we may decide to store more information in the -<l n='otf'/> table.</p> +<p>This module is sparsely documented because it is has been a moving target. The +table format of the reader changed a bit over time and we experiment a lot with +different methods for supporting features. By now the structures are quite stable</p> <p>Incrementing the version number will force a re-cache. We jump the number by one -when there's a fix in the <l n='fontforge'/> library or <l n='lua'/> code that -results in different tables.</p> +when there's a fix in the reader or processing code that can result in different +results.</p> + +<p>This code is also used outside context but in context it has to work with other +mechanisms. Both put some constraints on the code here.</p> + --ldx]]-- +-- Remark: We assume that cursives don't cross discretionaries which is okay because it +-- is only used in semitic scripts. +-- +-- Remark: We assume that marks precede base characters. +-- +-- Remark: When complex ligatures extend into discs nodes we can get side effects. Normally +-- this doesn't happen; ff\d{l}{l}{l} in lm works but ff\d{f}{f}{f}. +-- +-- Todo: check if we copy attributes to disc nodes if needed. +-- +-- Todo: it would be nice if we could get rid of components. In other places we can use +-- the unicode properties. +-- +-- Remark: We do some disc juggling where we need to keep in mind that the pre, post and +-- replace fields can have prev pointers to a nesting node ... I wonder if that is still +-- needed. +-- +-- Remark: This is not possible: +-- +-- \discretionary {alpha-} {betagammadelta} +-- {\discretionary {alphabeta-} {gammadelta} +-- {\discretionary {alphabetagamma-} {delta} +-- {alphabetagammadelta}}} +-- +-- Remark: Something is messed up: we have two mark / ligature indices, one at the +-- injection end and one here ... this is based on KE's patches but there is something +-- fishy there as I'm pretty sure that for husayni we need some connection (as it's much +-- more complex than an average font) but I need proper examples of all cases, not of +-- only some. +-- +-- Remark: I wonder if indexed would be faster than unicoded. It would be a major +-- rewrite to have char being unicode + an index field in glyph nodes. Also more +-- assignments have to be made in order to keep things in sync. So, it's a no-go. +-- +-- Remark: We can provide a fast loop when there are no disc nodes (tests show a 1% +-- gain). Smaller functions might perform better cache-wise. But ... memory becomes +-- faster anyway, so ... + local type, next, tonumber = type, next, tonumber local random = math.random local formatters = string.formatters local insert = table.insert -local logs, trackers, nodes, attributes = logs, trackers, nodes, attributes +local registertracker = trackers.register -local registertracker = trackers.register -local registerdirective = directives.register +local logs = logs +local trackers = trackers +local nodes = nodes +local attributes = attributes +local fonts = fonts -local fonts = fonts -local otf = fonts.handlers.otf +local otf = fonts.handlers.otf +local tracers = nodes.tracers -local trace_lookups = false registertracker("otf.lookups", function(v) trace_lookups = v end) local trace_singles = false registertracker("otf.singles", function(v) trace_singles = v end) local trace_multiples = false registertracker("otf.multiples", function(v) trace_multiples = v end) local trace_alternatives = false registertracker("otf.alternatives", function(v) trace_alternatives = v end) @@ -124,38 +136,30 @@ local trace_cursive = false registertracker("otf.cursive", function(v local trace_preparing = false registertracker("otf.preparing", function(v) trace_preparing = v end) local trace_bugs = false registertracker("otf.bugs", function(v) trace_bugs = v end) local trace_details = false registertracker("otf.details", function(v) trace_details = v end) -local trace_applied = false registertracker("otf.applied", function(v) trace_applied = v end) local trace_steps = false registertracker("otf.steps", function(v) trace_steps = v end) local trace_skips = false registertracker("otf.skips", function(v) trace_skips = v end) local trace_directions = false registertracker("otf.directions", function(v) trace_directions = v end) +local trace_plugins = false registertracker("otf.plugins", function(v) trace_plugins = v end) local trace_kernruns = false registertracker("otf.kernruns", function(v) trace_kernruns = v end) local trace_discruns = false registertracker("otf.discruns", function(v) trace_discruns = v end) local trace_compruns = false registertracker("otf.compruns", function(v) trace_compruns = v end) local trace_testruns = false registertracker("otf.testruns", function(v) trace_testruns = v end) -local quit_on_no_replacement = true -- maybe per font -local zwnjruns = true -local optimizekerns = true - -registerdirective("otf.zwnjruns", function(v) zwnjruns = v end) -registerdirective("otf.chain.quitonnoreplacement",function(value) quit_on_no_replacement = value end) +local optimizekerns = true -local report_direct = logs.reporter("fonts","otf direct") -local report_subchain = logs.reporter("fonts","otf subchain") -local report_chain = logs.reporter("fonts","otf chain") -local report_process = logs.reporter("fonts","otf process") ------ report_prepare = logs.reporter("fonts","otf prepare") -local report_warning = logs.reporter("fonts","otf warning") -local report_run = logs.reporter("fonts","otf run") -local report_check = logs.reporter("fonts","otf check") +local report_direct = logs.reporter("fonts","otf direct") +local report_subchain = logs.reporter("fonts","otf subchain") +local report_chain = logs.reporter("fonts","otf chain") +local report_process = logs.reporter("fonts","otf process") +local report_warning = logs.reporter("fonts","otf warning") +local report_run = logs.reporter("fonts","otf run") registertracker("otf.replacements", "otf.singles,otf.multiples,otf.alternatives,otf.ligatures") registertracker("otf.positions","otf.marks,otf.kerns,otf.cursive") registertracker("otf.actions","otf.replacements,otf.positions") registertracker("otf.injections","nodes.injections") - -registertracker("*otf.sample","otf.steps,otf.actions,otf.analyzing") +registertracker("otf.sample","otf.steps,otf.actions,otf.analyzing") local nuts = nodes.nuts local tonode = nuts.tonode @@ -182,28 +186,32 @@ local setchar = nuts.setchar local getdisc = nuts.getdisc local setdisc = nuts.setdisc local setlink = nuts.setlink +local getcomponents = nuts.getcomponents -- the original one, not yet node-aux +local setcomponents = nuts.setcomponents -- the original one, not yet node-aux +local getdir = nuts.getdir +local getwidth = nuts.getwidth local ischar = nuts.is_char -local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after -local delete_node = nuts.delete -local remove_node = nuts.remove local copy_node = nuts.copy local copy_node_list = nuts.copy_list local find_node_tail = nuts.tail local flush_node_list = nuts.flush_list -local free_node = nuts.free +local flush_node = nuts.flush_node local end_of_math = nuts.end_of_math local traverse_nodes = nuts.traverse local traverse_id = nuts.traverse_id +local set_components = nuts.set_components +local take_components = nuts.take_components +local count_components = nuts.count_components +local copy_no_components = nuts.copy_no_components +local copy_only_glyphs = nuts.copy_only_glyphs local setmetatableindex = table.setmetatableindex -local zwnj = 0x200C -local zwj = 0x200D -local wildcard = "*" -local default = "dflt" +----- zwnj = 0x200C +----- zwj = 0x200D local nodecodes = nodes.nodecodes local glyphcodes = nodes.glyphcodes @@ -219,15 +227,8 @@ local localpar_code = nodecodes.localpar local discretionary_code = disccodes.discretionary local ligature_code = glyphcodes.ligature -local privateattribute = attributes.private - --- Something is messed up: we have two mark / ligature indices, one at the injection --- end and one here ... this is based on KE's patches but there is something fishy --- there as I'm pretty sure that for husayni we need some connection (as it's much --- more complex than an average font) but I need proper examples of all cases, not --- of only some. - -local a_state = privateattribute('state') +local a_state = attributes.private('state') +local a_noligature = attributes.private("noligature") local injections = nodes.injections local setmark = injections.setmark @@ -239,57 +240,56 @@ local copyinjection = injections.copy local setligaindex = injections.setligaindex local getligaindex = injections.getligaindex -local cursonce = true - -local fonthashes = fonts.hashes -local fontdata = fonthashes.identifiers +local fontdata = fonts.hashes.identifiers +local fontfeatures = fonts.hashes.features -local otffeatures = fonts.constructors.newfeatures("otf") +local otffeatures = fonts.constructors.features.otf local registerotffeature = otffeatures.register local onetimemessage = fonts.loggers.onetimemessage or function() end -otf.defaultnodealternate = "none" -- first last - --- We use a few global variables. The handler can be called nested but this assumes that the --- same font is used. Nested calls are normally not needed (only for devanagari). - -local tfmdata = false -local characters = false -local descriptions = false -local marks = false -local currentfont = false -local factor = 0 -local threshold = 0 - -local sweepnode = nil -local sweepprev = nil -local sweepnext = nil -local sweephead = { } +local getrandom = utilities and utilities.randomizer and utilities.randomizer.get -local notmatchpre = { } -local notmatchpost = { } -local notmatchreplace = { } - -local handlers = { } - --- helper +otf.defaultnodealternate = "none" -- first last -local function isspace(n) - if getid(n) == glue_code then - local w = getfield(n,"width") - if w >= threshold then - return 32 - end - end +-- We use a few semi-global variables. The handler can be called nested but this assumes +-- that the same font is used. + +local tfmdata = false +local characters = false +local descriptions = false +local marks = false +local classes = false +local currentfont = false +local factor = 0 +local threshold = 0 +local checkmarks = false + +local sweepnode = nil +local sweepprev = nil +local sweepnext = nil +local sweephead = { } + +local notmatchpre = { } +local notmatchpost = { } +local notmatchreplace = { } + +local handlers = { } + +local isspace = injections.isspace +local getthreshold = injections.getthreshold + +local checkstep = (tracers and tracers.steppers.check) or function() end +local registerstep = (tracers and tracers.steppers.register) or function() end +local registermessage = (tracers and tracers.steppers.message) or function() end + +local function checkdisccontent(d) + local pre, post, replace = getdisc(d) + if pre then for n in traverse_id(glue_code,pre) do print("pre",nodes.idstostring(pre)) break end end + if post then for n in traverse_id(glue_code,post) do print("pos",nodes.idstostring(post)) break end end + if replace then for n in traverse_id(glue_code,replace) do print("rep",nodes.idstostring(replace)) break end end end --- we use this for special testing and documentation - -local checkstep = (nodes and nodes.tracers and nodes.tracers.steppers.check) or function() end -local registerstep = (nodes and nodes.tracers and nodes.tracers.steppers.register) or function() end -local registermessage = (nodes and nodes.tracers and nodes.tracers.steppers.message) or function() end - local function logprocess(...) if trace_steps then registermessage(...) @@ -354,6 +354,13 @@ local function mref(rlmode) end end +-- The next code is somewhat complicated by the fact that some fonts can have ligatures made +-- from ligatures that themselves have marks. This was identified by Kai in for instance +-- arabtype: KAF LAM SHADDA ALEF FATHA (0x0643 0x0644 0x0651 0x0627 0x064E). This becomes +-- KAF LAM-ALEF with a SHADDA on the first and a FATHA op de second component. In a next +-- iteration this becomes a KAF-LAM-ALEF with a SHADDA on the second and a FATHA on the +-- third component. + -- We can assume that languages that use marks are not hyphenated. We can also assume -- that at most one discretionary is present. @@ -363,27 +370,19 @@ end -- However, for arabic we need to keep them around for the sake of mark placement -- and indices. -local function copy_glyph(g) -- next and prev are untouched ! - local components = getfield(g,"components") - if components then - setfield(g,"components",nil) - local n = copy_node(g) - copyinjection(n,g) -- we need to preserve the lig indices - setfield(g,"components",components) - return n - else - local n = copy_node(g) - copyinjection(n,g) -- we need to preserve the lig indices - return n - end -end - local function flattendisk(head,disc) - local _, _, replace, _, _, replacetail = getdisc(disc,true) - setfield(disc,"replace",nil) - free_node(disc) - if head == disc then - local next = getnext(disc) + local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true) + local prev, next = getboth(disc) + local ishead = head == disc + setdisc(disc) + flush_node(disc) + if pre then + flush_node_list(pre) + end + if post then + flush_node_list(post) + end + if ishead then if replace then if next then setlink(replacetail,next) @@ -395,7 +394,6 @@ local function flattendisk(head,disc) return -- maybe warning end else - local prev, next = getboth(disc) if replace then if next then setlink(replacetail,next) @@ -416,66 +414,177 @@ local function appenddisc(disc,list) if post then setlink(posttail,posthead) else - post = phead + post = posthead end if replace then setlink(replacetail,replacehead) else - replace = rhead + replace = replacehead end setdisc(disc,pre,post,replace) end -- start is a mark and we need to keep that one +local take_components = getcomponents -- we overload here (for now) +local set_components = setcomponents -- we overload here (for now) +----- get_components = getcomponents -- we overload here (for now) + +local function count_components(start,marks) + if getid(start) ~= glyph_code then + return 0 + elseif getsubtype(start) == ligature_code then + local i = 0 + local components = getcomponents(start) + while components do + i = i + count_components(components,marks) + components = getnext(components) + end + return i + elseif not marks[getchar(start)] then + return 1 + else + return 0 + end +end + local function markstoligature(head,start,stop,char) if start == stop and getchar(start) == char then return head, start else local prev = getprev(start) local next = getnext(stop) - setprev(start,nil) - setnext(stop,nil) - local base = copy_glyph(start) + setprev(start) + setnext(stop) + local base = copy_no_components(start,copyinjection) if head == start then head = base end resetinjection(base) setchar(base,char) setsubtype(base,ligature_code) - setfield(base,"components",start) - setlink(prev,base) - setlink(base,next) + set_components(base,start) + setlink(prev,base,next) return head, base end end --- The next code is somewhat complicated by the fact that some fonts can have ligatures made --- from ligatures that themselves have marks. This was identified by Kai in for instance --- arabtype: KAF LAM SHADDA ALEF FATHA (0x0643 0x0644 0x0651 0x0627 0x064E). This becomes --- KAF LAM-ALEF with a SHADDA on the first and a FATHA op de second component. In a next --- iteration this becomes a KAF-LAM-ALEF with a SHADDA on the second and a FATHA on the --- third component. - -local function getcomponentindex(start) -- we could store this offset in the glyph (nofcomponents) - if getid(start) ~= glyph_code then -- and then get rid of all components - return 0 - elseif getsubtype(start) == ligature_code then - local i = 0 - local components = getfield(start,"components") - while components do - i = i + getcomponentindex(components) - components = getnext(components) - end - return i - elseif not marks[getchar(start)] then - return 1 - else - return 0 - end -end - -local a_noligature = attributes.private("noligature") +-- local function toligature(head,start,stop,char,dataset,sequence,markflag,discfound) -- brr head +-- if getattr(start,a_noligature) == 1 then +-- -- so we can do: e\noligature{ff}e e\noligature{f}fie (we only look at the first) +-- return head, start +-- end +-- if start == stop and getchar(start) == char then +-- resetinjection(start) +-- setchar(start,char) +-- return head, start +-- end +-- local prev = getprev(start) +-- local next = getnext(stop) +-- local comp = start +-- setprev(start) +-- setnext(stop) +-- local base = copy_no_components(start,copyinjection) +-- if start == head then +-- head = base +-- end +-- resetinjection(base) +-- setchar(base,char) +-- setsubtype(base,ligature_code) +-- set_components(base,comp) +-- setlink(prev,base,next) +-- if not discfound then +-- local deletemarks = markflag ~= "mark" +-- local components = start +-- local baseindex = 0 +-- local componentindex = 0 +-- local head = base +-- local current = base +-- -- first we loop over the glyphs in start .. stop +-- while start do +-- local char = getchar(start) +-- if not marks[char] then +-- baseindex = baseindex + componentindex +-- componentindex = getcomponentindex(start,marks) +-- elseif not deletemarks then -- quite fishy +-- setligaindex(start,baseindex + getligaindex(start,componentindex)) +-- if trace_marks then +-- logwarning("%s: keep mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) +-- end +-- local n = copy_node(start) +-- copyinjection(n,start) +-- head, current = insert_node_after(head,current,n) -- unlikely that mark has components +-- elseif trace_marks then +-- logwarning("%s: delete mark %s",pref(dataset,sequence),gref(char)) +-- end +-- start = getnext(start) +-- end +-- -- we can have one accent as part of a lookup and another following +-- -- local start = components -- was wrong (component scanning was introduced when more complex ligs in devanagari was added) +-- local start = getnext(current) +-- while start do +-- local char = ischar(start) +-- if char then +-- if marks[char] then +-- setligaindex(start,baseindex + getligaindex(start,componentindex)) +-- if trace_marks then +-- logwarning("%s: set mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) +-- end +-- start = getnext(start) +-- else +-- break +-- end +-- else +-- break +-- end +-- end +-- else +-- -- discfound ... forget about marks .. probably no scripts that hyphenate and have marks +-- local discprev, discnext = getboth(discfound) +-- if discprev and discnext then +-- -- we assume normalization in context, and don't care about generic ... especially +-- -- \- can give problems as there we can have a negative char but that won't match +-- -- anyway +-- local pre, post, replace, pretail, posttail, replacetail = getdisc(discfound,true) +-- if not replace then -- todo: signal simple hyphen +-- local prev = getprev(base) +-- local current = comp +-- local previous = nil +-- local copied = nil +-- while current do +-- if getid(current) == glyph_code then +-- local n = copy_node(current) +-- if copied then +-- setlink(previous,n) +-- else +-- copied = n +-- end +-- previous = n +-- end +-- current = getnext(current) +-- end +-- setprev(discnext) -- also blocks funny assignments +-- setnext(discprev) -- also blocks funny assignments +-- if pre then +-- setlink(discprev,pre) +-- end +-- pre = comp +-- if post then +-- setlink(posttail,discnext) +-- setprev(post) +-- else +-- post = discnext +-- end +-- setlink(prev,discfound,next) +-- setboth(base) +-- set_components(base,copied) +-- setdisc(discfound,pre,post,base) -- was discretionary_code +-- base = prev -- restart +-- end +-- end +-- end +-- return head, base +-- end local function toligature(head,start,stop,char,dataset,sequence,markflag,discfound) -- brr head if getattr(start,a_noligature) == 1 then @@ -487,33 +596,20 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou setchar(start,char) return head, start end - -- needs testing (side effects): - local components = getfield(start,"components") - if components then - -- we get a double free .. needs checking - -- flush_node_list(components) - end - -- local prev = getprev(start) local next = getnext(stop) local comp = start - setprev(start,nil) - setnext(stop,nil) - local base = copy_glyph(start) + setprev(start) + setnext(stop) + local base = copy_no_components(start,copyinjection) if start == head then head = base end resetinjection(base) setchar(base,char) setsubtype(base,ligature_code) - setfield(base,"components",comp) -- start can have components ... do we need to flush? - if prev then - setnext(prev,base) - end - if next then - setprev(next,base) - end - setboth(base,prev,next) + set_components(base,comp) + setlink(prev,base,next) if not discfound then local deletemarks = markflag ~= "mark" local components = start @@ -526,7 +622,7 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou local char = getchar(start) if not marks[char] then baseindex = baseindex + componentindex - componentindex = getcomponentindex(start) + componentindex = count_components(start,marks) elseif not deletemarks then -- quite fishy setligaindex(start,baseindex + getligaindex(start,componentindex)) if trace_marks then @@ -541,7 +637,6 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou start = getnext(start) end -- we can have one accent as part of a lookup and another following - -- local start = components -- was wrong (component scanning was introduced when more complex ligs in devanagari was added) local start = getnext(current) while start do local char = ischar(start) @@ -567,49 +662,37 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou -- \- can give problems as there we can have a negative char but that won't match -- anyway local pre, post, replace, pretail, posttail, replacetail = getdisc(discfound,true) - if not replace then -- todo: signal simple hyphen + if not replace then local prev = getprev(base) --- local copied = copy_node_list(comp) -local current = comp -local previous = nil -local copied = nil -while current do - if getid(current) == glyph_code then - local n = copy_node(current) - if copied then - setlink(previous,n) - else - copied = n - end - previous = n - end - current = getnext(current) -end - setprev(discnext,nil) -- also blocks funny assignments - setnext(discprev,nil) -- also blocks funny assignments + local comp = take_components(base) + local copied = copy_only_glyphs(comp) if pre then setlink(discprev,pre) + else + setnext(discprev) -- also blocks funny assignments end pre = comp if post then setlink(posttail,discnext) - setprev(post,nil) + setprev(post) else post = discnext + setprev(discnext) -- also blocks funny assignments end - setlink(prev,discfound) - setlink(discfound,next) - setboth(base,nil,nil) - setfield(base,"components",copied) - setdisc(discfound,pre,post,base,discretionary_code) - base = prev -- restart + setlink(prev,discfound,next) + setboth(base) + -- here components have a pointer so we can't free it! + set_components(base,copied) + replace = base + setdisc(discfound,pre,post,replace) -- was discretionary_code + base = prev end end end return head, base end -local function multiple_glyphs(head,start,multiple,ignoremarks) +local function multiple_glyphs(head,start,multiple,ignoremarks,what) local nofmultiples = #multiple if nofmultiples > 0 then resetinjection(start) @@ -617,17 +700,29 @@ local function multiple_glyphs(head,start,multiple,ignoremarks) if nofmultiples > 1 then local sn = getnext(start) for k=2,nofmultiples do --- untested: --- --- while ignoremarks and marks[getchar(sn)] then --- local sn = getnext(sn) --- end + -- untested: + -- + -- while ignoremarks and marks[getchar(sn)] then + -- local sn = getnext(sn) + -- end local n = copy_node(start) -- ignore components resetinjection(n) setchar(n,multiple[k]) insert_node_after(head,start,n) start = n end + if what == true then + -- we're ok + elseif what > 1 then + local m = multiple[nofmultiples] + for i=2,what do + local n = copy_node(start) -- ignore components + resetinjection(n) + setchar(n,m) + insert_node_after(head,start,n) + start = n + end + end end return head, start, true else @@ -640,8 +735,12 @@ end local function get_alternative_glyph(start,alternatives,value) local n = #alternatives - if value == "random" then - local r = random(1,n) + if n == 1 then + -- we could actually change that into a gsub and save some memory in the + -- font loader but it makes tracing more messy + return alternatives[1], trace_alternatives and "1 (only one present)" + elseif value == "random" then + local r = getrandom and getrandom("glyph",1,n) or random(1,n) return alternatives[r], trace_alternatives and formatters["value %a, taking %a"](value,r) elseif value == "first" then return alternatives[1], trace_alternatives and formatters["value %a, taking %a"](value,1) @@ -709,7 +808,7 @@ function handlers.gsub_multiple(head,start,dataset,sequence,multiple) if trace_multiples then logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple)) end - return multiple_glyphs(head,start,multiple,sequence.flags[1]) + return multiple_glyphs(head,start,multiple,sequence.flags[1],dataset[1]) end function handlers.gsub_ligature(head,start,dataset,sequence,ligature) @@ -854,7 +953,6 @@ function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,step,i,inje return head, start, false else local prev = start - local done = false while snext do local nextchar = ischar(snext,currentfont) if nextchar then @@ -874,8 +972,7 @@ function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,step,i,inje if trace_kerns then logprocess("%s: shifting single %s by %p",pref(dataset,sequence),gref(nextchar),k) end - done = true - break + return head, start, true end end if a and #a > 0 then @@ -892,15 +989,13 @@ function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,step,i,inje logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") end end - done = true - break + return head, start, true elseif krn ~= 0 then local k = setkern(snext,factor,rlmode,krn,injection) if trace_kerns then logprocess("%s: inserting kern %p between %s and %s as %s",pref(dataset,sequence),k,gref(getchar(prev)),gref(nextchar),injection or "injections") end - done = true - break + return head, start, true else -- can't happen break end @@ -908,7 +1003,7 @@ function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,step,i,inje break end end - return head, start, done + return head, start, false end end @@ -950,7 +1045,7 @@ function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode) local ba = markanchors[1][basechar] if ba then local ma = markanchors[2] - local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) + local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", pref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -1006,7 +1101,7 @@ function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlm local index = getligaindex(start) ba = ba[index] if ba then - local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) -- index + local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) if trace_marks then logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", pref(dataset,sequence),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy) @@ -1055,7 +1150,7 @@ function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode) local ba = markanchors[1][basechar] -- slot 1 has been made copy of the class hash if ba then local ma = markanchors[2] - local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true) + local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", pref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -1071,7 +1166,6 @@ function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode) end function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,step,i) -- to be checked - local done = false local startchar = getchar(start) if marks[startchar] then if trace_cursive then @@ -1079,7 +1173,7 @@ function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,st end else local nxt = getnext(start) - while not done and nxt do + while nxt do local nextchar = ischar(nxt,currentfont) if not nextchar then break @@ -1097,7 +1191,7 @@ function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,st if trace_cursive then logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,anchor,bound,mref(rlmode)) end - done = true + return head, start, true end end end @@ -1105,7 +1199,7 @@ function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,st end end end - return head, start, done + return head, start, false end --[[ldx-- @@ -1182,40 +1276,53 @@ as less as needed but that would also make the code even more messy.</p> -- this is messy: do we need this disc checking also in alternaties? +local function reportzerosteps(dataset,sequence) + logwarning("%s: no steps",cref(dataset,sequence)) +end + local function reportmoresteps(dataset,sequence) logwarning("%s: more than 1 step",cref(dataset,sequence)) end +-- local function reportbadsteps(dataset,sequence) +-- logwarning("%s: bad step, no proper return values",cref(dataset,sequence)) +-- end + function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,chainindex) local steps = currentlookup.steps local nofsteps = currentlookup.nofsteps if nofsteps > 1 then reportmoresteps(dataset,sequence) end - local current = start - while current do - local currentchar = ischar(current) - if currentchar then - local replacement = steps[1].coverage[currentchar] - if not replacement or replacement == "" then - if trace_bugs then - logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar)) + if nofsteps == 0 then + reportzerosteps(dataset,sequence) + else + local current = start + local mapping = steps[1].coverage + while current do + local currentchar = ischar(current) + if currentchar then + local replacement = mapping[currentchar] + if not replacement or replacement == "" then + if trace_bugs then + logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar)) + end + else + if trace_singles then + logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement)) + end + resetinjection(current) + setchar(current,replacement) end + return head, start, true + elseif currentchar == false then + -- can't happen + break + elseif current == stop then + break else - if trace_singles then - logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement)) - end - resetinjection(current) - setchar(current,replacement) + current = getnext(current) end - return head, start, true - elseif currentchar == false then - -- can't happen - break - elseif current == stop then - break - else - current = getnext(current) end end return head, start, false @@ -1231,17 +1338,21 @@ function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup if nofsteps > 1 then reportmoresteps(dataset,sequence) end - local startchar = getchar(start) - local replacement = steps[1].coverage[startchar] - if not replacement or replacement == "" then - if trace_bugs then - logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar)) - end + if nofsteps == 0 then + reportzerosteps(dataset,sequence) else - if trace_multiples then - logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement)) + local startchar = getchar(start) + local replacement = steps[1].coverage[startchar] + if not replacement or replacement == "" then + if trace_bugs then + logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar)) + end + else + if trace_multiples then + logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement)) + end + return multiple_glyphs(head,start,replacement,sequence.flags[1],dataset[1]) end - return multiple_glyphs(head,start,replacement,currentlookup.flags[1]) -- not sequence.flags? end return head, start, false end @@ -1264,36 +1375,41 @@ function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlooku if nofsteps > 1 then reportmoresteps(dataset,sequence) end - local kind = dataset[4] - local what = dataset[1] - local value = what == true and tfmdata.shared.features[kind] or what - local current = start - while current do - local currentchar = ischar(current) - if currentchar then - local alternatives = steps[1].coverage[currentchar] - if alternatives then - local choice, comment = get_alternative_glyph(current,alternatives,value) - if choice then - if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(char),choice,gref(choice),comment) - end - resetinjection(start) - setchar(start,choice) - else - if trace_alternatives then - logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(char),comment) + if nofsteps == 0 then + reportzerosteps(dataset,sequence) + else + local kind = dataset[4] + local what = dataset[1] + local value = what == true and tfmdata.shared.features[kind] or what -- todo: optimize in ctx + local current = start + local mapping = steps[1].coverage + while current do + local currentchar = ischar(current) + if currentchar then + local alternatives = mapping[currentchar] + if alternatives then + local choice, comment = get_alternative_glyph(current,alternatives,value) + if choice then + if trace_alternatives then + logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(char),choice,gref(choice),comment) + end + resetinjection(start) + setchar(start,choice) + else + if trace_alternatives then + logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(char),comment) + end end end + return head, start, true + elseif currentchar == false then + -- can't happen + break + elseif current == stop then + break + else + current = getnext(current) end - return head, start, true - elseif currentchar == false then - -- can't happen - break - elseif current == stop then - break - else - current = getnext(current) end end return head, start, false @@ -1311,75 +1427,79 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup if nofsteps > 1 then reportmoresteps(dataset,sequence) end - local startchar = getchar(start) - local ligatures = steps[1].coverage[startchar] - if not ligatures then - if trace_bugs then - logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar)) - end + if nofsteps == 0 then + reportzerosteps(dataset,sequence) else - local current = getnext(start) - local discfound = false - local last = stop - local nofreplacements = 1 - local skipmark = currentlookup.flags[1] -- sequence.flags? - while current do - -- todo: ischar ... can there really be disc nodes here? - local id = getid(current) - if id == disc_code then - if not discfound then - discfound = current - end - if current == stop then - break -- okay? or before the disc - else - current = getnext(current) - end - else - local schar = getchar(current) - if skipmark and marks[schar] then -- marks - -- if current == stop then -- maybe add this - -- break - -- else + local startchar = getchar(start) + local ligatures = steps[1].coverage[startchar] + if not ligatures then + if trace_bugs then + logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar)) + end + else + local current = getnext(start) + local discfound = false + local last = stop + local nofreplacements = 1 + local skipmark = currentlookup.flags[1] -- sequence.flags? + while current do + -- todo: ischar ... can there really be disc nodes here? + local id = getid(current) + if id == disc_code then + if not discfound then + discfound = current + end + if current == stop then + break -- okay? or before the disc + else current = getnext(current) - -- end + end else - local lg = ligatures[schar] - if lg then - ligatures = lg - last = current - nofreplacements = nofreplacements + 1 - if current == stop then - break - else + local schar = getchar(current) + if skipmark and marks[schar] then -- marks + -- if current == stop then -- maybe add this + -- break + -- else current = getnext(current) - end + -- end else - break + local lg = ligatures[schar] + if lg then + ligatures = lg + last = current + nofreplacements = nofreplacements + 1 + if current == stop then + break + else + current = getnext(current) + end + else + break + end end end end - end - local ligature = ligatures.ligature - if ligature then - if chainindex then - stop = last - end - if trace_ligatures then + local ligature = ligatures.ligature + if ligature then + if chainindex then + stop = last + end + if trace_ligatures then + if start == stop then + logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature)) + else + logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature)) + end + end + head, start = toligature(head,start,stop,ligature,dataset,sequence,skipmark,discfound) + return head, start, true, nofreplacements, discfound + elseif trace_bugs then if start == stop then - logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature)) + logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar)) else - logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature)) + logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop))) end end - head, start = toligature(head,start,stop,ligature,dataset,sequence,skipmark,discfound) - return head, start, true, nofreplacements, discfound - elseif trace_bugs then - if start == stop then - logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar)) - else - logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop))) - end end end return head, start, false, 0, false @@ -1391,20 +1511,24 @@ function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,r if nofsteps > 1 then reportmoresteps(dataset,sequence) end - local startchar = getchar(start) - local step = steps[1] - local kerns = step.coverage[startchar] - if not kerns then - -- skip - elseif step.format == "pair" then - local dx, dy, w, h = setpair(start,factor,rlmode,sequence.flags[4],kerns) -- currentlookup.flags ? - if trace_kerns then - logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),dx,dy,w,h) - end - else -- needs checking .. maybe no kerns format for single - local k = setkern(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %p",cref(dataset,sequence),gref(startchar),k) + if nofsteps == 0 then + reportzerosteps(dataset,sequence) + else + local startchar = getchar(start) + local step = steps[1] + local kerns = step.coverage[startchar] + if not kerns then + -- skip + elseif step.format == "pair" then + local dx, dy, w, h = setpair(start,factor,rlmode,sequence.flags[4],kerns) -- currentlookup.flags ? + if trace_kerns then + logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),dx,dy,w,h) + end + else -- needs checking .. maybe no kerns format for single + local k = setkern(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %p",cref(dataset,sequence),gref(startchar),k) + end end end return head, start, false @@ -1416,67 +1540,66 @@ function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlm if nofsteps > 1 then reportmoresteps(dataset,sequence) end - local snext = getnext(start) - if snext then - local startchar = getchar(start) - local step = steps[1] - local kerns = step.coverage[startchar] -- always 1 step - if kerns then - local prev = start - local done = false - while snext do - local nextchar = ischar(snext,currentfont) - if not nextchar then - break - end - local krn = kerns[nextchar] - if not krn and marks[nextchar] then - prev = snext - snext = getnext(snext) - elseif not krn then - break - elseif step.format == "pair" then - local a, b = krn[1], krn[2] - if optimizekerns then - -- this permits a mixed table, but we could also decide to optimize this - -- in the loader and use format 'kern' - if not b and a[1] == 0 and a[2] == 0 and a[4] == 0 then - local k = setkern(snext,factor,rlmode,a[3],"injections") + if nofsteps == 0 then + reportzerosteps(dataset,sequence) + else + local snext = getnext(start) + if snext then + local startchar = getchar(start) + local step = steps[1] + local kerns = step.coverage[startchar] -- always 1 step + if kerns then + local prev = start + while snext do + local nextchar = ischar(snext,currentfont) + if not nextchar then + break + end + local krn = kerns[nextchar] + if not krn and marks[nextchar] then + prev = snext + snext = getnext(snext) + elseif not krn then + break + elseif step.format == "pair" then + local a, b = krn[1], krn[2] + if optimizekerns then + -- this permits a mixed table, but we could also decide to optimize this + -- in the loader and use format 'kern' + if not b and a[1] == 0 and a[2] == 0 and a[4] == 0 then + local k = setkern(snext,factor,rlmode,a[3],"injections") + if trace_kerns then + logprocess("%s: shifting single %s by %p",cref(dataset,sequence),gref(startchar),k) + end + return head, start, true + end + end + if a and #a > 0 then + local startchar = getchar(start) + local x, y, w, h = setpair(start,factor,rlmode,sequence.flags[4],a,"injections") -- currentlookups flags? if trace_kerns then - logprocess("%s: shifting single %s by %p",cref(dataset,sequence),gref(startchar),k) + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) end - done = true - break end - end - if a and #a > 0 then - local startchar = getchar(start) - local x, y, w, h = setpair(start,factor,rlmode,sequence.flags[4],a,"injections") -- currentlookups flags? - if trace_kerns then - logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + if b and #b > 0 then + local startchar = getchar(start) + local x, y, w, h = setpair(snext,factor,rlmode,sequence.flags[4],b,"injections") + if trace_kerns then + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end end - end - if b and #b > 0 then - local startchar = getchar(start) - local x, y, w, h = setpair(snext,factor,rlmode,sequence.flags[4],b,"injections") + return head, start, true + elseif krn ~= 0 then + local k = setkern(snext,factor,rlmode,krn) if trace_kerns then - logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + logprocess("%s: inserting kern %s between %s and %s",cref(dataset,sequence),k,gref(getchar(prev)),gref(nextchar)) end + return head, start, true + else + break end - done = true - break - elseif krn ~= 0 then - local k = setkern(snext,factor,rlmode,krn) - if trace_kerns then - logprocess("%s: inserting kern %s between %s and %s",cref(dataset,sequence),k,gref(getchar(prev)),gref(nextchar)) - end - done = true - break - else - break end end - return head, start, done end end return head, start, false @@ -1488,60 +1611,64 @@ function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlooku if nofsteps > 1 then reportmoresteps(dataset,sequence) end - local markchar = getchar(start) - if marks[markchar] then - local markanchors = steps[1].coverage[markchar] -- always 1 step - if markanchors then - local base = getprev(start) -- [glyph] [start=mark] - if base then - local basechar = ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base = getprev(base) - if base then - local basechar = ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break + if nofsteps == 0 then + reportzerosteps(dataset,sequence) + else + local markchar = getchar(start) + if marks[markchar] then + local markanchors = steps[1].coverage[markchar] -- always 1 step + if markanchors then + local base = getprev(start) -- [glyph] [start=mark] + if base then + local basechar = ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base = getprev(base) + if base then + local basechar = ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) + end + return head, start, false end else if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) end return head, start, false end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) - end - return head, start, false end end - end - local ba = markanchors[1][basechar] - if ba then - local ma = markanchors[2] - if ma then - local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) - if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", - cref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) + local ba = markanchors[1][basechar] + if ba then + local ma = markanchors[2] + if ma then + local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", + cref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) + end + return head, start, true end - return head, start, true end + elseif trace_bugs then + logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1) end elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1) + logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2) end elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2) + logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) end elseif trace_bugs then - logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) end - elseif trace_bugs then - logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) end return head, start, false end @@ -1552,64 +1679,68 @@ function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentl if nofsteps > 1 then reportmoresteps(dataset,sequence) end - local markchar = getchar(start) - if marks[markchar] then - local markanchors = steps[1].coverage[markchar] -- always 1 step - if markanchors then - local base = getprev(start) -- [glyph] [optional marks] [start=mark] - if base then - local basechar = ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base = getprev(base) - if base then - local basechar = ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break + if nofsteps == 0 then + reportzerosteps(dataset,sequence) + else + local markchar = getchar(start) + if marks[markchar] then + local markanchors = steps[1].coverage[markchar] -- always 1 step + if markanchors then + local base = getprev(start) -- [glyph] [optional marks] [start=mark] + if base then + local basechar = ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base = getprev(base) + if base then + local basechar = ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1) + end + return head, start, false end else if trace_bugs then - logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1) + logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2) end return head, start, false end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2) - end - return head, start, false end end - end - local ba = markanchors[1][basechar] - if ba then - local ma = markanchors[2] - if ma then - local index = getligaindex(start) - ba = ba[index] - if ba then - local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) - if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", - cref(dataset,sequence),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy) + local ba = markanchors[1][basechar] + if ba then + local ma = markanchors[2] + if ma then + local index = getligaindex(start) + ba = ba[index] + if ba then + local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", + cref(dataset,sequence),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy) + end + return head, start, true end - return head, start, true end end + elseif trace_bugs then + logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1) end elseif trace_bugs then - logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1) + logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2) end elseif trace_bugs then - logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2) + logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar)) end elseif trace_bugs then - logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar)) end - elseif trace_bugs then - logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar)) end return head, start, false end @@ -1620,48 +1751,52 @@ function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlooku if nofsteps > 1 then reportmoresteps(dataset,sequence) end - local markchar = getchar(start) - if marks[markchar] then - local markanchors = steps[1].coverage[markchar] -- always 1 step - if markanchors then - local base = getprev(start) -- [glyph] [basemark] [start=mark] - local slc = getligaindex(start) - if slc then -- a rather messy loop ... needs checking with husayni - while base do - local blc = getligaindex(base) - if blc and blc ~= slc then - base = getprev(base) - else - break + if nofsteps == 0 then + reportzerosteps(dataset,sequence) + else + local markchar = getchar(start) + if marks[markchar] then + local markanchors = steps[1].coverage[markchar] -- always 1 step + if markanchors then + local base = getprev(start) -- [glyph] [basemark] [start=mark] + local slc = getligaindex(start) + if slc then -- a rather messy loop ... needs checking with husayni + while base do + local blc = getligaindex(base) + if blc and blc ~= slc then + base = getprev(base) + else + break + end end end - end - if base then -- subtype test can go - local basechar = ischar(base,currentfont) - if basechar then - local ba = markanchors[1][basechar] - if ba then - local ma = markanchors[2] - if ma then - local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true) - if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", - cref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) + if base then -- subtype test can go + local basechar = ischar(base,currentfont) + if basechar then + local ba = markanchors[1][basechar] + if ba then + local ma = markanchors[2] + if ma then + local dx, dy, bound = setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", + cref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) + end + return head, start, true end - return head, start, true end + elseif trace_bugs then + logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1) end elseif trace_bugs then - logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1) + logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2) end elseif trace_bugs then - logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2) + logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) end elseif trace_bugs then - logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) end - elseif trace_bugs then - logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) end return head, start, false end @@ -1672,52 +1807,51 @@ function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup, if nofsteps > 1 then reportmoresteps(dataset,sequence) end - local startchar = getchar(start) - local exitanchors = steps[1].coverage[startchar] -- always 1 step - if exitanchors then - local done = false - if marks[startchar] then - if trace_cursive then - logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) - end - else - local nxt = getnext(start) - while not done and nxt do - local nextchar = ischar(nxt,currentfont) - if not nextchar then - break - elseif marks[nextchar] then - -- should not happen (maybe warning) - nxt = getnext(nxt) - else - local exit = exitanchors[3] - if exit then - local entry = exitanchors[1][nextchar] - if entry then - entry = entry[2] + if nofsteps == 0 then + reportzerosteps(dataset,sequence) + else + local startchar = getchar(start) + local exitanchors = steps[1].coverage[startchar] -- always 1 step + if exitanchors then + if marks[startchar] then + if trace_cursive then + logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) + end + else + local nxt = getnext(start) + while nxt do + local nextchar = ischar(nxt,currentfont) + if not nextchar then + break + elseif marks[nextchar] then + -- should not happen (maybe warning) + nxt = getnext(nxt) + else + local exit = exitanchors[3] + if exit then + local entry = exitanchors[1][nextchar] if entry then - local dx, dy, bound = setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar]) - if trace_cursive then - logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,anchor,bound,mref(rlmode)) + entry = entry[2] + if entry then + local dx, dy, bound = setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar]) + if trace_cursive then + logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,anchor,bound,mref(rlmode)) + end + return head, start, true end - done = true - break end + elseif trace_bugs then + onetimemessage(currentfont,startchar,"no entry anchors",report_fonts) end - elseif trace_bugs then - onetimemessage(currentfont,startchar,"no entry anchors",report_fonts) + break end - break end end - end - return head, start, done - else - if trace_cursive and trace_details then + elseif trace_cursive and trace_details then logprocess("%s, cursive %s is already done",pref(dataset,sequence),gref(getchar(start)),alreadydone) end - return head, start, false end + return head, start, false end -- what pointer to return, spec says stop @@ -1754,7 +1888,150 @@ end -- order to handle that we need more complex code which also slows down even more. The main -- loop variant could deal with that: test, collapse, backtrack. -local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,ck,chainproc) +local new_kern = nuts.pool.kern + +local function checked(head) + local current = head + while current do + if getid(current) == glue_code then + local kern = new_kern(getwidth(current)) + if head == current then + local next = getnext(current) + if next then + setlink(kern,next) + end + flush_node(current) + head = kern + current = next + else + local prev, next = getboth(current) + setlink(prev,kern,next) + flush_node(current) + current = next + end + else + current = getnext(current) + end + end + return head +end + +local function setdiscchecked(d,pre,post,replace) + if pre then pre = checked(pre) end + if post then post = checked(post) end + if replace then replace = checked(replace) end + setdisc(d,pre,post,replace) +end + +local noflags = { false, false, false, false } + +local function chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped) + + local size = ck[5] - ck[4] + 1 + local flags = sequence.flags or noflags + local done = false + local skipmark = flags[1] + local chainlookups = ck[6] + + -- current match + if chainlookups then + local nofchainlookups = #chainlookups + -- Lookups can be like { 1, false, 3 } or { false, 2 } or basically anything and + -- #lookups can be less than #current + if size == 1 then + -- if nofchainlookups > size then + -- -- bad rules + -- end + local chainlookup = chainlookups[1] + for j=1,#chainlookup do + local chainstep = chainlookup[j] + local chainkind = chainstep.type + local chainproc = chainprocs[chainkind] + if chainproc then + local ok + head, start, ok = chainproc(head,start,last,dataset,sequence,chainstep,rlmode,1) + if ok then + done = true + end + else + logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind) + end + end + else + -- See LookupType 5: Contextual Substitution Subtable. Now it becomes messy. The + -- easiest case is where #current maps on #lookups i.e. one-to-one. But what if + -- we have a ligature. Cf the spec we then need to advance one character but we + -- really need to test it as there are fonts out there that are fuzzy and have + -- too many lookups: + -- + -- U+1105 U+119E U+1105 U+119E : sourcehansansklight: script=hang ccmp=yes + -- + -- Even worse are these family emoji shapes as they can have multiple lookups + -- per slot (probably only for gpos). + local i = 1 + while start do + if skipped then + while start do + local char = getchar(start) + local class = classes[char] + if class then + if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then + start = getnext(start) + else + break + end + else + break + end + end + end + local chainlookup = chainlookups[i] + if chainlookup then + for j=1,#chainlookup do + local chainstep = chainlookup[j] + local chainkind = chainstep.type + local chainproc = chainprocs[chainkind] + if chainproc then + local ok, n + head, start, ok, n = chainproc(head,start,last,dataset,sequence,chainstep,rlmode,i) + -- messy since last can be changed ! + if ok then + done = true + if n and n > 1 and i + n > nofchainlookups then + -- this is a safeguard, we just ignore the rest of the lookups + break + end + end + else + -- actually an error + logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind) + end + end + end + i = i + 1 + if i > size or not start then + break + elseif start then + start = getnext(start) + end + end + end + else + -- todo: needs checking for holes in the replacements + local replacements = ck[7] + if replacements then + head, start, done = reversesub(head,start,last,dataset,sequence,replacements,rlmode) + else + done = true + if trace_contexts then + logprocess("%s: skipping match",cref(dataset,sequence)) + end + end + end + return head, start, done +end + +local function chaindisk(head,start,dataset,sequence,rlmode,ck,skipped) if not start then return head, start, false @@ -1769,15 +2046,16 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c local sweepnode = sweepnode local sweeptype = sweeptype local sweepoverflow = false - local checkdisc = getprev(head) -- hm bad name head local keepdisc = not sweepnode local lookaheaddisc = nil local backtrackdisc = nil local current = start local last = start local prev = getprev(start) + local hasglue = false -- fishy: so we can overflow and then go on in the sweep? + -- todo : id can also be glue_code as we checked spaces local i = f while i <= l do @@ -1786,21 +2064,30 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c i = i + 1 last = current current = getnext(current) + elseif id == glue_code then + i = i + 1 + last = current + current = getnext(current) + hasglue = true elseif id == disc_code then if keepdisc then - keepdisc = false - if notmatchpre[current] ~= notmatchreplace[current] then - lookaheaddisc = current - end + keepdisc = false + lookaheaddisc = current local replace = getfield(current,"replace") - while replace and i <= l do - if getid(replace) == glyph_code then - i = i + 1 + if not replace then + sweepoverflow = true + sweepnode = current + current = getnext(current) + else + while replace and i <= l do + if getid(replace) == glyph_code then + i = i + 1 + end + replace = getnext(replace) end - replace = getnext(replace) + current = getnext(replace) end - last = current - current = getnext(c) + last = current else head, current = flattendisk(head,current) end @@ -1838,8 +2125,8 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c tail = find_node_tail(head) end setnext(sweepnode,current) - setprev(head,nil) - setnext(tail,nil) + setprev(head) + setnext(tail) appenddisc(sweepnode,head) end end @@ -1852,13 +2139,18 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c if id == glyph_code then i = i + 1 current = getnext(current) + elseif id == glue_code then + i = i + 1 + current = getnext(current) + hasglue = true elseif id == disc_code then if keepdisc then keepdisc = false if notmatchpre[current] ~= notmatchreplace[current] then lookaheaddisc = current end - local replace = getfield(c,"replace") + -- we assume a simple text only replace (we could use nuts.count) + local replace = getfield(current,"replace") while replace and i < s do if getid(replace) == glyph_code then i = i + 1 @@ -1894,12 +2186,16 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c local id = getid(current) if id == glyph_code then i = i - 1 + elseif id == glue_code then + i = i - 1 + hasglue = true elseif id == disc_code then if keepdisc then keepdisc = false if notmatchpost[current] ~= notmatchreplace[current] then backtrackdisc = current end + -- we assume a simple text only replace (we could use nuts.count) local replace = getfield(current,"replace") while replace and i > 1 do if getid(replace) == glyph_code then @@ -1918,7 +2214,8 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c end end - local ok = false + local done = false + if lookaheaddisc then local cf = start @@ -1937,43 +2234,53 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c break end end - - setprev(lookaheaddisc,cprev) - if cprev then - setnext(cprev,lookaheaddisc) - end - setprev(cf,nil) - setnext(cl,nil) + setlink(cprev,lookaheaddisc) + setprev(cf) + setnext(cl) if startishead then head = lookaheaddisc end local pre, post, replace = getdisc(lookaheaddisc) local new = copy_node_list(cf) local cnew = new + if pre then + setlink(find_node_tail(cf),pre) + end + if replace then + local tail = find_node_tail(new) + setlink(tail,replace) + end for i=1,insertedmarks do cnew = getnext(cnew) end + cl = start local clast = cnew for i=f,l do + cl = getnext(cl) clast = getnext(clast) end if not notmatchpre[lookaheaddisc] then - cf, start, ok = chainproc(cf,start,last,dataset,sequence,chainlookup,rlmode,k) + local ok = false + cf, start, ok = chainrun(cf,start,cl,dataset,sequence,rlmode,ck,skipped) + if ok then + done = true + end end if not notmatchreplace[lookaheaddisc] then - new, cnew, ok = chainproc(new,cnew,clast,dataset,sequence,chainlookup,rlmode,k) - end - if pre then - setlink(cl,pre) + local ok = false + new, cnew, ok = chainrun(new,cnew,clast,dataset,sequence,rlmode,ck,skipped) + if ok then + done = true + end end - if replace then - local tail = find_node_tail(new) - setlink(tail,replace) + if hasglue then + setdiscchecked(lookaheaddisc,cf,post,new) + else + setdisc(lookaheaddisc,cf,post,new) end - setdisc(lookaheaddisc,cf,post,new) start = getprev(lookaheaddisc) sweephead[cf] = getnext(clast) - sweephead[new] = getnext(last) + sweephead[new] = getnext(cl) elseif backtrackdisc then @@ -1996,8 +2303,8 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c setprev(cnext,backtrackdisc) end setnext(backtrackdisc,cnext) - setprev(cf,nil) - setnext(cl,nil) + setprev(cf) + setnext(cl) local pre, post, replace, pretail, posttail, replacetail = getdisc(backtrackdisc,true) local new = copy_node_list(cf) local cnew = find_node_tail(new) @@ -2009,10 +2316,18 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c clast = getnext(clast) end if not notmatchpost[backtrackdisc] then - cf, start, ok = chainproc(cf,start,last,dataset,sequence,chainlookup,rlmode,k) + local ok = false + cf, start, ok = chainrun(cf,start,last,dataset,sequence,rlmode,ck,skipped) + if ok then + done = true + end end if not notmatchreplace[backtrackdisc] then - new, cnew, ok = chainproc(new,cnew,clast,dataset,sequence,chainlookup,rlmode,k) + local ok = false + new, cnew, ok = chainrun(new,cnew,clast,dataset,sequence,rlmode,ck,skipped) + if ok then + done = true + end end if post then setlink(posttail,cf) @@ -2024,89 +2339,45 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c else replace = new end - setdisc(backtrackdisc,pre,post,replace) + if hasglue then + setdiscchecked(backtrackdisc,pre,post,replace) + else + setdisc(backtrackdisc,pre,post,replace) + end start = getprev(backtrackdisc) sweephead[post] = getnext(clast) sweephead[replace] = getnext(last) else - head, start, ok = chainproc(head,start,last,dataset,sequence,chainlookup,rlmode,k) + local ok = false + head, start, ok = chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped) + if ok then + done = true + end end - return head, start, ok + return head, start, done end --- helpers from elsewhere - --- local function currentmatch(current,n,l) --- while current do --- if getid(current) ~= glyph_code then --- return false --- elseif seq[n][getchar(current)] then --- n = n + 1 --- current = getnext(current) --- if not current then --- return true, n, current --- elseif n > l then --- -- match = false --- return true, n, current --- end --- else --- return false --- end --- end --- end --- --- local function aftermatch(current,n,l) --- while current do --- if getid(current) ~= glyph_code then --- return false --- elseif seq[n][getchar(current)] then --- n = n + 1 --- current = getnext(current) --- if not current then --- return true, n, current --- elseif n > l then --- -- match = false --- return true, n, current --- end --- else --- return false --- end --- end --- end --- --- local function beforematch(current,n) --- local finish = getprev(current) --- local current = find_node_tail(current) --- while current do --- if getid(current) ~= glyph_code then --- return false --- elseif seq[n][getchar(current)] then --- n = n - 1 --- current = getprev(current) --- if not current or current == finish then --- return true, n, current --- elseif n < 1 then --- -- match = false --- return true, n, current --- end --- else --- return false --- end --- end --- end - -local noflags = { false, false, false, false } +local function chaintrac(head,start,dataset,sequence,rlmode,ck,skipped) + local rule = ck[1] + local lookuptype = ck[8] or ck[2] + local nofseq = #ck[3] + local first = ck[4] + local last = ck[5] + local char = getchar(start) + logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %a", + cref(dataset,sequence),rule,gref(char),first-1,last-first+1,nofseq-last,lookuptype) +end local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) local sweepnode = sweepnode local sweeptype = sweeptype local currentfont = currentfont local diskseen = false - local checkdisc = getprev(head) + local checkdisc = sweeptype and getprev(head) local flags = sequence.flags or noflags local done = false local skipmark = flags[1] @@ -2114,6 +2385,8 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) local skipbase = flags[3] local markclass = sequence.markclass local skipped = false + local startprev, + startnext = getboth(start) for k=1,#contexts do -- i've only seen ccmp having > 1 (e.g. dejavu) local match = true local current = start @@ -2121,12 +2394,15 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) local ck = contexts[k] local seq = ck[3] local s = #seq + local size = 1 -- f..l = mid string if s == 1 then - -- never happens + -- this seldom happens as it makes no sense (bril, ebgaramond, husayni, minion) local char = ischar(current,currentfont) if char then - match = seq[1][char] + if not seq[1][char] then + match = false + end end else -- maybe we need a better space check (maybe check for glue or category or combination) @@ -2134,155 +2410,163 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) local f = ck[4] local l = ck[5] -- current match - if f == 1 and f == l then -- current only - -- already a hit - -- match = true - else -- before/current/after | before/current | current/after - -- no need to test first hit (to be optimized) - if f == l then -- new, else last out of sync (f is > 1) - -- match = true - else - local discfound = nil - local n = f + 1 - last = getnext(last) -- the second in current (first already matched) - while n <= l do - if not last and (sweeptype == "post" or sweeptype == "replace") then - last = getnext(sweepnode) - sweeptype = nil - end - if last then - local char, id = ischar(last,currentfont) - if char then - local ccd = descriptions[char] - if ccd then - local class = ccd.class or "base" - if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then - skipped = true - if trace_skips then - show_skip(dataset,sequence,char,ck,class) - end + size = l - f + 1 + if size > 1 then + -- before/current/after | before/current | current/after + local discfound -- = nil + local n = f + 1 + -- last = getnext(last) -- the second in current (first already matched) + last = startnext -- the second in current (first already matched) + while n <= l do + if not last and (sweeptype == "post" or sweeptype == "replace") then + last = getnext(sweepnode) + sweeptype = nil + end + if last then + local char, id = ischar(last,currentfont) + if char then + local class = classes[char] + if class then + if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then + skipped = true + if trace_skips then + show_skip(dataset,sequence,char,ck,class) + end + last = getnext(last) + elseif seq[n][char] then + if n < l then last = getnext(last) - elseif seq[n][char] then - if n < l then - last = getnext(last) - end - n = n + 1 - else - if discfound then - notmatchreplace[discfound] = true - match = not notmatchpre[discfound] - else - match = false - end - break end + n = n + 1 else if discfound then notmatchreplace[discfound] = true - match = not notmatchpre[discfound] + if notmatchpre[discfound] then + match = false + end else match = false end break end - elseif char == false then + else if discfound then notmatchreplace[discfound] = true - match = not notmatchpre[discfound] + if notmatchpre[discfound] then + match = false + end else match = false end break - elseif id == disc_code then - diskseen = true - discfound = last - notmatchpre[last] = nil - notmatchpost[last] = true - notmatchreplace[last] = nil - local pre, post, replace = getdisc(last) - if pre then - local n = n - while pre do - if seq[n][getchar(pre)] then - n = n + 1 - pre = getnext(pre) - if n > l then - break - end - else - notmatchpre[last] = true + end + elseif char == false then + if discfound then + notmatchreplace[discfound] = true + if notmatchpre[discfound] then + match = false + end + else + match = false + end + break + elseif id == disc_code then + diskseen = true + discfound = last + notmatchpre[last] = nil + notmatchpost[last] = true + notmatchreplace[last] = nil + local pre, post, replace = getdisc(last) + if pre then + local n = n + while pre do + if seq[n][getchar(pre)] then + n = n + 1 + pre = getnext(pre) + if n > l then break end - end - if n <= l then + else notmatchpre[last] = true + break end - else + end + if n <= l then notmatchpre[last] = true end - if replace then - -- so far we never entered this branch - while replace do - if seq[n][getchar(replace)] then - n = n + 1 - replace = getnext(replace) - if n > l then - break - end - else - notmatchreplace[last] = true - match = not notmatchpre[last] + else + notmatchpre[last] = true + end + if replace then + -- so far we never entered this branch + while replace do + if seq[n][getchar(replace)] then + n = n + 1 + replace = getnext(replace) + if n > l then break end + else + notmatchreplace[last] = true + if notmatchpre[last] then + match = false + end + break end - match = not notmatchpre[last] end - -- maybe only if match - last = getnext(last) - else - match = false - break + -- why here again + if notmatchpre[last] then + match = false + end end + -- maybe only if match + last = getnext(last) else match = false break end + else + match = false + break end end end -- before if match and f > 1 then - local prev = getprev(start) - if prev then + -- local prev = getprev(start) + -- if prev then + if startprev then + local prev = startprev if prev == checkdisc and (sweeptype == "pre" or sweeptype == "replace") then prev = getprev(sweepnode) -- sweeptype = nil end if prev then - local discfound = nil + local discfound -- = nil local n = f - 1 while n >= 1 do if prev then local char, id = ischar(prev,currentfont) if char then - local ccd = descriptions[char] - if ccd then - local class = ccd.class + local class = classes[char] + if class then if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then skipped = true if trace_skips then show_skip(dataset,sequence,char,ck,class) end - prev = getprev(prev) -- moved here + prev = getprev(prev) elseif seq[n][char] then - if n > 1 then -- new test - prev = getprev(prev) -- moved here + if n > 1 then + prev = getprev(prev) end n = n - 1 else if discfound then notmatchreplace[discfound] = true - match = not notmatchpost[discfound] + if notmatchpost[discfound] then + match = false + end else match = false end @@ -2291,17 +2575,20 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) else if discfound then notmatchreplace[discfound] = true - match = not notmatchpost[discfound] + if notmatchpost[discfound] then + match = false + end else match = false end break end - -- prev = getprev(prev) -- moved up elseif char == false then if discfound then notmatchreplace[discfound] = true - match = not notmatchpost[discfound] + if notmatchpost[discfound] then + match = false + end else match = false end @@ -2354,7 +2641,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end else notmatchreplace[prev] = true - match = not notmatchpost[prev] + if notmatchpost[prev] then + match = false + end break end end @@ -2365,16 +2654,13 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end -- maybe only if match prev = getprev(prev) - elseif seq[n][32] then + elseif id == glue_code and seq[n][32] and isspace(prev,threshold,id) then n = n - 1 prev = getprev(prev) else match = false break end - elseif seq[n][32] then -- somewhat special, as zapfino can have many preceding spaces - n = n - 1 - prev = getprev(prev) -- was absent else match = false break @@ -2390,23 +2676,20 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) -- after if match and s > l then local current = last and getnext(last) - if not current then - if sweeptype == "post" or sweeptype == "replace" then - current = getnext(sweepnode) - -- sweeptype = nil - end + if not current and (sweeptype == "post" or sweeptype == "replace") then + current = getnext(sweepnode) + -- sweeptype = nil end if current then - local discfound = nil + local discfound -- = nil -- removed optimization for s-l == 1, we have to deal with marks anyway local n = l + 1 while n <= s do if current then local char, id = ischar(current,currentfont) if char then - local ccd = descriptions[char] - if ccd then - local class = ccd.class + local class = classes[char] + if class then if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then skipped = true if trace_skips then @@ -2421,7 +2704,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) else if discfound then notmatchreplace[discfound] = true - match = not notmatchpre[discfound] + if notmatchpre[discfound] then + match = false + end else match = false end @@ -2430,7 +2715,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) else if discfound then notmatchreplace[discfound] = true - match = not notmatchpre[discfound] + if notmatchpre[discfound] then + match = false + end else match = false end @@ -2439,7 +2726,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) elseif char == false then if discfound then notmatchreplace[discfound] = true - match = not notmatchpre[discfound] + if notmatchpre[discfound] then + match = false + end else match = false end @@ -2482,7 +2771,10 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end else notmatchreplace[current] = true - match = notmatchpre[current] + -- different than others, needs checking if "not" is okay + if not notmatchpre[current] then + match = false + end break end end @@ -2494,15 +2786,13 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end -- maybe only if match current = getnext(current) - elseif seq[n][32] then -- brrr + elseif id == glue_code and seq[n][32] and isspace(current,threshold,id) then n = n + 1 + current = getnext(current) else match = false break end - elseif seq[n][32] then - n = n + 1 - current = getnext(current) else match = false break @@ -2514,114 +2804,13 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end end if match then - -- can lookups be of a different type ? - local diskchain = diskseen or sweepnode if trace_contexts then - local rule = ck[1] - local lookuptype = ck[8] or ck[2] - local first = ck[4] - local last = ck[5] - local char = getchar(start) - logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %a", - cref(dataset,sequence),rule,gref(char),first-1,last-first+1,s-last,lookuptype) - end - local chainlookups = ck[6] - if chainlookups then - local nofchainlookups = #chainlookups - -- we can speed this up if needed - if nofchainlookups == 1 then - local chainlookup = chainlookups[1] - local chainkind = chainlookup.type - local chainproc = chainprocs[chainkind] - if chainproc then - local ok - if diskchain then - head, start, ok = chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,1,ck,chainproc) - else - head, start, ok = chainproc(head,start,last,dataset,sequence,chainlookup,rlmode,1) - end - if ok then - done = true - end - else - logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind) - end - else - local i = 1 - while start and true do - if skipped then - while start do -- todo: use properties - local char = getchar(start) - local ccd = descriptions[char] - if ccd then - local class = ccd.class or "base" - if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then - start = getnext(start) - else - break - end - else - break - end - end - end - -- see remark in ms standard under : LookupType 5: Contextual Substitution Subtable - local chainlookup = chainlookups[1] -- should be i when they can be different - if not chainlookup then - -- we just advance - i = i + 1 -- shouldn't that be #current - else - local chainkind = chainlookup.type - local chainproc = chainprocs[chainkind] - if chainproc then - local ok, n - if diskchain then - head, start, ok = chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,i,ck,chainproc) - else - head, start, ok, n = chainproc(head,start,last,dataset,sequence,chainlookup,rlmode,i) - end - -- messy since last can be changed ! - if ok then - done = true - if n and n > 1 then - -- we have a ligature (cf the spec we advance one but we really need to test it - -- as there are fonts out there that are fuzzy and have too many lookups: - -- - -- U+1105 U+119E U+1105 U+119E : sourcehansansklight: script=hang ccmp=yes - -- - if i + n > nofchainlookups then - -- if trace_contexts then - -- logprocess("%s: quitting lookups",cref(dataset,sequence)) - -- end - break - else - -- we need to carry one - end - end - end - else - -- actually an error - logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind) - end - i = i + 1 - end - if i > nofchainlookups or not start then - break - elseif start then - start = getnext(start) - end - end - end + chaintrac(head,start,dataset,sequence,rlmode,ck,skipped) + end + if diskseen or sweepnode then + head, start, done = chaindisk(head,start,dataset,sequence,rlmode,ck,skipped) else - local replacements = ck[7] - if replacements then - head, start, done = reversesub(head,start,last,dataset,sequence,replacements,rlmode) - else - done = quit_on_no_replacement -- can be meant to be skipped / quite inconsistent in fonts - if trace_contexts then - logprocess("%s: skipping match",cref(dataset,sequence)) - end - end + head, start, done = chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped) end if done then break -- out of contexts (new, needs checking) @@ -2659,6 +2848,24 @@ chainprocs.gsub_reversecontextchain = chained_contextchain chainprocs.gpos_contextchain = chained_contextchain chainprocs.gpos_context = chained_contextchain +-- experiment (needs no handler in font-otc so not now): +-- +-- function otf.registerchainproc(name,f) +-- -- chainprocs[name] = f +-- chainprocs[name] = function(head,start,stop,dataset,sequence,currentlookup,rlmode) +-- local done = currentlookup.nofsteps > 0 +-- if not done then +-- reportzerosteps(dataset,sequence) +-- else +-- head, start, done = f(head,start,stop,dataset,sequence,currentlookup,rlmode) +-- if not head or not start then +-- reportbadsteps(dataset,sequence) +-- end +-- end +-- return head, start, done +-- end +-- end + local missing = setmetatableindex("table") local function logprocess(...) @@ -2694,79 +2901,96 @@ end) -- fonts.hashes.sequences = sequencelists -local autofeatures = fonts.analyzers.features -local featuretypes = otf.tables.featuretypes -local defaultscript = otf.features.checkeddefaultscript -local defaultlanguage = otf.features.checkeddefaultlanguage - -local function initialize(sequence,script,language,enabled,autoscript,autolanguage) - local features = sequence.features - if features then - local order = sequence.order - if order then - local featuretype = featuretypes[sequence.type or "unknown"] - for i=1,#order do - local kind = order[i] - local valid = enabled[kind] - if valid then - local scripts = features[kind] - local languages = scripts and ( - scripts[script] or - scripts[wildcard] or - (autoscript and defaultscript(featuretype,autoscript,scripts)) - ) - local enabled = languages and ( - languages[language] or - languages[wildcard] or - (autolanguage and defaultlanguage(featuretype,autolanguage,languages)) - ) - if enabled then - return { valid, autofeatures[kind] or false, sequence, kind } +do -- overcome local limit + + local autofeatures = fonts.analyzers.features + local featuretypes = otf.tables.featuretypes + local defaultscript = otf.features.checkeddefaultscript + local defaultlanguage = otf.features.checkeddefaultlanguage + + local wildcard = "*" + local default = "dflt" + + local function initialize(sequence,script,language,enabled,autoscript,autolanguage) + local features = sequence.features + if features then + local order = sequence.order + if order then + local featuretype = featuretypes[sequence.type or "unknown"] + for i=1,#order do + local kind = order[i] + local valid = enabled[kind] + if valid then + local scripts = features[kind] + local languages = scripts and ( + scripts[script] or + scripts[wildcard] or + (autoscript and defaultscript(featuretype,autoscript,scripts)) + ) + local enabled = languages and ( + languages[language] or + languages[wildcard] or + (autolanguage and defaultlanguage(featuretype,autolanguage,languages)) + ) + if enabled then + return { valid, autofeatures[kind] or false, sequence, kind } + end end end + else + -- can't happen end - else - -- can't happen end + return false end - return false -end -function otf.dataset(tfmdata,font) -- generic variant, overloaded in context - local shared = tfmdata.shared - local properties = tfmdata.properties - local language = properties.language or "dflt" - local script = properties.script or "dflt" - local enabled = shared.features - local autoscript = enabled and enabled.autoscript - local autolanguage = enabled and enabled.autolanguage - local res = resolved[font] - if not res then - res = { } - resolved[font] = res - end - local rs = res[script] - if not rs then - rs = { } - res[script] = rs - end - local rl = rs[language] - if not rl then - rl = { - -- indexed but we can also add specific data by key - } - rs[language] = rl - local sequences = tfmdata.resources.sequences - for s=1,#sequences do - local v = enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage) - if v then - rl[#rl+1] = v + function otf.dataset(tfmdata,font) -- generic variant, overloaded in context + local shared = tfmdata.shared + local properties = tfmdata.properties + local language = properties.language or "dflt" + local script = properties.script or "dflt" + local enabled = shared.features + local autoscript = enabled and enabled.autoscript + local autolanguage = enabled and enabled.autolanguage + local res = resolved[font] + if not res then + res = { } + resolved[font] = res + end + local rs = res[script] + if not rs then + rs = { } + res[script] = rs + end + local rl = rs[language] + if not rl then + rl = { + -- indexed but we can also add specific data by key + } + rs[language] = rl + local sequences = tfmdata.resources.sequences + if sequences then + for s=1,#sequences do + local v = enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage) + if v then + rl[#rl+1] = v + end + end end end + return rl end - return rl + end +-- Functions like kernrun, comprun etc evolved over time and in the end look rather +-- complex. It's a bit of a compromis between extensive copying and creating subruns. +-- The logic has been improved a lot by Kai and Ivo who use complex fonts which +-- really helped to identify border cases on the one hand and get insight in the diverse +-- ways fonts implement features (not always that consistent and efficient). At the same +-- time I tried to keep the code relatively efficient so that the overhead in runtime +-- stays acceptable. + local function report_disc(what,n) report_run("%s: %s > %s",what,n,languages.serializediscretionary(n)) end @@ -2800,10 +3024,10 @@ local function kernrun(disc,k_run,font,attr,...) end end -- - if prev and (pre or replace) and not ischar(prev,font) then + if prev and not ischar(prev,font) then -- and (pre or replace) prev = false end - if next and (post or replace) and not ischar(next,font) then + if next and not ischar(next,font) then -- and (post or replace) next = false end -- @@ -2820,6 +3044,7 @@ local function kernrun(disc,k_run,font,attr,...) done = true end setprev(pre,nest) +-- setprev(pre) setnext(prev,disc) end end @@ -2833,7 +3058,7 @@ local function kernrun(disc,k_run,font,attr,...) if k_run(posttail,"postinjections",next,font,attr,...) then done = true end - setnext(posttail,nil) + setnext(posttail) setprev(next,disc) end end @@ -2849,6 +3074,7 @@ local function kernrun(disc,k_run,font,attr,...) done = true end setprev(replace,nest) + -- setprev(replace) setnext(prev,disc) end if next then @@ -2856,7 +3082,7 @@ local function kernrun(disc,k_run,font,attr,...) if k_run(replacetail,"replaceinjections",next,font,attr,...) then done = true end - setnext(replacetail,nil) + setnext(replacetail) setprev(next,disc) end elseif prev and next then @@ -2864,13 +3090,15 @@ local function kernrun(disc,k_run,font,attr,...) if k_run(prevmarks,"emptyinjections",next,font,attr,...) then done = true end - setlink(prev,disc) - setlink(disc,next) + setlink(prev,disc,next) end return nextstart, done end -local function comprun(disc,c_run,...) +-- fonts like ebgaramond do ligatures this way (less efficient than e.g. dejavu which +-- will do the testrun variant) + +local function comprun(disc,c_run,...) -- vararg faster than the whole list if trace_compruns then report_disc("comp",disc) end @@ -2880,7 +3108,7 @@ local function comprun(disc,c_run,...) -- if pre then sweepnode = disc - sweeptype = "pre" -- in alternative code preinjections is uc_c_sed (also used then for proeprties, saves a variable) + sweeptype = "pre" -- in alternative code preinjections is uc_c_sed (also used then for properties, saves a variable) local new, done = c_run(pre,...) if done then pre = new @@ -2917,6 +3145,83 @@ local function comprun(disc,c_run,...) return getnext(disc), renewed end +-- local function testrun(disc,t_run,c_run,...) +-- if trace_testruns then +-- report_disc("test",disc) +-- end +-- local prev, next = getboth(disc) +-- if not next then +-- -- weird discretionary +-- return +-- end +-- local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true) +-- local done = false +-- if replace and prev then +-- -- this is a bit strange as we only do replace here and not post +-- -- anyway, we only look ahead ... the idea is that we discard a +-- -- disc when there is a ligature crossing the replace boundary +-- setlink(replacetail,next) +-- local ok, overflow = t_run(replace,next,...) +-- if ok and overflow then +-- -- so, we can have crossed the boundary +-- setfield(disc,"replace") +-- setlink(prev,replace) +-- -- setlink(replacetail,next) +-- setboth(disc) +-- flush_node_list(disc) +-- return replace, true -- restart .. tricky ! +-- else +-- -- we stay inside the disc +-- setnext(replacetail) +-- setprev(next,disc) +-- end +-- -- pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true) +-- end +-- -- +-- -- like comprun +-- -- +-- local renewed = false +-- -- +-- if pre then +-- sweepnode = disc +-- sweeptype = "pre" +-- local new, ok = c_run(pre,...) +-- if ok then +-- pre = new +-- renewed = true +-- end +-- end +-- -- +-- if post then +-- sweepnode = disc +-- sweeptype = "post" +-- local new, ok = c_run(post,...) +-- if ok then +-- post = new +-- renewed = true +-- end +-- end +-- -- +-- if replace then +-- sweepnode = disc +-- sweeptype = "replace" +-- local new, ok = c_run(replace,...) +-- if ok then +-- replace = new +-- renewed = true +-- end +-- end +-- -- +-- sweepnode = nil +-- sweeptype = nil +-- if renewed then +-- setdisc(disc,pre,post,replace) +-- return next, true +-- else +-- return next, done +-- end +-- end + local function testrun(disc,t_run,c_run,...) if trace_testruns then report_disc("test",disc) @@ -2928,23 +3233,59 @@ local function testrun(disc,t_run,c_run,...) end local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true) local done = false - if replace and prev then - -- this is a bit strange as we only do replace here and not post - -- anyway, we only look ahead ... the idea is that we discard a - -- disc when there is a ligature crossing the replace boundary - setlink(replacetail,next) - local ok, overflow = t_run(replace,next,...) - if ok and overflow then - -- so, we can have crossed the boundary - setfield(disc,"replace",nil) - setlink(prev,replace) - -- setlink(replacetail,next) - setboth(disc) - flush_node_list(disc) - return replace, true -- restart .. tricky ! + if (post or replace) and prev then + if post then + setlink(posttail,next) + else + post = next + end + if replace then + setlink(replacetail,next) + else + replace = next + end + local d_post = t_run(post,next,...) + local d_replace = t_run(replace,next,...) + if (d_post and d_post > 0) or (d_replace and d_replace > 0) then + local d = d_replace or d_post + if d_post and d < d_post then + d = d_post + end + local head, tail = getnext(disc), disc + for i=1,d do + tail = getnext(tail) + if getid(tail) == disc_code then + head, tail = flattendisk(head,tail) + end + end + local next = getnext(tail) + setnext(tail) + setprev(head) + local new = copy_node_list(head) + if posttail then + setlink(posttail,head) + else + post = head + end + if replacetail then + setlink(replacetail,new) + else + replace = new + end + setlink(disc,next) else -- we stay inside the disc + if posttail then + setnext(posttail) + else + post = nil + end setnext(replacetail) + if replacetail then + setnext(replacetail) + else + replace = nil + end setprev(next,disc) end -- pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true) @@ -2994,41 +3335,6 @@ local function testrun(disc,t_run,c_run,...) end end --- A discrun happens when we have a zwnj. We're gpossing so it is unlikely that --- there has been a match changing the character. Now, as we check again here --- the question is: why do we do this ... needs checking as drun seems useless --- ... maybe that code can go away - --- local function discrun(disc,drun,krun) --- local prev, next = getboth(disc) --- if trace_discruns then --- report_disc("disc",disc) --- end --- if next and prev then --- setnext(prev,next) --- -- setprev(next,prev) --- drun(prev) --- setnext(prev,disc) --- -- setprev(next,disc) --- end --- -- --- if krun then -- currently always false --- local pre = getfield(disc,"pre") --- if not pre then --- -- go on --- elseif prev then --- local nest = getprev(pre) --- setlink(prev,pre) --- krun(prev,"preinjections") --- setprev(pre,nest) --- setnext(prev,disc) --- else --- krun(pre,"preinjections") --- end --- end --- return next --- end - -- We can make some assumptions with respect to discretionaries. First of all it is very -- unlikely that some of the analysis related attributes applies. Then we can also assume -- that the ConTeXt specific dynamic attribute is different, although we do use explicit @@ -3048,7 +3354,12 @@ end -- -- local a = getattr(start,0) -- -- if not a or (a == attr) then -- --- and even that one is probably not needed. +-- and even that one is probably not needed. However, we can handle interesting +-- cases now: +-- +-- 1{2{\oldstyle\discretionary{3}{4}{5}}6}7\par +-- 1{2\discretionary{3{\oldstyle3}}{{\oldstyle4}4}{5{\oldstyle5}5}6}7\par + local nesting = 0 @@ -3064,7 +3375,10 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm while start do local char = ischar(start,font) if char then - local a = attr and getattr(start,0) + local a -- happens often so no assignment is faster + if attr then + a = getattr(start,0) + end if not a or (a == attr) then local lookupmatch = lookupcache[char] if lookupmatch then @@ -3078,6 +3392,7 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm start = getnext(start) end else + -- go on can be a mixed one start = getnext(start) end elseif char == false then @@ -3093,63 +3408,130 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm return head, done end +-- local function t_run_single(start,stop,font,attr,lookupcache) +-- while start ~= stop do +-- local char = ischar(start,font) +-- if char then +-- local a -- happens often so no assignment is faster +-- if attr then +-- a = getattr(start,0) +-- end +-- local startnext = getnext(start) +-- if not a or (a == attr) then +-- local lookupmatch = lookupcache[char] +-- if lookupmatch then -- hm, hyphens can match (tlig) so we need to really check +-- -- if we need more than ligatures we can outline the code and use functions +-- local s = startnext +-- local l = nil +-- local d = 0 +-- while s do +-- if s == stop then +-- d = 1 +-- elseif d > 0 then +-- d = d + 1 +-- end +-- local lg = lookupmatch[getchar(s)] +-- if lg then +-- l = lg +-- s = getnext(s) +-- else +-- break +-- end +-- end +-- if l and l.ligature then +-- return true, d > 1 +-- end +-- end +-- else +-- -- go on can be a mixed one +-- end +-- start = starttnext +-- else +-- break +-- end +-- end +-- end + local function t_run_single(start,stop,font,attr,lookupcache) + local lastd = nil while start ~= stop do local char = ischar(start,font) if char then - local a = attr and getattr(start,0) + local a -- happens often so no assignment is faster + if attr then + a = getattr(start,0) + end + local startnext = getnext(start) if not a or (a == attr) then local lookupmatch = lookupcache[char] if lookupmatch then -- hm, hyphens can match (tlig) so we need to really check -- if we need more than ligatures we can outline the code and use functions - local s = getnext(start) + local s = startnext + local ss = nil + local sstop = s == stop + if not s then + s = ss + ss = nil + end + while getid(s) == disc_code do + ss = getnext(s) + s = getfield(s,"replace") + if not s then + s = ss + ss = nil + end + end local l = nil local d = 0 while s do - if s == stop then - d = 1 - elseif d > 0 then - d = d + 1 - end local lg = lookupmatch[getchar(s)] if lg then + if sstop then + d = 1 + elseif d > 0 then + d = d + 1 + end l = lg s = getnext(s) + sstop = s == stop + if not s then + s = ss + ss = nil + end + while getid(s) == disc_code do + ss = getnext(s) + s = getfield(s,"replace") + if not s then + s = ss + ss = nil + end + end else break end end if l and l.ligature then - return true, d > 1 + lastd = d end end + else + -- go on can be a mixed one end - start = getnext(start) + if lastd then + return lastd + end + start = startnext else break end end end --- local function d_run_single(prev,font,attr,lookupcache,step,dataset,sequence,rlmode,handler) --- local a = attr and getattr(prev,0) --- if not a or (a == attr) then --- local char = ischar(prev) -- can be disc --- if char then --- local lookupmatch = lookupcache[char] --- if lookupmatch then --- local h, d, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,step,1) --- if ok then --- done = true --- success = true --- end --- end --- end --- end --- end - local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,handler) - local a = attr and getattr(sub,0) + local a -- happens often so no assignment is faster + if attr then + a = getattr(sub,0) + end if not a or (a == attr) then for n in traverse_nodes(sub) do -- only gpos if n == last then @@ -3181,7 +3563,10 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm while start do local char = ischar(start,font) if char then - local a = attr and getattr(start,0) + local a -- happens often so no assignment is faster + if attr then + a = getattr(start,0) + end if not a or (a == attr) then for i=1,nofsteps do local step = steps[i] @@ -3208,6 +3593,7 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm start = getnext(start) end else + -- go on can be a mixed one start = getnext(start) end elseif char == false then @@ -3224,11 +3610,68 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm return head, done end +-- local function t_run_multiple(start,stop,font,attr,steps,nofsteps) +-- while start ~= stop do +-- local char = ischar(start,font) +-- if char then +-- local a -- happens often so no assignment is faster +-- if attr then +-- a = getattr(start,0) +-- end +-- local startnext = getnext(start) +-- if not a or (a == attr) then +-- for i=1,nofsteps do +-- local step = steps[i] +-- local lookupcache = step.coverage +-- if lookupcache then +-- local lookupmatch = lookupcache[char] +-- if lookupmatch then +-- -- if we need more than ligatures we can outline the code and use functions +-- local s = startnext +-- local l = nil +-- local d = 0 +-- while s do +-- if s == stop then +-- d = 1 +-- elseif d > 0 then +-- d = d + 1 +-- end +-- local lg = lookupmatch[getchar(s)] +-- if lg then +-- l = lg +-- s = getnext(s) +-- else +-- break +-- end +-- end +-- if l and l.ligature then +-- return true, d > 1 +-- end +-- end +-- else +-- report_missing_coverage(dataset,sequence) +-- end +-- end +-- else +-- -- go on can be a mixed one +-- end +-- start = startnext +-- else +-- break +-- end +-- end +-- end + local function t_run_multiple(start,stop,font,attr,steps,nofsteps) + local lastd = nil while start ~= stop do local char = ischar(start,font) if char then - local a = attr and getattr(start,0) + local a -- happens often so no assignment is faster + if attr then + a = getattr(start,0) + end + local startnext = getnext(start) if not a or (a == attr) then for i=1,nofsteps do local step = steps[i] @@ -3237,67 +3680,76 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) local lookupmatch = lookupcache[char] if lookupmatch then -- if we need more than ligatures we can outline the code and use functions - local s = getnext(start) + local s = startnext + local ss = nil + local sstop = s == stop + if not s then + s = ss + ss = nil + end + while getid(s) == disc_code do + ss = getnext(s) + s = getfield(s,"replace") + if not s then + s = ss + ss = nil + end + end local l = nil local d = 0 while s do - if s == stop then - d = 1 - elseif d > 0 then - d = d + 1 - end local lg = lookupmatch[getchar(s)] if lg then + if sstop then + d = 1 + elseif d > 0 then + d = d + 1 + end l = lg s = getnext(s) + sstop = s == stop + if not s then + s = ss + ss = nil + end + while getid(s) == disc_code do + ss = getnext(s) + s = getfield(s,"replace") + if not s then + s = ss + ss = nil + end + end else break end end if l and l.ligature then - return true, d > 1 + lastd = d end end else report_missing_coverage(dataset,sequence) end end + else + -- go on can be a mixed one end - start = getnext(start) + if lastd then + return lastd + end + start = startnext else break end end end --- local function d_run_multiple(prev,attr,steps,nofsteps,dataset,sequence,rlmode,handler) --- local a = attr and getattr(prev,0) --- if not a or (a == attr) then --- local char = ischar(prev) -- can be disc --- if char then --- for i=1,nofsteps do --- local step = steps[i] --- local lookupcache = step.coverage --- if lookupcache then --- local lookupmatch = lookupcache[char] --- if lookupmatch then --- -- we could move all code inline but that makes things even more unreadable --- local h, d, ok = handler(head,prev,dataset,sequence,lookupmatch,rlmode,step,i) --- if ok then --- done = true --- break --- end --- end --- else --- report_missing_coverage(dataset,sequence) --- end --- end --- end --- end --- end - local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler) - local a = attr and getattr(sub,0) + local a -- happens often so no assignment is faster + if attr then + a = getattr(sub,0) + end if not a or (a == attr) then for n in traverse_nodes(sub) do -- only gpos if n == last then @@ -3325,11 +3777,11 @@ local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,datase end end --- to be checkedL nowadays we probably can assume properly matched directions +-- to be checked, nowadays we probably can assume properly matched directions -- so maybe we no longer need a stack local function txtdirstate(start,stack,top,rlparmode) - local dir = getfield(start,"dir") + local dir = getdir(start) local new = 1 if dir == "+TRT" then top = top + 1 @@ -3353,7 +3805,7 @@ local function txtdirstate(start,stack,top,rlparmode) end local function pardirstate(start) - local dir = getfield(start,"dir") + local dir = getdir(start) local new = 0 if dir == "TLT" then new = 1 @@ -3366,7 +3818,19 @@ local function pardirstate(start) return getnext(start), new, new end -local function featuresprocessor(head,font,attr) +otf.helpers = otf.helpers or { } +otf.helpers.txtdirstate = txtdirstate +otf.helpers.pardirstate = pardirstate + +-- This is the main loop. We run over the node list dealing with a specific font. The +-- attribute is a context specific thing. We could work on sub start-stop ranges instead +-- but I wonder if there is that much speed gain (experiments showed that it made not +-- much sense) and we need to keep track of directions anyway. Also at some point I +-- want to play with font interactions and then we do need the full sweeps. Apart from +-- optimizations the principles of processing the features hasn't changed much since +-- the beginning. + +local function featuresprocessor(head,font,attr,direction) local sequences = sequencelists[font] -- temp hack @@ -3377,14 +3841,16 @@ local function featuresprocessor(head,font,attr) nesting = nesting + 1 if nesting == 1 then - - currentfont = font - tfmdata = fontdata[font] - descriptions = tfmdata.descriptions - characters = tfmdata.characters - marks = tfmdata.resources.marks - factor = tfmdata.parameters.factor - threshold = tfmdata.parameters.spacing.width or 65536*10 + currentfont = font + tfmdata = fontdata[font] + descriptions = tfmdata.descriptions -- only needed in gref so we could pass node there instead + characters = tfmdata.characters -- but this branch is not entered that often anyway + local resources = tfmdata.resources + marks = resources.marks + classes = resources.classes + threshold, + factor = getthreshold(font) + checkmarks = tfmdata.properties.checkmarks elseif currentfont ~= font then @@ -3394,9 +3860,13 @@ local function featuresprocessor(head,font,attr) end - if attr == 0 then - attr = false -- some 10% faster when no dynamics but hardly measureable on real runs - end + -- some 10% faster when no dynamics but hardly measureable on real runs .. but: it only + -- works when we have no other dynamics as otherwise the zero run will be applied to the + -- whole stream for which we then need to pass another variable which we won't + + -- if attr == 0 then + -- attr = false + -- end head = tonut(head) @@ -3404,24 +3874,17 @@ local function featuresprocessor(head,font,attr) checkstep(head) end - local rlmode = 0 + local initialrl = direction == "TRT" and -1 or 0 local done = false local datasets = otf.dataset(tfmdata,font,attr) - local dirstack = { } -- could move outside function but we can have local runs - sweephead = { } - -- We could work on sub start-stop ranges instead but I wonder if there is that - -- much speed gain (experiments showed that it made not much sense) and we need - -- to keep track of directions anyway. Also at some point I want to play with - -- font interactions and then we do need the full sweeps. + -- Keeping track of the headnode is needed for devanagari. (I generalized it a bit + -- so that multiple cases are also covered.) We could prepend a temp node. - -- Keeping track of the headnode is needed for devanagari (I generalized it a bit - -- so that multiple cases are also covered.) - - -- We don't goto the next node of a disc node is created so that we can then treat + -- We don't goto the next node when a disc node is created so that we can then treat -- the pre, post and replace. It's a bit of a hack but works out ok for most cases. for s=1,#datasets do @@ -3429,9 +3892,8 @@ local function featuresprocessor(head,font,attr) ----- featurevalue = dataset[1] -- todo: pass to function instead of using a global local attribute = dataset[2] local sequence = dataset[3] -- sequences[s] -- also dataset[5] - local rlparmode = 0 + local rlparmode = initialrl local topstack = 0 - local success = false local typ = sequence.type local gpossing = typ == "gpos_single" or typ == "gpos_pair" -- store in dataset local handler = handlers[typ] @@ -3439,23 +3901,24 @@ local function featuresprocessor(head,font,attr) local nofsteps = sequence.nofsteps if not steps then -- this permits injection, watch the different arguments - local h, d, ok = handler(head,start,dataset,sequence,nil,nil,nil,0,font,attr) + local h, d, ok = handler(head,head,dataset,sequence,nil,nil,nil,0,font,attr) if ok then - success = true + done = true if h then head = h end - if d then - start = d - end end elseif typ == "gsub_reversecontextchain" then -- this is a limited case, no special treatments like 'init' etc - local start = find_node_tail(head) + local start = find_node_tail(head) + local rlmode = 0 -- how important is this .. do we need to check for dir? while start do local char = ischar(start,font) if char then - local a = attr and getattr(start,0) + local a -- happens often so no assignment is faster + if attr then + a = getattr(start,0) + end if not a or (a == attr) then for i=1,nofsteps do local step = steps[i] @@ -3467,7 +3930,7 @@ local function featuresprocessor(head,font,attr) local ok head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i) if ok then - success = true + done = true break end end @@ -3486,10 +3949,9 @@ local function featuresprocessor(head,font,attr) end end else - local start = head -- local ? - rlmode = 0 -- to be checked ? + local start = head + local rlmode = initialrl if nofsteps == 1 then -- happens often - local step = steps[1] local lookupcache = step.coverage if not lookupcache then @@ -3498,11 +3960,19 @@ local function featuresprocessor(head,font,attr) while start do local char, id = ischar(start,font) if char then - local a = attr and getattr(start,0) - if a then - a = (a == attr) and (not attribute or getprop(start,a_state) == attribute) - else - a = not attribute or getprop(start,a_state) == attribute + -- local a = attr and getattr(start,0) + -- if a then + -- a = (a == attr) and (not attribute or getprop(start,a_state) == attribute) + -- else + -- a = not attribute or getprop(start,a_state) == attribute + -- end + local a -- happens often so no assignment is faster + if attr then + if getattr(start,0) == attr and (not attribute or getprop(start,a_state) == attribute) then + a = true + end + elseif not attribute or getprop(start,a_state) == attribute then + a = true end if a then local lookupmatch = lookupcache[char] @@ -3510,12 +3980,8 @@ local function featuresprocessor(head,font,attr) local ok head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,step,1) if ok then - success = true - -- elseif gpossing and zwnjruns and char == zwnj then - -- discrun(start,d_run,font,attr,lookupcache) + done = true end - -- elseif gpossing and zwnjruns and char == zwnj then - -- discrun(start,d_run,font,attr,lookupcache) end if start then start = getnext(start) @@ -3526,6 +3992,9 @@ local function featuresprocessor(head,font,attr) elseif char == false then -- whatever glyph start = getnext(start) + elseif id == glue_code then + -- happens often + start = getnext(start) elseif id == disc_code then local ok if gpossing then @@ -3536,7 +4005,7 @@ local function featuresprocessor(head,font,attr) start, ok = comprun(start,c_run_single, font,attr,lookupcache,step,dataset,sequence,rlmode,handler) end if ok then - success = true + done = true end elseif id == math_code then start = getnext(end_of_math(start)) @@ -3551,15 +4020,22 @@ local function featuresprocessor(head,font,attr) end else - while start do local char, id = ischar(start,font) if char then - local a = attr and getattr(start,0) - if a then - a = (a == attr) and (not attribute or getprop(start,a_state) == attribute) - else - a = not attribute or getprop(start,a_state) == attribute + -- local a = attr and getattr(start,0) + -- if a then + -- a = (a == attr) and (not attribute or getprop(start,a_state) == attribute) + -- else + -- a = not attribute or getprop(start,a_state) == attribute + -- end + local a -- happens often so no assignment is faster + if attr then + if getattr(start,0) == attr and (not attribute or getprop(start,a_state) == attribute) then + a = true + end + elseif not attribute or getprop(start,a_state) == attribute then + a = true end if a then for i=1,nofsteps do @@ -3572,16 +4048,12 @@ local function featuresprocessor(head,font,attr) local ok head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i) if ok then - success = true + done = true break elseif not start then -- don't ask why ... shouldn't happen break - -- elseif gpossing and zwnjruns and char == zwnj then - -- discrun(start,d_run,font,attr,steps,nofsteps) end - -- elseif gpossing and zwnjruns and char == zwnj then - -- discrun(start,d_run,font,attr,steps,nofsteps) end else report_missing_coverage(dataset,sequence) @@ -3594,6 +4066,10 @@ local function featuresprocessor(head,font,attr) start = getnext(start) end elseif char == false then + -- whatever glyph + start = getnext(start) + elseif id == glue_code then + -- happens often start = getnext(start) elseif id == disc_code then local ok @@ -3605,7 +4081,7 @@ local function featuresprocessor(head,font,attr) start, ok = comprun(start,c_run_multiple, font,attr,steps,nofsteps,dataset,sequence,rlmode,handler) end if ok then - success = true + done = true end elseif id == math_code then start = getnext(end_of_math(start)) @@ -3620,9 +4096,6 @@ local function featuresprocessor(head,font,attr) end end - if success then - done = true - end if trace_steps then -- ? registerstep(head) end @@ -3637,6 +4110,34 @@ end -- so far +local plugins = { } +otf.plugins = plugins + +function otf.registerplugin(name,f) + if type(name) == "string" and type(f) == "function" then + plugins[name] = { name, f } + end +end + +local function plugininitializer(tfmdata,value) + if type(value) == "string" then + tfmdata.shared.plugin = plugins[value] + end +end + +local function pluginprocessor(head,font) + local s = fontdata[font].shared + local p = s and s.plugin + if p then + if trace_plugins then + report_process("applying plugin %a",p[1]) + end + return p[2](head,font) + else + return head, false + end +end + local function featuresinitializer(tfmdata,value) -- nothing done here any more end @@ -3648,9 +4149,11 @@ registerotffeature { initializers = { position = 1, node = featuresinitializer, + plug = plugininitializer, }, processors = { node = featuresprocessor, + plug = pluginprocessor, } } @@ -3665,12 +4168,29 @@ otf.handlers = handlers -- used in devanagari local setspacekerns = nodes.injections.setspacekerns if not setspacekerns then os.exit() end -function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) - -- if not setspacekerns then - -- setspacekerns = nodes.injections.setspacekerns - -- end - setspacekerns(font,sequence) - return head, start, true +if fontfeatures then + + function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) + local features = fontfeatures[font] + local enabled = features and features.spacekern and features.kern + if enabled then + setspacekerns(font,sequence) + end + return head, start, enabled + end + +else -- generic (no hashes) + + function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) + local shared = fontdata[font].shared + local features = shared and shared.features + local enabled = features and features.spacekern and features.kern + if enabled then + setspacekerns(font,sequence) + end + return head, start, enabled + end + end local function hasspacekerns(data) @@ -3705,11 +4225,13 @@ otf.readers.registerextender { end } +-- we merge the lookups but we still honor the language / script + local function spaceinitializer(tfmdata,value) -- attr local resources = tfmdata.resources local spacekerns = resources and resources.spacekerns - if spacekerns == nil then - local properties = tfmdata.properties + local properties = tfmdata.properties + if value and spacekerns == nil then if properties and properties.hasspacekerns then local sequences = resources.sequences local left = { } @@ -3722,28 +4244,57 @@ local function spaceinitializer(tfmdata,value) -- attr if steps then local kern = sequence.features.kern if kern then - feat = feat or kern -- or maybe merge + if feat then + for script, languages in next, kern do + local f = feat[script] + if f then + for l in next, languages do + f[l] = true + end + else + feat[script] = languages + end + end + else + feat = kern + end for i=1,#steps do - local step = steps[i] + local step = steps[i] local coverage = step.coverage - if coverage then - local kerns = coverage[32] + local rules = step.rules + local format = step.format + if rules then + -- not now: analyze (simple) rules + elseif coverage then + -- what to do if we have no [1] but only [2] + local single = format == gpos_single + local kerns = coverage[32] if kerns then for k, v in next, kerns do - if type(v) == "table" then - right[k] = v[3] -- needs checking - else + if type(v) ~= "table" then right[k] = v + elseif single then + right[k] = v[3] + else + local one = v[1] + if one then + right[k] = one[3] + end end end end for k, v in next, coverage do local kern = v[32] if kern then - if type(kern) == "table" then - left[k] = kern[3] -- needs checking - else + if type(kern) ~= "table" then left[k] = kern + elseif single then + left[k] = v[3] + else + local one = v[1] + if one then + left[k] = one[3] + end end end end @@ -3794,3 +4345,17 @@ registerotffeature { node = spaceinitializer, }, } + +local function markinitializer(tfmdata,value) + local properties = tfmdata.properties + properties.checkmarks = value +end + +registerotffeature { + name = "checkmarks", + description = "check mark widths", + default = true, + initializers = { + node = markinitializer, + }, +} diff --git a/tex/context/base/mkiv/font-ott.lua b/tex/context/base/mkiv/font-ott.lua index f8d74a317..cba3758dc 100644 --- a/tex/context/base/mkiv/font-ott.lua +++ b/tex/context/base/mkiv/font-ott.lua @@ -18,7 +18,6 @@ local allocate = utilities.storage.allocate local fonts = fonts local otf = fonts.handlers.otf local otffeatures = otf.features -local registerotffeature = otffeatures.register local tables = otf.tables or { } otf.tables = tables @@ -1083,6 +1082,8 @@ table.setmetatableindex(usedfeatures, function(t,k) if k then local v = { } t[k] storage.register("fonts/otf/usedfeatures", usedfeatures, "fonts.handlers.otf.statistics.usedfeatures" ) +local normalizedaxis = otf.readers.helpers.normalizedaxis or function(s) return s end + function otffeatures.normalize(features) if features then local h = { } @@ -1094,6 +1095,11 @@ function otffeatures.normalize(features) elseif k == "script" then local v = gsub(lower(value),"[^a-z0-9]","") h.script = rawget(verbosescripts,v) or (scripts[v] and v) or "dflt" -- auto adds + elseif k == "axis" then + h[k] = normalizedaxis(value) +if not callbacks.supported.glyph_stream_provider then + h.variableshapes = true -- for the moment +end else local uk = usedfeatures[key] local uv = uk[value] diff --git a/tex/context/base/mkiv/font-oup.lua b/tex/context/base/mkiv/font-oup.lua index bd47e71dd..75ae08526 100644 --- a/tex/context/base/mkiv/font-oup.lua +++ b/tex/context/base/mkiv/font-oup.lua @@ -29,7 +29,12 @@ local f_index = formatters["I%05X"] local f_character_y = formatters["%C"] local f_character_n = formatters["[ %C ]"] -local doduplicates = true -- can become an option (pseudo feature) +local check_duplicates = true -- can become an option (pseudo feature) / aways needed anyway +local check_soft_hyphen = false -- can become an option (pseudo feature) / needed for tagging + +directives.register("otf.checksofthyphen",function(v) + check_soft_hyphen = v +end) local function replaced(list,index,replacement) if type(list) == "number" then @@ -106,7 +111,7 @@ local function unifyresources(fontdata,indices) -- local done = { } -- we need to deal with shared ! -- - local duplicates = doduplicates and resources.duplicates + local duplicates = check_duplicates and resources.duplicates if duplicates and not next(duplicates) then duplicates = false end @@ -359,12 +364,34 @@ local function unifyresources(fontdata,indices) end local function copyduplicates(fontdata) - if doduplicates then + if check_duplicates then local descriptions = fontdata.descriptions local resources = fontdata.resources local duplicates = resources.duplicates + if check_soft_hyphen then + -- ebgaramond has a zero width empty soft hyphen + local ds = descriptions[0xAD] + if not ds or ds.width == 0 then + if ds then + descriptions[0xAD] = nil + report("patching soft hyphen") + else + report("adding soft hyphen") + end + if not duplicates then + duplicates = { } + resources.duplicates = duplicates + end + local dh = duplicates[0x2D] + if dh then + dh[#dh+1] = { [0xAD] = true } + else + duplicates[0x2D] = { [0xAD] = true } + end + end + end if duplicates then - for u, d in next, duplicates do + for u, d in next, duplicates do local du = descriptions[u] if du then local t = { f_character_y(u), "@", f_index(du.index), "->" } @@ -707,6 +734,19 @@ local function unifyglyphs(fontdata,usenames) end end -- + local colorpalettes = resources.colorpalettes + if colorpalettes then + for index=1,#glyphs do + local colors = glyphs[index].colors + if colors then + for i=1,#colors do + local c = colors[i] + c.slot = indices[c.slot] + end + end + end + end + -- fontdata.private = private fontdata.glyphs = nil fontdata.names = names @@ -835,6 +875,8 @@ function readers.getcomponents(fontdata) -- handy for resolving ligatures when n end end +readers.unifymissing = unifymissing + function readers.rehash(fontdata,hashmethod) -- TODO: combine loops in one if not (fontdata and fontdata.glyphs) then return @@ -849,7 +891,7 @@ function readers.rehash(fontdata,hashmethod) -- TODO: combine loops in one unifymissing(fontdata) -- stripredundant(fontdata) else - fontdata.hashmethod = "unicode" + fontdata.hashmethod = "unicodes" local indices = unifyglyphs(fontdata) unifyresources(fontdata,indices) copyduplicates(fontdata) @@ -866,10 +908,10 @@ function readers.checkhash(fontdata) elseif hashmethod == "names" and fontdata.names then unifyresources(fontdata,fontdata.names) copyduplicates(fontdata) - fontdata.hashmethod = "unicode" + fontdata.hashmethod = "unicodes" fontdata.names = nil -- no need for it else - readers.rehash(fontdata,"unicode") + readers.rehash(fontdata,"unicodes") end end @@ -1159,6 +1201,8 @@ function readers.pack(data) local sequences = resources.sequences local sublookups = resources.sublookups local features = resources.features + local palettes = resources.colorpalettes + local variable = resources.variabledata local chardata = characters and characters.data local descriptions = data.descriptions or data.glyphs @@ -1191,6 +1235,14 @@ function readers.pack(data) end end end + -- if palettes then + -- local color = description.color + -- if color then + -- for i=1,#color do + -- color[i] = pack_normal(color[i]) + -- end + -- end + -- end end local function packthem(sequences) @@ -1280,7 +1332,8 @@ function readers.pack(data) local r = rule.before if r then for i=1,#r do r[i] = pack_boolean(r[i]) end end local r = rule.after if r then for i=1,#r do r[i] = pack_boolean(r[i]) end end local r = rule.current if r then for i=1,#r do r[i] = pack_boolean(r[i]) end end - local r = rule.replacements if r then rule.replacements = pack_flat (r) end -- can have holes + -- local r = rule.lookups if r then rule.lookups = pack_mixed (r) end + local r = rule.replacements if r then rule.replacements = pack_flat (r) end end end end @@ -1315,6 +1368,63 @@ function readers.pack(data) end end + if palettes then + for i=1,#palettes do + local p = palettes[i] + for j=1,#p do + p[j] = pack_indexed(p[j]) + end + end + + end + + if variable then + + -- todo: segments + + local instances = variable.instances + if instances then + for i=1,#instances do + local v = instances[i].values + for j=1,#v do + v[j] = pack_normal(v[j]) + end + end + end + + local function packdeltas(main) + if main then + local deltas = main.deltas + if deltas then + for i=1,#deltas do + local di = deltas[i] + local d = di.deltas + local r = di.regions + for j=1,#d do + d[j] = pack_indexed(d[j]) + end + di.regions = pack_indexed(di.regions) + end + end + local regions = main.regions + if regions then + for i=1,#regions do + local r = regions[i] + for j=1,#r do + r[j] = pack_normal(r[j]) + end + end + end + end + end + + packdeltas(variable.global) + packdeltas(variable.horizontal) + packdeltas(variable.vertical) + packdeltas(variable.metrics) + + end + if not success(1,pass) then return end @@ -1391,10 +1501,23 @@ function readers.pack(data) if sublookups then packthem(sublookups) end - -- features - if not success(2,pass) then - -- return + if variable then + local function unpackdeltas(main) + if main then + local regions = main.regions + if regions then + main.regions = pack_normal(regions) + end + end + end + unpackdeltas(variable.global) + unpackdeltas(variable.horizontal) + unpackdeltas(variable.vertical) + unpackdeltas(variable.metrics) end + -- if not success(2,pass) then + -- -- return + -- end end for pass=1,2 do @@ -1462,6 +1585,8 @@ function readers.unpack(data) local sequences = resources.sequences local sublookups = resources.sublookups local features = resources.features + local palettes = resources.colorpalettes + local variable = resources.variabledata local unpacked = { } setmetatable(unpacked,unpacked_mt) for unicode, description in next, descriptions do @@ -1488,6 +1613,17 @@ function readers.unpack(data) end end end + -- if palettes then + -- local color = description.color + -- if color then + -- for i=1,#color do + -- local tv = tables[color[i]] + -- if tv then + -- color[i] = tv + -- end + -- end + -- end + -- end end local function unpackthem(sequences) @@ -1659,9 +1795,16 @@ function readers.unpack(data) end end end + -- local lookups = rule.lookups + -- if lookups then + -- local tv = tables[lookups] + -- if tv then + -- rule.lookups = tv + -- end + -- end local replacements = rule.replacements if replacements then - local tv = tables[replace] + local tv = tables[replacements] if tv then rule.replacements = tv end @@ -1717,6 +1860,82 @@ function readers.unpack(data) end end + if palettes then + for i=1,#palettes do + local p = palettes[i] + for j=1,#p do + local tv = tables[p[j]] + if tv then + p[j] = tv + end + end + end + end + + if variable then + + -- todo: segments + + local instances = variable.instances + if instances then + for i=1,#instances do + local v = instances[i].values + for j=1,#v do + local tv = tables[v[j]] + if tv then + v[j] = tv + end + end + end + end + + local function unpackdeltas(main) + if main then + local deltas = main.deltas + if deltas then + for i=1,#deltas do + local di = deltas[i] + local d = di.deltas + local r = di.regions + for j=1,#d do + local tv = tables[d[j]] + if tv then + d[j] = tv + end + end + local tv = di.regions + if tv then + di.regions = tv + end + end + end + local regions = main.regions + if regions then + local tv = tables[regions] + if tv then + main.regions = tv + regions = tv + end + for i=1,#regions do + local r = regions[i] + for j=1,#r do + local tv = tables[r[j]] + if tv then + r[j] = tv + end + end + end + end + end + end + + unpackdeltas(variable.global) + unpackdeltas(variable.horizontal) + unpackdeltas(variable.vertical) + unpackdeltas(variable.metrics) + + end + data.tables = nil end end @@ -2115,15 +2334,20 @@ function readers.expand(data) local lookups = rule.lookups or false local subtype = nil if lookups then - for k, v in next, lookups do - local lookup = sublookups[v] - if lookup then - lookups[k] = lookup - if not subtype then - subtype = lookup.type + for i=1,#lookups do + local lookups = lookups[i] + if lookups then + for k, v in next, lookups do + local lookup = sublookups[v] + if lookup then + lookups[k] = lookup + if not subtype then + subtype = lookup.type + end + else + -- already expanded + end end - else - -- already expanded end end end diff --git a/tex/context/base/mkiv/font-pre.mkiv b/tex/context/base/mkiv/font-pre.mkiv index 3b3a76d9c..9336fa352 100644 --- a/tex/context/base/mkiv/font-pre.mkiv +++ b/tex/context/base/mkiv/font-pre.mkiv @@ -40,6 +40,10 @@ trep=yes] % texligatures=yes,texquotes=yes \definefontfeature + [original] % a clone of default so we can revert + [default] + +\definefontfeature [smallcaps] [always] [smcp=yes, @@ -127,6 +131,11 @@ [script=arab] \definefontfeature + [syriac] + [arabic] + [fin2=yes,fin3=yes,med2=yes] + +\definefontfeature [hebrew] [semitic-complete] [script=hebr] @@ -240,16 +249,28 @@ \definefontfeature [mathematics] [mode=base, - liga=yes, kern=yes, - tlig=yes, - trep=yes, + % liga=yes, % makes no sense + % tlig=yes, % makes no sense + % trep=yes, % makes no sense + mathnolimitsmode={0,800}, % this looks okay on the average font mathalternates=yes, mathitalics=yes, % we pass them + mathdimensions=all, % mathgaps=yes, language=dflt, script=math] +\ifdefined\mathnolimitsmode + \mathnolimitsmode\plusone % font driven (only opentype) +\fi + +\ifdefined\mathitalicsmode + \mathitalicsmode\plusone % experiment +\fi + +% \adaptfontfeature[*math*][mathnolimitsmode=1000] % only subscript + \definefontfeature [mathematics-l2r] [mathematics] @@ -266,7 +287,6 @@ [mathematics-r2l] [mathematics] [rtlm=yes, - %dtls=yes, locl=yes] \definefontfeature[virtualmath] [mathematics] % downward compatibility @@ -305,6 +325,10 @@ protrusion=quality] \definefontfeature + [fullprotrusion] + [protrusion=pure] + +\definefontfeature [slanted] [slant=.2] @@ -312,6 +336,15 @@ [boldened] [extend=1.2] +%D Emoji: + +\definefontfeature[bandw:overlay][ccmp=yes,dist=yes] +\definefontfeature[color:overlay][ccmp=yes,dist=yes,colr=yes] +%definefontfeature[bandw:svg] [ccmp=yes,dist=yes] +\definefontfeature[color:svg] [ccmp=yes,dist=yes,svg=yes] +%definefontfeature[bandw:bitmap] [ccmp=yes,dist=yes,sbix=yes] +\definefontfeature[color:bitmap] [ccmp=yes,dist=yes,sbix=yes] + %D We define some colors that are used in tracing (for instance \OPENTYPE\ %D features). We cannot yet inherit because no colors are predefined. @@ -656,14 +689,27 @@ \definefontfeature[f:oldstyle] [onum=yes] \definefontfeature[f:tabular] [tnum=yes] \definefontfeature[f:superiors][sups=yes] +\definefontfeature[f:fractions][frac=yes] +\definefontfeature[f:kern] [kern=yes] +\definefontfeature[f:kerns] [kern=yes] \definealternativestyle [\v!smallcaps] [\setsmallcaps] [\setsmallcaps] \definealternativestyle [\v!oldstyle] [\setoldstyle ] [\setoldstyle ] +\definealternativestyle [\v!fractions] [\setfractions\resetbreakpoints] [\setfractions\resetbreakpoints] \unexpanded\def\setsmallcaps{\doaddfeature{f:smallcaps}} \unexpanded\def\setoldstyle {\doaddfeature{f:oldstyle}} \unexpanded\def\settabular {\doaddfeature{f:tabular}} \unexpanded\def\setsuperiors{\doaddfeature{f:superiors}} +\unexpanded\def\setfractions{\doaddfeature{f:fractions}} + +% \unexpanded\def\frc#1#2% +% {\dontleavehmode +% \begingroup +% \addff{frac}% +% \resetbreakpoints +% #1/#2% +% \endgroup} %D \macros %D {tinyfont} @@ -676,7 +722,7 @@ %D %D For tracing purposes we define: -\definefont[tinyfont][dejavusansmono at 1ex] +\definefont[tinyfont][file:dejavusansmono at 1ex] %D \macros %D {infofont} @@ -689,10 +735,11 @@ \let\infofont \relax % satisfy dep checker \let\infofontbold\relax % satisfy dep checker -\definefont[infofont] [dejavusansmono at 6pt] % todo \the\everybodyfont -\definefont[infofontbold][dejavusansmonobold at 6pt] % todo \the\everybodyfont +\definefont[infofont] [file:dejavusansmono at 6pt] % todo \the\everybodyfont +\definefont[infofontbold][file:dejavusansmono-bold at 6pt] % todo \the\everybodyfont -%D Optimization (later we overload in math): +%D Optimization (later we overload in math). Also needed in order to get \type {\ss} +%D properly defined. \unexpanded\def\normaltf{\let\fontalternative\s!tf\font_helpers_synchronize_font} \unexpanded\def\normalbf{\let\fontalternative\s!bf\font_helpers_synchronize_font} @@ -708,6 +755,14 @@ \let\bi\normalbi \let\bs\normalbs +\unexpanded\def\normalrm{\font_helpers_set_current_font_style{\s!rm}} +\unexpanded\def\normalss{\font_helpers_set_current_font_style{\s!ss}} +\unexpanded\def\normaltt{\font_helpers_set_current_font_style{\s!tt}} + +\let\rm\normalrm +\let\ss\normalss +\let\tt\normaltt + \protect \endinput % LM math vs CM math (analysis by Taco): diff --git a/tex/context/base/mkiv/font-run.mkiv b/tex/context/base/mkiv/font-run.mkiv index e9a6f9ddb..ebb3a576c 100644 --- a/tex/context/base/mkiv/font-run.mkiv +++ b/tex/context/base/mkiv/font-run.mkiv @@ -14,6 +14,8 @@ %D [This code is hooked into the core macros and saves some format %D space. It needs a cleanup as it's real old derioved \MKII\ code] +%D +%D Better use \type{\bTABLE...\eTABLE}. \unprotect diff --git a/tex/context/base/mkiv/font-sel.lua b/tex/context/base/mkiv/font-sel.lua index 4c80ff1fb..b4dd9a555 100644 --- a/tex/context/base/mkiv/font-sel.lua +++ b/tex/context/base/mkiv/font-sel.lua @@ -1,64 +1,63 @@ if not modules then modules = { } end modules ['font-sel'] = { - version = 1.000, + version = 1.001, comment = "companion to font-sel.mkvi", author = "Wolfgang Schuster", copyright = "Wolfgang Schuster", license = "GNU General Public License" } -local context = context -local cleanname = fonts.names.cleanname -local gsub, splitup, find = string.gsub, string.splitup, string.find -local concat, sortedkeys = table.concat, table.sortedkeys -local merge, remove = table.merge, table.remove -local splitbase, removesuffix = file.splitbase, file.removesuffix -local splitat, lpegmatch = lpeg.splitat, lpeg.match - -local formatters = string.formatters -local settings_to_array = utilities.parsers.settings_to_array -local settings_to_hash = utilities.parsers.settings_to_hash - -local v_yes = interfaces.variables.yes -local v_default = interfaces.variables.default - -local implement = interfaces.implement - -local selectfont = fonts.select or { } -fonts.select = selectfont - -local data = selectfont.data or { } -selectfont.data = data - -local fallbacks = selectfont.fallbacks or { } -selectfont.fallbacks = fallbacks - -local methods = selectfont.methods or { } -selectfont.methods = methods - -local extras = selectfont.extras or { } -selectfont.extras = extras - -local alternatives = selectfont.alternatives or { } -selectfont.alternatives = alternatives - -local presets = selectfont.presets or { } -selectfont.presets = presets - -local defaults = selectfont.defaults or { } -selectfont.defaults = defaults - -local getlookups = fonts.names.getlookups -local registerdesignsizes = fonts.goodies.designsizes.register -local bodyfontsizes = storage.shared.bodyfontsizes - -local ctx_definefontsynonym = context.definefontsynonym -local ctx_resetfontfallback = context.resetfontfallback -local ctx_startfontclass = context.startfontclass -local ctx_stopfontclass = context.stopfontclass -local ctx_loadfontgoodies = context.loadfontgoodies -local ctx_definefontfallback = context.definefontfallback -local ctx_definetypeface = context.definetypeface -local ctx_definebodyfont = context.definebodyfont +local context = context +local cleanname = fonts.names.cleanname +local gsub, splitup, find, lower = string.gsub, string.splitup, string.find, string.lower +local concat, sortedkeys = table.concat, table.sortedkeys +local merge, remove = table.merge, table.remove +local splitbase, removesuffix = file.splitbase, file.removesuffix +local splitat, lpegmatch = lpeg.splitat, lpeg.match + +local formatters = string.formatters +local settings_to_array = utilities.parsers.settings_to_array +local settings_to_hash = utilities.parsers.settings_to_hash +local allocate = utilities.storage.allocate + +local v_default = interfaces.variables.default + +local implement = interfaces.implement + +local fonts = fonts + +local getlookups = fonts.names.getlookups +local registerdesignsizes = fonts.goodies.designsizes.register +local bodyfontsizes = storage.shared.bodyfontsizes + +fonts.select = fonts.select or { } +local selectfont = fonts.select + +selectfont.data = selectfont.data or allocate() +selectfont.fallbacks = selectfont.fallbacks or allocate() +selectfont.methods = selectfont.methods or allocate() +selectfont.extras = selectfont.extras or allocate() +selectfont.alternatives = selectfont.alternatives or allocate() +selectfont.presets = selectfont.presets or allocate() +selectfont.defaults = selectfont.defaults or allocate() + +storage.register("fonts/select/presets", selectfont.presets, "fonts.select.presets") + +local data = selectfont.data +local fallbacks = selectfont.fallbacks +local methods = selectfont.methods +local extras = selectfont.extras +local alternatives = selectfont.alternatives +local presets = selectfont.presets +local defaults = selectfont.defaults + +local ctx_definefontsynonym = context.definefontsynonym +local ctx_resetfontfallback = context.resetfontfallback +local ctx_startfontclass = context.startfontclass +local ctx_stopfontclass = context.stopfontclass +local ctx_loadfontgoodies = context.loadfontgoodies +local ctx_definefontfallback = context.definefontfallback +local ctx_definetypeface = context.definetypeface +local ctx_definebodyfont = context.definebodyfont local trace_register = false trackers.register("selectfont.register", function(v) trace_register = v end) local trace_files = false trackers.register("selectfont.files", function(v) trace_files = v end) @@ -71,7 +70,6 @@ local report_selectfont = logs.reporter("selectfont") local report_files = logs.reporter("selectfont","files") local report_features = logs.reporter("selectfont","features") local report_goodies = logs.reporter("selectfont","goodies") -local report_alternatives = logs.reporter("selectfont","alternatives") local report_typescript = logs.reporter("selectfont","typescripts") defaults["rm"] = { features = { ["sc"] = "*,f:smallcaps" } } @@ -83,6 +81,8 @@ defaults["dejavumath"] = { options = { extras = "dejavu", defaults["neoeuler"] = { options = { extras = "euler-math", features = "math\\mathsizesuffix" } } defaults["latinmodernmath"] = { options = { extras = "lm,lm-math", features = "math\\mathsizesuffix,lm-math", goodies = "lm" } } defaults["lucidabrightmathot"] = { options = { extras = "lucida-opentype-math", features = "math\\mathsizesuffix", goodies = "lucida-opentype-math" } } +defaults["minionmath"] = { options = { extras = "minion-math", features = "math\\mathsizesuffix", goodies = "minion-math" } } +defaults["texgyredejavumath"] = { options = { extras = "dejavu", features = "math\\mathsizesuffix" } } defaults["texgyrepagellamath"] = { options = { extras = "texgyre", features = "math\\mathsizesuffix" } } defaults["texgyrebonummath"] = { options = { extras = "texgyre", features = "math\\mathsizesuffix" } } defaults["texgyrescholamath"] = { options = { extras = "texgyre", features = "math\\mathsizesuffix" } } @@ -148,9 +148,9 @@ methods["name"] = function(data,alternative,name) local fontname = getlookups{ fontname = filename } local fullname = getlookups{ fullname = filename } if #fontname > 0 then - selectfont_savefile(data,alternative,0,"default",fullname[1]) - elseif #fullname > 0 then selectfont_savefile(data,alternative,0,"default",fontname[1]) + elseif #fullname > 0 then + selectfont_savefile(data,alternative,0,"default",fullname[1]) else if trace_alternatives then report_selectfont("Alternative '%s': No font was found for the requested name '%s'",alternative,filename) @@ -227,7 +227,7 @@ local m_alternative = { ["sl"] = "italic", ["bi"] = "bolditalic", ["bs"] = "bolditalic", - ["sc"] = "regular" + ["sc"] = "smallcaps" } --~ methods["style"] = function(data,alternative,style) @@ -294,6 +294,20 @@ local function m_style_family(family) end end +local function m_style_subfamily(entries,style,family) + local t = { } + local style = cleanname(style) + local family = cleanname(family) + for index, entry in next, entries do + if entry["familyname"] == family and entry["subfamilyname"] == style then -- familyname + subfamilyname + t[#t+1] = entry + elseif entry["family"] == family and entry["subfamily"] == style then -- family + subfamily + t[#t+1] = entry + end + end + return #t ~= 0 and t or nil +end + local function m_style_weight(entries,style) local t = { } local weight = m_name[style] and m_name[style]["weight"] or "regular" @@ -396,13 +410,18 @@ methods["style"] = function(data,alternative,style) local fontstyle = m_alternative[style] or style local entries = m_style_family(fontfamily) if entries then - entries = m_style_weight(entries,fontstyle) - if entries then - entries = m_style_style(entries,fontstyle) + local subfamily = m_style_subfamily(entries,fontstyle,fontfamily) + if subfamily then + entries = subfamily + else + entries = m_style_weight(entries,fontstyle) if entries then - entries = m_style_variant(entries,fontstyle) - if entries and #entries > 1 and designsize == "default" then - entries = m_style_width(entries,fontstyle) + entries = m_style_style(entries,fontstyle) + if entries then + entries = m_style_variant(entries,fontstyle) + if entries and #entries > 1 and designsize == "default" then + entries = m_style_width(entries,fontstyle) + end end end end @@ -543,7 +562,7 @@ function selectfont.registerfontalternative(alternative) end function selectfont.registerfallback(index) - local data = data[index] + local data = data[index] local fontclass = data.metadata.typeface local fontstyle = data.metadata.style local fallback = fallbacks[fontclass] @@ -640,18 +659,19 @@ function selectfont.fontsynonym(data,class,style,alternative,index) local fontfiles = data.files[alternative] or data.files["tf"] local fontsizes = sortedkeys(fontfiles) local fallback = index ~= 0 + local fontclass = lower(class) --~ local fontfeature = data.features and data.features[alternative] or data.options.features --~ local fontgoodie = data.goodies and data.goodies [alternative] or data.options.goodies local fontfeature = selectfont.features(data,style,alternative) local fontgoodie = selectfont.goodies (data,style,alternative) local synonym = m_synonym[style] and m_synonym[style][alternative] - local fontfile = formatters ["file-%s-%s-%s"](class,style,alternative) - local fontsynonym = formatters ["synonym-%s-%s-%s"](class,style,alternative) + local fontfile = formatters ["file-%s-%s-%s"](fontclass,style,alternative) + local fontsynonym = formatters ["synonym-%s-%s-%s"](fontclass,style,alternative) if fallback then - fontfile = formatters ["file-%s-%s-%s-%s"](class,style,alternative,index) - fontsynonym = formatters ["synonym-%s-%s-%s-%s"](class,style,alternative,index) + fontfile = formatters ["file-%s-%s-%s-%s"](fontclass,style,alternative,index) + fontsynonym = formatters ["synonym-%s-%s-%s-%s"](fontclass,style,alternative,index) end - local fontfallback = formatters["fallback-%s-%s-%s"](class,style,alternative) + local fontfallback = formatters["fallback-%s-%s-%s"](fontclass,style,alternative) for _, fontsize in next, fontsizes do --~ if trace_typescript then --~ report_typescript("Synonym: '%s', Size: '%s', File: '%s'",fontfile,fontfiles[fontsize][1],fontfiles[fontsize][2]) @@ -678,13 +698,14 @@ function selectfont.fontsynonym(data,class,style,alternative,index) end function selectfont.fontfallback(data,class,style,alternative,index) - local range = data.options.range - local scale = data.options.rscale ~= "" and data.options.rscale or 1 - local check = data.options.check ~= "" and data.options.check or "yes" - local force = data.options.force ~= "" and data.options.force or "no" - local fontfeature = data.features and data.features[alternative] or data.options.features - local fontsynonym = formatters["synonym-%s-%s-%s-%s"](class,style,alternative,index) - local fontfallback = formatters["fallback-%s-%s-%s"] (class,style,alternative) + local range = data.options.range + local scale = data.options.rscale ~= "" and data.options.rscale or 1 + local check = data.options.check ~= "" and data.options.check or "" + local force = data.options.force ~= "" and data.options.force or "" + local fontfeature = data.features and data.features[alternative] or data.options.features + local fontclass = lower(class) + local fontsynonym = formatters ["synonym-%s-%s-%s-%s"](fontclass,style,alternative,index) + local fontfallback = formatters["fallback-%s-%s-%s"] (fontclass,style,alternative) if index == 1 then ctx_resetfontfallback( { fontfallback } ) end @@ -702,7 +723,8 @@ function selectfont.filefallback(data,class,style,alternative,index) local force = data.options.force ~= "" and data.options.force or "yes" local fontfile = data.files[alternative] and data.files[alternative][0] or data.files["tf"][0] local fontfeature = data.features and data.features[alternative] or data.options.features - local fontfallback = formatters["fallback-%s-%s-%s"](class,style,alternative) + local fontclass = lower(class) + local fontfallback = formatters["fallback-%s-%s-%s"](fontclass,style,alternative) if index == 1 then ctx_resetfontfallback( { fontfallback } ) end @@ -713,7 +735,7 @@ function selectfont.filefallback(data,class,style,alternative,index) end function selectfont.mathfallback(index,entry,class,style) - local data = data[entry] + local data = data[entry] ctx_startfontclass( { class } ) for alternative, _ in next, alternatives do if alternative == "tf" or alternative == "bf" then @@ -724,7 +746,7 @@ function selectfont.mathfallback(index,entry,class,style) end function selectfont.textfallback(index,entry,class,style) - local data = data[entry] + local data = data[entry] ctx_startfontclass( { class } ) for alternative, _ in next, alternatives do selectfont.fontsynonym (data,class,style,alternative,index) @@ -780,8 +802,9 @@ function selectfont.typescript(data) end function selectfont.bodyfont(data) - local fontclass = data.metadata.typeface + local class = data.metadata.typeface local fontstyle = data.metadata.style + local fontclass = lower(class) local fontsizes = concat(sortedkeys(bodyfontsizes),",") local fontsynonym = nil local fontlist = { } @@ -793,7 +816,7 @@ function selectfont.bodyfont(data) --~ end end fontlist = concat(fontlist,",") - ctx_definebodyfont( { fontclass }, { fontsizes }, { fontstyle }, { fontlist } ) + ctx_definebodyfont( { class }, { fontsizes }, { fontstyle }, { fontlist } ) end local m_style = { @@ -814,11 +837,7 @@ function selectfont.typeface(data) --~ if trace_typescript then --~ report_typescript("Class: '%s', Style: '%s', Size: '%s', Scale: '%s'",fontclass,fontstyle,size,scale) --~ end - if fontstyle == "mm" then -- math uses the default bodyfont settings because it uses 'ma' and 'mb' as alternative names - ctx_definetypeface( { fontclass }, { fontstyle }, { style }, { "" }, { "default" }, { designsize = size, rscale = scale } ) - else - ctx_definetypeface( { fontclass }, { fontstyle }, { "" }, { "" }, { "" }, { designsize = size, rscale = scale } ) - end + ctx_definetypeface( { fontclass }, { fontstyle }, { style }, { "" }, { "default" }, { designsize = size, rscale = scale } ) end function selectfont.default(data) @@ -923,4 +942,4 @@ implement { name = "definefontfamilypreset", actions = selectfont.definefontfamilypreset, arguments = { "string", "string" } -}
\ No newline at end of file +} diff --git a/tex/context/base/mkiv/font-sel.mkvi b/tex/context/base/mkiv/font-sel.mkvi index 4e74f6864..a78742928 100644 --- a/tex/context/base/mkiv/font-sel.mkvi +++ b/tex/context/base/mkiv/font-sel.mkvi @@ -1,6 +1,6 @@ %D \module %D [ file=font-sel, -%D version=2016.05.16, +%D version=2016.08.28, %D title=\CONTEXT\ User Module, %D subtitle=Selectfont, %D author=Wolfgang Schuster, @@ -10,15 +10,17 @@ \writestatus{loading}{ConTeXt User Module / Selectfont} -\registerctxluafile{font-sel}{1.000} +\registerctxluafile{font-sel}{1.001} \unprotect \installcorenamespace {selectfont} \installsimplecommandhandler \??selectfont {selectfont} -\unexpanded\def\selectfont_register[#settings]% +\unexpanded\def\selectfont_register[#style][#settings]% {\begingroup + \edef\currentselectfont{\expandnamespacevalue\??fontshortstyle{#style}\s!rm}% + \checkselectfontparent \setupcurrentselectfont[#settings]% \edef\p_selectfont_preset{\selectfontparameter\c!preset}% \ifx\p_selectfont_preset\empty \else @@ -37,17 +39,17 @@ designsize {\selectfontparameter\s!designsize}% rscale {\selectfontparameter\s!rscale}% goodies {\selectfontparameter\c!goodies}% - extras {\selectfontparameter\c!extras}% + extras {\selectfontparameter\c!extras}% features {\selectfontparameter\c!features}% - preset {\selectfontparameter\c!preset}% + preset {\selectfontparameter\c!preset}% range {\selectfontparameter\c!range}% fallback only offset {\selectfontparameter\c!offset}% fallback only check {\selectfontparameter\c!check}% fallback only force {\selectfontparameter\c!force}% fallback only } - userdata {% - \luaexpanded{#settings}% - }}% + userdata {% + \luaexpanded{#settings}% + }}% \endgroup} %D \macros @@ -174,7 +176,7 @@ %D The \tex{definefontfamily} creates like \tex{definetypeface} a collection of font %D with different styles which can be later called with the \tex{setupbodyfont} command. %D -%D The command takes three mendatory commands which are (a) the name of the fontclass, +%D The command takes three mandatory commands which are (a) the name of the fontclass, %D (b) the styles of the font and (c) the name of the font. %D %D \starttyping @@ -233,7 +235,7 @@ %D \stoptext %D \stoptyping %D -%D Another feature of the module is the \type{opticalsize} key which allows one to enable +%D Another feature of the module is the \type{designsize} key which allows one to enable %D optical sizes when they are a feature of the requested font. %D %D \starttyping @@ -257,8 +259,8 @@ \def\selectfont_family_define[#typeface][#style][#family][#settings]% {\doifelseassignment{#settings} - {\selectfont_register[\c!label={#typeface},\c!style={#style},\c!name={#family},#settings]} - {\selectfont_register[\c!label={#typeface},\c!style={#style},\c!name={#family},\c!preset={#settings}]}% + {\selectfont_register[#style][\c!label={#typeface},\c!style={#style},\c!name={#family},#settings]} + {\selectfont_register[#style][\c!label={#typeface},\c!style={#style},\c!name={#family},\c!preset={#settings}]}% \clf_definefontfamily\selectfont_index\relax} \unexpanded\def\definefallbackfamily @@ -266,13 +268,26 @@ \def\selectfont_fallback_define[#typeface][#style][#family][#settings]% {\doifelseassignment{#settings} - {\selectfont_register[\c!label={#typeface},\c!style={#style},\c!name={#family},#settings]} - {\selectfont_register[\c!label={#typeface},\c!style={#style},\c!name={#family},\c!preset={#settings}]}% + {\selectfont_register[#style][\c!label={#typeface},\c!style={#style},\c!name={#family},#settings]} + {\selectfont_register[#style][\c!label={#typeface},\c!style={#style},\c!name={#family},\c!preset={#settings}]}% \clf_definefallbackfamily\selectfont_index\relax} +\unexpanded\def\setupfontfamily + {\dodoubleargument\selectfont_family_setup} + +\def\selectfont_family_setup[#style][#settings]% + {\ifsecondargument + \edef\currentselectfont{\expandnamespacevalue\??fontshortstyle{#style}\s!rm}% + \setupcurrentselectfont[#settings]% + \else + \let\currentselectfont\empty + \setupcurrentselectfont[#style]% + \fi} + \setupselectfont [ \c!features=\s!default, \s!designsize=\s!default, - \s!rscale=1] + \s!rscale=\selectfontparameter\c!scale, + \c!scale=1] -\protect
\ No newline at end of file +\protect diff --git a/tex/context/base/mkiv/font-set.mkvi b/tex/context/base/mkiv/font-set.mkvi index b29545ace..2c6d065d8 100644 --- a/tex/context/base/mkiv/font-set.mkvi +++ b/tex/context/base/mkiv/font-set.mkvi @@ -137,7 +137,7 @@ \unexpanded\def\font_preloads_fourth_stage {\begingroup %ifzeropt\fontcharwd\font\number`!\relax - \setbox\scratchbox\hbox{c o n t e x t}% + \setbox\scratchbox\hpack{\tf c o n t e x t}% \ifzeropt\wd\scratchbox \writeline \writestatus\m!fonts{!! No bodyfont has been defined and no defaults have been}% diff --git a/tex/context/base/mkiv/font-shp.lua b/tex/context/base/mkiv/font-shp.lua new file mode 100644 index 000000000..6e21848a4 --- /dev/null +++ b/tex/context/base/mkiv/font-shp.lua @@ -0,0 +1,410 @@ +if not modules then modules = { } end modules ['font-shp'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local tonumber = tonumber +local concat = table.concat +local formatters = string.formatters + +local otf = fonts.handlers.otf +local afm = fonts.handlers.afm + +local hashes = fonts.hashes +local identifiers = hashes.identifiers + +local version = 0.007 +local shapescache = containers.define("fonts", "shapes", version, true) +local streamscache = containers.define("fonts", "streams", version, true) + +-- shapes (can be come a separate file at some point) + +local function packoutlines(data,makesequence) + local subfonts = data.subfonts + if subfonts then + for i=1,#subfonts do + packoutlines(subfonts[i],makesequence) + end + return + end + local common = data.segments + if common then + return + end + local glyphs = data.glyphs + if not glyphs then + return + end + if makesequence then + for index=1,#glyphs do + local glyph = glyphs[index] + local segments = glyph.segments + if segments then + local sequence = { } + local nofsequence = 0 + for i=1,#segments do + local segment = segments[i] + local nofsegment = #segment + nofsequence = nofsequence + 1 + sequence[nofsequence] = segment[nofsegment] + for i=1,nofsegment-1 do + nofsequence = nofsequence + 1 + sequence[nofsequence] = segment[i] + end + end + glyph.sequence = sequence + glyph.segments = nil + end + end + else + local hash = { } + local common = { } + local reverse = { } + local last = 0 + for index=1,#glyphs do + local segments = glyphs[index].segments + if segments then + for i=1,#segments do + local h = concat(segments[i]," ") + hash[h] = (hash[h] or 0) + 1 + end + end + end + for index=1,#glyphs do + local segments = glyphs[index].segments + if segments then + for i=1,#segments do + local segment = segments[i] + local h = concat(segment," ") + if hash[h] > 1 then -- minimal one shared in order to hash + local idx = reverse[h] + if not idx then + last = last + 1 + reverse[h] = last + common[last] = segment + idx = last + end + segments[i] = idx + end + end + end + end + if last > 0 then + data.segments = common + end + end +end + +local function unpackoutlines(data) + local subfonts = data.subfonts + if subfonts then + for i=1,#subfonts do + unpackoutlines(subfonts[i]) + end + return + end + local common = data.segments + if not common then + return + end + local glyphs = data.glyphs + if not glyphs then + return + end + for index=1,#glyphs do + local segments = glyphs[index].segments + if segments then + for i=1,#segments do + local c = common[segments[i]] + if c then + segments[i] = c + end + end + end + end + data.segments = nil +end + +-- todo: loaders per format + +local readers = otf.readers +local cleanname = readers.helpers.cleanname + +local function makehash(filename,sub,instance) + local name = cleanname(file.basename(filename)) + if instance then + return formatters["%s-%s-%s"](name,sub or 0,cleanname(instance)) + else + return formatters["%s-%s"] (name,sub or 0) + end +end + +local function loadoutlines(cache,filename,sub,instance) + local base = file.basename(filename) + local name = file.removesuffix(base) + local kind = file.suffix(filename) + local attr = lfs.attributes(filename) + local size = attr and attr.size or 0 + local time = attr and attr.modification or 0 + local sub = tonumber(sub) + + -- fonts.formats + + if size > 0 and (kind == "otf" or kind == "ttf" or kind == "tcc") then + local hash = makehash(filename,sub,instance) + data = containers.read(cache,hash) + if not data or data.time ~= time or data.size ~= size then + data = readers.loadshapes(filename,sub,instance) + if data then + data.size = size + data.format = data.format or (kind == "otf" and "opentype") or "truetype" + data.time = time + packoutlines(data) + containers.write(cache,hash,data) + data = containers.read(cache,hash) -- frees old mem + end + end + unpackoutlines(data) + elseif size > 0 and (kind == "pfb") then + local hash = containers.cleanname(base) -- including suffix + data = containers.read(cache,hash) + if not data or data.time ~= time or data.size ~= size then + data = afm.readers.loadshapes(filename) + if data then + data.size = size + data.format = "type1" + data.time = time + packoutlines(data) + containers.write(cache,hash,data) + data = containers.read(cache,hash) -- frees old mem + end + end + unpackoutlines(data) + else + data = { + filename = filename, + size = 0, + time = time, + format = "unknown", + units = 1000, + glyphs = { } + } + end + return data +end + +local function loadstreams(cache,filename,sub,instance) + local base = file.basename(filename) + local name = file.removesuffix(base) + local kind = file.suffix(filename) + local attr = lfs.attributes(filename) + local size = attr and attr.size or 0 + local time = attr and attr.modification or 0 + local sub = tonumber(sub) + + -- fonts.formats + + if size > 0 and (kind == "otf" or kind == "ttf" or kind == "tcc") then + local hash = makehash(filename,sub,instance) + data = containers.read(cache,hash) + if not data or data.time ~= time or data.size ~= size then + data = readers.loadshapes(filename,sub,instance,true) + if data then + local glyphs = data.glyphs + local streams = { } + if glyphs then + for i=0,#glyphs do + streams[i] = glyphs[i].stream or "" + end + end + data.streams = streams + data.glyphs = nil + data.size = size + data.format = data.format or (kind == "otf" and "opentype") or "truetype" + data.time = time + containers.write(cache,hash,data) + data = containers.read(cache,hash) -- frees old mem + end + end + else + data = { + filename = filename, + size = 0, + time = time, + format = "unknown", + glyphs = { } + } + end + return data +end + +local loadedshapes = { } +local loadedstreams = { } + +local function loadoutlinedata(fontdata,streams) + local properties = fontdata.properties + local filename = properties.filename + local subindex = fontdata.subindex + local instance = properties.instance + local hash = makehash(filename,subindex,instance) + local loaded = loadedshapes[hash] + if not loaded then + loaded = loadoutlines(shapescache,filename,subindex,instance) + loadedshapes[hash] = loaded + end + return loaded +end + +hashes.shapes = table.setmetatableindex(function(t,k) + local f = identifiers[k] + if f then + return loadoutlinedata(f) + end +end) + +local function loadstreamdata(fontdata,streams) + local properties = fontdata.properties + local filename = properties.filename + local subindex = fontdata.subindex + local instance = properties.instance + local hash = makehash(filename,subindex,instance) + local loaded = loadedstreams[hash] + if not loaded then + loaded = loadstreams(streamscache,filename,subindex,instance) + loadedstreams[hash] = loaded + end + return loaded +end + +hashes.streams = table.setmetatableindex(function(t,k) + local f = identifiers[k] + if f then + return loadstreamdata(f,true) + end +end) + +otf.loadoutlinedata = loadoutlinedata -- not public +otf.loadstreamdata = loadstreamdata -- not public +otf.loadshapes = loadshapes + +-- experimental code, for me only ... unsupported + +local f_c = string.formatters["%F %F %F %F %F %F c"] +local f_l = string.formatters["%F %F l"] +local f_m = string.formatters["%F %F m"] + +local function segmentstopdf(segments,factor,bt,et) + local t = { } + local m = 0 + local n = #segments + local d = false + for i=1,n do + local s = segments[i] + local w = s[#s] + if w == "c" then + m = m + 1 + t[m] = f_c(s[1]*factor,s[2]*factor,s[3]*factor,s[4]*factor,s[5]*factor,s[6]*factor) + elseif w == "l" then + m = m + 1 + t[m] = f_l(s[1]*factor,s[2]*factor) + elseif w == "m" then + m = m + 1 + t[m] = f_m(s[1]*factor,s[2]*factor) + elseif w == "q" then + local p = segments[i-1] + local n = #p + local l_x, l_y = factor*p[n-2], factor*p[n-1] + local m_x, m_y = factor*s[1], factor*s[2] + local r_x, r_y = factor*s[3], factor*s[4] + m = m + 1 + t[m] = f_c ( + l_x + 2/3 * (m_x-l_x), l_y + 2/3 * (m_y-l_y), + r_x + 2/3 * (m_x-r_x), r_y + 2/3 * (m_y-r_y), + r_x, r_y + ) + end + end + m = m + 1 + t[m] = "h f" -- B* + if bt and et then + t[0] = bt + t[m+1] = et + return concat(t,"\n",0,m+1) + else + return concat(t,"\n") + end +end + +local function addvariableshapes(tfmdata,key,value) + if value then + local shapes = otf.loadoutlinedata(tfmdata) + if not shapes then + return + end + local glyphs = shapes.glyphs + if not glyphs then + return + end + local characters = tfmdata.characters + local parameters = tfmdata.parameters + local hfactor = parameters.hfactor * (7200/7227) + local factor = hfactor / 65536 + local getactualtext = otf.getactualtext + for unicode, char in next, characters do + if not char.commands then + local shape = glyphs[char.index] + if shape then + local segments = shape.segments + if segments then + -- we need inline in order to support color + local bt, et = getactualtext(char.tounicode or char.unicode or unicode) + char.commands = { + { "special", "pdf:" .. segmentstopdf(segments,factor,bt,et) } + } + end + end + end + end + end +end + +otf.features.register { + name = "variableshapes", -- enforced for now + description = "variable shapes", + manipulators = { + base = addvariableshapes, + node = addvariableshapes, + } +} + +-- In the end it is easier to just provide the new charstring (cff) and points (ttdf). First +-- of all we already have the right information so there is no need to patch the already complex +-- backend code (we only need to make sure the cff is valid). Also, I prototyped support for +-- these fonts using (converted to) normal postscript shapes, a functionality that was already +-- present for a while for metafun. This solution even permits us to come up with usage of such +-- fonts in unexpected ways. It also opens the road to shapes generated with metafun includes +-- as real cff (or ttf) shapes instead of virtual in-line shapes. +-- +-- This is probably a prelude to writing a complete backend font inclusion plugin in lua. After +-- all I already have most info. For this we just need to pass a list of used glyphs (or analyze +-- them ourselves). + +local streams = fonts.hashes.streams + +if callbacks.supported.glyph_stream_provider then + + callback.register("glyph_stream_provider",function(id,index,mode) + if id > 0 then + local streams = streams[id].streams + -- print(id,index,streams[index]) + if streams then + return streams[index] or "" + end + end + return "" + end) + +end diff --git a/tex/context/base/mkiv/font-sol.lua b/tex/context/base/mkiv/font-sol.lua index 8d45552a5..82fc3dc40 100644 --- a/tex/context/base/mkiv/font-sol.lua +++ b/tex/context/base/mkiv/font-sol.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['font-sol'] = { -- this was: node license = "see context related readme files" } +-- We can speed this up. + -- This module is dedicated to the oriental tex project and for -- the moment is too experimental to be publicly supported. -- @@ -21,8 +23,7 @@ if not modules then modules = { } end modules ['font-sol'] = { -- this was: node local gmatch, concat, format, remove = string.gmatch, table.concat, string.format, table.remove local next, tostring, tonumber = next, tostring, tonumber local insert, remove = table.insert, table.remove -local utfchar = utf.char -local random = math.random +local getrandom = utilities.randomizer.get local utilities, logs, statistics, fonts, trackers = utilities, logs, statistics, fonts, trackers local interfaces, commands, attributes = interfaces, commands, attributes @@ -64,17 +65,18 @@ local getattr = nuts.getattr local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getlist = nuts.getlist +local getdir = nuts.getdir +local getwidth = nuts.getwidth -local setfield = nuts.setfield local setattr = nuts.setattr local setlink = nuts.setlink local setnext = nuts.setnext local setlist = nuts.setlist local find_node_tail = nuts.tail -local free_node = nuts.free -local free_nodelist = nuts.flush_list -local copy_nodelist = nuts.copy_list +local flush_node = nuts.flush_node +local flush_node_list = nuts.flush_list +local copy_node_list = nuts.copy_list local traverse_nodes = nuts.traverse local traverse_ids = nuts.traverse_id local hpack_nodes = nuts.hpack @@ -121,9 +123,7 @@ local stoptiming = statistics.stoptiming local inject_kerns = nodes.injections.handler local fonthashes = fonts.hashes -local fontdata = fonthashes.identifiers local setfontdynamics = fonthashes.setdynamics -local fontprocesses = fonthashes.processes local texsetattribute = tex.setattribute local unsetvalue = attributes.unsetvalue @@ -166,9 +166,10 @@ local dummy = { local function checksettings(r,settings) local s = r.settings - local method = settings_to_hash(settings.method or "") + local method = settings_to_array(settings.method or "") local optimize, preroll, splitwords - for k, v in next, method do + for i=1,#method do + local k = method[i] if k == v_preroll then preroll = true elseif k == v_split then @@ -235,6 +236,7 @@ local function convert(featuresets,name,list) fs = contextsetups[feature] fn = fs and fs.number end +-- inspect(fs) if fn then nofnumbers = nofnumbers + 1 numbers[nofnumbers] = fn @@ -350,7 +352,8 @@ function splitters.split(head) local function flush() -- we can move this local font = getfont(start) local last = getnext(stop) - local list = last and copy_nodelist(start,last) or copy_nodelist(start) +-- local list = last and copy_node_list(start,last) or copy_node_list(start) + local list = last and copy_node_list(start,stop) or copy_node_list(start) local n = #cache + 1 if encapsulate then local user_one = new_usernumber(splitter_one,n) @@ -368,7 +371,8 @@ function splitters.split(head) end end end - if rlmode == "TRT" or rlmode == "+TRT" then + local r2l = rlmode == "TRT" or rlmode == "+TRT" + if r2l then local dirnode = new_textdir("+TRT") setlink(dirnode,list) list = dirnode @@ -376,16 +380,17 @@ function splitters.split(head) local c = { original = list, attribute = attribute, - direction = rlmode, + -- direction = rlmode, font = font } if trace_split then report_splitters("cached %4i: font %a, attribute %a, direction %a, word %a", - n, font, attribute, nodes_to_utf(list,true), rlmode and "r2l" or "l2r") + n, font, attribute, nodes_to_utf(list,true), r2l and "r2l" or "l2r") end cache[n] = c local solution = solutions[attribute] - local l, m = #solution.less, #solution.more + local l = #solution.less + local m = #solution.more if l > max_less then max_less = l end if m > max_more then max_more = m end start, stop, done = nil, nil, true @@ -421,7 +426,7 @@ function splitters.split(head) if start then flush() end - rlmode = getfield(current,"dir") + rlmode = getdir(current) else if start then flush() @@ -569,14 +574,15 @@ local function doit(word,list,best,width,badness,line,set,listdir) return false, changed end end - local original, attribute, direction = found.original, found.attribute, found.direction - local solution = solutions[attribute] - local features = solution and solution[set] + local original = found.original + local attribute = found.attribute + local solution = solutions[attribute] + local features = solution and solution[set] if features then local featurenumber = features[best] -- not ok probably if featurenumber then noftries = noftries + 1 - local first = copy_nodelist(original) + local first = copy_node_list(original) if not trace_colors then for n in traverse_nodes(first) do -- maybe fast force so no attr needed setattr(n,0,featurenumber) -- this forces dynamics @@ -608,7 +614,7 @@ first = tonut(first) if getid(first) == whatsit_code then local temp = first first = getnext(first) - free_node(temp) + flush_node(temp) end local last = find_node_tail(first) -- replace [u]h->t by [u]first->last @@ -622,7 +628,7 @@ first = tonut(first) local temp, b = repack_hlist(list,width,'exactly',listdir) if b > badness then if trace_optimize then - report_optimizers("line %a, badness before %a, after %a, criterium %a, verdict %a",line,badness,b,criterium,"quit") + report_optimizers("line %a, set %a, badness before %a, after %a, criterium %a, verdict %a",line,set or "?",badness,b,criterium,"quit") end -- remove last insert setlink(prev,h) @@ -632,14 +638,14 @@ first = tonut(first) setnext(t) end setnext(last) - free_nodelist(first) + flush_node_list(first) else if trace_optimize then - report_optimizers("line %a, badness before: %a, after %a, criterium %a, verdict %a",line,badness,b,criterium,"continue") + report_optimizers("line %a, set %a, badness before: %a, after %a, criterium %a, verdict %a",line,set or "?",badness,b,criterium,"continue") end -- free old h->t setnext(t) - free_nodelist(h) -- somhow fails + flush_node_list(h) -- somehow fails if not encapsulate then word[2] = first word[3] = last @@ -701,7 +707,7 @@ end variants[v_random] = function(words,list,best,width,badness,line,set,listdir) local changed = 0 while #words > 0 do - local done, c = doit(remove(words,random(1,#words)),list,best,width,badness,line,set,listdir) + local done, c = doit(remove(words,getrandom("solution",1,#words)),list,best,width,badness,line,set,listdir) changed = changed + c if done then break @@ -752,8 +758,8 @@ function splitters.optimize(head) for current in traverse_ids(hlist_code,tonut(head)) do line = line + 1 local sign = getfield(current,"glue_sign") - local dir = getfield(current,"dir") - local width = getfield(current,"width") + local dir = getdir(current) + local width = getwidth(current) local list = getlist(current) if not encapsulate and getid(list) == glyph_code then -- nasty .. we always assume a prev being there .. future luatex will always have a leftskip set @@ -786,9 +792,9 @@ function splitters.optimize(head) local bb, base for i=1,max do if base then - free_nodelist(base) + flush_node_list(base) end - base = copy_nodelist(list) + base = copy_node_list(list) local words = collect_words(base) -- beware: words is adapted for j=i,max do local temp, done, changes, b = optimize(words,base,j,width,badness,line,set,dir) @@ -814,7 +820,7 @@ function splitters.optimize(head) break end end - free_nodelist(base) + flush_node_list(base) end local words = collect_words(list) for best=lastbest or 1,max do @@ -842,7 +848,7 @@ function splitters.optimize(head) end for i=1,nc do local ci = cache[i] - free_nodelist(ci.original) + flush_node_list(ci.original) end cache = { } tex.hbadness = tex_hbadness diff --git a/tex/context/base/mkiv/font-sty.mkvi b/tex/context/base/mkiv/font-sty.mkvi index 6b2c072e5..cf49cd5eb 100644 --- a/tex/context/base/mkiv/font-sty.mkvi +++ b/tex/context/base/mkiv/font-sty.mkvi @@ -409,4 +409,25 @@ \let\dostopattributes\endgroup +%D New but it needs to be supported explicitly (as in natural tables). + +\newconditional\c_font_styles_math + +\unexpanded\def\font_styles_math_reset + {\setfalse\c_font_styles_math} + +\unexpanded\def\font_styles_math_start + {\ifconditional\c_font_styles_math + \startimath + \fi + \relax} + +\unexpanded\def\font_styles_math_stop + {\relax + \ifconditional\c_font_styles_math + \stopimath + \fi} + +\definealternativestyle[\v!math][\settrue\c_font_styles_math] + \protect \endinput diff --git a/tex/context/base/mkiv/font-sym.mkvi b/tex/context/base/mkiv/font-sym.mkvi index c1ffd6361..0e709f161 100644 --- a/tex/context/base/mkiv/font-sym.mkvi +++ b/tex/context/base/mkiv/font-sym.mkvi @@ -173,6 +173,8 @@ \unexpanded\def\getnamedglyphdirect#fontname#character{{\setdirectsymbolicfont{#fontname}\clf_fontchar{#character}}} \unexpanded\def\getglyphstyled #fontname#character{{\setstyledsymbolicfont{#fontname}\doifelsenumber{#character}\char\donothing#character}} \unexpanded\def\getglyphdirect #fontname#character{{\setdirectsymbolicfont{#fontname}\doifelsenumber{#character}\char\donothing#character}} +\unexpanded\def\resolvedglyphstyled#fontname#character{{\setstyledsymbolicfont{#fontname}\clf_tochar{#character}}} +\unexpanded\def\resolvedglyphdirect#fontname#character{{\setdirectsymbolicfont{#fontname}\clf_tochar{#character}}} % this one is wrong: diff --git a/tex/context/base/mkiv/font-syn.lua b/tex/context/base/mkiv/font-syn.lua index 435aa1ddc..c4dcf0bcd 100644 --- a/tex/context/base/mkiv/font-syn.lua +++ b/tex/context/base/mkiv/font-syn.lua @@ -16,7 +16,7 @@ if not modules then modules = { } end modules ['font-syn'] = { local next, tonumber, type, tostring = next, tonumber, type, tostring local sub, gsub, match, find, lower, upper = string.sub, string.gsub, string.match, string.find, string.lower, string.upper -local concat, sort = table.concat, table.sort +local concat, sort, fastcopy = table.concat, table.sort, table.fastcopy local serialize, sortedhash = table.serialize, table.sortedhash local lpegmatch = lpeg.match local unpack = unpack or table.unpack @@ -128,8 +128,8 @@ local weights = Cs ( -- not extra + P("ultralight") + P("extralight") + P("bold") - + P("demi") - + P("semi") + + P("demi") -- / "semibold" + + P("semi") -- / "semibold" + P("light") + P("medium") + P("heavy") @@ -140,15 +140,16 @@ local weights = Cs ( -- not extra + P("regular") / "normal" ) --- numeric_weights = { --- 200 = "extralight", --- 300 = "light", --- 400 = "book", --- 500 = "medium", --- 600 = "demi", --- 700 = "bold", --- 800 = "heavy", --- 900 = "black", +-- local weights = { +-- [100] = "thin", +-- [200] = "extralight", +-- [300] = "light", +-- [400] = "normal", +-- [500] = "medium", +-- [600] = "semibold", -- demi demibold +-- [700] = "bold", +-- [800] = "extrabold", +-- [900] = "black", -- } local normalized_weights = sparse { @@ -517,9 +518,11 @@ local function cleanfilename(fullname,defaultsuffix) end local sorter = function(a,b) - return a > b -- to be checked + return a > b -- longest first end +-- local sorter = nil + names.cleanname = cleanname names.cleanfilename = cleanfilename @@ -567,6 +570,7 @@ local function check_name(data,result,filename,modification,suffix,subfont) -- local compatiblename = result.compatiblename -- local cfffullname = result.cfffullname local weight = result.weight + local width = result.width local italicangle = tonumber(result.italicangle) local subfont = subfont local rawname = fullname or fontname or familyname @@ -582,11 +586,12 @@ local function check_name(data,result,filename,modification,suffix,subfont) -- compatiblename = compatiblename and cleanname(compatiblename) -- cfffullname = cfffullname and cleanname(cfffullname) weight = weight and cleanname(weight) + width = width and cleanname(width) italicangle = italicangle == 0 and nil -- analyze local a_name, a_weight, a_style, a_width, a_variant = analyzespec(fullname or fontname or familyname) -- check - local width = a_width + local width = width or a_width local variant = a_variant local style = subfamilyname or subfamily -- can re really trust subfamilyname? if style then @@ -618,7 +623,9 @@ local function check_name(data,result,filename,modification,suffix,subfont) local pfmwidth = result.pfmwidth or 0 local pfmweight = result.pfmweight or 0 -- - specifications[#specifications + 1] = { + local instancenames = result.instancenames + -- + specifications[#specifications+1] = { filename = filename, -- unresolved cleanfilename = cleanfilename, -- subfontindex = subfont, @@ -645,6 +652,7 @@ local function check_name(data,result,filename,modification,suffix,subfont) maxsize = maxsize ~= 0 and maxsize or nil, designsize = designsize ~= 0 and designsize or nil, modification = modification ~= 0 and modification or nil, + instancenames = instancenames or nil, } end @@ -796,11 +804,13 @@ local function collecthashes() local noffallbacks = 0 if specifications then -- maybe multiple passes (for the compatible and cffnames so that they have less preference) + local conflicts = setmetatableindex("table") for index=1,#specifications do local specification = specifications[index] local format = specification.format local fullname = specification.fullname local fontname = specification.fontname + -- local rawname = specification.rawname -- local compatiblename = specification.compatiblename -- local cfffullname = specification.cfffullname local familyname = specification.familyname or specification.family @@ -809,6 +819,7 @@ local function collecthashes() local weight = specification.weight local mapping = mappings[format] local fallback = fallbacks[format] + local instancenames = specification.instancenames if fullname and not mapping[fullname] then mapping[fullname] = index nofmappings = nofmappings + 1 @@ -817,6 +828,13 @@ local function collecthashes() mapping[fontname] = index nofmappings = nofmappings + 1 end + if instancenames then + for i=1,#instancenames do + local instance = fullname .. instancenames[i] + mapping[instance] = index + nofmappings = nofmappings + 1 + end + end -- if compatiblename and not mapping[compatiblename] then -- mapping[compatiblename] = index -- nofmappings = nofmappings + 1 @@ -847,10 +865,22 @@ local function collecthashes() noffallbacks = noffallbacks + 1 end end + -- dangerous ... first match takes slot if not mapping[familyname] and not fallback[familyname] then fallback[familyname] = index noffallbacks = noffallbacks + 1 end + local conflict = conflicts[format] + conflict[familyname] = (conflict[familyname] or 0) + 1 + end + end + for format, conflict in next, conflicts do + local fallback = fallbacks[format] + for familyname, n in next, conflict do + if n > 1 then + fallback[familyname] = nil + noffallbacks = noffallbacks - n + end end end end @@ -890,7 +920,6 @@ local function checkduplicate(where) -- fails on "Romantik" but that's a border local ok = true local fn = s.filename for i=1,#h do - local hn = s.filename if h[i] == fn then ok = false break @@ -939,8 +968,9 @@ local function sorthashes() sort(sorted_mappings [l],sorter) sort(sorted_fallbacks[l],sorter) end - data.sorted_families = table.keys(data.families) - sort(data.sorted_families,sorter) + local sorted_families = table.keys(data.families) + data.sorted_families = sorted_families + sort(sorted_families,sorter) end local function unpackreferences() @@ -1076,16 +1106,10 @@ local function analyzefiles(olddata) if result then if #result > 0 then for r=1,#result do - local ok = check_name(data,result[r],storedname,modification,suffix,r) -- subfonts start at zero - -- if not ok then - -- nofskipped = nofskipped + 1 - -- end + check_name(data,result[r],storedname,modification,suffix,r) -- subfonts start at zero end else - local ok = check_name(data,result,storedname,modification,suffix) - -- if not ok then - -- nofskipped = nofskipped + 1 - -- end + check_name(data,result,storedname,modification,suffix) end if trace_warnings and message and message ~= "" then report_names("warning when identifying %s font %a, %s",suffix,completename,message) @@ -1366,6 +1390,23 @@ end -- we could cache a lookup .. maybe some day ... (only when auto loaded!) +local function checkinstance(found,askedname) + local instancenames = found.instancenames + if instancenames then + local fullname = found.fullname + for i=1,#instancenames do + local instancename = instancenames[i] + if fullname .. instancename == askedname then + local f = fastcopy(found) + f.instances = nil + f.instance = instancename + return f + end + end + end + return found +end + local function foundname(name,sub) -- sub is not used currently local data = names.data local mappings = data.mappings @@ -1383,7 +1424,7 @@ local function foundname(name,sub) -- sub is not used currently if trace_names then report_names("resolved via direct name match: %a",name) end - return found + return checkinstance(found,name) end end for i=1,#list do @@ -1393,7 +1434,7 @@ local function foundname(name,sub) -- sub is not used currently if trace_names then report_names("resolved via fuzzy name match: %a onto %a",name,fname) end - return found + return checkinstance(found,name) end end for i=1,#list do @@ -1403,7 +1444,7 @@ local function foundname(name,sub) -- sub is not used currently if trace_names then report_names("resolved via direct fallback match: %a",name) end - return found + return checkinstance(found,name) end end for i=1,#list do @@ -1413,7 +1454,7 @@ local function foundname(name,sub) -- sub is not used currently if trace_names then report_names("resolved via fuzzy fallback match: %a onto %a",name,fname) end - return found + return checkinstance(found,name) end end if trace_names then @@ -1436,7 +1477,7 @@ end function names.resolve(askedname,sub) local found = names.resolvedspecification(askedname,sub) if found then - return found.filename, found.subfont and found.rawname, found.subfont + return found.filename, found.subfont and found.rawname, found.subfont, found.instance end end diff --git a/tex/context/base/mkiv/font-tfm.lua b/tex/context/base/mkiv/font-tfm.lua index 8e92c4808..6584190ce 100644 --- a/tex/context/base/mkiv/font-tfm.lua +++ b/tex/context/base/mkiv/font-tfm.lua @@ -6,8 +6,9 @@ if not modules then modules = { } end modules ['font-tfm'] = { license = "see context related readme files" } -local next = next -local match = string.match +local next, type = next, type +local match, format = string.match, string.format +local concat, sortedhash = table.concat, table.sortedhash local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) local trace_features = false trackers.register("tfm.features", function(v) trace_features = v end) @@ -16,6 +17,7 @@ local report_defining = logs.reporter("fonts","defining") local report_tfm = logs.reporter("fonts","tfm loading") local findbinfile = resolvers.findbinfile +local setmetatableindex = table.setmetatableindex local fonts = fonts local handlers = fonts.handlers @@ -23,14 +25,20 @@ local readers = fonts.readers local constructors = fonts.constructors local encodings = fonts.encodings -local tfm = constructors.newhandler("tfm") +local tfm = constructors.handlers.tfm tfm.version = 1.000 tfm.maxnestingdepth = 5 tfm.maxnestingsize = 65536*1024 -local tfmfeatures = constructors.newfeatures("tfm") +local otf = fonts.handlers.otf +local otfenhancers = otf.enhancers + +local tfmfeatures = constructors.features.tfm local registertfmfeature = tfmfeatures.register +local tfmenhancers = constructors.enhancers.tfm +local registertfmenhancer = tfmenhancers.register + constructors.resolvevirtualtoo = false -- wil be set in font-ctx.lua fonts.formats.tfm = "type1" -- we need to have at least a value here @@ -71,6 +79,42 @@ end local depth = { } -- table.setmetatableindex("number") +-- Normally we just load the tfm data and go on. However there was some demand for +-- loading good old tfm /pfb files where afm files were lacking and even enc files +-- of dubious quality so we now support loading such (often messy) setups too. +-- +-- Because such fonts also use (ugly) tweaks achieve some purpose (like swapping +-- accents) we need to delay the unicoding actions till after the features have been +-- applied. +-- +-- It must be noted that in ConTeXt we don't expect this to be used at all. Here is +-- example: +-- +-- tfm metrics + pfb vector for index + pfb file for shapes +-- +-- \font\foo=file:csr10.tfm:reencode=auto;mode=node;liga=yes;kern=yes +-- +-- tfm metrics + pfb vector for index + enc file for tfm mapping + pfb file for shapes +-- +-- \font\foo=file:csr10.tfm:reencode=csr.enc;mode=node;liga=yes;kern=yes +-- +-- tfm metrics + enc file for mapping to tfm + bitmaps shapes +-- +-- \font\foo=file:csr10.tfm:reencode=csr.enc;bitmap=yes;mode=node;liga=yes;kern=yes +-- +-- One can add features: +-- +-- fonts.handlers.otf.addfeature { +-- name = "czechdqcheat", +-- type = "substitution", +-- data = { +-- quotedblright = "csquotedblright", +-- }, +-- } +-- +-- So "czechdqcheat=yes" is then a valid feature. And yes, it's a cheat. + + local function read_from_tfm(specification) local filename = specification.filename local size = specification.size @@ -80,26 +124,116 @@ local function read_from_tfm(specification) end local tfmdata = font.read_tfm(filename,size) -- not cached, fast enough if tfmdata then - local features = specification.features and specification.features.normal or { } + + local features = specification.features and specification.features.normal or { } + local features = constructors.checkedfeatures("tfm",features) + specification.features.normal = features + + -- If reencode returns a new table, we assume that we're doing something + -- special. An 'auto' reencode pickt up its vector from the pfb file. + + local newtfmdata = (depth[filename] == 1) and tfm.reencode(tfmdata,specification) + if newtfmdata then + tfmdata = newtfmdata + end + local resources = tfmdata.resources or { } local properties = tfmdata.properties or { } local parameters = tfmdata.parameters or { } local shared = tfmdata.shared or { } - properties.name = tfmdata.name - properties.fontname = tfmdata.fontname - properties.psname = tfmdata.psname - properties.filename = specification.filename - properties.format = fonts.formats.tfm -- better than nothing - parameters.size = size + -- + shared.features = features + shared.resources = resources + -- + properties.name = tfmdata.name -- todo: fallback + properties.fontname = tfmdata.fontname -- todo: fallback + properties.psname = tfmdata.psname -- todo: fallback + properties.fullname = tfmdata.fullname -- todo: fallback + properties.filename = specification.filename -- todo: fallback + properties.format = fonts.formats.tfm -- better than nothing -- tfmdata.properties = properties tfmdata.resources = resources tfmdata.parameters = parameters tfmdata.shared = shared -- - shared.rawdata = { } + shared.rawdata = { resources = resources } shared.features = features + -- + -- The next branch is only entered when we have a proper encoded file i.e. + -- unicodes and such. It really nakes no sense to do feature juggling when + -- we have no names and unicodes. + -- + if newtfmdata then + -- + -- Some opentype processing assumes these to be present: + -- + if not resources.marks then + resources.marks = { } + end + if not resources.sequences then + resources.sequences = { } + end + if not resources.features then + resources.features = { + gsub = { }, + gpos = { }, + } + end + if not tfmdata.changed then + tfmdata.changed = { } + end + if not tfmdata.descriptions then + tfmdata.descriptions = tfmdata.characters + end + -- + -- It might be handy to have this: + -- + otf.readers.addunicodetable(tfmdata) + -- + -- We make a pseudo opentype font, e.g. kerns and ligatures etc: + -- + tfmenhancers.apply(tfmdata,filename) + -- + -- Now user stuff can kick in. + -- + constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm) + -- + -- As that can also mess with names and such, we are now ready for finalizing + -- the unicode information. This is a different order that for instance type one + -- (afm) files. First we try to deduce unicodes from already present information. + -- + otf.readers.unifymissing(tfmdata) + -- + -- Next we fill in the gaps, based on names from teh agl. Probably not much will + -- happen here. + -- + fonts.mappings.addtounicode(tfmdata,filename) + -- + -- The tounicode data is passed to the backend that constructs the vectors for us. + -- + tfmdata.tounicode = 1 + local tounicode = fonts.mappings.tounicode + for unicode, v in next, tfmdata.characters do + local u = v.unicode + if u then + v.tounicode = tounicode(u) + end + end + -- + -- However, when we use a bitmap font those vectors can't be constructed because + -- that information is not carried with those fonts (there is no name info, nor + -- proper index info, nor unicodes at that end). So, we provide it ourselves. + -- + if tfmdata.usedbitmap then + tfm.addtounicode(tfmdata) + end + end + -- shared.processes = next(features) and tfm.setfeatures(tfmdata,features) or nil + -- + parameters.factor = 1 -- already scaled + parameters.size = size parameters.slant = parameters.slant or parameters[1] or 0 parameters.space = parameters.space or parameters[2] or 0 parameters.space_stretch = parameters.space_stretch or parameters[3] or 0 @@ -110,7 +244,12 @@ local function read_from_tfm(specification) -- constructors.enhanceparameters(parameters) -- official copies for us -- - if constructors.resolvevirtualtoo then + if newtfmdata then + -- + -- We do nothing as we assume flat tfm files. It would become real messy + -- otherwise and I don't have something for testing on my system anyway. + -- + elseif constructors.resolvevirtualtoo then fonts.loggers.register(tfmdata,file.suffix(filename),specification) -- strange, why here local vfname = findbinfile(specification.name, 'ovf') if vfname and vfname ~= "" then @@ -145,21 +284,26 @@ local function read_from_tfm(specification) end end -- - local allfeatures = tfmdata.shared.features or specification.features.normal - constructors.applymanipulators("tfm",tfmdata,allfeatures.normal,trace_features,report_tfm) - if not features.encoding then - local encoding, filename = match(properties.filename,"^(.-)%-(.*)$") -- context: encoding-name.* - if filename and encoding and encodings.known and encodings.known[encoding] then - features.encoding = encoding - end - end - -- let's play safe: + -- This is for old times sake (and context specific) so we comment it. It has + -- to do with encoding prefixes (a context naming that was later adopted by + -- the lm/gyre project) + -- + -- if not features.encoding then + -- local encoding, filename = match(properties.filename,"^(.-)%-(.*)$") + -- if filename and encoding and encodings.known and encodings.known[encoding] then + -- features.encoding = encoding + -- end + -- end + -- + -- Some afterthoughts: + -- properties.haskerns = true properties.hasligatures = true resources.unicodes = { } resources.lookuptags = { } -- depth[filename] = depth[filename] - 1 + -- return tfmdata else depth[filename] = depth[filename] - 1 @@ -199,3 +343,369 @@ function readers.tfm(specification) end readers.ofm = readers.tfm + +-- The reencoding acts upon the 'reencode' feature which can have values 'auto' or +-- an enc file. You can also specify a 'pfbfile' feature (but it defaults to the +-- tfm filename) and a 'bitmap' feature. When no enc file is givven (auto) we will +-- get the vectors from the pfb file. + +do + + local outfiles = { } + + local tfmcache = table.setmetatableindex(function(t,tfmdata) + local id = font.define(tfmdata) + t[tfmdata] = id + return id + end) + + local encdone = table.setmetatableindex("table") + + function tfm.reencode(tfmdata,specification) + + local features = specification.features + + if not features then + return + end + + local features = features.normal + + if not features then + return + end + + local tfmfile = file.basename(tfmdata.name) + local encfile = features.reencode -- or features.enc + local pfbfile = features.pfbfile -- or features.pfb + local bitmap = features.bitmap -- or features.pk + + if not encfile then + return + end + + local pfbfile = outfiles[tfmfile] + + if pfbfile == nil then + if bitmap then + pfbfile = false + elseif type(pfbfile) ~= "string" then + pfbfile = tfmfile + end + if type(pfbfile) == "string" then + pfbfile = file.addsuffix(pfbfile,"pfb") + -- pdf.mapline(tfmfile .. "<" .. pfbfile) + report_tfm("using type1 shapes from %a for %a",pfbfile,tfmfile) + else + report_tfm("using bitmap shapes for %a",tfmfile) + pfbfile = false -- use bitmap + end + outfiles[tfmfile] = pfbfile + end + + local encoding = false + local vector = false + + if type(pfbfile) == "string" then + local pfb = fonts.constructors.handlers.pfb + if pfb and pfb.loadvector then + local v, e = pfb.loadvector(pfbfile) + if v then + vector = v + end + if e then + encoding = e + end + end + end + if type(encfile) == "string" and encfile ~= "auto" then + encoding = fonts.encodings.load(file.addsuffix(encfile,"enc")) + if encoding then + encoding = encoding.vector + end + end + if not encoding then + report_tfm("bad encoding for %a, quitting",tfmfile) + return + end + + local unicoding = fonts.encodings.agl and fonts.encodings.agl.unicodes + local virtualid = tfmcache[tfmdata] + local tfmdata = table.copy(tfmdata) -- good enough for small fonts + local characters = { } + local originals = tfmdata.characters + local indices = { } + local parentfont = { "font", 1 } + local private = fonts.constructors.privateoffset + local reported = encdone[tfmfile][encfile] + + -- create characters table + + local backmap = vector and table.swapped(vector) + local done = { } -- prevent duplicate + + for index, name in sortedhash(encoding) do -- predictable order + local unicode = unicoding[name] + local original = originals[index] + if original then + if unicode then + original.unicode = unicode + else + unicode = private + private = private + 1 + if not reported then + report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode) + end + end + characters[unicode] = original + indices[index] = unicode + original.name = name -- so one can lookup weird names + if backmap then + original.index = backmap[name] + else -- probably bitmap + original.commands = { parentfont, { "char", index } } + original.oindex = index + end + done[name] = true + elseif not done[name] then + report_tfm("bad index %a in font %a with name %a",index,tfmfile,name) + end + end + + encdone[tfmfile][encfile] = true + + -- redo kerns and ligatures + + for k, v in next, characters do + local kerns = v.kerns + if kerns then + local t = { } + for k, v in next, kerns do + local i = indices[k] + if i then + t[i] = v + end + end + v.kerns = next(t) and t or nil + end + local ligatures = v.ligatures + if ligatures then + local t = { } + for k, v in next, ligatures do + local i = indices[k] + if i then + t[i] = v + v.char = indices[v.char] + end + end + v.ligatures = next(t) and t or nil + end + end + + -- wrap up + + tfmdata.fonts = { { id = virtualid } } + tfmdata.characters = characters + tfmdata.fullname = tfmdata.fullname or tfmdata.name + tfmdata.psname = file.nameonly(pfbfile or tfmdata.name) + tfmdata.filename = pfbfile + tfmdata.encodingbytes = 2 + tfmdata.format = "type1" + tfmdata.tounicode = 1 + tfmdata.embedding = "subset" + tfmdata.usedbitmap = bitmap and virtualid + + return tfmdata + end + +end + +-- This code adds a ToUnicode vector for bitmap fonts. We don't bother about +-- ranges because we have small fonts. it works ok with acrobat but fails with +-- the other viewers (they get confused by the bitmaps I guess). + +do + + local template = [[ +/CIDInit /ProcSet findresource begin + 12 dict begin + begincmap + /CIDSystemInfo << /Registry (TeX) /Ordering (bitmap-%s) /Supplement 0 >> def + /CMapName /TeX-bitmap-%s def + /CMapType 2 def + 1 begincodespacerange + <00> <FF> + endcodespacerange + %s beginbfchar +%s + endbfchar + endcmap +CMapName currentdict /CMap defineresource pop end +end +end +]] + + local flushstreamobject = lpdf and lpdf.flushstreamobject + local setfontattributes = pdf.setfontattributes + + if not flushstreamobject then + flushstreamobject = function(data) + return pdf.obj { + immediate = true, + type = "stream", + string = data, + } + end + end + + if not setfontattributes then + setfontattributes = function(id,data) + print(format("your luatex is too old so no tounicode bitmap font%i",id)) + end + end + + function tfm.addtounicode(tfmdata) + local id = tfmdata.usedbitmap + local map = { } + local char = { } -- no need for range, hardly used + for k, v in next, tfmdata.characters do + local index = v.oindex + local tounicode = v.tounicode + if index and tounicode then + map[index] = tounicode + end + end + for k, v in sortedhash(map) do + char[#char+1] = format("<%02X> <%s>",k,v) + end + char = concat(char,"\n") + local stream = format(template,id,id,#char,char) + local reference = flushstreamobject(stream,nil,true) + setfontattributes(id,format("/ToUnicode %i 0 R",reference)) + end + +end + +-- Now we implement the regular features handlers. We need to convert the +-- tfm specific structures to opentype structures. In basemode they are +-- converted back so that is a bti of a waste but it's fast enough. + +do + + local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } } + local noflags = { false, false, false, false } + + local function enhance_normalize_features(data) + local ligatures = setmetatableindex("table") + local kerns = setmetatableindex("table") + local characters = data.characters + for u, c in next, characters do + local l = c.ligatures + local k = c.kerns + if l then + ligatures[u] = l + for u, v in next, l do + l[u] = { ligature = v.char } + end + c.ligatures = nil + end + if k then + kerns[u] = k + for u, v in next, k do + k[u] = v -- { v, 0 } + end + c.kerns = nil + end + end + + for u, l in next, ligatures do + for k, v in next, l do + local vl = v.ligature + local dl = ligatures[vl] + if dl then + for kk, vv in next, dl do + v[kk] = vv -- table.copy(vv) + end + end + end + end + + local features = { + gpos = { }, + gsub = { }, + } + local sequences = { + -- only filled ones + } + if next(ligatures) then + features.gsub.liga = everywhere + data.properties.hasligatures = true + sequences[#sequences+1] = { + features = { + liga = everywhere, + }, + flags = noflags, + name = "s_s_0", + nofsteps = 1, + order = { "liga" }, + type = "gsub_ligature", + steps = { + { + coverage = ligatures, + }, + }, + } + end + if next(kerns) then + features.gpos.kern = everywhere + data.properties.haskerns = true + sequences[#sequences+1] = { + features = { + kern = everywhere, + }, + flags = noflags, + name = "p_s_0", + nofsteps = 1, + order = { "kern" }, + type = "gpos_pair", + steps = { + { + format = "kern", + coverage = kerns, + }, + }, + } + end + data.resources.features = features + data.resources.sequences = sequences + data.shared.resources = data.shared.resources or resources + end + + registertfmenhancer("normalize features", enhance_normalize_features) + registertfmenhancer("check extra features", otfenhancers.enhance) + +end + +-- As with type one (afm) loading, we just use the opentype ones: + +registertfmfeature { + name = "mode", + description = "mode", + initializers = { + base = otf.modeinitializer, + node = otf.modeinitializer, + } +} + +registertfmfeature { + name = "features", + description = "features", + default = true, + initializers = { + base = otf.basemodeinitializer, + node = otf.nodemodeinitializer, + }, + processors = { + node = otf.featuresprocessor, + } +} diff --git a/tex/context/base/mkiv/font-tra.mkiv b/tex/context/base/mkiv/font-tra.mkiv index f5290d614..38b172ba6 100644 --- a/tex/context/base/mkiv/font-tra.mkiv +++ b/tex/context/base/mkiv/font-tra.mkiv @@ -287,4 +287,16 @@ \stopotfsample \endgroup} +% new + +\unexpanded\def\savefont[#1]% not yet in i-*.xml + {\begingroup + \getdummyparameters[#1]% + \clf_savefont { + filename {\dummyparameter\c!file} + fontname {\dummyparameter\c!name} + method {\dummyparameter\c!method} + }% + \endgroup} + \protect \endinput diff --git a/tex/context/base/mkiv/font-ttf.lua b/tex/context/base/mkiv/font-ttf.lua index 6df339214..339764d4a 100644 --- a/tex/context/base/mkiv/font-ttf.lua +++ b/tex/context/base/mkiv/font-ttf.lua @@ -6,42 +6,83 @@ if not modules then modules = { } end modules ['font-ttf'] = { license = "see context related readme files" } +-- This version is different from previous in the sense that we no longer store +-- contours but keep points and contours (endpoints) separate for a while +-- because later on we need to apply deltas and that is easier on a list of +-- points. + +-- The code is a bit messy. I looked at the ff code but it's messy too. It has +-- to do with the fact that we need to look at points on the curve and control +-- points in between. This also means that we start at point 2 and have to look +-- at point 1 when we're at the end. We still use a ps like storage with the +-- operator last in an entry. It's typical code that evolves stepwise till a +-- point of no comprehension. + +-- For deltas we need a rather complex loop over points that can have holes and +-- be less than nofpoints and even can have duplicates and also the x and y value +-- lists can be shorter than etc. I need fonts in order to complete this simply +-- because I need to visualize in order to understand (what the standard tries +-- to explain). + +-- 0 point then none applied +-- 1 points then applied to all +-- otherwise inferred deltas using nearest +-- if no lower point then use highest referenced point +-- if no higher point then use lowest referenced point +-- factor = (target-left)/(right-left) +-- delta = (1-factor)*left + factor * right + local next, type, unpack = next, type, unpack -local bittest = bit32.btest -local sqrt = math.sqrt +local bittest, band, rshift = bit32.btest, bit32.band, bit32.rshift +local sqrt, round = math.sqrt, math.round +local char = string.char +local concat = table.concat + +local report = logs.reporter("otf reader","ttf") -local report = logs.reporter("otf reader","ttf") +local trace_deltas = false -local readers = fonts.handlers.otf.readers -local streamreader = readers.streamreader +local readers = fonts.handlers.otf.readers +local streamreader = readers.streamreader -local setposition = streamreader.setposition -local getposition = streamreader.getposition -local skipbytes = streamreader.skip -local readbyte = streamreader.readcardinal1 -- 8-bit unsigned integer -local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer -local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer -local readchar = streamreader.readinteger1 -- 8-bit signed integer -local readshort = streamreader.readinteger2 -- 16-bit signed integer -local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed number with the low 14 bits of fraction (2.14) (F2DOT14) +local setposition = streamreader.setposition +local getposition = streamreader.getposition +local skipbytes = streamreader.skip +local readbyte = streamreader.readcardinal1 -- 8-bit unsigned integer +local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer +local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer +local readchar = streamreader.readinteger1 -- 8-bit signed integer +local readshort = streamreader.readinteger2 -- 16-bit signed integer +local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed number with the low 14 bits of fraction (2.14) (F2DOT14) +local readinteger = streamreader.readinteger1 + +local helpers = readers.helpers +local gotodatatable = helpers.gotodatatable local function mergecomposites(glyphs,shapes) + -- todo : deltas + local function merge(index,shape,components) local contours = { } + local points = { } local nofcontours = 0 + local nofpoints = 0 + local offset = 0 + local deltas = shape.deltas for i=1,#components do local component = components[i] local subindex = component.index local subshape = shapes[subindex] local subcontours = subshape.contours + local subpoints = subshape.points if not subcontours then local subcomponents = subshape.components if subcomponents then - subcontours = merge(subindex,subshape,subcomponents) + subcontours, subpoints = merge(subindex,subshape,subcomponents) end end - if subcontours then + if subpoints then local matrix = component.matrix local xscale = matrix[1] local xrotate = matrix[2] @@ -49,36 +90,39 @@ local function mergecomposites(glyphs,shapes) local yscale = matrix[4] local xoffset = matrix[5] local yoffset = matrix[6] + for i=1,#subpoints do + local p = subpoints[i] + local x = p[1] + local y = p[2] + nofpoints = nofpoints + 1 + points[nofpoints] = { + xscale * x + xrotate * y + xoffset, + yscale * y + yrotate * x + yoffset, + p[3] + } + end for i=1,#subcontours do - local points = subcontours[i] - local result = { } - for i=1,#points do - local p = points[i] - local x = p[1] - local y = p[2] - result[i] = { - xscale * x + xrotate * y + xoffset, - yscale * y + yrotate * x + yoffset, - p[3] - } - end nofcontours = nofcontours + 1 - contours[nofcontours] = result + contours[nofcontours] = offset + subcontours[i] end + offset = offset + #subpoints else report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex) end end + shape.points = points -- todo : phantom points shape.contours = contours shape.components = nil - return contours + return contours, points end for index=1,#glyphs do - local shape = shapes[index] - local components = shape.components - if components then - merge(index,shape,components) + local shape = shapes[index] + if shape then + local components = shape.components + if components then + merge(index,shape,components) + end end end @@ -92,145 +136,561 @@ end -- begin of converter --- make paths: the ff code is quite complex but it looks like we need to deal --- with all kind of on curve border cases - local function curveto(m_x,m_y,l_x,l_y,r_x,r_y) -- todo: inline this - return { + return l_x + 2/3 *(m_x-l_x), l_y + 2/3 *(m_y-l_y), r_x + 2/3 *(m_x-r_x), r_y + 2/3 *(m_y-r_y), - r_x, r_y, "c" -- "curveto" - } + r_x, r_y, "c" end -- We could omit the operator which saves some 10%: -- --- #2=lineto #4=quadratic #6=cubic #3=moveto (with "m") +-- #2=lineto #4=quadratic #6=cubic #3=moveto (with "m") -- --- For the moment we keep the original outlines but that default might change --- in the future. In any case, a backend should support both. +-- This is tricky ... something to do with phantom points .. however, the hvar +-- and vvar tables should take care of the width .. the test font doesn't have +-- those so here we go then (we need a flag for hvar). -- --- The code is a bit messy. I looked at the ff code but it's messy too. It has --- to do with the fact that we need to look at points on the curve and control --- points in between. This also means that we start at point 2 and have to look at --- point 1 when we're at the end. We still use a ps like storage with the operator --- last in an entry. It's typical code that evolves stepwise till a point of no --- comprehension. - -local function contours2outlines(glyphs,shapes) - local quadratic = true - -- local quadratic = false +-- h-advance left-side-bearing v-advance top-side-bearing +-- +-- We had two loops (going backward) but can do it in one loop .. but maybe we +-- should only accept fonts with proper hvar tables. + +local function applyaxis(glyph,shape,deltas,dowidth) + local points = shape.points + if points then + local nofpoints = #points + local h = nofpoints + 2 -- weird, the example font seems to have left first + local l = nofpoints + 1 + ----- v = nofpoints + 3 + ----- t = nofpoints + 4 + local dw = 0 + local dl = 0 + for i=1,#deltas do + local deltaset = deltas[i] + local xvalues = deltaset.xvalues + local yvalues = deltaset.yvalues + local dpoints = deltaset.points + local factor = deltaset.factor + if dpoints then + -- todo: interpolate + local nofdpoints = #dpoints + for i=1,nofdpoints do + local d = dpoints[i] + local p = points[d] + if p then + if xvalues then + local x = xvalues[i] + if x and x ~= 0 then + p[1] = p[1] + factor * x + end + end + if yvalues then + local y = yvalues[i] + if y and y ~= 0 then + p[2] = p[2] + factor * y + end + end + elseif dowidth then + -- we've now ran into phantom points which is a bit fuzzy because: + -- are there gaps in there? + -- + -- todo: move this outside the loop (when we can be sure of all 4 being there) + if d == h then + -- we have a phantom point hadvance + local x = xvalues[i] + if x then + dw = dw + factor * x + end + elseif d == l then + local x = xvalues[i] + if x then + dl = dl + factor * x + end + end + end + end + else + for i=1,nofpoints do + local p = points[i] + if xvalues then + local x = xvalues[i] + if x and x ~= 0 then + p[1] = p[1] + factor * x + end + end + if yvalues then + local y = yvalues[i] + if y and y ~= 0 then + p[2] = p[2] + factor * y + end + end + end + if dowidth then + local x = xvalues[h] + if x then + dw = dw + factor * x + end + local x = xvalues[l] + if x then + dl = dl + factor * x + end + end + end + end + -- for i=1,nofpoints do + -- local p = points[i] + -- p[1] = round(p[1]) + -- p[2] = round(p[2]) + -- end + if dowidth then + local width = glyph.width or 0 + -- local lsb = glyph.lsb or 0 + glyph.width = width + dw - dl + end + else + report("no points for glyph %a",glyph.name) + end +end + +-- round or not ? + +-- local quadratic = true -- both methods work, todo: install a directive +local quadratic = false + +local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox overhead for index=1,#glyphs do - local glyph = glyphs[index] - local shape = shapes[index] - local contours = shape.contours - if contours then - local nofcontours = #contours - local segments = { } - local nofsegments = 0 - glyph.segments = segments - if nofcontours > 0 then - for i=1,nofcontours do - local contour = contours[i] - local nofcontour = #contour - if nofcontour > 0 then - local first_pt = contour[1] - local first_on = first_pt[3] - -- todo no new tables but reuse lineto and quadratic - if nofcontour == 1 then - -- this can influence the boundingbox - first_pt[3] = "m" -- "moveto" - nofsegments = nofsegments + 1 - segments[nofsegments] = first_pt - else -- maybe also treat n == 2 special - local first_on = first_pt[3] - local last_pt = contour[nofcontour] - local last_on = last_pt[3] - local start = 1 - local control_pt = false - if first_on then - start = 2 - else - if last_on then - first_pt = last_pt + local shape = shapes[index] + if shape then + local glyph = glyphs[index] + local contours = shape.contours + local points = shape.points + if contours then + local nofcontours = #contours + local segments = { } + local nofsegments = 0 + glyph.segments = segments + if nofcontours > 0 then + local px, py = 0, 0 -- we could use these in calculations which saves a copy + local first = 1 + for i=1,nofcontours do + local last = contours[i] + if last >= first then + local first_pt = points[first] + local first_on = first_pt[3] + -- todo no new tables but reuse lineto and quadratic + if first == last then + first_pt[3] = "m" -- "moveto" + nofsegments = nofsegments + 1 + segments[nofsegments] = first_pt + else -- maybe also treat n == 2 special + local first_on = first_pt[3] + local last_pt = points[last] + local last_on = last_pt[3] + local start = 1 + local control_pt = false + if first_on then + start = 2 else - first_pt = { (first_pt[1]+last_pt[1])/2, (first_pt[2]+last_pt[2])/2, false } + if last_on then + first_pt = last_pt + else + first_pt = { (first_pt[1]+last_pt[1])/2, (first_pt[2]+last_pt[2])/2, false } + end + control_pt = first_pt end - control_pt = first_pt - end - nofsegments = nofsegments + 1 - segments[nofsegments] = { first_pt[1], first_pt[2], "m" } -- "moveto" - local previous_pt = first_pt - for i=start,nofcontour do - local current_pt = contour[i] - local current_on = current_pt[3] - local previous_on = previous_pt[3] - if previous_on then - if current_on then - -- both normal points + local x, y = first_pt[1], first_pt[2] + if not done then + xmin, ymin, xmax, ymax = x, y, x, y + done = true + end + nofsegments = nofsegments + 1 + segments[nofsegments] = { x, y, "m" } -- "moveto" + if not quadratic then + px, py = x, y + end + local previous_pt = first_pt + for i=first,last do + local current_pt = points[i] + local current_on = current_pt[3] + local previous_on = previous_pt[3] + if previous_on then + if current_on then + -- both normal points + local x, y = current_pt[1], current_pt[2] + nofsegments = nofsegments + 1 + segments[nofsegments] = { x, y, "l" } -- "lineto" + if not quadratic then + px, py = x, y + end + else + control_pt = current_pt + end + elseif current_on then + local x1, y1 = control_pt[1], control_pt[2] + local x2, y2 = current_pt[1], current_pt[2] nofsegments = nofsegments + 1 - segments[nofsegments] = { current_pt[1], current_pt[2], "l" } -- "lineto" + if quadratic then + segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto" + else + x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2) + segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto" + end + control_pt = false else + local x2, y2 = (previous_pt[1]+current_pt[1])/2, (previous_pt[2]+current_pt[2])/2 + local x1, y1 = control_pt[1], control_pt[2] + nofsegments = nofsegments + 1 + if quadratic then + segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto" + else + x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2) + segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto" + end control_pt = current_pt end - elseif current_on then - local ps = segments[nofsegments] + previous_pt = current_pt + end + if first_pt == last_pt then + -- we're already done, probably a simple curve + else nofsegments = nofsegments + 1 - if quadratic then - segments[nofsegments] = { control_pt[1], control_pt[2], current_pt[1], current_pt[2], "q" } -- "quadraticto" + local x2, y2 = first_pt[1], first_pt[2] + if not control_pt then + segments[nofsegments] = { x2, y2, "l" } -- "lineto" + elseif quadratic then + local x1, y1 = control_pt[1], control_pt[2] + segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto" else - local p = segments[nofsegments-1] local n = #p - segments[nofsegments] = curveto(control_pt[1],control_pt[2],p[n-2],p[n-1],current_pt[1],current_pt[2]) + local x1, y1 = control_pt[1], control_pt[2] + x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2) + segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto" + -- px, py = x2, y2 end - control_pt = false + end + end + end + first = last + 1 + end + end + end + end + end +end + +local function contours2outlines_shaped(glyphs,shapes,keepcurve) + for index=1,#glyphs do + local shape = shapes[index] + if shape then + local glyph = glyphs[index] + local contours = shape.contours + local points = shape.points + if contours then + local nofcontours = #contours + local segments = keepcurve and { } or nil + local nofsegments = 0 + if keepcurve then + glyph.segments = segments + end + if nofcontours > 0 then + local xmin, ymin, xmax, ymax, done = 0, 0, 0, 0, false + local px, py = 0, 0 -- we could use these in calculations which saves a copy + local first = 1 + for i=1,nofcontours do + local last = contours[i] + if last >= first then + local first_pt = points[first] + local first_on = first_pt[3] + -- todo no new tables but reuse lineto and quadratic + if first == last then + -- this can influence the boundingbox + if keepcurve then + first_pt[3] = "m" -- "moveto" + nofsegments = nofsegments + 1 + segments[nofsegments] = first_pt + end + else -- maybe also treat n == 2 special + local first_on = first_pt[3] + local last_pt = points[last] + local last_on = last_pt[3] + local start = 1 + local control_pt = false + if first_on then + start = 2 else + if last_on then + first_pt = last_pt + else + first_pt = { (first_pt[1]+last_pt[1])/2, (first_pt[2]+last_pt[2])/2, false } + end + control_pt = first_pt + end + local x, y = first_pt[1], first_pt[2] + if not done then + xmin, ymin, xmax, ymax = x, y, x, y + done = true + else + if x < xmin then xmin = x elseif x > xmax then xmax = x end + if y < ymin then ymin = y elseif y > ymax then ymax = y end + end + if keepcurve then nofsegments = nofsegments + 1 - local halfway_x = (previous_pt[1]+current_pt[1])/2 - local halfway_y = (previous_pt[2]+current_pt[2])/2 + segments[nofsegments] = { x, y, "m" } -- "moveto" + end + if not quadratic then + px, py = x, y + end + local previous_pt = first_pt + for i=first,last do + local current_pt = points[i] + local current_on = current_pt[3] + local previous_on = previous_pt[3] + if previous_on then + if current_on then + -- both normal points + local x, y = current_pt[1], current_pt[2] + if x < xmin then xmin = x elseif x > xmax then xmax = x end + if y < ymin then ymin = y elseif y > ymax then ymax = y end + if keepcurve then + nofsegments = nofsegments + 1 + segments[nofsegments] = { x, y, "l" } -- "lineto" + end + if not quadratic then + px, py = x, y + end + else + control_pt = current_pt + end + elseif current_on then + local x1, y1 = control_pt[1], control_pt[2] + local x2, y2 = current_pt[1], current_pt[2] + if quadratic then + if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end + if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end + if keepcurve then + nofsegments = nofsegments + 1 + segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto" + end + else + x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2) + if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end + if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end + if x2 < xmin then xmin = x2 elseif x2 > xmax then xmax = x2 end + if y2 < ymin then ymin = y2 elseif y2 > ymax then ymax = y2 end + if px < xmin then xmin = px elseif px > xmax then xmax = px end + if py < ymin then ymin = py elseif py > ymax then ymax = py end + if keepcurve then + nofsegments = nofsegments + 1 + segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto" + end + end + control_pt = false + else + local x2, y2 = (previous_pt[1]+current_pt[1])/2, (previous_pt[2]+current_pt[2])/2 + local x1, y1 = control_pt[1], control_pt[2] + if quadratic then + if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end + if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end + if keepcurve then + nofsegments = nofsegments + 1 + segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto" + end + else + x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2) + if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end + if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end + if x2 < xmin then xmin = x2 elseif x2 > xmax then xmax = x2 end + if y2 < ymin then ymin = y2 elseif y2 > ymax then ymax = y2 end + if px < xmin then xmin = px elseif px > xmax then xmax = px end + if py < ymin then ymin = py elseif py > ymax then ymax = py end + if keepcurve then + nofsegments = nofsegments + 1 + segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto" + end + end + control_pt = current_pt + end + previous_pt = current_pt + end + if first_pt == last_pt then + -- we're already done, probably a simple curve + elseif not control_pt then + if keepcurve then + nofsegments = nofsegments + 1 + segments[nofsegments] = { first_pt[1], first_pt[2], "l" } -- "lineto" + end + else + local x1, y1 = control_pt[1], control_pt[2] + local x2, y2 = first_pt[1], first_pt[2] + if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end + if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end if quadratic then - segments[nofsegments] = { control_pt[1], control_pt[2], halfway_x, halfway_y, "q" } -- "quadraticto" + if keepcurve then + nofsegments = nofsegments + 1 + segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto" + end else - local p = segments[nofsegments-1] local n = #p - segments[nofsegments] = curveto(control_pt[1],control_pt[2],p[n-2],p[n-1],halfway_x,halfway_y) + x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2) + if x2 < xmin then xmin = x2 elseif x2 > xmax then xmax = x2 end + if y2 < ymin then ymin = y2 elseif y2 > ymax then ymax = y2 end + if px < xmin then xmin = px elseif px > xmax then xmax = px end + if py < ymin then ymin = py elseif py > ymax then ymax = py end + if keepcurve then + nofsegments = nofsegments + 1 + segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto" + end + -- px, py = x2, y2 end - control_pt = current_pt end - previous_pt = current_pt end - if first_pt == last_pt then - -- we're already done, probably a simple curve + end + first = last + 1 + end + glyph.boundingbox = { round(xmin), round(ymin), round(xmax), round(ymax) } + end + end + end + end +end + +-- optimize for zero + +local c_zero = char(0) +local s_zero = char(0,0) + +local function toushort(n) + return char(band(rshift(n,8),0xFF),band(n,0xFF)) +end + +local function toshort(n) + if n < 0 then + n = n + 0x10000 + end + return char(band(rshift(n,8),0xFF),band(n,0xFF)) +end + +-- todo: we can reuse result, xpoints and ypoints + +local function repackpoints(glyphs,shapes) + local noboundingbox = { 0, 0, 0, 0 } + local result = { } -- reused + for index=1,#glyphs do + local shape = shapes[index] + if shape then + local r = 0 + local glyph = glyphs[index] + if false then -- shape.type == "composite" + -- we merged them + else + local contours = shape.contours + local nofcontours = contours and #contours or 0 + local boundingbox = glyph.boundingbox or noboundingbox + r = r + 1 result[r] = toshort(nofcontours) + r = r + 1 result[r] = toshort(boundingbox[1]) -- xmin + r = r + 1 result[r] = toshort(boundingbox[2]) -- ymin + r = r + 1 result[r] = toshort(boundingbox[3]) -- xmax + r = r + 1 result[r] = toshort(boundingbox[4]) -- ymax + if nofcontours > 0 then + for i=1,nofcontours do + r = r + 1 result[r] = toshort(contours[i]-1) + end + r = r + 1 result[r] = s_zero -- no instructions + local points = shape.points + local currentx = 0 + local currenty = 0 + local xpoints = { } + local ypoints = { } + local x = 0 + local y = 0 + local lastflag = nil + local nofflags = 0 + for i=1,#points do + local pt = points[i] + local px = pt[1] + local py = pt[2] + local fl = pt[3] and 0x01 or 0x00 + if px == currentx then + fl = fl + 0x10 + else + local dx = round(px - currentx) + if dx < -255 or dx > 255 then + x = x + 1 xpoints[x] = toshort(dx) + elseif dx < 0 then + fl = fl + 0x02 + x = x + 1 xpoints[x] = char(-dx) + elseif dx > 0 then + fl = fl + 0x12 + x = x + 1 xpoints[x] = char(dx) else - nofsegments = nofsegments + 1 - if not control_pt then - segments[nofsegments] = { first_pt[1], first_pt[2], "l" } -- "lineto" - elseif quadratic then - segments[nofsegments] = { control_pt[1], control_pt[2], first_pt[1], first_pt[2], "q" } -- "quadraticto" - else - local p = last_pt local n = #p - segments[nofsegments] = curveto(control_pt[1],control_pt[2],p[n-2],p[n-1],first_pt[1],first_pt[2]) - end + fl = fl + 0x02 + x = x + 1 xpoints[x] = c_zero end end + if py == currenty then + fl = fl + 0x20 + else + local dy = round(py - currenty) + if dy < -255 or dy > 255 then + y = y + 1 ypoints[y] = toshort(dy) + elseif dy < 0 then + fl = fl + 0x04 + y = y + 1 ypoints[y] = char(-dy) + elseif dy > 0 then + fl = fl + 0x24 + y = y + 1 ypoints[y] = char(dy) + else + fl = fl + 0x04 + y = y + 1 ypoints[y] = c_zero + end + end + currentx = px + currenty = py + if lastflag == fl then + nofflags = nofflags + 1 + else -- if > 255 + if nofflags == 1 then + r = r + 1 result[r] = char(lastflag) + elseif nofflags == 2 then + r = r + 1 result[r] = char(lastflag,lastflag) + elseif nofflags > 2 then + lastflag = lastflag + 0x08 + r = r + 1 result[r] = char(lastflag,nofflags-1) + end + nofflags = 1 + lastflag = fl + end + end + if nofflags == 1 then + r = r + 1 result[r] = char(lastflag) + elseif nofflags == 2 then + r = r + 1 result[r] = char(lastflag,lastflag) + elseif nofflags > 2 then + lastflag = lastflag + 0x08 + r = r + 1 result[r] = char(lastflag,nofflags-1) end + r = r + 1 result[r] = concat(xpoints) + r = r + 1 result[r] = concat(ypoints) end end + glyph.stream = concat(result,"",1,r) + else + -- fatal end end end -- end of converter -local function readglyph(f,nofcontours) +local function readglyph(f,nofcontours) -- read deltas here, saves space local points = { } - local endpoints = { } + local contours = { } local instructions = { } local flags = { } for i=1,nofcontours do - endpoints[i] = readshort(f) + 1 + contours[i] = readshort(f) + 1 end - local nofpoints = endpoints[nofcontours] + local nofpoints = contours[nofcontours] local nofinstructions = readushort(f) --- f:seek("set",f:seek()+nofinstructions) skipbytes(f,nofinstructions) -- because flags can repeat we don't know the amount ... in fact this is -- not that efficient (small files but more mem) @@ -238,7 +698,7 @@ local function readglyph(f,nofcontours) while i <= nofpoints do local flag = readbyte(f) flags[i] = flag - if bittest(flag,0x0008) then + if bittest(flag,0x08) then for j=1,readbyte(f) do i = i + 1 flags[i] = flag @@ -251,8 +711,8 @@ local function readglyph(f,nofcontours) local x = 0 for i=1,nofpoints do local flag = flags[i] - local short = bittest(flag,0x0002) - local same = bittest(flag,0x0010) + local short = bittest(flag,0x02) + local same = bittest(flag,0x10) if short then if same then x = x + readbyte(f) @@ -264,13 +724,13 @@ local function readglyph(f,nofcontours) else x = x + readshort(f) end - points[i] = { x, y, bittest(flag,0x0001) } + points[i] = { x, 0, bittest(flag,0x01) } end local y = 0 for i=1,nofpoints do local flag = flags[i] - local short = bittest(flag,0x0004) - local same = bittest(flag,0x0020) + local short = bittest(flag,0x04) + local same = bittest(flag,0x20) if short then if same then y = y + readbyte(f) @@ -284,17 +744,11 @@ local function readglyph(f,nofcontours) end points[i][2] = y end - -- we could integrate this if needed - local first = 1 - for i=1,#endpoints do - local last = endpoints[i] - endpoints[i] = { unpack(points,first,last) } - first = last + 1 - end return { - type = "glyph", - -- points = points, - contours = endpoints, + type = "glyph", + points = points, + contours = contours, + nofpoints = nofpoints, } end @@ -384,8 +838,8 @@ local function readcomposite(f) end end return { - type = "composite", - components = components, + type = "composite", + components = components, } end @@ -407,15 +861,13 @@ function readers.loca(f,fontdata,specification) local locations = { } setposition(f,datatable.offset) if format == 1 then - local nofglyphs = datatable.length/4 - 1 - -1 + local nofglyphs = datatable.length/4 - 2 for i=0,nofglyphs do locations[i] = offset + readulong(f) end fontdata.nofglyphs = nofglyphs else - local nofglyphs = datatable.length/2 - 1 - -1 + local nofglyphs = datatable.length/2 - 2 for i=0,nofglyphs do locations[i] = offset + readushort(f) * 2 end @@ -427,54 +879,374 @@ function readers.loca(f,fontdata,specification) end function readers.glyf(f,fontdata,specification) -- part goes to cff module - if specification.glyphs then - local datatable = fontdata.tables.glyf - if datatable then - local locations = fontdata.locations - if locations then - local glyphs = fontdata.glyphs - local nofglyphs = fontdata.nofglyphs - local filesize = fontdata.filesize - local nothing = { 0, 0, 0, 0 } - local shapes = { } - local loadshapes = specification.shapes - for index=0,nofglyphs do - local location = locations[index] - if location >= filesize then - report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1) - fontdata.nofglyphs = index - 1 - fontdata.badfont = true - break - elseif location > 0 then - setposition(f,location) - local nofcontours = readshort(f) - glyphs[index].boundingbox = { - readshort(f), -- xmin - readshort(f), -- ymin - readshort(f), -- xmax - readshort(f), -- ymax - } - if not loadshapes then - -- save space - elseif nofcontours == 0 then - shapes[index] = readnothing(f,nofcontours) - elseif nofcontours > 0 then - shapes[index] = readglyph(f,nofcontours) + local tableoffset = gotodatatable(f,fontdata,"glyf",specification.glyphs) + if tableoffset then + local locations = fontdata.locations + if locations then + local glyphs = fontdata.glyphs + local nofglyphs = fontdata.nofglyphs + local filesize = fontdata.filesize + local nothing = { 0, 0, 0, 0 } + local shapes = { } + local loadshapes = specification.shapes or specification.instance + for index=0,nofglyphs do + local location = locations[index] + if location >= filesize then + report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1) + fontdata.nofglyphs = index - 1 + fontdata.badfont = true + break + elseif location > 0 then + setposition(f,location) + local nofcontours = readshort(f) + glyphs[index].boundingbox = { + readshort(f), -- xmin + readshort(f), -- ymin + readshort(f), -- xmax + readshort(f), -- ymax + } + if not loadshapes then + -- save space + elseif nofcontours == 0 then + shapes[index] = readnothing(f,nofcontours) + elseif nofcontours > 0 then + shapes[index] = readglyph(f,nofcontours) + else + shapes[index] = readcomposite(f,nofcontours) + end + else + if loadshapes then + shapes[index] = { } + end + glyphs[index].boundingbox = nothing + end + end + if loadshapes then + if readers.gvar then + readers.gvar(f,fontdata,specification,glyphs,shapes) + end + mergecomposites(glyphs,shapes) + if specification.instance then + if specification.streams then + repackpoints(glyphs,shapes) + else + contours2outlines_shaped(glyphs,shapes,specification.shapes) + end + elseif specification.shapes then + contours2outlines_normal(glyphs,shapes) + end + end + end + end +end + +-- gvar is a bit crazy format and one can really wonder if the bit-jugling obscurity +-- is still needed in these days .. cff is much nicer with these blends while the ttf +-- coding variant looks quite horrible + +local function readtuplerecord(f,nofaxis) + local record = { } + for i=1,nofaxis do + record[i] = read2dot14(f) + end + return record +end + +-- (1) the first is a real point the rest deltas +-- (2) points can be present more than once (multiple deltas then) + +local function readpoints(f) + local count = readbyte(f) + if count == 0 then + -- second byte not used, deltas for all point numbers + return nil, 0 -- todo + else + if count < 128 then + -- no second byte, use count + elseif bittest(count,0x80) then + count = band(count,0x7F) * 256 + readbyte(f) + else + -- bad news + end + local points = { } + local p = 0 + local n = 1 -- indices + while p < count do + local control = readbyte(f) + local runreader = bittest(control,0x80) and readushort or readbyte + local runlength = band(control,0x7F) + for i=1,runlength+1 do + n = n + runreader(f) + p = p + 1 + points[p] = n + end + end + return points, p + end +end + +local function readdeltas(f,nofpoints) + local deltas = { } + local p = 0 + local z = 0 + while nofpoints > 0 do + local control = readbyte(f) +if not control then + break +end + local allzero = bittest(control,0x80) + local runlength = band(control,0x3F) + 1 + if allzero then + z = z + runlength + else + local runreader = bittest(control,0x40) and readshort or readinteger + if z > 0 then + for i=1,z do + p = p + 1 + deltas[p] = 0 + end + z = 0 + end + for i=1,runlength do + p = p + 1 + deltas[p] = runreader(f) + end + end + nofpoints = nofpoints - runlength + end + -- saves space +-- if z > 0 then +-- for i=1,z do +-- p = p + 1 +-- deltas[p] = 0 +-- end +-- end + if p > 0 then + -- forget about trailing zeros + return deltas + else + -- forget about all zeros + end +end + +local function readdeltas(f,nofpoints) + local deltas = { } + local p = 0 + while nofpoints > 0 do + local control = readbyte(f) + if control then + local allzero = bittest(control,0x80) + local runlength = band(control,0x3F) + 1 + if allzero then + for i=1,runlength do + p = p + 1 + deltas[p] = 0 + end + else + local runreader = bittest(control,0x40) and readshort or readinteger + for i=1,runlength do + p = p + 1 + deltas[p] = runreader(f) + end + end + nofpoints = nofpoints - runlength + else + -- it happens + break + end + end + -- saves space + if p > 0 then + return deltas + else + -- forget about all zeros + end +end + +function readers.gvar(f,fontdata,specification,glyphdata,shapedata) + -- this is one of the messiest tables + local instance = specification.instance + if not instance then + return + end + local factors = specification.factors + if not factors then + return + end + local tableoffset = gotodatatable(f,fontdata,"gvar",specification.variable or specification.shapes) + if tableoffset then + local version = readulong(f) -- 1.0 + local nofaxis = readushort(f) + local noftuples = readushort(f) + local tupleoffset = tableoffset + readulong(f) + local nofglyphs = readushort(f) + local flags = readushort(f) + local dataoffset = tableoffset + readulong(f) + local data = { } + local tuples = { } + local glyphdata = fontdata.glyphs + local dowidth = not fontdata.variabledata.hvarwidths + -- there is one more offset (so that one can calculate the size i suppose) + -- so we could test for overflows but we simply assume sane font files + if bittest(flags,0x0001) then + for i=1,nofglyphs+1 do + data[i] = dataoffset + readulong(f) + end + else + for i=1,nofglyphs+1 do + data[i] = dataoffset + 2*readushort(f) + end + end + -- + if noftuples > 0 then + setposition(f,tupleoffset) + for i=1,noftuples do + tuples[i] = readtuplerecord(f,nofaxis) + end + end + local nextoffset = false + local startoffset = data[1] + for i=1,nofglyphs do -- hm one more cf spec + nextoffset = data[i+1] + local glyph = glyphdata[i-1] + local name = trace_deltas and glyph.name + if startoffset == nextoffset then + if name then + report("no deltas for glyph %a",name) + end + else + local shape = shapedata[i-1] -- todo 0 + if not shape then + if name then + report("no shape for glyph %a",name) + end + else + lastoffset = startoffset + setposition(f,startoffset) + local flags = readushort(f) + local count = band(flags,0x0FFF) + local offset = startoffset + readushort(f) -- to serialized + local deltas = { } + local allpoints = (shape.nofpoints or 0) -- + 1 + local shared = false + local nofshared = 0 + if bittest(flags,0x8000) then -- has shared points + -- go to the packed stream (get them once) + local current = getposition(f) + setposition(f,offset) + shared, nofshared = readpoints(f) + offset = getposition(f) + setposition(f,current) + -- and back to the table + end + for j=1,count do + local size = readushort(f) -- check + local flags = readushort(f) + local index = band(flags,0x0FFF) + local haspeak = bittest(flags,0x8000) + local intermediate = bittest(flags,0x4000) + local private = bittest(flags,0x2000) + local peak = nil + local start = nil + local stop = nil + local xvalues = nil + local yvalues = nil + local points = shared -- we default to shared + local nofpoints = nofshared -- we default to shared + -- local advance = 4 + if haspeak then + peak = readtuplerecord(f,nofaxis) + -- advance = advance + 2*nofaxis else - shapes[index] = readcomposite(f,nofcontours) + if index+1 > #tuples then + report("error, bad tuple index",index) + end + peak = tuples[index+1] -- hm, needs checking, only peak? end - else - if loadshapes then - shapes[index] = { } + if intermediate then + start = readtuplerecord(f,nofaxis) + stop = readtuplerecord(f,nofaxis) + -- advance = advance + 4*nofaxis + end + -- get the deltas + if size > 0 then + local current = getposition(f) + -- goto the packed stream + setposition(f,offset) + if private then + points, nofpoints = readpoints(f) + end -- else + if nofpoints == 0 then + nofpoints = allpoints + 4 + end + if nofpoints > 0 then + -- a nice test is to do only one + xvalues = readdeltas(f,nofpoints) + yvalues = readdeltas(f,nofpoints) + end + -- resync offset + offset = offset + size + -- back to the table + setposition(f,current) + end + if not xvalues and not yvalues then + points = nil + end + local s = 1 + for i=1,nofaxis do + local f = factors[i] + local peak = peak and peak [i] or 0 + -- local start = start and start[i] or 0 + -- local stop = stop and stop [i] or 0 + local start = start and start[i] or (peak < 0 and peak or 0) + local stop = stop and stop [i] or (peak > 0 and peak or 0) + -- do we really need these tests ... can't we assume sane values + if start > peak or peak > stop then + -- * 1 + elseif start < 0 and stop > 0 and peak ~= 0 then + -- * 1 + elseif peak == 0 then + -- * 1 + elseif f < start or f > stop then + -- * 0 + s = 0 + break + elseif f < peak then +-- s = - s * (f - start) / (peak - start) + s = s * (f - start) / (peak - start) + elseif f > peak then + s = s * (stop - f) / (stop - peak) + else + -- * 1 + end + end + if s == 0 then + if name then + report("no deltas applied for glyph %a",name) + end + else + deltas[#deltas+1] = { + factor = s, + points = points, + xvalues = xvalues, + yvalues = yvalues, + } end - glyphs[index].boundingbox = nothing end - end - if loadshapes then - mergecomposites(glyphs,shapes) - contours2outlines(glyphs,shapes) + if shape.type == "glyph" then +-- if glyph.name == "u1f31d" then +-- if glyph.unicode == 127773 then +-- inspect(deltas) +-- end + applyaxis(glyph,shape,deltas,dowidth) + else + -- todo: args_are_xy_values mess .. i have to be really bored + -- and motivated to deal with it + shape.deltas = deltas + end end end + startoffset = nextoffset end end end diff --git a/tex/context/base/mkiv/font-vf.lua b/tex/context/base/mkiv/font-vf.lua index 7037c6c8b..401e84956 100644 --- a/tex/context/base/mkiv/font-vf.lua +++ b/tex/context/base/mkiv/font-vf.lua @@ -22,7 +22,7 @@ local fastcopy = table.fastcopy local fonts = fonts local constructors = fonts.constructors -local vf = constructors.newhandler("vf") +local vf = constructors.handlers.vf vf.version = 1.000 -- same as tfm --[[ldx-- diff --git a/tex/context/base/mkiv/font-web.lua b/tex/context/base/mkiv/font-web.lua new file mode 100644 index 000000000..452a8f59b --- /dev/null +++ b/tex/context/base/mkiv/font-web.lua @@ -0,0 +1,202 @@ +if not modules then modules = { } end modules ['font-otr'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- Okay, compressing fonts this way is rather simple but one might wonder what the gain +-- is in this time of 4K youtube movies and most of the web pages wasting space and +-- bandwidth on advertisements. For version 2 we can use "woff2_decompress" from google +-- and in a tex environment one can as well store the ttf/otf files in the tex tree. So, +-- eventually we might even remove this code when version 1 is obsolete. + +local ioopen = io.open +local replacesuffix = file.replacesuffix + +local readers = fonts and fonts.handlers.otf.readers + +local streamreader = readers and readers.streamreader or utilities.files +local streamwriter = readers and readers.streamwriter or utilities.files + +local readstring = streamreader.readstring +local readcardinal2 = streamreader.readcardinal2 +local readcardinal4 = streamreader.readcardinal4 + +local writestring = streamwriter.writestring +local writecardinal4 = streamwriter.writecardinal4 +local writecardinal2 = streamwriter.writecardinal2 +local writebyte = streamwriter.writebyte + +local getsize = streamreader.getsize +local setposition = streamreader.setposition +local getposition = streamreader.getposition + +local decompress = zlib.decompress + +local infotags = { + ["os/2"] = true, + ["head"] = true, + ["maxp"] = true, + ["hhea"] = true, + ["hmtx"] = true, + ["post"] = true, + ["cmap"] = true, +} + +local report = logs.reporter("fonts","woff") + +local runner = sandbox.registerrunner { + name = "woff2otf", + method = "execute", + program = "woff2_decompress", + template = "%inputfile% %outputfile%", + reporter = report, + checkers = { + inputfile = "readable", + outputfile = "writable", + } +} + +local function woff2otf(inpname,outname,infoonly) + + local outname = outname or replacesuffix(inpname,"otf") + local inp = ioopen(inpname,"rb") + + if not inp then + report("invalid input file %a",inpname) + return + end + + local signature = readstring(inp,4) + + if not (signature == "wOFF" or signature == "wOF2") then + inp:close() + report("invalid signature in %a",inpname) + return + end + + local flavor = readstring(inp,4) + + if not (flavor == "OTTO" or flavor == "true" or flavor == "\0\1\0\0") then + inp:close() + report("unsupported flavor %a in %a",flavor,inpname) + return + end + + if signature == "wOF2" then + inp:close() + if false then + if runner then + runner { + inputfile = inpname, + outputfile = outname, + } + end + return outname, flavor + else + report("skipping version 2 file %a",inpname) + return + end + end + + local out = ioopen(outname,"wb") + + if not out then + inp:close() + report("invalid output file %a",outname) + return + end + + local header = { + signature = signature, + flavor = flavor, + length = readcardinal4(inp), + numtables = readcardinal2(inp), + reserved = readcardinal2(inp), + totalsfntsize = readcardinal4(inp), + majorversion = readcardinal2(inp), + minorversion = readcardinal2(inp), + metaoffset = readcardinal4(inp), + metalength = readcardinal4(inp), + metaoriglength = readcardinal4(inp), + privoffset = readcardinal4(inp), + privlength = readcardinal4(inp), + } + + local entries = { } + + for i=1,header.numtables do + local entry = { + tag = readstring (inp,4), + offset = readcardinal4(inp), + compressed = readcardinal4(inp), + size = readcardinal4(inp), + checksum = readcardinal4(inp), + } + if not infoonly or infotags[lower(entry.tag)] then + entries[#entries+1] = entry + end + end + + local nofentries = #entries + local entryselector = 0 -- we don't need these + local searchrange = 0 -- we don't need these + local rangeshift = 0 -- we don't need these + + writestring (out,flavor) + writecardinal2(out,nofentries) + writecardinal2(out,entryselector) + writecardinal2(out,searchrange) + writecardinal2(out,rangeshift) + + local offset = 12 + nofentries * 16 + local offsets = { } + + for i=1,nofentries do + local entry = entries[i] + local size = entry.size + writestring(out,entry.tag) + writecardinal4(out,entry.checksum) + writecardinal4(out,offset) -- the new offset + writecardinal4(out,size) + offsets[i] = offset + offset = offset + size + local p = 4 - offset % 4 + if p > 0 then + offset = offset + p + end + end + + for i=1,nofentries do + local entry = entries[i] + local offset = offsets[i] + local size = entry.size + setposition(inp,entry.offset+1) + local data = readstring(inp,entry.compressed) + if #data ~= size then + data = decompress(data) + end + setposition(out,offset+1) + writestring(out,data) + local p = 4 - offset + size % 4 + if p > 0 then + for i=1,p do + writebyte(out,0) + end + end + end + + inp:close() + out:close() + + return outname, flavor + +end + +if readers then + readers.woff2otf = woff2otf +else + return woff2otf +end diff --git a/tex/context/base/mkiv/good-ctx.lua b/tex/context/base/mkiv/good-ctx.lua new file mode 100644 index 000000000..00e4ed78d --- /dev/null +++ b/tex/context/base/mkiv/good-ctx.lua @@ -0,0 +1,300 @@ +if not modules then modules = { } end modules ['good-ctx'] = { + version = 1.000, + comment = "companion to font-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- depends on ctx + +local type, next, tonumber = type, next, tonumber +local find, splitup = string.find, string.splitup + +local fonts = fonts +local nodes = nodes +local attributes = attributes + +----- trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end) +----- report_goodies = logs.reporter("fonts","goodies") + +local allocate = utilities.storage.allocate +local setmetatableindex = table.setmetatableindex + +local implement = interfaces.implement + +local registerotffeature = fonts.handlers.otf.features.register +----- registerafmfeature = fonts.handlers.afm.features.register +----- registertfmfeature = fonts.handlers.tfm.features.register + +local fontgoodies = fonts.goodies or { } + +local glyph_code = nodes.nodecodes.glyph + +local nuts = nodes.nuts +local tonut = nuts.tonut +local getfont = nuts.getfont +local getchar = nuts.getchar +local getattr = nuts.getattr +local traverse_id = nuts.traverse_id + +-- colorschemes + +local colorschemes = fontgoodies.colorschemes or allocate { } +fontgoodies.colorschemes = colorschemes +colorschemes.data = colorschemes.data or { } + +local privatestoo = true + +local function setcolorscheme(tfmdata,scheme) + if type(scheme) == "string" then + local goodies = tfmdata.goodies + -- todo : check for already defined in shared + if goodies then + local what + for i=1,#goodies do + -- last one counts + local g = goodies[i] + what = g.colorschemes and g.colorschemes[scheme] or what + end + if type(what) == "table" then + -- this is font bound but we can share them if needed + -- just as we could hash the conversions (per font) + local hash = tfmdata.resources.unicodes + local reverse = { } + local characters = tfmdata.characters + for i=1,#what do + local w = what[i] + for j=1,#w do + local name = w[j] + local kind = type(name) + if name == "*" then + -- inefficient but only used for tracing anyway + for _, unicode in next, hash do + reverse[unicode] = i + end + elseif kind == "number" then + reverse[name] = i + elseif kind ~= "string" then + -- ignore invalid entries + elseif find(name,":",1,true) then + local start, stop = splitup(name,":") + start = tonumber(start) + stop = tonumber(stop) + if start and stop then + -- limited usage: we only deal with non reassigned + -- maybe some day I'll also support the ones with a + -- tounicode in this range + for unicode=start,stop do + if characters[unicode] then + reverse[unicode] = i + end + end + end + else + local unicode = hash[name] + if unicode then + reverse[unicode] = i + end + end + end + end + if privatestoo then + local private = fonts.constructors.privateoffset + local descriptions = tfmdata.descriptions + for unicode, data in next, characters do + if unicode >= private then + if not reverse[unicode] then + local d = descriptions[unicode] + if d then + local u = d.unicode + if u then + local r = reverse[u] -- also catches tables + if r then + reverse[unicode] = r + end + end + end + end + end + end + end + tfmdata.properties.colorscheme = reverse + return + end + end + end + tfmdata.properties.colorscheme = false +end + +local fontproperties = fonts.hashes.properties + +local a_colorscheme = attributes.private('colorscheme') +local setnodecolor = nodes.tracers.colors.set + +-- function colorschemes.coloring(head) +-- local lastfont, lastscheme +-- local done = false +-- for n in traverse_id(glyph_code,tonut(head)) do +-- local a = getattr(n,a_colorscheme) +-- if a then +-- local f = getfont(n) +-- if f ~= lastfont then +-- lastscheme = fontproperties[f].colorscheme +-- lastfont = f +-- end +-- if lastscheme then +-- local sc = lastscheme[getchar(n)] +-- if sc then +-- done = true +-- setnodecolor(n,"colorscheme:"..a..":"..sc) -- slow +-- end +-- end +-- end +-- end +-- return head, done +-- end + +-- seldom used, mostly in manuals, so non critical .. anyhow, somewhat faster: + +-- function colorschemes.coloring(head) +-- local lastfont = nil +-- local lastattr = nil +-- local lastscheme = nil +-- local lastprefix = nil +-- local done = nil +-- for n in traverse_id(glyph_code,tonut(head)) do +-- local a = getattr(n,a_colorscheme) +-- if a then +-- if a ~= lastattr then +-- lastattr = a +-- lastprefix = "colorscheme:" .. a .. ":" +-- end +-- local f = getfont(n) +-- if f ~= lastfont then +-- lastfont = f +-- lastscheme = fontproperties[f].colorscheme +-- end +-- if lastscheme then +-- local sc = lastscheme[getchar(n)] +-- if sc then +-- setnodecolor(n,lastprefix .. sc) -- slow +-- done = true +-- end +-- end +-- end +-- end +-- return head, done +-- end + +-- ok, in case we have hundreds of pages colored: + +local cache = { } -- this could be a weak table + +setmetatableindex(cache,function(t,a) + local v = { } + setmetatableindex(v,function(t,c) + local v = "colorscheme:" .. a .. ":" .. c + t[c] = v + return v + end) + t[a]= v + return v +end) + +function colorschemes.coloring(head) + local lastfont = nil + local lastattr = nil + local lastcache = nil + local lastscheme = nil + local done = nil + for n in traverse_id(glyph_code,tonut(head)) do + local a = getattr(n,a_colorscheme) + if a then + local f = getfont(n) + if f ~= lastfont then + lastfont = f + lastscheme = fontproperties[f].colorscheme + end + if a ~= lastattr then + lastattr = a + lastcache = cache[a] + end + if lastscheme then + local sc = lastscheme[getchar(n)] + if sc then + setnodecolor(n,lastcache[sc]) -- we could inline this one + done = true + end + end + end + end + return head, done +end + +function colorschemes.enable() + nodes.tasks.appendaction("processors","fonts","fonts.goodies.colorschemes.coloring") + function colorschemes.enable() end +end + +registerotffeature { + name = "colorscheme", + description = "goodie color scheme", + initializers = { + base = setcolorscheme, + node = setcolorscheme, + } +} + +-- kern hackery: +-- +-- yes : use goodies table +-- auto : assume features to be set (often ccmp only) + +local function setkeepligatures(tfmdata) + if not tfmdata.properties.keptligatures then + local goodies = tfmdata.goodies + if goodies then + for i=1,#goodies do + local g = goodies[i] + local letterspacing = g.letterspacing + if letterspacing then + local keptligatures = letterspacing.keptligatures + if keptligatures then + local unicodes = tfmdata.resources.unicodes -- so we accept names + local hash = { } + for k, v in next, keptligatures do + local u = unicodes[k] + if u then + hash[u] = true + else + -- error: unknown name + end + end + tfmdata.properties.keptligatures = hash + end + end + end + end + end +end + +registerotffeature { + name = "keepligatures", + description = "keep ligatures in letterspacing", + initializers = { + base = setkeepligatures, + node = setkeepligatures, + } +} + +if implement then + + implement { + name = "enablefontcolorschemes", + onlyonce = true, + actions = colorschemes.enable, + overload = true, -- for now, permits new font loader + } + +end diff --git a/tex/context/base/mkiv/good-gen.lua b/tex/context/base/mkiv/good-gen.lua new file mode 100644 index 000000000..cee6b3172 --- /dev/null +++ b/tex/context/base/mkiv/good-gen.lua @@ -0,0 +1,208 @@ +if not modules then modules = { } end modules ['good-gen'] = { + version = 1.000, + comment = "companion to font-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- depends on ctx + +local type, next = type, next +local lower = string.lower + +local fonts = fonts + +----- trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end) +----- report_goodies = logs.reporter("fonts","goodies") + +local allocate = utilities.storage.allocate +local texsp = tex.sp +local fontgoodies = fonts.goodies or { } +local findfile = resolvers.findfile + + +local typefaces = fonts.typefaces or { } +fonts.typefaces = typefaces + +-- the following takes care of explicit file specifications +-- +-- files = { +-- name = "antykwapoltawskiego", +-- list = { +-- ["AntPoltLtCond-Regular.otf"] = { +-- -- name = "antykwapoltawskiego", +-- style = "regular", +-- weight = "light", +-- width = "condensed", +-- }, +-- }, +-- } + +-- files + +local function initialize(goodies) + local files = goodies.files + if files then + fonts.names.register(files) + end +end + +fontgoodies.register("files", initialize) + +-- some day we will have a define command and then we can also do some +-- proper tracing +-- +-- fonts.typefaces["antykwapoltawskiego-condensed"] = { +-- shortcut = "rm", +-- shape = "serif", +-- fontname = "antykwapoltawskiego", +-- normalweight = "light", +-- boldweight = "medium", +-- width = "condensed", +-- size = "default", +-- features = "default", +-- } + +local function initialize(goodies) + local typefaces = goodies.typefaces + if typefaces then + local ft = fonts.typefaces + for k, v in next, typefaces do + ft[k] = v + end + end +end + +fontgoodies.register("typefaces", initialize) + +local compositions = { } + +function fontgoodies.getcompositions(tfmdata) + return compositions[file.nameonly(tfmdata.properties.filename or "")] +end + +local function initialize(goodies) + local gc = goodies.compositions + if gc then + for k, v in next, gc do + compositions[k] = v + end + end +end + +fontgoodies.register("compositions", initialize) + +-- extra treatments (on top of defaults): \loadfontgoodies[mytreatments] + +local treatmentdata = fonts.treatments.data + +local function initialize(goodies) + local treatments = goodies.treatments + if treatments then + for name, data in next, treatments do + treatmentdata[name] = data -- always wins + end + end +end + +fontgoodies.register("treatments", initialize) + +local filenames = fontgoodies.filenames or allocate() +fontgoodies.filenames = filenames + +local filedata = filenames.data or allocate() +filenames.data = filedata + +local function initialize(goodies) -- design sizes are registered global + local fn = goodies.filenames + if fn then + for usedname, alternativenames in next, fn do + filedata[usedname] = alternativenames + end + end +end + +fontgoodies.register("filenames", initialize) + +function fontgoodies.filenames.resolve(name) + local fd = filedata[name] + if fd and findfile(name) == "" then + for i=1,#fd do + local fn = fd[i] + if findfile(fn) ~= "" then + return fn + end + end + else + -- no lookup, just use the regular mechanism + end + return name +end + +local designsizes = fontgoodies.designsizes or allocate() +fontgoodies.designsizes = designsizes + +local designdata = designsizes.data or allocate() +designsizes.data = designdata + +local function initialize(goodies) -- design sizes are registered global + local gd = goodies.designsizes + if gd then + for name, data in next, gd do + local ranges = { } + for size, file in next, data do + if size ~= "default" then + ranges[#ranges+1] = { texsp(size), file } -- also lower(file) + end + end + table.sort(ranges,function(a,b) return a[1] < b[1] end) + designdata[lower(name)] = { -- overloads, doesn't merge! + default = data.default, + ranges = ranges, + } + end + end +end + +fontgoodies.register("designsizes", initialize) + +function fontgoodies.designsizes.register(name,size,specification) + local d = designdata[name] + if not d then + d = { + ranges = { }, + default = nil, -- so we have no default set + } + designdata[name] = d + end + if size == "default" then + d.default = specification + else + if type(size) == "string" then + size = texsp(size) -- hm + end + local ranges = d.ranges + ranges[#ranges+1] = { size, specification } + end +end + +function fontgoodies.designsizes.filename(name,spec,size) -- returns nil of no match + local data = designdata[lower(name)] + if data then + if not spec or spec == "" or spec == "default" then + return data.default + elseif spec == "auto" then + local ranges = data.ranges + if ranges then + for i=1,#ranges do + local r = ranges[i] + if r[1] >= size then -- todo: rounding so maybe size - 100 + return r[2] + end + end + end + return data.default or (ranges and ranges[#ranges][2]) + end + end +end diff --git a/tex/context/base/mkiv/good-ini.lua b/tex/context/base/mkiv/good-ini.lua new file mode 100644 index 000000000..22ca12d28 --- /dev/null +++ b/tex/context/base/mkiv/good-ini.lua @@ -0,0 +1,397 @@ +if not modules then modules = { } end modules ['good-ini'] = { + version = 1.000, + comment = "companion to font-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- depends on ctx + +local type, next = type, next +local gmatch = string.gmatch +local sortedhash, insert = table.sortedhash, table.insert + +local fonts = fonts + +local trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end) +local report_goodies = logs.reporter("fonts","goodies") + +local allocate = utilities.storage.allocate +local implement = interfaces.implement +local findfile = resolvers.findfile +local formatters = string.formatters + +local otf = fonts.handlers.otf +local afm = fonts.handlers.afm +local tfm = fonts.handlers.tfm + +local registerotffeature = otf.features.register +local registerafmfeature = afm.features.register +local registertfmfeature = tfm.features.register + +local addotffeature = otf.enhancers.addfeature + +local fontgoodies = fonts.goodies or { } +fonts.goodies = fontgoodies + +local data = fontgoodies.data or { } +fontgoodies.data = data -- no allocate as we want to see what is there + +local list = fontgoodies.list or { } +fontgoodies.list = list -- no allocate as we want to see what is there + +fontgoodies.suffixes = { "lfg", "lua" } -- lfg is context specific and should not be used elsewhere + +local contextsetups = fonts.specifiers.contextsetups + +function fontgoodies.report(what,trace,goodies) + if trace_goodies or trace then + local whatever = goodies[what] + if whatever then + report_goodies("goodie %a found in %a",what,goodies.name) + end + end +end + +local function locate(filename) + local suffixes = fontgoodies.suffixes + for i=1,#suffixes do + local suffix = suffixes[i] + local fullname = findfile(file.addsuffix(filename,suffix)) + if fullname and fullname ~= "" then + return fullname + end + end +end + +local function loadgoodies(filename) -- maybe a merge is better + local goodies = data[filename] -- we assume no suffix is given + if goodies ~= nil then + -- found or tagged unfound + elseif type(filename) == "string" then + local fullname = locate(filename) + if not fullname or fullname == "" then + report_goodies("goodie file %a is not found (suffixes: % t)",filename,fontgoodies.suffixes) + data[filename] = false -- signal for not found + else + goodies = dofile(fullname) or false + if not goodies then + report_goodies("goodie file %a is invalid",fullname) + return nil + elseif trace_goodies then + report_goodies("goodie file %a is loaded",fullname) + end + goodies.name = goodies.name or "no name" + for i=1,#list do + local g = list[i] + if trace_goodies then + report_goodies("handling goodie %a",g[1]) + end + g[2](goodies) + end + goodies.initialized = true + data[filename] = goodies + end + end + return goodies +end + +function fontgoodies.register(name,fnc,prepend) -- will be a proper sequencer + for i=1,#list do + local g = list[i] + if g[1] == name then + g[2] = fnc --overload + return + end + end + local g = { name, fnc } + if prepend then + insert(list,g,prepend == true and 1 or prepend) + else + insert(list,g) + end +end + +fontgoodies.load = loadgoodies + +if implement then + + implement { + name = "loadfontgoodies", + actions = loadgoodies, + arguments = "string", + overload = true, -- for now, permits new font loader + } + +end + +-- register goodies file + +local function setgoodies(tfmdata,value) + local goodies = tfmdata.goodies + if not goodies then -- actually an error + goodies = { } + tfmdata.goodies = goodies + end + for filename in gmatch(value,"[^, ]+") do + -- we need to check for duplicates + local ok = loadgoodies(filename) + if ok then + if trace_goodies then + report_goodies("assigning goodie %a",filename) + end + goodies[#goodies+1] = ok + end + end +end + +-- featuresets + +local function flattenedfeatures(t,tt) + -- first set value dominates + local tt = tt or { } + for i=1,#t do + local ti = t[i] + local ty = type(ti) + if ty == "table" then + flattenedfeatures(ti,tt) + elseif ty == "string" then + local set = contextsetups[ti] + if set then + for k, v in next, set do + if k ~= "number" then + tt[k] = v or nil + end + end + else + -- bad + end + elseif tt[ti] == nil then + tt[ti] = true + end + end + for k, v in next, t do + if type(k) ~= "number" then -- not tonumber(k) + if type(v) == "table" then + flattenedfeatures(v,tt) + elseif tt[k] == nil then + tt[k] = v + end + end + end + return tt +end + +-- fonts.features.flattened = flattenedfeatures + +local function prepare_features(goodies,name,set) + if set then + local ff = flattenedfeatures(set) + local fullname = goodies.name .. "::" .. name + local n, s = fonts.specifiers.presetcontext(fullname,"",ff) + goodies.featuresets[name] = s -- set + if trace_goodies then + report_goodies("feature set %a gets number %a and name %a",name,n,fullname) + end + return n + end +end + +fontgoodies.prepare_features = prepare_features + +local function initialize(goodies) + local featuresets = goodies.featuresets + if featuresets then + if trace_goodies then + report_goodies("checking featuresets in %a",goodies.name) + end + for name, set in next, featuresets do + prepare_features(goodies,name,set) + end + end +end + +fontgoodies.register("featureset",initialize) + +local function setfeatureset(tfmdata,set,features) + local goodies = tfmdata.goodies -- shared ? + if goodies then + local properties = tfmdata.properties + local what + for i=1,#goodies do + -- last one wins + local g = goodies[i] + what = g.featuresets and g.featuresets[set] or what + end + if what then + for feature, value in next, what do + if features[feature] == nil then + features[feature] = value + end + end + properties.mode = what.mode or properties.mode + end + end +end + +-- postprocessors (we could hash processor and share code) + +function fontgoodies.registerpostprocessor(tfmdata,f,prepend) + local postprocessors = tfmdata.postprocessors + if not postprocessors then + tfmdata.postprocessors = { f } + elseif prepend then + insert(postprocessors,f,prepend == true and 1 or prepend) + else + insert(postprocessors,f) + end +end + +local function setpostprocessor(tfmdata,processor) + local goodies = tfmdata.goodies + if goodies and type(processor) == "string" then + local found = { } + local asked = utilities.parsers.settings_to_array(processor) + for i=1,#goodies do + local g = goodies[i] + local p = g.postprocessors + if p then + for i=1,#asked do + local a = asked[i] + local f = p[a] + if type(f) == "function" then + found[a] = f + end + end + end + end + local postprocessors = tfmdata.postprocessors or { } + for i=1,#asked do + local a = asked[i] + local f = found[a] + if f then + postprocessors[#postprocessors+1] = f + end + end + if #postprocessors > 0 then + tfmdata.postprocessors = postprocessors + end + end +end + +local function setextrafeatures(tfmdata) + local goodies = tfmdata.goodies + if goodies then + for i=1,#goodies do + local g = goodies[i] + local f = g.features + if f then + local rawdata = tfmdata.shared.rawdata + local done = { } + -- indexed + for i=1,#f do + local specification = f[i] + local feature = specification.name + if feature then + addotffeature(rawdata,feature,specification) + registerotffeature { + name = feature, + description = formatters["extra: %s"](feature) + } + end + done[i] = true + end + -- hashed + for feature, specification in sortedhash(f) do + if not done[feature] then + feature = specification.name or feature + specification.name = feature + addotffeature(rawdata,feature,specification) + registerotffeature { + name = feature, + description = formatters["extra: %s"](feature) + } + end + end + end + end + end +end + +local function setextensions(tfmdata) + local goodies = tfmdata.goodies + if goodies then + for i=1,#goodies do + local g = goodies[i] + local e = g.extensions + if e then + local goodie = g.name or "unknown" + for i=1,#e do + local name = "extension-" .. i + -- report_goodies("adding extension %s from %s",name,goodie) + otf.enhancers.addfeature(tfmdata.shared.rawdata,name,e[i]) + end + end + end + end +end + +-- installation + +local goodies_specification = { + name = "goodies", + description = "goodies on top of built in features", + initializers = { + position = 1, + base = setgoodies, + node = setgoodies, + } +} + +registerotffeature(goodies_specification) +registerafmfeature(goodies_specification) +registertfmfeature(goodies_specification) + +-- maybe more of the following could be for type one too + +registerotffeature { + name = "extrafeatures", + description = "extra features", + default = true, + initializers = { + position = 2, + base = setextrafeatures, + node = setextrafeatures, + } +} + +registerotffeature { + name = "extensions", + description = "extensions to features", + default = true, + initializers = { + position = 2, + base = setextensions, + node = setextensions, + } +} + +registerotffeature { + name = "featureset", + description = "goodie feature set", + initializers = { + position = 3, + base = setfeatureset, + node = setfeatureset, + } +} + +registerotffeature { + name = "postprocessor", + description = "goodie postprocessor", + initializers = { + base = setpostprocessor, + node = setpostprocessor, + } +} diff --git a/tex/context/base/mkiv/good-mth.lua b/tex/context/base/mkiv/good-mth.lua new file mode 100644 index 000000000..661189350 --- /dev/null +++ b/tex/context/base/mkiv/good-mth.lua @@ -0,0 +1,312 @@ +if not modules then modules = { } end modules ['good-mth'] = { + version = 1.000, + comment = "companion to font-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local type, next = type, next +local ceil = math.ceil + +local fonts = fonts + +local trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end) +local report_goodies = logs.reporter("fonts","goodies") + +local registerotffeature = fonts.handlers.otf.features.register +local fontgoodies = fonts.goodies or { } + +local fontcharacters = fonts.hashes.characters + +local nuts = nodes.nuts + +local setlink = nuts.setlink + +local nodepool = nuts.pool + +local new_kern = nodepool.kern +local new_glyph = nodepool.glyph +local new_hlist = nodepool.hlist +local new_vlist = nodepool.vlist + +local insert_node_after = nuts.insert_after + +-- experiment, we have to load the definitions immediately as they precede +-- the definition so they need to be initialized in the typescript + +local function finalize(tfmdata,feature,value) + mathematics.overloaddimensions(tfmdata,tfmdata,value) +end + +registerotffeature { + name = "mathdimensions", + description = "manipulate math dimensions", + -- default = true, + manipulators = { + base = finalize, + node = finalize, + } +} + +local function initialize(goodies) + local mathgoodies = goodies.mathematics + if mathgoodies then + local virtuals = mathgoodies.virtuals + local mapfiles = mathgoodies.mapfiles + local maplines = mathgoodies.maplines + if virtuals then + for name, specification in next, virtuals do + -- beware, they are all constructed + mathematics.makefont(name,specification,goodies) + end + end + if mapfiles then + for i=1,#mapfiles do + fonts.mappings.loadfile(mapfiles[i]) -- todo: backend function + end + end + if maplines then + for i=1,#maplines do + fonts.mappings.loadline(maplines[i]) -- todo: backend function + end + end + end +end + +fontgoodies.register("mathematics", initialize) + +local enabled = false directives.register("fontgoodies.mathkerning",function(v) enabled = v end) + +local function initialize(tfmdata) + if enabled and tfmdata.mathparameters then -- funny, cambria text has this + local goodies = tfmdata.goodies + if goodies then + local characters = tfmdata.characters + if characters[0x1D44E] then -- 119886 + -- we have at least an italic a + for i=1,#goodies do + local mathgoodies = goodies[i].mathematics + if mathgoodies then + local kerns = mathgoodies.kerns + if kerns then + for unicode, specification in next, kerns do + local chardata = characters[unicode] + if chardata and (not chardata.mathkerns or specification.force) then + chardata.mathkerns = specification + end + end + return + end + end + end + else + return -- no proper math font anyway + end + end + end +end + +registerotffeature { + name = "mathkerns", + description = "math kerns", + default = true, + initializers = { + base = initialize, + node = initialize, + } +} + +-- math italics (not really needed) +-- +-- it would be nice to have a \noitalics\font option + +local function initialize(tfmdata) + local goodies = tfmdata.goodies + if goodies then + local shared = tfmdata.shared + for i=1,#goodies do + local mathgoodies = goodies[i].mathematics + if mathgoodies then + local mathitalics = mathgoodies.italics + if mathitalics then + local properties = tfmdata.properties + if properties.setitalics then + mathitalics = mathitalics[file.nameonly(properties.name)] or mathitalics + if mathitalics then + if trace_goodies then + report_goodies("loading mathitalics for font %a",properties.name) + end + local corrections = mathitalics.corrections + local defaultfactor = mathitalics.defaultfactor + -- properties.mathitalic_defaultfactor = defaultfactor -- we inherit outer one anyway (name will change) + if corrections then + fontgoodies.registerpostprocessor(tfmdata, function(tfmdata) -- this is another tfmdata (a copy) + -- better make a helper so that we have less code being defined + local properties = tfmdata.properties + local parameters = tfmdata.parameters + local characters = tfmdata.characters + properties.mathitalic_defaultfactor = defaultfactor + properties.mathitalic_defaultvalue = defaultfactor * parameters.quad + if trace_goodies then + report_goodies("assigning mathitalics for font %a",properties.name) + end + local quad = parameters.quad + local hfactor = parameters.hfactor + for k, v in next, corrections do + local c = characters[k] + if c then + if v > -1 and v < 1 then + c.italic = v * quad + else + c.italic = v * hfactor + end + else + report_goodies("invalid mathitalics entry %U for font %a",k,properties.name) + end + end + end) + end + return -- maybe not as these can accumulate + end + end + end + end + end + end +end + +registerotffeature { + name = "mathitalics", + description = "additional math italic corrections", + -- default = true, + initializers = { + base = initialize, + node = initialize, + } +} + +-- fontgoodies.register("mathitalics", initialize) + +local function mathradicalaction(n,h,v,font,mchar,echar) + local characters = fontcharacters[font] + local mchardata = characters[mchar] + local echardata = characters[echar] + local ewidth = echardata.width + local mwidth = mchardata.width + local delta = h - ewidth + local glyph = new_glyph(font,echar) + local head = glyph + if delta > 0 then + local count = ceil(delta/mwidth) + local kern = (delta - count * mwidth) / count + for i=1,count do + local k = new_kern(kern) + local g = new_glyph(font,mchar) + setlink(k,head) + setlink(g,k) + head = g + end + end + local height = mchardata.height + local list = new_hlist(head) + local kern = new_kern(height-v) + list = setlink(kern,list) + local list = new_vlist(kern) + insert_node_after(n,n,list) +end + +local function mathhruleaction(n,h,v,font,bchar,mchar,echar) + local characters = fontcharacters[font] + local bchardata = characters[bchar] + local mchardata = characters[mchar] + local echardata = characters[echar] + local bwidth = bchardata.width + local mwidth = mchardata.width + local ewidth = echardata.width + local delta = h - ewidth - bwidth + local glyph = new_glyph(font,echar) + local head = glyph + if delta > 0 then + local count = ceil(delta/mwidth) + local kern = (delta - count * mwidth) / (count+1) + for i=1,count do + local k = new_kern(kern) + local g = new_glyph(font,mchar) + setlink(k,head) + setlink(g,k) + head = g + end + local k = new_kern(kern) + setlink(k,head) + head = k + end + local g = new_glyph(font,bchar) + setlink(g,head) + head = g + local height = mchardata.height + local list = new_hlist(head) + local kern = new_kern(height-v) + list = setlink(kern,list) + local list = new_vlist(kern) + insert_node_after(n,n,list) +end + +local function initialize(tfmdata) + local goodies = tfmdata.goodies + if goodies then + local resources = tfmdata.resources + local ruledata = { } + for i=1,#goodies do + local mathematics = goodies[i].mathematics + if mathematics then + local rules = mathematics.rules + if rules then + for tag, name in next, rules do + ruledata[tag] = name + end + end + end + end + if next(ruledata) then + local characters = tfmdata.characters + local unicodes = resources.unicodes + if characters and unicodes then + local mathruleactions = resources.mathruleactions + if not mathruleactions then + mathruleactions = { } + resources.mathruleactions = mathruleactions + end + -- + local mchar = unicodes[ruledata["radical.extender"] or false] + local echar = unicodes[ruledata["radical.end"] or false] + if mchar and echar then + mathruleactions.radicalaction = function(n,h,v,font) + mathradicalaction(n,h,v,font,mchar,echar) + end + end + -- + local bchar = unicodes[ruledata["hrule.begin"] or false] + local mchar = unicodes[ruledata["hrule.extender"] or false] + local echar = unicodes[ruledata["hrule.end"] or false] + if bchar and mchar and echar then + mathruleactions.hruleaction = function(n,h,v,font) + mathhruleaction(n,h,v,font,bchar,mchar,echar) + end + end + -- not that nice but we need to register it at the tex end + -- context.enablemathrules("\\fontclass") + end + end + end +end + +registerotffeature { + name = "mathrules", + description = "check math rules", + default = true, + initializers = { + base = initialize, + node = initialize, + } +} diff --git a/tex/context/base/mkiv/grph-con.lua b/tex/context/base/mkiv/grph-con.lua new file mode 100644 index 000000000..49b5952df --- /dev/null +++ b/tex/context/base/mkiv/grph-con.lua @@ -0,0 +1,421 @@ +if not modules then modules = { } end modules ['grph-con'] = { + version = 1.001, + comment = "companion to grph-inc.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local P, R, S, Cc, C, Cs, Ct, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.Cc, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.match + +local longtostring = string.longtostring +local formatters = string.formatters +local expandfilename = dir.expandname + +local settings_to_array = utilities.parsers.settings_to_array +local settings_to_hash = utilities.parsers.settings_to_hash +local allocate = utilities.storage.allocate +local setmetatableindex = table.setmetatableindex + +local codeinjections = backends.codeinjections +local nodeinjections = backends.nodeinjections + +local report_figures = logs.reporter("system","graphics") + +local variables = interfaces.variables +local v_high = variables.high +local v_low = variables.low +local v_medium = variables.medium + +local figures = figures + +local converters = figures.converters +local programs = figures.programs + +local runprogram = programs.run + +do -- eps | ps + + -- \externalfigure[cow.eps] + -- \externalfigure[cow.pdf][conversion=stripped] + + -- todo: colorspace + -- todo: lowres + + local epsconverter = converters.eps + converters.ps = epsconverter + + local resolutions = { + [v_low] = "screen", + [v_medium] = "ebook", + [v_high] = "prepress", + } + + local runner = sandbox.registerrunner { + name = "eps to pdf", + program = { + windows = os.platform == "win64" and "gswin64c" or "gswin32c", + unix = "gs", + }, + template = longtostring [[ + -q + -sDEVICE=pdfwrite + -dNOPAUSE + -dNOCACHE + -dBATCH + -dAutoRotatePages=/None + -dPDFSETTINGS=/%presets% + -dEPSCrop + -dCompatibilityLevel=%level% + -sOutputFile="%newname%" + %colorspace% + "%oldname%" + -c quit + ]], + checkers = { + oldname = "readable", + newname = "writable", + presets = "string", + level = "string", + colorspace = "string", + }, + } + + programs.epstopdf = { resolutions = epstopdf, runner = runner } + programs.gs = programs.epstopdf + + local cleanups = { } + local cleaners = { } + + local whitespace = lpeg.patterns.whitespace + local quadruple = Ct((whitespace^0 * lpeg.patterns.number/tonumber * whitespace^0)^4) + local betterbox = P("%%BoundingBox:") * quadruple + * P("%%HiResBoundingBox:") * quadruple + * P("%AI3_Cropmarks:") * quadruple + * P("%%CropBox:") * quadruple + / function(b,h,m,c) + return formatters["%%%%BoundingBox: %r %r %r %r\n%%%%HiResBoundingBox: %F %F %F %F\n%%%%CropBox: %F %F %F %F\n"]( + m[1],m[2],m[3],m[4], -- rounded integer + m[1],m[2],m[3],m[4], -- real number + m[1],m[2],m[3],m[4] + ) + end + local nocrap = P("%") / "" * ( + (P("AI9_PrivateDataBegin") * P(1)^0) / "%%%%EOF" + + (P("%EOF") * whitespace^0 * P("%AI9_PrintingDataEnd") * P(1)^0) / "%%%%EOF" + + (P("AI7_Thumbnail") * (1-P("%%EndData"))^0 * P("%%EndData")) / "" + ) + local whatever = nocrap + P(1) + local pattern = Cs((betterbox * whatever^1 + whatever)^1) + + directives.register("graphics.conversion.eps.cleanup.ai",function(v) cleanups.ai = v end) + + cleaners.ai = function(name) + local tmpname = name .. ".tmp" + io.savedata(tmpname,lpegmatch(pattern,io.loaddata(name) or "")) + return tmpname + end + + function epsconverter.pdf(oldname,newname,resolution,colorspace) -- the resolution interface might change + local presets = resolutions[resolution or "high"] or resolutions.high + local level = codeinjections.getformatoption("pdf_level") or "1.3" + local tmpname = oldname + if not tmpname or tmpname == "" or not lfs.isfile(tmpname) then + return + end + if cleanups.ai then + tmpname = cleaners.ai(oldname) + end + if colorspace == "gray" then + colorspace = "-sColorConversionStrategy=Gray -sProcessColorModel=DeviceGray" + -- colorspace = "-sColorConversionStrategy=Gray" + else + colorspace = nil + end + runner { + newname = newname, + oldname = tmpname, + presets = presets, + level = tostring(level), + colorspace = colorspace, + } + if tmpname ~= oldname then + os.remove(tmpname) + end + end + + epsconverter["gray.pdf"] = function(oldname,newname,resolution) -- the resolution interface might change + epsconverter.pdf(oldname,newname,resolution,"gray") + end + + epsconverter.default = epsconverter.pdf + +end + +-- do -- pdf +-- +-- local pdfconverter = converters.pdf +-- +-- programs.pdftoeps = { +-- runner = sandbox.registerrunner { +-- name = "pdf to ps", +-- command = "pdftops", +-- template = [[-eps "%oldname%" "%newname%"]], +-- checkers = { +-- oldname = "readable", +-- newname = "writable", +-- } +-- } +-- } +-- +-- pdfconverter.stripped = function(oldname,newname) +-- local pdftoeps = programs.pdftoeps -- can be changed +-- local epstopdf = programs.epstopdf -- can be changed +-- local presets = epstopdf.resolutions[resolution or ""] or epstopdf.resolutions.high +-- local level = codeinjections.getformatoption("pdf_level") or "1.3" +-- local tmpname = newname .. ".tmp" +-- pdftoeps.runner { oldname = oldname, newname = tmpname, presets = presets, level = level } +-- epstopdf.runner { oldname = tmpname, newname = newname, presets = presets, level = level } +-- os.remove(tmpname) +-- end +-- +-- figures.registersuffix("stripped","pdf") +-- +-- end + +do -- svg + + local svgconverter = converters.svg + converters.svgz = svgconverter + + -- inkscape on windows only works with complete paths .. did the command line + -- arguments change again? Ok, it's weirder, with -A then it's a name only when + -- not . (current) + + local runner = sandbox.registerrunner { + name = "svg to something", + program = "inkscape", + template = longtostring [[ + "%oldname%" + --export-dpi=%resolution% + --export-%format%="%newname%" + ]], + checkers = { + oldname = "readable", + newname = "writable", + format = "string", + resolution = "string", + }, + defaults = { + format = "pdf", + resolution = "600", + } + } + + programs.inkscape = { + runner = runner, + } + + function svgconverter.pdf(oldname,newname) + runner { + format = "pdf", + resolution = "600", + newname = expandfilename(newname), + oldname = expandfilename(oldname), + } + end + + function svgconverter.png(oldname,newname) + runner { + format = "png", + resolution = "600", + newname = expandfilename(newname), + oldname = expandfilename(oldname), + } + end + + svgconverter.default = svgconverter.pdf + +end + +do -- gif | tif + + local gifconverter = converters.gif + local tifconverter = converters.tif + local bmpconverter = converters.bmp + + programs.convert = { + command = "gm", -- graphicmagick + argument = [[convert "%oldname%" "%newname%"]], + } + + local function converter(oldname,newname) + local convert = programs.convert + runprogram(convert.command, convert.argument, { + newname = newname, + oldname = oldname, + } ) + end + + tifconverter.pdf = converter + gifconverter.pdf = converter + bmpconverter.pdf = converter + + gifconverter.default = converter + tifconverter.default = converter + bmpconverter.default = converter + +end + +do -- png | jpg | profiles + + -- ecirgb_v2.icc + -- ecirgb_v2_iccv4.icc + -- isocoated_v2_300_eci.icc + -- isocoated_v2_eci.icc + -- srgb.icc + -- srgb_v4_icc_preference.icc + + -- [[convert %?colorspace: -colorspace "%colorspace%" ?%]] + + local rgbprofile = "srgb_v4_icc_preference.icc" -- srgb.icc + local cmykprofile = "isocoated_v2_300_eci.icc" -- isocoated_v2_eci.icc + + directives.register("graphics.conversion.rgbprofile", function(v) rgbprofile = type(v) == "string" and v or rgbprofile end) + directives.register("graphics.conversion.cmykprofile",function(v) cmykprofile = type(v) == "string" and v or cmykprofile end) + + local jpgconverters = converters.jpg + local pngconverters = converters.png + + local function profiles() + if not lfs.isfile(rgbprofile) then + local found = resolvers.findfile(rgbprofile) + if found and found ~= "" then + rgbprofile = found + else + report_figures("unknown profile %a",rgbprofile) + end + end + if not lfs.isfile(cmykprofile) then + local found = resolvers.findfile(cmykprofile) + if found and found ~= "" then + cmykprofile = found + else + report_figures("unknown profile %a",cmykprofile) + end + end + return rgbprofile, cmykprofile + end + + local checkers = { + oldname = "readable", + newname = "writable", + rgbprofile = "string", + cmykprofile = "string", + resolution = "string", + color = "string", + } + + local defaults = { + resolution = "600", + } + + local pngtocmykpdf = sandbox.registerrunner { + name = "png to cmyk pdf", + program = "gm", + template = [[convert -compress Zip -strip +profile "*" -profile "%rgbprofile%" -profile "%cmykprofile%" -sampling-factor 1x1 "%oldname%" "%newname%"]], + checkers = checkers, + defaults = defaults, + } + + local jpgtocmykpdf = sandbox.registerrunner { + name = "jpg to cmyk pdf", + program = "gm", + template = [[convert -compress JPEG -strip +profile "*" -profile "%rgbprofile%" -profile "%cmykprofile%" -sampling-factor 1x1 "%oldname%" "%newname%"]], + checkers = checkers, + defaults = defaults, + } + + local pngtograypdf = sandbox.registerrunner { + name = "png to gray pdf", + program = "gm", + template = [[convert -colorspace gray -compress Zip -sampling-factor 1x1 "%oldname%" "%newname%"]], + checkers = checkers, + defaults = defaults, + } + + local jpgtograypdf = sandbox.registerrunner { + name = "jpg to gray pdf", + program = "gm", + template = [[convert -colorspace gray -compress Zip -sampling-factor 1x1 "%oldname%" "%newname%"]], + checkers = checkers, + defaults = defaults, + } + + programs.pngtocmykpdf = { runner = pngtocmykpdf } + programs.jpgtocmykpdf = { runner = jpgtocmykpdf } + programs.pngtograypdf = { runner = pngtograypdf } + programs.jpgtograypdf = { runner = jpgtograypdf } + + pngconverters["cmyk.pdf"] = function(oldname,newname,resolution) + local rgbprofile, cmykprofile = profiles() + pngtocmykpdf { + oldname = oldname, + newname = newname, + rgbprofile = rgbprofile, + cmykprofile = cmykprofile, + resolution = resolution, + } + end + + pngconverters["gray.pdf"] = function(oldname,newname,resolution) + pngtograypdf { + oldname = oldname, + newname = newname, + resolution = resolution, + } + end + + jpgconverters["cmyk.pdf"] = function(oldname,newname,resolution) + local rgbprofile, cmykprofile = profiles() + jpgtocmykpdf { + oldname = oldname, + newname = newname, + rgbprofile = rgbprofile, + cmykprofile = cmykprofile, + resolution = resolution, + } + end + + jpgconverters["gray.pdf"] = function(oldname,newname,resolution) + jpgtograypdf { + oldname = oldname, + newname = newname, + resolution = resolution, + } + end + + -- recolor + + local recolorpng = sandbox.registerrunner { + name = "recolor png", + program = "gm", + template = [[convert -recolor "%color%" "%oldname%" "%newname%"]], + checkers = checkers, + defaults = defaults, + } + + -- this is now built in so not really needed any more + + programs.recolor = { runner = recolorpng } + + pngconverters["recolor.png"] = function(oldname,newname,resolution,arguments) + recolorpng { + oldname = oldname, + newname = newname, + resolution = resolution, + color = arguments or ".5 0 0 .7 0 0 .9 0 0", + } + end + +end diff --git a/tex/context/base/mkiv/grph-fig.mkiv b/tex/context/base/mkiv/grph-fig.mkiv index 80b094d83..1fdc0caa0 100644 --- a/tex/context/base/mkiv/grph-fig.mkiv +++ b/tex/context/base/mkiv/grph-fig.mkiv @@ -53,7 +53,7 @@ \fi\fi} \def\grph_buffers_typeset_indeed[#1][#2]% we could use the via files - {\doifnot{#1}{*}{\xdef\lasttypesetbuffer{\clf_runbuffer{#1}}}% + {\doifnot{#1}{*}{\xdef\lasttypesetbuffer{\clf_typesetbuffer{#1}}}% \ifcase\c_grph_buffers_mode % typesetonly \or @@ -61,6 +61,13 @@ \fi \egroup} +\unexpanded\def\runbuffer % for now + {\dotripleempty\grph_buffers_run_indeed} + +\def\grph_buffers_run_indeed[#1][#2]% + {\xdef\lasttypesetbuffer{\clf_runbuffer{#1}{#2}}} + + % For manuals and such: % % \definetypesetting [name] [options] [settings-a] diff --git a/tex/context/base/mkiv/grph-fil.lua b/tex/context/base/mkiv/grph-fil.lua index e774d097e..3c069da37 100644 --- a/tex/context/base/mkiv/grph-fil.lua +++ b/tex/context/base/mkiv/grph-fil.lua @@ -42,6 +42,16 @@ end job.register('job.files.collected', tobesaved, initializer) +local runner = sandbox.registerrunner { + name = "hashed context run", + program = "context", + template = [[%options% "%filename%"]], + checkers = { + options = "string", + filename = "readable", + } +} + function jobfiles.run(name,action) local usedname = addsuffix(name,inputsuffix) -- we assume tex if not set local oldchecksum = collected[usedname] @@ -55,7 +65,10 @@ function jobfiles.run(name,action) if ta == "function" then action(name) elseif ta == "string" and action ~= "" then + -- can be anything but we assume it gets checked by the sandbox os.execute(action) + elseif ta == "table" then + runner(action) else report_run("processing file, no action given for processing %a",name) end @@ -79,7 +92,7 @@ function jobfiles.context(name,options) else local result = replacesuffix(name,resultsuffix) if not done[result] then - jobfiles.run(name,"context ".. (options or "") .. " " .. name) + jobfiles.run(name, { options = options, filename = name }) done[result] = true end return result diff --git a/tex/context/base/mkiv/grph-inc.lua b/tex/context/base/mkiv/grph-inc.lua index d13d45a29..b5e74b4c1 100644 --- a/tex/context/base/mkiv/grph-inc.lua +++ b/tex/context/base/mkiv/grph-inc.lua @@ -40,14 +40,14 @@ run TeX code from within Lua. Some more functionality will move to Lua. -- todo: store loaded pages per pdf file someplace -local format, lower, find, match, gsub, gmatch = string.format, string.lower, string.find, string.match, string.gsub, string.gmatch +local format, lower, find, match, gsub = string.format, string.lower, string.find, string.match, string.gsub +local longtostring = string.longtostring local contains = table.contains local concat, insert, remove = table.concat, table.insert, table.remove local todimen = string.todimen local collapsepath = file.collapsepath local formatters = string.formatters -local longtostring = string.longtostring -local expandfilename = dir.expandname +local formatcolumns = utilities.formatters.formatcolumns local P, R, S, Cc, C, Cs, Ct, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.Cc, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.match @@ -84,34 +84,44 @@ local trace_bases = false trackers.register ("graphics.bases", func local trace_programs = false trackers.register ("graphics.programs", function(v) trace_programs = v end) local trace_conversion = false trackers.register ("graphics.conversion", function(v) trace_conversion = v end) local trace_inclusion = false trackers.register ("graphics.inclusion", function(v) trace_inclusion = v end) +local trace_usage = false trackers.register ("graphics.usage", function(v) trace_usage = v end) -local extra_check = false directives.register("graphics.extracheck", function(v) extra_check = v end) +local extra_check = false directives.register("graphics.extracheck", function(v) extra_check = v end) +local auto_transform = true directives.register("graphics.autotransform", function(v) auto_transform = v end) + +if LUATEXVERSION <= 1 then + auto_transform = false +end local report_inclusion = logs.reporter("graphics","inclusion") local report_figures = logs.reporter("system","graphics") local report_figure = logs.reporter("used graphic") +local report_newline = logs.newline -local f_hash_part = formatters["%s->%s->%s"] -local f_hash_full = formatters["%s->%s->%s->%s->%s->%s->%s"] +local f_hash_part = formatters["%s->%s->%s->%s"] +local f_hash_full = formatters["%s->%s->%s->%s->%s->%s->%s->%s"] -local v_yes = variables.yes -local v_low = variables.low -local v_medium = variables.medium -local v_high = variables.high -local v_global = variables["global"] -local v_local = variables["local"] -local v_default = variables.default -local v_auto = variables.auto +local v_yes = variables.yes +local v_global = variables["global"] +local v_local = variables["local"] +local v_default = variables.default +local v_auto = variables.auto -local maxdimen = 2^30-1 +local maxdimen = 2^30-1 + +local ctx_doscalefigure = context.doscalefigure +local ctx_relocateexternalfigure = context.relocateexternalfigure +local ctx_startfoundexternalfigure = context.startfoundexternalfigure +local ctx_stopfoundexternalfigure = context.stopfoundexternalfigure +local ctx_dosetfigureobject = context.dosetfigureobject +local ctx_doboxfigureobject = context.doboxfigureobject function images.check(figure) if figure then local width = figure.width local height = figure.height if width <= 0 or height <= 0 then - report_inclusion("image %a has bad dimensions (%p,%p), discarding", - figure.filename,width,height) + report_inclusion("image %a has bad dimensions (%p,%p), discarding",figure.filename,width,height) return false, "bad dimensions" end local xres = figure.xres @@ -295,39 +305,31 @@ function figures.badname(name) end end -local trace_names = false - -trackers.register("graphics.lognames", function(v) - if v and not trace_names then - luatex.registerstopactions(function() - if figures.nofprocessed > 0 then - local report_newline = logs.newline - logs.pushtarget("logfile") - report_newline() - report_figures("start names") - for _, data in table.sortedhash(figures_found) do - report_newline() - report_figure("asked : %s",data.askedname) - if data.found then - report_figure("format : %s",data.format) - report_figure("found : %s",data.foundname) - report_figure("used : %s",data.fullname) - if data.badname then - report_figure("comment : %s","bad name") - elseif data.comment then - report_figure("comment : %s",data.comment) - end - else - report_figure("comment : %s","not found") - end +luatex.registerstopactions(function() + if trace_usage and figures.nofprocessed > 0 then + logs.pushtarget("logfile") + report_newline() + report_figures("start names") + for _, data in table.sortedhash(figures_found) do + report_newline() + report_figure("asked : %s",data.askedname) + if data.found then + report_figure("format : %s",data.format) + report_figure("found : %s",data.foundname) + report_figure("used : %s",data.fullname) + if data.badname then + report_figure("comment : %s","bad name") + elseif data.comment then + report_figure("comment : %s",data.comment) end - report_newline() - report_figures("stop names") - report_newline() - logs.poptarget() + else + report_figure("comment : %s","not found") end - end) - trace_names = true + end + report_newline() + report_figures("stop names") + report_newline() + logs.poptarget() end end) @@ -495,6 +497,8 @@ local function new() -- we could use metatables status -> used -> request but it mask = false, conversion = false, resolution = false, + color = false, + arguments = false, cache = false, prefix = false, size = false, @@ -642,6 +646,14 @@ local function rejected(specification) end end +local function wipe(str) + if str == "" or str == "default" or str == "unknown" then + return nil + else + return str + end +end + local function register(askedname,specification) if not specification then specification = { askedname = askedname, comment = "invalid specification" } @@ -656,24 +668,26 @@ local function register(askedname,specification) elseif not rejected(specification) then local format = specification.format if format then - local conversion = specification.conversion - local resolution = specification.resolution - if conversion == "" then - conversion = nil - end - if resolution == "" then - resolution = nil - end - local newformat = conversion + local conversion = wipe(specification.conversion) + local resolution = wipe(specification.resolution) + local arguments = wipe(specification.arguments) + local newformat = conversion if not newformat or newformat == "" then newformat = defaultformat end if trace_conversion then - report_inclusion("checking conversion of %a, fullname %a, old format %a, new format %a, conversion %a, resolution %a", - askedname,specification.fullname,format,newformat,conversion or "default",resolution or "default") + report_inclusion("checking conversion of %a, fullname %a, old format %a, new format %a, conversion %a, resolution %a, arguments %a", + askedname, + specification.fullname, + format, + newformat, + conversion or "default", + resolution or "default", + arguments or "" + ) end -- quick hack - local converter = (newformat ~= format or resolution) and converters[format] + local converter = (newformat ~= format or resolution or arguments) and converters[format] if converter then if converter[newformat] then converter = converter[newformat] @@ -729,8 +743,15 @@ local function register(askedname,specification) if prefix and prefix ~= "" then newbase = prefix .. newbase end - if resolution and resolution ~= "" then -- the order might change - newbase = newbase .. "_" .. resolution + local hash = "" + if resolution then + hash = hash .. "[r:" .. resolution .. "]" + end + if arguments then + hash = hash .. "[a:" .. arguments .. "]" + end + if hash ~= "" then + newbase = newbase .. "_" .. md5.hex(hash) end -- -- see *, we had: @@ -744,7 +765,6 @@ local function register(askedname,specification) -- sticking around) -- local newbase = newbase .. "." .. newformat - -- local newname = file.join(newpath,newbase) oldname = collapsepath(oldname) newname = collapsepath(newname) @@ -754,7 +774,7 @@ local function register(askedname,specification) if trace_conversion then report_inclusion("converting %a (%a) from %a to %a",askedname,oldname,format,newformat) end - converter(oldname,newname,resolution or "") + converter(oldname,newname,resolution or "", arguments or "") else if trace_conversion then report_inclusion("no need to convert %a (%a) from %a to %a",askedname,oldname,format,newformat) @@ -817,7 +837,12 @@ local function register(askedname,specification) specification.foundname = nil end specification.badname = figures.badname(askedname) - local askedhash = f_hash_part(askedname,specification.conversion or "default",specification.resolution or "default") + local askedhash = f_hash_part( + askedname, + specification.conversion or "default", + specification.resolution or "default", + specification.arguments or "" + ) figures_found[askedhash] = specification return specification end @@ -834,16 +859,22 @@ local internalschemes = { local function locate(request) -- name, format, cache -- not resolvers.cleanpath(request.name) as it fails on a!b.pdf and b~c.pdf -- todo: more restricted cleanpath - local askedname = request.name or "" - local askedhash = f_hash_part(askedname,request.conversion or "default",request.resolution or "default") - local foundname = figures_found[askedhash] + local askedname = request.name or "" + local askedcache = request.cache + local askedconversion = request.conversion + local askedresolution = request.resolution + local askedarguments = request.arguments + local askedhash = f_hash_part( + askedname, + askedconversion or "default", + askedresolution or "default", + askedarguments or "" + ) + local foundname = figures_found[askedhash] if foundname then return foundname end -- - local askedcache = request.cache - local askedconversion = request.conversion - local askedresolution = request.resolution -- local askedformat = request.format if not askedformat or askedformat == "" or askedformat == "unknown" then @@ -892,6 +923,7 @@ local function locate(request) -- name, format, cache cache = askedcache, conversion = askedconversion, resolution = askedresolution, + arguments = askedarguments, }) end end @@ -927,6 +959,7 @@ local function locate(request) -- name, format, cache -- foundname = foundname, -- no conversion = askedconversion, resolution = askedresolution, + arguments = askedarguments, internal = internal, }) elseif quitscanning then @@ -947,6 +980,7 @@ local function locate(request) -- name, format, cache cache = askedcache, conversion = askedconversion, resolution = askedresolution, + arguments = askedarguments, }) end else @@ -965,6 +999,7 @@ local function locate(request) -- name, format, cache cache = askedcache, conversion = askedconversion, resolution = askedresolution, + arguments = askedarguments, }) end end @@ -978,6 +1013,7 @@ local function locate(request) -- name, format, cache cache = askedcache, conversion = askedconversion, resolution = askedresolution, + arguments = askedarguments, }) end end @@ -1001,6 +1037,7 @@ local function locate(request) -- name, format, cache cache = askedcache, conversion = askedconversion, resolution = askedresolution, + arguments = askedarguments, }) end end @@ -1035,6 +1072,7 @@ local function locate(request) -- name, format, cache cache = askedcache, conversion = askedconversion, resolution = askedresolution, + arguments = askedarguments }) end end @@ -1062,6 +1100,7 @@ local function locate(request) -- name, format, cache cache = askedcache, conversion = askedconversion, resolution = askedresolution, + arguments = askedarguments, }) end end @@ -1086,6 +1125,7 @@ local function locate(request) -- name, format, cache cache = askedcache, conversion = askedconversion, resolution = askedresolution, + arguments = askedarguments, }) end end @@ -1095,6 +1135,7 @@ local function locate(request) -- name, format, cache return register(askedname, { -- these two are needed for hashing 'found' conversion = askedconversion, resolution = askedresolution, + arguments = askedarguments, }) end @@ -1117,12 +1158,14 @@ end function figures.identify(data) data = data or callstack[#callstack] or lastfiguredata - local list = identifiers.list -- defined at the end - for i=1,#list do - local identifier = list[i] - local data = identifier(data) - if data and (not data.status and data.status.status > 0) then - break + if data then + local list = identifiers.list -- defined at the end + for i=1,#list do + local identifier = list[i] + local data = identifier(data) + if data and (not data.status and data.status.status > 0) then + break + end end end return data @@ -1137,18 +1180,18 @@ function figures.check(data) return (checkers[data.status.format] or checkers.generic)(data) end -local trace_usage = false local used_images = { } -trackers.register("graphics.usage", function(v) - if v and not trace_usage then - luatex.registerstopactions(function() +statistics.register("used graphics",function() + if trace_usage then + local filename = file.nameonly(environment.jobname) .. "-figures-usage.lua" + if next(figures_found) then local found = { } - for _, t in table.sortedhash(figures_found) do - found[#found+1] = t - for k, v in next, t do + for _, data in table.sortedhash(figures_found) do + found[#found+1] = data + for k, v in next, data do if v == false or v == "" then - t[k] = nil + data[k] = nil end end end @@ -1163,18 +1206,20 @@ trackers.register("graphics.usage", function(v) end for _, t in next, u do for k, v in next, t do - if v == false or v == "" then + if v == false or v == "" or k == "private" then t[k] = nil end end end end - table.save(file.nameonly(environment.jobname) .. "-figures-usage.lua",{ + table.save(filename,{ found = found, used = used_images, } ) - end) - trace_usage = true + return format("log saved in '%s'",filename) + else + os.remove(filename) + end end end) @@ -1188,7 +1233,7 @@ end function figures.scale(data) -- will become lua code data = data or callstack[#callstack] or lastfiguredata - context.doscalefigure() + ctx_doscalefigure() return data end @@ -1199,9 +1244,22 @@ function figures.done(data) local box = texgetbox(nr) ds.width = box.width 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 + -- somehow this fails on some of tacos files + -- ds.xscale = ds.width /(du.width or 1) + -- ds.yscale = ds.height/(du.height or 1) + -- du.width and du.height can be false + if du.width and du.height and du.width > 0 and du.height > 0 then + ds.xscale = ds.width /du.width + ds.yscale = ds.height/du.height + elseif du.xsize and du.ysize and du.xsize > 0 and du.ysize > 0 then + ds.xscale = ds.width /du.xsize + ds.yscale = ds.height/du.ysize + else + ds.xscale = 1 + ds.yscale = 1 + end + -- sort of redundant but can be limited + ds.page = ds.page or du.page or dr.page return data end @@ -1244,22 +1302,72 @@ function existers.generic(askedname,resolve) return result end +-- pdf : 0-3: 0 90 180 270 +-- jpeg: 0 unset 1-4: 0 90 180 270 5-8: flipped r/c + +local transforms = setmetatableindex ( + { + ["orientation-1"] = 0, ["R0"] = 0, + ["orientation-2"] = 4, ["R0MH"] = 4, + ["orientation-3"] = 2, ["R180"] = 2, + ["orientation-4"] = 6, ["R0MV"] = 6, + ["orientation-5"] = 5, ["R270MH"] = 5, + ["orientation-6"] = 3, ["R90"] = 3, + ["orientation-7"] = 7, ["R90MH"] = 7, + ["orientation-8"] = 1, ["R270"] = 1, + }, + function(t,k) -- transforms are 0 .. 7 + local v = tonumber(k) or 0 + if v < 0 or v > 7 then + v = 0 + end + t[k] = v + return v + end +) + +local function checktransform(figure,forced) + if auto_transform then + local orientation = (forced ~= "" and forced ~= v_auto and forced) or figure.orientation or 0 + local transform = transforms["orientation-"..orientation] + figure.transform = transform + if math.odd(transform) then + return figure.height, figure.width + else + return figure.width, figure.height + end + end +end + function checkers.generic(data) local dr, du, ds = data.request, data.used, data.status - local name = du.fullname or "unknown generic" - local page = du.page or dr.page - local size = dr.size or "crop" - local color = dr.color or "natural" - local mask = dr.mask or "none" + local name = du.fullname or "unknown generic" + local page = du.page or dr.page + local size = dr.size or "crop" + local color = dr.color or "natural" + local mask = dr.mask or "none" local conversion = dr.conversion local resolution = dr.resolution + local arguments = dr.arguments if not conversion or conversion == "" then - conversion = "unknown" + conversion = "default" end if not resolution or resolution == "" then - resolution = "unknown" - end - local hash = f_hash_full(name,page,size,color,conversion,resolution,mask) + resolution = "default" + end + if not arguments or arguments == "" then + arguments = "default" + end + local hash = f_hash_full( + name, + page, + size, + color, + mask, + conversion, + resolution, + arguments + ) local figure = figures_loaded[hash] if figure == nil then figure = images.new { @@ -1292,8 +1400,10 @@ function checkers.generic(data) end end if figure then - du.width = figure.width - du.height = figure.height + local width, height = checktransform(figure,dr.transform) + -- + du.width = width + du.height = height du.pages = figure.pages du.depth = figure.depth or 0 du.colordepth = figure.colordepth or 0 @@ -1301,6 +1411,8 @@ function checkers.generic(data) du.yresolution = figure.yres or 0 du.xsize = figure.xsize or 0 du.ysize = figure.ysize or 0 + du.rotation = figure.rotation or 0 -- in pdf multiples or 90% in jpeg 1 + du.orientation = figure.orientation or 0 -- jpeg 1 2 3 4 (0=unset) ds.private = figure ds.hash = hash end @@ -1350,7 +1462,7 @@ function includers.generic(data) box.width, box.height, box.depth = figure.width, figure.height, 0 -- new, hm, tricky, we need to do that in tex (yet) texsetbox(nr,box) ds.objectnumber = figure.objnum - context.relocateexternalfigure() + ctx_relocateexternalfigure() end return data end @@ -1367,9 +1479,9 @@ local function checkers_nongeneric(data,command) -- todo: macros and context.* if type(command) == "function" then command() end - context.dosetfigureobject("FIG",hash) + ctx_dosetfigureobject("FIG",hash) end - context.doboxfigureobject("FIG",hash) + ctx_doboxfigureobject("FIG",hash) elseif type(command) == "function" then command() end @@ -1396,7 +1508,7 @@ function checkers.mov(data) report_inclusion("including movie %a, width %p, height %p",foundname,width,height) end -- we need to push the node.write in between ... we could make a shared helper for this - context.startfoundexternalfigure(width .. "sp",height .. "sp") + ctx_startfoundexternalfigure(width .. "sp",height .. "sp") context(function() nodeinjections.insertmovie { width = width, @@ -1409,7 +1521,7 @@ function checkers.mov(data) foundname = foundname, } end) - context.stopfoundexternalfigure() + ctx_stopfoundexternalfigure() return data end @@ -1421,6 +1533,9 @@ internalschemes.mprun = true -- mprun.foo.1 mprun.6 mprun:foo.2 +local ctx_docheckfiguremprun = context.docheckfiguremprun +local ctx_docheckfiguremps = context.docheckfiguremps + local function internal(askedname) local spec, mprun, mpnum = match(lower(askedname),"mprun([:%.]?)(.-)%.(%d+)") if spec ~= "" then @@ -1442,9 +1557,9 @@ end function checkers.mps(data) local mprun, mpnum = internal(data.used.fullname) if mpnum then - return checkers_nongeneric(data,function() context.docheckfiguremprun(mprun,mpnum) end) + return checkers_nongeneric(data,function() ctx_docheckfiguremprun(mprun,mpnum) end) else - return checkers_nongeneric(data,function() context.docheckfiguremps(data.used.fullname) end) + return checkers_nongeneric(data,function() ctx_docheckfiguremps(data.used.fullname) end) end end @@ -1452,19 +1567,23 @@ includers.mps = includers.nongeneric -- -- -- tex -- -- -- +local ctx_docheckfiguretex = context.docheckfiguretex + function existers.tex(askedname) askedname = resolvers.findfile(askedname) return askedname ~= "" and askedname or false, true, "tex", true end function checkers.tex(data) - return checkers_nongeneric(data,function() context.docheckfiguretex(data.used.fullname) end) + return checkers_nongeneric(data,function() ctx_docheckfiguretex(data.used.fullname) end) end includers.tex = includers.nongeneric -- -- -- buffer -- -- -- +local ctx_docheckfigurebuffer = context.docheckfigurebuffer + function existers.buffer(askedname) local name = file.nameonly(askedname) local okay = buffers.exists(name) @@ -1472,7 +1591,7 @@ function existers.buffer(askedname) end function checkers.buffer(data) - return checkers_nongeneric(data,function() context.docheckfigurebuffer(file.nameonly(data.used.fullname)) end) + return checkers_nongeneric(data,function() ctx_docheckfigurebuffer(file.nameonly(data.used.fullname)) end) end includers.buffers = includers.nongeneric @@ -1495,28 +1614,32 @@ includers.auto = includers.generic -- -- -- cld -- -- -- +local ctx_docheckfigurecld = context.docheckfigurecld + function existers.cld(askedname) askedname = resolvers.findfile(askedname) return askedname ~= "" and askedname or false, true, "cld", true end function checkers.cld(data) - return checkers_nongeneric(data,function() context.docheckfigurecld(data.used.fullname) end) + return checkers_nongeneric(data,function() ctx_docheckfigurecld(data.used.fullname) end) end includers.cld = includers.nongeneric -- -- -- converters -- -- -- -local function makeoptions(options) +setmetatableindex(converters,"table") + +-- We keep this helper because it has been around for a while and therefore it can +-- be a depedency in an existing workflow. + +function programs.makeoptions(options) local to = type(options) return (to == "table" and concat(options," ")) or (to == "string" and options) or "" end --- programs.makeoptions = makeoptions - -local function runprogram(binary,argument,variables) - -- move this check to the runner code +function programs.run(binary,argument,variables) local found = nil if type(binary) == "table" then for i=1,#binary do @@ -1551,306 +1674,7 @@ local function runprogram(binary,argument,variables) end end -programs.run = runprogram - --- -- -- eps & pdf -- -- -- --- --- \externalfigure[cow.eps] --- \externalfigure[cow.pdf][conversion=stripped] - -local epsconverter = converters.eps or { } -converters.eps = epsconverter -converters.ps = epsconverter - --- todo: colorspace - -local epstopdf = { - resolutions = { - [v_low] = "screen", - [v_medium] = "ebook", - [v_high] = "prepress", - }, - command = os.type == "windows" and { "gswin64c", "gswin32c" } or "gs", - -- -dProcessDSCComments=false - argument = [[ - -q - -sDEVICE=pdfwrite - -dNOPAUSE - -dNOCACHE - -dBATCH - -dAutoRotatePages=/None - -dPDFSETTINGS=/%presets% - -dEPSCrop - -dCompatibilityLevel=%level% - -sOutputFile="%newname%" - %colorspace% - "%oldname%" - -c quit - ]], -} - -programs.epstopdf = epstopdf -programs.gs = epstopdf - -local cleanups = { } -local cleaners = { } - -local whitespace = lpeg.patterns.whitespace -local quadruple = Ct((whitespace^0 * lpeg.patterns.number/tonumber * whitespace^0)^4) -local betterbox = P("%%BoundingBox:") * quadruple - * P("%%HiResBoundingBox:") * quadruple - * P("%AI3_Cropmarks:") * quadruple - * P("%%CropBox:") * quadruple - / function(b,h,m,c) - return formatters["%%%%BoundingBox: %i %i %i %i\n%%%%HiResBoundingBox: %F %F %F %F\n%%%%CropBox: %F %F %F %F\n"]( - m[1],m[2],m[3],m[4], - m[1],m[2],m[3],m[4], - m[1],m[2],m[3],m[4] - ) - end -local nocrap = P("%") / "" * ( - (P("AI9_PrivateDataBegin") * P(1)^0) / "%%%%EOF" - + (P("%EOF") * whitespace^0 * P("%AI9_PrintingDataEnd") * P(1)^0) / "%%%%EOF" - + (P("AI7_Thumbnail") * (1-P("%%EndData"))^0 * P("%%EndData")) / "" - ) -local whatever = nocrap + P(1) -local pattern = Cs((betterbox * whatever^1 + whatever)^1) - -directives.register("graphics.conversion.eps.cleanup.ai",function(v) cleanups.ai = v end) - -cleaners.ai = function(name) - local tmpname = name .. ".tmp" - io.savedata(tmpname,lpegmatch(pattern,io.loaddata(name) or "")) - return tmpname -end - -function epsconverter.pdf(oldname,newname,resolution,colorspace) -- the resolution interface might change - local epstopdf = programs.epstopdf -- can be changed - local presets = epstopdf.resolutions[resolution or "high"] or epstopdf.resolutions.high - local level = codeinjections.getformatoption("pdf_level") or "1.3" - local tmpname = oldname - if not tmpname or tmpname == "" or not lfs.isfile(tmpname) then - return - end - if cleanups.ai then - tmpname = cleaners.ai(oldname) - end - if colorspace == "gray" then - colorspace = "-sColorConversionStrategy=Gray -sProcessColorModel=DeviceGray" - -- colorspace = "-sColorConversionStrategy=Gray" - else - colorspace = nil - end - runprogram(epstopdf.command, epstopdf.argument, { - newname = newname, - oldname = tmpname, - presets = presets, - level = tostring(level), - colorspace = colorspace, - } ) - if tmpname ~= oldname then - os.remove(tmpname) - end -end - -epsconverter["gray.pdf"] = function(oldname,newname,resolution) -- the resolution interface might change - epsconverter.pdf(oldname,newname,resolution,"gray") -end - -epsconverter.default = epsconverter.pdf - -local pdfconverter = converters.pdf or { } -converters.pdf = pdfconverter - --- programs.pdftoeps = { --- command = "pdftops", --- argument = [[-eps "%oldname%" "%newname%"]], --- } --- --- pdfconverter.stripped = function(oldname,newname) --- local pdftoeps = programs.pdftoeps -- can be changed --- local epstopdf = programs.epstopdf -- can be changed --- local presets = epstopdf.resolutions[resolution or ""] or epstopdf.resolutions.high --- local level = codeinjections.getformatoption("pdf_level") or "1.3" --- local tmpname = newname .. ".tmp" --- runprogram(pdftoeps.command, pdftoeps.argument, { oldname = oldname, newname = tmpname, presets = presets, level = level }) --- runprogram(epstopdf.command, epstopdf.argument, { oldname = tmpname, newname = newname, presets = presets, level = level }) --- os.remove(tmpname) --- end --- --- figures.registersuffix("stripped","pdf") - --- -- -- svg -- -- -- - -local svgconverter = { } -converters.svg = svgconverter -converters.svgz = svgconverter - --- inkscape on windows only works with complete paths - -programs.inkscape = { - command = "inkscape", - pdfargument = [[ - "%oldname%" - --export-dpi=600 - -A - "%newname%" - ]], - pngargument = [[ - "%oldname%" - --export-dpi=600 - --export-png="%newname%" - ]], -} - -function svgconverter.pdf(oldname,newname) - local inkscape = programs.inkscape -- can be changed - runprogram(inkscape.command, inkscape.pdfargument, { - newname = expandfilename(newname), - oldname = expandfilename(oldname), - } ) -end - -function svgconverter.png(oldname,newname) - local inkscape = programs.inkscape - runprogram(inkscape.command, inkscape.pngargument, { - newname = expandfilename(newname), - oldname = expandfilename(oldname), - } ) -end - -svgconverter.default = svgconverter.pdf - --- -- -- gif -- -- -- --- -- -- tif -- -- -- - -local gifconverter = converters.gif or { } -local tifconverter = converters.tif or { } -local bmpconverter = converters.bmp or { } - -converters.gif = gifconverter -converters.tif = tifconverter -converters.bmp = bmpconverter - -programs.convert = { - command = "gm", -- graphicmagick - argument = [[convert "%oldname%" "%newname%"]], -} - -local function converter(oldname,newname) - local convert = programs.convert - runprogram(convert.command, convert.argument, { - newname = newname, - oldname = oldname, - } ) -end - -tifconverter.pdf = converter -gifconverter.pdf = converter -bmpconverter.pdf = converter - -gifconverter.default = converter -tifconverter.default = converter -bmpconverter.default = converter - --- todo: lowres - --- cmyk conversion - --- ecirgb_v2.icc --- ecirgb_v2_iccv4.icc --- isocoated_v2_300_eci.icc --- isocoated_v2_eci.icc --- srgb.icc --- srgb_v4_icc_preference.icc - --- [[convert %?colorspace: -colorspace "%colorspace%" ?%]] - -local rgbprofile = "srgb_v4_icc_preference.icc" -- srgb.icc -local cmykprofile = "isocoated_v2_300_eci.icc" -- isocoated_v2_eci.icc - -directives.register("graphics.conversion.rgbprofile", function(v) rgbprofile = type(v) == "string" and v or rgbprofile end) -directives.register("graphics.conversion.cmykprofile",function(v) cmykprofile = type(v) == "string" and v or cmykprofile end) - -local function profiles() - if not lfs.isfile(rgbprofile) then - local found = resolvers.findfile(rgbprofile) - if found and found ~= "" then - rgbprofile = found - else - report_figures("unknown profile %a",rgbprofile) - end - end - if not lfs.isfile(cmykprofile) then - local found = resolvers.findfile(cmykprofile) - if found and found ~= "" then - cmykprofile = found - else - report_figures("unknown profile %a",cmykprofile) - end - end - return rgbprofile, cmykprofile -end - -programs.pngtocmykpdf = { - command = "gm", - argument = [[convert -compress Zip -strip +profile "*" -profile "%rgbprofile%" -profile "%cmykprofile%" -sampling-factor 1x1 "%oldname%" "%newname%"]], -} - -programs.jpgtocmykpdf = { - command = "gm", - argument = [[convert -compress JPEG -strip +profile "*" -profile "%rgbprofile%" -profile "%cmykprofile%" -sampling-factor 1x1 "%oldname%" "%newname%"]], -} - -programs.pngtograypdf = { - command = "gm", - argument = [[convert -colorspace gray -compress Zip -sampling-factor 1x1 "%oldname%" "%newname%"]], -} - -programs.jpgtograypdf = { - command = "gm", - argument = [[convert -colorspace gray -compress Zip -sampling-factor 1x1 "%oldname%" "%newname%"]], -} - -figures.converters.png = { - ["cmyk.pdf"] = function(oldname,newname,resolution) - local rgbprofile, cmykprofile = profiles() - runprogram(programs.pngtocmykpdf.command, programs.pngtocmykpdf.argument, { - -- runprogram(programs.pngtocmykpdf, { - rgbprofile = rgbprofile, - cmykprofile = cmykprofile, - oldname = oldname, - newname = newname, - } ) - end, - ["gray.pdf"] = function(oldname,newname,resolution) - runprogram(programs.pngtograypdf.command, programs.pngtograypdf.argument, { - -- runprogram(programs.pngtograypdf, { - oldname = oldname, - newname = newname, - } ) - end, -} - -figures.converters.jpg = { - ["cmyk.pdf"] = function(oldname,newname,resolution) - local rgbprofile, cmykprofile = profiles() - runprogram(programs.jpgtocmykpdf.command, programs.jpgtocmykpdf.argument, { - -- runprogram(programs.jpgtocmykpdf, { - rgbprofile = rgbprofile, - cmykprofile = cmykprofile, - oldname = oldname, - newname = newname, - } ) - end, - ["gray.pdf"] = function(oldname,newname,resolution) - runprogram(programs.jpgtograypdf.command, programs.jpgtograypdf.argument, { - -- runprogram(programs.jpgtograypdf, { - oldname = oldname, - newname = newname, - } ) - end, -} +-- the rest of the code has been moved to grph-con.lua -- -- -- bases -- -- -- @@ -2072,7 +1896,9 @@ implement { { "conversion" }, { "resolution" }, { "color" }, + { "arguments" }, { "repeat" }, + { "transform" }, { "width", "dimen" }, { "height", "dimen" }, } @@ -2122,6 +1948,8 @@ implement { local registered = { } +local ctx_doexternalfigurerepeat = context.doexternalfigurerepeat + interfaces.implement { name = "figure_register_page", arguments = { "string", "string", "string" }, @@ -2144,7 +1972,7 @@ interfaces.implement { actions = function(n) local f = registered[tonumber(n)] if f then - context.doexternalfigurerepeat(f[1],f[2],f[3],n) + ctx_doexternalfigurerepeat(f[1],f[2],f[3],n) end end } diff --git a/tex/context/base/mkiv/grph-inc.mkiv b/tex/context/base/mkiv/grph-inc.mkiv index de5a2227a..25058b3f7 100644 --- a/tex/context/base/mkiv/grph-inc.mkiv +++ b/tex/context/base/mkiv/grph-inc.mkiv @@ -21,7 +21,9 @@ \writestatus{loading}{ConTeXt Graphic Macros / Figure Inclusion} \registerctxluafile{grph-inc}{1.001} +\registerctxluafile{grph-con}{1.001} \registerctxluafile{grph-fil}{1.001} +\registerctxluafile{grph-mem}{1.001} \registerctxluafile{grph-u3d}{1.001} % this will change \registerctxluafile{grph-swf}{1.001} % this will change @@ -59,6 +61,7 @@ \c!preset =\v!yes, \c!split =, \c!color =, + \c!arguments =, \c!symbol =\v!no, \c!controls =\v!no, \c!resources =, @@ -100,6 +103,7 @@ \c!xmax =, \c!align =\v!none, % New, for Tacos extremely large graphics. \c!crossreference =\v!no, + \c!transform =\v!auto, ] %D Defining figures. @@ -312,7 +316,7 @@ \edef\p_reference{\externalfigureparameter\c!reference}% % \dostarttagged\t!image\empty - \clf_figure_push + \clf_figure_push { name {\p_grph_include_name}% label {\ifx\p_label\empty\p_grph_include_label\else\p_label\fi}% page {\externalfigureparameter\c!page}% @@ -329,15 +333,17 @@ mask {\externalfigureparameter\c!mask}% conversion {\externalfigureparameter\c!conversion}% resolution {\externalfigureparameter\c!resolution}% - color {\internalspotcolorparent{\externalfigureparameter\c!color}}% hack is needed + color {\externalfigureparameter\c!color}% unprocessed raw key + arguments {\externalfigureparameter\c!arguments}% used for converters repeat {\externalfigureparameter\c!repeat}% + transform {\externalfigureparameter\c!transform}% \ifx\p_width\empty \else width \dimexpr\p_width\relax \fi \ifx\p_height\empty \else height \dimexpr\p_height\relax \fi - \relax + }%\relax \clf_figure_identify \relax \ifconditional\c_grph_include_test_only @@ -527,6 +533,9 @@ \def\figurefilepage {\clf_figurerequest{page}{1}} \def\figurefileoptions {\clf_figurerequest{options}{}} \def\figurefileconversion{\clf_figurerequest{conversion}{}} +\def\figurefileresolution{\clf_figurerequest{resolution}{}} +\def\figurefilecolor {\clf_figurerequest{color}{}} +\def\figurefilearguments {\clf_figurerequest{arguments}{}} \def\figurefilecache {\clf_figurerequest{cache}{}} \def\figurefileprefix {\clf_figurerequest{prefix}{}} @@ -534,6 +543,8 @@ \def\figurenaturalheight {\clf_figureused{height}{\number\dimexpr\defaultfigureheight\relax}sp} \def\figurexresolution {\clf_figureused{xresolution}{0}} \def\figureyresolution {\clf_figureused{yresolution}{0}} +\def\figureorientation {\clf_figureused{orientation}{1}} +\def\figurerotation {\clf_figureused{rotation}{0}} \def\figurexsize {\clf_figureused{xsize}{0}} \def\figureysize {\clf_figureused{ysize}{0}} \def\figurecolordepth {\clf_figureused{colordepth}{0}} @@ -859,12 +870,184 @@ [\jobname.buffer] [\c!object=\v!no] -% Another one: +% Another two: \defineexternalfigure [\v!inline] [\c!height=\lineheight] +\defineexternalfigure + [\v!combination] + [\c!width=\dimexpr(% + \textwidth-\effectiveleftskip-\effectiverightskip + -\numexpr\combinationparameter\c!nx-\plusone\relax\dimexpr\combinationparameter\c!distance\relax + )/\combinationparameter\c!nx\relax] + +% \startcombination[nx=2,ny=1] +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% \stopcombination + +% \startcombination[nx=2,ny=2] +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% \stopcombination + +% \startcombination[nx=3,ny=1] +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% \stopcombination + +% \startcombination[nx=4,ny=1] +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% {\externalfigure[dummy][combination]} {} +% \stopcombination + \unexpanded\def\inlinefigure[#1]{\dontleavehmode\sbox{\externalfigure[#1][\v!inline]}} \protect \endinput + +% Moved here because this already old code is nowhere documents (so I need to +% check it: +% +% \starttext +% +% \startluaparameterset [u3d:myset:controls:1] +% view = { +% name = 'default', +% bg = {1,1,1}, +% mag = 100, +% coo = {0,0,0}, +% c2c = {0,0,1}, +% rot = {40,0,60}, +% roo = 6, +% lights = 'CAD' +% }, +% js = 'cloudq.js' +% \stopluaparameterset +% +% \startluaparameterset [u3d:myset:controls:2] +% views = { +% { +% name = 'AnglePositioning', +% bg = {1,1,1}, +% azimuth = 45, +% altitude = 45, +% roo = 50, +% aac = 2.5, +% lights = 'Artwork' +% }, +% { +% name = 'RotationPositioning', +% bg = {1,1,1}, +% rot = {0,45,45}, +% roo = 50, +% aac = 2.5, +% lights = 'Artwork' +% }, +% { +% name = 'VectorPositioning', +% bg = {1,0,0}, +% c2c = {1,1,math.sqrt(2)}, +% roo = 50, +% aac = 2.5, +% lights = 'CAD' +% }, +% { +% name = 'PositionPositioning', +% bg = {1,0,0}, +% pos = {1+25,1+25,1+50/math.sqrt(2)}, +% aac = 2.5, +% lights = 'CAD' +% }, +% { +% name = 'ortho', +% bg = {1,1,1}, +% mag = 300, +% lights = 'CAD', +% crossection = {} +% } +% }, +% view = { +% name = 'default', +% bg = {1,1,1}, +% c2c = {-1,-1,0}, +% roo = 50, +% aac = 2.5, +% roll = 45, +% lights = 'CAD', +% crossection = { +% normal = {-1,-1,-1}, +% transparent = true +% }, +% nodes = { +% { +% name = 'xlabel', +% visible = false +% }, +% { +% name = 'ylabel', +% opacity = 0.5 +% }, +% { +% name = 'zlabel', +% rendermode = 'Wireframe' +% } +% } +% } +% \stopluaparameterset +% +% \useexternalfigure +% [cloudq] +% [cloudq.u3d] +% [width=0.7\textwidth, +% height=.7\textwidth, +% display=u3d:myset:display:1, +% controls=u3d:myset:controls:1] +% +% \useexternalfigure +% [axes] +% [axes.u3d] +% [width=0.7\textwidth, +% height=.7\textwidth, +% controls=u3d:myset:controls:1] +% +% \startluaparameterset[u3d:myset:display:2] +% toolbar = true, +% preview = 'cloudq.png' +% \stopluaparameterset +% \startluaparameterset[u3d:myset:display:3] +% toolbar = true, +% tree = false, +% preview = 'axes.png' +% \stopluaparameterset +% \startluaparameterset[u3d:myset:display:4] +% toolbar = true, +% tree = false, +% view = { +% name = 'view', +% bg = {0.1,0.1,0.1}, +% c2c = {-1,-1,0}, +% roo = 50, +% aac = 2.5, +% roll = 45, +% lights = 'Red' +% } +% \stopluaparameterset +% \startluaparameterset[u3d:myset:display:5] +% toolbar = true, +% tree = false, +% view = 'ortho' +% \stopluaparameterset +% +% \placefigure[here]{none}{\externalfigure[cloudq][frame=on,display=u3d:myset:display:2]} +% \placefigure[here]{none}{\externalfigure[axes] [frame=on,display=u3d:myset:display:3]} +% \placefigure[here]{none}{\externalfigure[axes] [frame=on,display=u3d:myset:display:4]} +% \placefigure[here]{none}{\externalfigure[axes] [frame=on,display=u3d:myset:display:5,width=0.5\textwidth,height=.5\textwidth]} +% +% \stoptext diff --git a/tex/context/base/mkiv/grph-mem.lua b/tex/context/base/mkiv/grph-mem.lua new file mode 100644 index 000000000..bb48ae8d5 --- /dev/null +++ b/tex/context/base/mkiv/grph-mem.lua @@ -0,0 +1,106 @@ +if not modules then modules = { } end modules ['grph-mem'] = { + version = 1.001, + comment = "companion to grph-inc.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- very experimental and likely to change +-- +-- \startluacode +-- figures.setmemstream("whatever",io.loaddata("t:/sources/cow.pdf")) +-- \stopluacode +-- +-- \externalfigure[memstream:///t:/sources/cow.pdf] +-- \externalfigure[memstream:///whatever] + +local gsub = string.gsub + +local report = logs.reporter("memstream") +local trace = false trackers.register ("graphics.memstreams", function(v) trace = v end) +local data = { } +local opened = { } + +local function setmemstream(name,stream,once) + if once and data[name] then + if trace then + report("not overloading %a",name) -- + end + return data[name] + end + local memstream, identifier = epdf.openMemStream(stream,#stream,name) + if not identifier then + report("no valid stream %a",name) + identifier = "invalid-memstream" + elseif trace then + report("setting %a with identifier %a",name,identifier) + end + data [name] = identifier + opened[name] = memstream + return identifier +end + +resolvers.setmemstream = setmemstream + +function resolvers.finders.memstream(specification) + local name = specification.path + local identifier = data[name] + if identifier then + if trace then + report("reusing %a with identifier %a",name,identifier) + end + return identifier + end + local stream = io.loaddata(name) + if not stream or stream == "" then + if trace then + report("no valid file %a",name) + end + return resolvers.finders.notfound() + else + return setmemstream(name,stream) + end +end + +local flush = { } + +function resolvers.resetmemstream(name,afterpage) + if afterpage then + flush[#flush+1] = name + else + opened[name] = nil + end +end + +luatex.registerpageactions(function() + if #flush > 0 then + for i=1,#flush do + opened[flush[i]] = nil -- we keep of course data[name] because of reuse + end + flush = { } + end +end) + +figures.identifiers.list[#figures.identifiers.list+1] = function(specification) + local name = specification.request.name + if name then + local base = gsub(name,"^memstream:///","") + if base ~= name then + local identifier = data[base] + if identifier then + if trace then + report("requested %a has identifier %s",name,identifier) + end + specification.status.status = 1 + specification.used.fullname = name + else + if trace then + report("requested %a is not found",name) + end + end + end + end +end + +figures.setmemstream = resolvers.setmemstream diff --git a/tex/context/base/mkiv/grph-pat.lua b/tex/context/base/mkiv/grph-pat.lua new file mode 100644 index 000000000..c5e4b9f64 --- /dev/null +++ b/tex/context/base/mkiv/grph-pat.lua @@ -0,0 +1,74 @@ +if not modules then modules = { } end modules ['grph-pat'] = { + version = 1.001, + comment = "companion to grph-pat.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is just a proof of concept. Viewers behave different (offsets) and Acrobat doesn't +-- show xform based patterns. +-- +-- This module will be cleaned up and use codeinjections and such. + +local texsetbox = tex.setbox +local texgetbox = tex.getbox + +local nodepool = nodes.pool +local new_literal = nodepool.pdforiginliteral -- really ? +local new_hlist = nodepool.hlist + +local names = { } + +interfaces.implement { + name = "registerpattern", + arguments = { { + { "name" }, + { "number", "integer" }, + { "width", "dimension" }, + { "height", "dimension" }, + { "hoffset", "dimension" }, + { "voffset", "dimension" }, + } }, + actions = function(specification) + local number = specification.number + local name = specification.name + local box = texgetbox(number) + if not name or name == "" then + return + end + nodes.handlers.finalize(box) + names[name] = lpdf.registerpattern { + number = number, + width = specification.width or box.width, + height = specification.height or (box.height + box.depth) , + hoffset = specification.hoffset, + voffset = specification.voffset, + } + end +} + +interfaces.implement { + name = "applypattern", + arguments = { { + { "name" }, + { "number", "integer" }, + { "width", "dimension" }, + { "height", "dimension" }, + } }, + actions = function(specification) + local number = specification.number + local name = specification.name + local width = specification.width + local height = specification.height + if not name or name == "" then + return + end + local p = names[name] + if p then + local l = new_literal(lpdf.patternstream(p,width,height)) + local h = new_hlist(l,width,height) + texsetbox(number,h) + end + end +} diff --git a/tex/context/base/mkiv/grph-pat.mkiv b/tex/context/base/mkiv/grph-pat.mkiv new file mode 100644 index 000000000..0126647cc --- /dev/null +++ b/tex/context/base/mkiv/grph-pat.mkiv @@ -0,0 +1,125 @@ +%D \module +%D [ file=grph-par, +%D version=2016.07.08, +%D title=\CONTEXT\ Graphic Macros, +%D subtitle=Patterns, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This works ok in Okular and MuPDF but somehow xforms don't work in Acrobat +%D (full nor reader). Also the basic offset is kind of unspecified. So \unknown\ +%D we're dealing with a fragile feature. So, don't rely on where the first (ulr) +%D tile occurs. +%D +%D The two commands introduced here are not documented (yet). + +\writestatus{loading}{ConTeXt Graphic Macros / Patterns} + +\unprotect + +\registerctxluafile{grph-pat}{1.001} + +\unexpanded\def\registerpattern + {\begingroup + \letdummyparameter\c!name \s!dummy + \letdummyparameter\c!width \v!auto + \letdummyparameter\c!height \v!auto + \letdummyparameter\c!hoffset\zeropoint + \letdummyparameter\c!voffset\zeropoint + \dodoubleempty\syst_boxes_registerpattern} + +\def\syst_boxes_registerpattern[#1][#2]% + {\ifsecondargument + \setdummyparameter\c!name{#1}% + \getdummyparameters[#2]% + \else\iffirstargument + \doifassignmentelse{#1} + {\getdummyparameters[#1]}% + {\setdummyparameter\c!name{#1}}% + \fi\fi + \dowithnextboxcs\syst_boxes_registerpattern_indeed\hbox} + +\edef\v!auto_m{-\v!auto} + +\def\syst_boxes_registerpattern_indeed + {%\finalizeobjectbox\nextbox + \edef\p_width {\dummyparameter\c!width}% + \edef\p_height {\dummyparameter\c!height}% + \edef\p_hoffset{\dummyparameter\c!hoffset}% + \edef\p_voffset{\dummyparameter\c!voffset}% + \scratchwidth \dimexpr\ifx\p_width \v!auto\wd \nextbox \else\p_width \fi\relax + \scratchheight \dimexpr\ifx\p_height \v!auto\htdp\nextbox \else\p_height \fi\relax + \scratchhoffset\dimexpr\ifx\p_hoffset\v!auto\scratchwidth /2\else\ifx\p_hoffset\v!auto_m-\scratchwidth /2\else\p_hoffset\fi\fi\relax + \scratchvoffset\dimexpr\ifx\p_voffset\v!auto\scratchheight/2\else\ifx\p_voffset\v!auto_m-\scratchheight/2\else\p_voffset\fi\fi\relax + \clf_registerpattern + name {\dummyparameter\c!name} + number \nextbox + width \scratchwidth + height \scratchheight + hoffset \scratchhoffset + voffset \scratchvoffset + \relax + \endgroup} + +\unexpanded\def\applypattern + {\hbox\bgroup + \letdummyparameter\c!name \s!dummy + \letdummyparameter\c!width \zeropoint + \letdummyparameter\c!height\zeropoint + \dodoubleempty\syst_boxes_applypattern} + +\def\syst_boxes_applypattern[#1][#2]% + {\ifsecondargument + \setdummyparameter\c!name{#1}% + \getdummyparameters[#2]% + \else\iffirstargument + \doifassignmentelse{#1} + {\getdummyparameters[#1]}% + {\setdummyparameter\c!name{#1}}% + \fi\fi + \clf_applypattern + name {\dummyparameter\c!name} + number \nextbox + width \dimexpr\dummyparameter\c!width\relax + height \dimexpr\dummyparameter\c!height\relax + \relax + \box\nextbox + \egroup} + +\protect + +\continueifinputfile{grph-pat.mkiv} + +\nopdfcompression + +\starttext + + \registerpattern[demo]{It \darkred Works!} + + \framed[offset=overlay]{\applypattern[demo][width=7cm,height=4cm]} + + \blank + + \registerpattern[name=more,hoffset=0bp,voffset=0pt]{\externalfigure[cow.pdf][width=1cm]} + + \framed[offset=overlay]{\applypattern[name=more,width=7cm,height=4cm]} + + \blank + + \registerpattern[name=more,hoffset=auto,voffset=auto]{\externalfigure[cow.pdf][width=1cm]} + + \framed[offset=overlay]{\applypattern[name=more,width=7cm,height=4cm]} + + \blank + + \registerpattern[name=more,hoffset=-auto,voffset=-auto]{\externalfigure[cow.pdf][width=1cm]} + + \framed[offset=overlay]{\applypattern[name=more,width=7cm,height=4cm]} + +\stoptext + diff --git a/tex/context/base/mkiv/grph-rul.lua b/tex/context/base/mkiv/grph-rul.lua index 556763812..e3d1d8963 100644 --- a/tex/context/base/mkiv/grph-rul.lua +++ b/tex/context/base/mkiv/grph-rul.lua @@ -15,11 +15,14 @@ local userrule = nodes.rules.userrule local bpfactor = number.dimenfactors.bp local pdfprint = pdf.print +local current_attr = nodes.current_attr +local setfield = nodes.setfield + local getattribute = tex.getattribute local a_color = attributes.private('color') local a_transparency = attributes.private('transparency') -local a_colorspace = attributes.private('colormodel') +local a_colormodel = attributes.private('colormodel') local mpcolor = attributes.colors.mpcolor @@ -28,7 +31,7 @@ local trace_mp = false trackers.register("rules.mp", function(v) trace_mp local report_mp = logs.reporter("rules","mp") local floor = math.floor -local random = math.random +local getrandom = utilities.randomizer.get local formatters = string.formatters do @@ -77,6 +80,8 @@ RuleOption := "%option%" ; RuleWidth := %width% ; RuleHeight := %height% ; RuleDepth := %depth% ; +RuleH := %h% ; +RuleV := %v% ; RuleThickness := %line% ; RuleFactor := %factor% ; RuleOffset := %offset% ; @@ -100,11 +105,13 @@ def RuleColor = %color% enddef ; color = mpcolor(p.ma,p.ca,p.ta), option = p.option or "", direction = p.direction or "TLT", + h = h * bpfactor, + v = v * bpfactor, } if not initialized then initialized = true - simplemetapost("rulefun",formatters["randomseed := %s;"](random(0,4095))) + simplemetapost("rulefun",formatters["randomseed := %s;"](getrandom("rulefun",0,4095))) end local pdf = caching and cache[code] or simplemetapost("rulefun",code) -- w, h, d if trace_mp then @@ -168,20 +175,22 @@ interfaces.implement { { "name", "string" }, } } , actions = function(t) - local r = userrule(t) - local ma = getattribute(a_colorspace) or 1 + -- no nuts ! + local rule = userrule(t) + local ma = getattribute(a_colormodel) or 1 local ca = getattribute(a_color) local ta = getattribute(a_transparency) + setfield(rule,"attr",current_attr()) if t.type == "mp" then t.ma = ma t.ca = ca t.ta = ta else - r[a_colorspace] = ma - r[a_color] = ca - r[a_transparency] = ta + rule[a_colormodel] = ma + rule[a_color] = ca + rule[a_transparency] = ta end - context(r) + context(rule) end } @@ -196,17 +205,19 @@ interfaces.implement { } } , actions = function(t) local factor = t.factor or 0 + local amount = getrandom("fakeword",t.min,t.max) local rule = userrule { height = 1.25*factor, depth = 0.25*factor, - width = floor(random(t.min,t.max)/10000) * 10000, + width = floor(amount/10000) * 10000, line = 0.10*factor, - ma = getattribute(a_colorspace) or 1, + ma = getattribute(a_colormodel) or 1, ca = getattribute(a_color), ta = getattribute(a_transparency), type = "mp", name = t.name, } + setfield(rule,"attr",current_attr()) context(rule) end } diff --git a/tex/context/base/mkiv/grph-u3d.lua b/tex/context/base/mkiv/grph-u3d.lua index 6961c5503..748f9808d 100644 --- a/tex/context/base/mkiv/grph-u3d.lua +++ b/tex/context/base/mkiv/grph-u3d.lua @@ -47,5 +47,8 @@ end figures.includers.u3d = figures.includers.nongeneric +-- figures.checkers .prc = figures.checkers.u3d +-- figures.includers.prc = figures.includers.nongeneric + figures.registersuffix("u3d","u3d") figures.registersuffix("prc","u3d") diff --git a/tex/context/base/mkiv/l-dir.lua b/tex/context/base/mkiv/l-dir.lua index 81ac65e50..bc691d536 100644 --- a/tex/context/base/mkiv/l-dir.lua +++ b/tex/context/base/mkiv/l-dir.lua @@ -335,6 +335,36 @@ end dir.globfiles = globfiles +local function globdirs(path,recurse,func,files) -- func == pattern or function + if type(func) == "string" then + local s = func + func = function(name) return find(name,s) end + end + files = files or { } + local noffiles = #files + for name in walkdir(path) do + if find(name,"^%.") then + --- skip + else + local mode = attributes(name,'mode') + if mode == "directory" then + if not func or func(name) then + noffiles = noffiles + 1 + files[noffiles] = path .. "/" .. name + if recurse then + globdirs(path .. "/" .. name,recurse,func,files) + end + end + end + end + end + return files +end + +dir.globdirs = globdirs + +-- inspect(globdirs("e:/tmp")) + -- t = dir.glob("c:/data/develop/context/sources/**/????-*.tex") -- t = dir.glob("c:/data/develop/tex/texmf/**/*.tex") -- t = dir.glob("c:/data/develop/context/texmf/**/*.tex") @@ -557,9 +587,13 @@ file.expandname = dir.expandname -- for convenience local stack = { } function dir.push(newdir) - insert(stack,currentdir()) + local curdir = currentdir() + insert(stack,curdir) if newdir and newdir ~= "" then chdir(newdir) + return newdir + else + return curdir end end diff --git a/tex/context/base/mkiv/l-file.lua b/tex/context/base/mkiv/l-file.lua index b6822e954..f2a27ad18 100644 --- a/tex/context/base/mkiv/l-file.lua +++ b/tex/context/base/mkiv/l-file.lua @@ -607,14 +607,17 @@ function file.robustname(str,strict) end end -file.readdata = io.loaddata -file.savedata = io.savedata +local loaddata = io.loaddata +local savedata = io.savedata + +file.readdata = loaddata +file.savedata = savedata function file.copy(oldname,newname) if oldname and newname then - local data = io.loaddata(oldname) + local data = loaddata(oldname) if data and data ~= "" then - file.savedata(newname,data) + savedata(newname,data) end end end diff --git a/tex/context/base/mkiv/l-io.lua b/tex/context/base/mkiv/l-io.lua index a91d44d87..75e704a34 100644 --- a/tex/context/base/mkiv/l-io.lua +++ b/tex/context/base/mkiv/l-io.lua @@ -7,6 +7,7 @@ if not modules then modules = { } end modules ['l-io'] = { } local io = io +local open, flush, write, read = io.open, io.flush, io.write, io.read local byte, find, gsub, format = string.byte, string.find, string.gsub, string.format local concat = table.concat local floor = math.floor @@ -18,59 +19,136 @@ else io.fileseparator, io.pathseparator = "/" , ":" end -local function readall(f) - return f:read("*all") -end +-- local function readall(f) +-- return f:read("*all") +-- end -- The next one is upto 50% faster on large files and less memory consumption due -- to less intermediate large allocations. This phenomena was discussed on the -- luatex dev list. +local large = 2^24 -- 16 MB +local medium = large / 16 -- 1 MB +local small = medium / 8 + +-- local function readall(f) +-- local size = f:seek("end") +-- if size == 0 then +-- return "" +-- end +-- f:seek("set",0) +-- if size < medium then +-- return f:read('*all') +-- else +-- local step = (size > large) and large or (floor(size/(medium)) * small) +-- local data = { } +-- while true do +-- local r = f:read(step) +-- if not r then +-- return concat(data) +-- else +-- data[#data+1] = r +-- end +-- end +-- end +-- end + local function readall(f) +-- return f:read("*all") local size = f:seek("end") - if size == 0 then - return "" - elseif size < 1024*1024 then + if size > 0 then f:seek("set",0) - return f:read('*all') + return f:read(size) else - local done = f:seek("set",0) - local step - if size < 1024*1024 then - step = 1024 * 1024 - elseif size > 16*1024*1024 then - step = 16*1024*1024 - else - step = floor(size/(1024*1024)) * 1024 * 1024 / 8 - end - local data = { } - while true do - local r = f:read(step) - if not r then - return concat(data) - else - data[#data+1] = r - end - end + return "" end end io.readall = readall function io.loaddata(filename,textmode) -- return nil if empty - local f = io.open(filename,(textmode and 'r') or 'rb') + local f = open(filename,(textmode and 'r') or 'rb') if f then - -- local data = f:read('*all') - local data = readall(f) + local size = f:seek("end") + local data = nil + if size > 0 then + -- data = f:read("*all") + f:seek("set",0) + data = f:read(size) + end f:close() - if #data > 0 then - return data + return data + end +end + +-- function io.copydata(source,target,action) +-- local f = open(source,"rb") +-- if f then +-- local g = open(target,"wb") +-- if g then +-- local size = f:seek("end") +-- if size == 0 then +-- -- empty +-- else +-- f:seek("set",0) +-- if size < medium then +-- local data = f:read('*all') +-- if action then +-- data = action(data) +-- end +-- if data then +-- g:write(data) +-- end +-- else +-- local step = (size > large) and large or (floor(size/(medium)) * small) +-- while true do +-- local data = f:read(step) +-- if data then +-- if action then +-- data = action(data) +-- end +-- if data then +-- g:write(data) +-- end +-- else +-- break +-- end +-- end +-- end +-- end +-- g:close() +-- end +-- f:close() +-- flush() +-- end +-- end + +function io.copydata(source,target,action) + local f = open(source,"rb") + if f then + local g = open(target,"wb") + if g then + local size = f:seek("end") + if size > 0 then + -- local data = f:read('*all') + f:seek("set",0) + local data = f:read(size) + if action then + data = action(data) + end + if data then + g:write(data) + end + end + g:close() end + f:close() + flush() end end function io.savedata(filename,data,joiner) - local f = io.open(filename,"wb") + local f = open(filename,"wb") if f then if type(data) == "table" then f:write(concat(data,joiner or "")) @@ -80,7 +158,7 @@ function io.savedata(filename,data,joiner) f:write(data or "") end f:close() - io.flush() + flush() return true else return false @@ -89,36 +167,74 @@ end -- we can also chunk this one if needed: io.lines(filename,chunksize,"*l") -function io.loadlines(filename,n) -- return nil if empty - local f = io.open(filename,'r') - if not f then - -- no file - elseif n then - local lines = { } - for i=1,n do - local line = f:read("*lines") - if line then - lines[#lines+1] = line - else - break +-- ffi.readline + +if fio and fio.readline then + + local readline = fio.readline + + function io.loadlines(filename,n) -- return nil if empty + local f = open(filename,'r') + if not f then + -- no file + elseif n then + local lines = { } + for i=1,n do + local line = readline(f) + if line then + lines[i] = line + else + break + end + end + f:close() + lines = concat(lines,"\n") + if #lines > 0 then + return lines + end + else + local line = readline(f) + f:close() + if line and #line > 0 then + return line end end - f:close() - lines = concat(lines,"\n") - if #lines > 0 then - return lines - end - else - local line = f:read("*line") or "" - f:close() - if #line > 0 then - return line + end + +else + + function io.loadlines(filename,n) -- return nil if empty + local f = open(filename,'r') + if not f then + -- no file + elseif n then + local lines = { } + for i=1,n do + local line = f:read("*lines") + if line then + lines[i] = line + else + break + end + end + f:close() + lines = concat(lines,"\n") + if #lines > 0 then + return lines + end + else + local line = f:read("*line") or "" + f:close() + if #line > 0 then + return line + end end end + end function io.loadchunk(filename,n) - local f = io.open(filename,'rb') + local f = open(filename,'rb') if f then local data = f:read(n or 1024) f:close() @@ -129,7 +245,7 @@ function io.loadchunk(filename,n) end function io.exists(filename) - local f = io.open(filename) + local f = open(filename) if f == nil then return false else @@ -139,7 +255,7 @@ function io.exists(filename) end function io.size(filename) - local f = io.open(filename) + local f = open(filename) if f == nil then return 0 else @@ -149,17 +265,18 @@ function io.size(filename) end end -function io.noflines(f) +local function noflines(f) if type(f) == "string" then - local f = io.open(filename) + local f = open(filename) if f then - local n = f and io.noflines(f) or 0 + local n = f and noflines(f) or 0 f:close() return n else return 0 end else + -- todo: load and lpeg local n = 0 for _ in f:lines() do n = n + 1 @@ -169,6 +286,10 @@ function io.noflines(f) end end +io.noflines = noflines + +-- inlined is faster ... beware, better use util-fil + local nextchar = { [ 4] = function(f) return f:read(1,1,1,1) @@ -250,16 +371,16 @@ end function io.ask(question,default,options) while true do - io.write(question) + write(question) if options then - io.write(format(" [%s]",concat(options,"|"))) + write(format(" [%s]",concat(options,"|"))) end if default then - io.write(format(" [%s]",default)) + write(format(" [%s]",default)) end - io.write(format(" ")) - io.flush() - local answer = io.read() + write(format(" ")) + flush() + local answer = read() answer = gsub(answer,"^%s*(.*)%s*$","%1") if answer == "" and default then return default @@ -282,7 +403,7 @@ function io.ask(question,default,options) end end -local function readnumber(f,n,m) +local function readnumber(f,n,m) -- to be replaced if m then f:seek("set",n) n = m @@ -291,38 +412,32 @@ local function readnumber(f,n,m) return byte(f:read(1)) elseif n == 2 then local a, b = byte(f:read(2),1,2) - return 256 * a + b + return 0x100 * a + b elseif n == 3 then local a, b, c = byte(f:read(3),1,3) - return 256*256 * a + 256 * b + c + return 0x10000 * a + 0x100 * b + c elseif n == 4 then local a, b, c, d = byte(f:read(4),1,4) - return 256*256*256 * a + 256*256 * b + 256 * c + d + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d elseif n == 8 then local a, b = readnumber(f,4), readnumber(f,4) - return 256 * a + b + return 0x100 * a + b elseif n == 12 then local a, b, c = readnumber(f,4), readnumber(f,4), readnumber(f,4) - return 256*256 * a + 256 * b + c + return 0x10000 * a + 0x100 * b + c elseif n == -2 then local b, a = byte(f:read(2),1,2) - return 256*a + b + return 0x100 * a + b elseif n == -3 then local c, b, a = byte(f:read(3),1,3) - return 256*256 * a + 256 * b + c + return 0x10000 * a + 0x100 * b + c elseif n == -4 then local d, c, b, a = byte(f:read(4),1,4) - return 256*256*256 * a + 256*256 * b + 256*c + d + return 0x1000000 * a + 0x10000 * b + 0x100*c + d elseif n == -8 then local h, g, f, e, d, c, b, a = byte(f:read(8),1,8) - return 256*256*256*256*256*256*256 * a + - 256*256*256*256*256*256 * b + - 256*256*256*256*256 * c + - 256*256*256*256 * d + - 256*256*256 * e + - 256*256 * f + - 256 * g + - h + return 0x100000000000000 * a + 0x1000000000000 * b + 0x10000000000 * c + 0x100000000 * d + + 0x1000000 * e + 0x10000 * f + 0x100 * g + h else return 0 end diff --git a/tex/context/base/mkiv/l-lpeg.lua b/tex/context/base/mkiv/l-lpeg.lua index 959ca553e..c34ba6ad4 100644 --- a/tex/context/base/mkiv/l-lpeg.lua +++ b/tex/context/base/mkiv/l-lpeg.lua @@ -187,18 +187,20 @@ local fullstripper = whitespace^0 * C((whitespace^0 * nonwhitespace^1)^0) ----- collapser = Cs(spacer^0/"" * ((spacer^1 * endofstring / "") + (spacer^1/" ") + P(1))^0) local collapser = Cs(spacer^0/"" * nonspacer^0 * ((spacer^0/" " * nonspacer^1)^0)) +local nospacer = Cs((whitespace^1/"" + nonwhitespace^1)^0) local b_collapser = Cs( whitespace^0 /"" * (nonwhitespace^1 + whitespace^1/" ")^0) local e_collapser = Cs((whitespace^1 * P(-1)/"" + nonwhitespace^1 + whitespace^1/" ")^0) local m_collapser = Cs( (nonwhitespace^1 + whitespace^1/" ")^0) -local b_stripper = Cs( spacer^0 /"" * (nonspacer^1 + spacer^1/" ")^0) -local e_stripper = Cs((spacer^1 * P(-1)/"" + nonspacer^1 + spacer^1/" ")^0) -local m_stripper = Cs( (nonspacer^1 + spacer^1/" ")^0) +local b_stripper = Cs( spacer^0 /"" * (nonspacer^1 + spacer^1/" ")^0) +local e_stripper = Cs((spacer^1 * P(-1)/"" + nonspacer^1 + spacer^1/" ")^0) +local m_stripper = Cs( (nonspacer^1 + spacer^1/" ")^0) patterns.stripper = stripper patterns.fullstripper = fullstripper patterns.collapser = collapser +patterns.nospacer = nospacer patterns.b_collapser = b_collapser patterns.m_collapser = m_collapser @@ -839,28 +841,48 @@ end local p_false = P(false) local p_true = P(true) -local function make(t) - local function making(t) - local p = p_false - local keys = sortedkeys(t) - for i=1,#keys do - local k = keys[i] - if k ~= "" then - local v = t[k] - if v == true then - p = p + P(k) * p_true - elseif v == false then - -- can't happen - else - p = p + P(k) * making(v) - end - end - end - if t[""] then - p = p + p_true - end - return p - end +-- local function making(t) +-- local p = p_false +-- local keys = sortedkeys(t) +-- for i=1,#keys do +-- local k = keys[i] +-- if k ~= "" then +-- local v = t[k] +-- if v == true then +-- p = p + P(k) * p_true +-- elseif v == false then +-- -- can't happen +-- else +-- p = p + P(k) * making(v) +-- end +-- end +-- end +-- if t[""] then +-- p = p + p_true +-- end +-- return p +-- end + +-- local function make(t) +-- local p = p_false +-- local keys = sortedkeys(t) +-- for i=1,#keys do +-- local k = keys[i] +-- if k ~= "" then +-- local v = t[k] +-- if v == true then +-- p = p + P(k) * p_true +-- elseif v == false then +-- -- can't happen +-- else +-- p = p + P(k) * making(v) +-- end +-- end +-- end +-- return p +-- end + +local function make(t,rest) local p = p_false local keys = sortedkeys(t) for i=1,#keys do @@ -872,10 +894,13 @@ local function make(t) elseif v == false then -- can't happen else - p = p + P(k) * making(v) + p = p + P(k) * make(v,v[""]) end end end + if rest then + p = p + p_true + end return p end @@ -990,21 +1015,21 @@ end -- local t = { "a", "abc", "ac", "abe", "abxyz", "xy", "bef","aa" } -- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1) --- inspect(lpegmatch(p,"a")) --- inspect(lpegmatch(p,"aa")) --- inspect(lpegmatch(p,"aaaa")) --- inspect(lpegmatch(p,"ac")) --- inspect(lpegmatch(p,"bc")) --- inspect(lpegmatch(p,"zzbczz")) --- inspect(lpegmatch(p,"zzabezz")) --- inspect(lpegmatch(p,"ab")) --- inspect(lpegmatch(p,"abc")) --- inspect(lpegmatch(p,"abe")) --- inspect(lpegmatch(p,"xa")) --- inspect(lpegmatch(p,"bx")) --- inspect(lpegmatch(p,"bax")) --- inspect(lpegmatch(p,"abxyz")) --- inspect(lpegmatch(p,"foobarbefcrap")) +-- inspect(lpegmatch(p,"a")=="A") +-- inspect(lpegmatch(p,"aa")=="AA") +-- inspect(lpegmatch(p,"aaaa")=="AAAA") +-- inspect(lpegmatch(p,"ac")=="AC") +-- inspect(lpegmatch(p,"bc")=="bc") +-- inspect(lpegmatch(p,"zzbczz")=="zzbczz") +-- inspect(lpegmatch(p,"zzabezz")=="zzABEzz") +-- inspect(lpegmatch(p,"ab")=="Ab") +-- inspect(lpegmatch(p,"abc")=="ABC") +-- inspect(lpegmatch(p,"abe")=="ABE") +-- inspect(lpegmatch(p,"xa")=="xA") +-- inspect(lpegmatch(p,"bx")=="bx") +-- inspect(lpegmatch(p,"bax")=="bAx") +-- inspect(lpegmatch(p,"abxyz")=="ABXYZ") +-- inspect(lpegmatch(p,"foobarbefcrap")=="foobArBEFcrAp") -- local t = { ["^"] = 1, ["^^"] = 2, ["^^^"] = 3, ["^^^^"] = 4 } -- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/t + 1)^1) diff --git a/tex/context/base/mkiv/l-lua.lua b/tex/context/base/mkiv/l-lua.lua index b90f37e3d..88cde6d1e 100644 --- a/tex/context/base/mkiv/l-lua.lua +++ b/tex/context/base/mkiv/l-lua.lua @@ -188,7 +188,7 @@ if lua then lua.mask = load([[τεχ = 1]]) and "utf" or "ascii" end -local flush = io.flush +local flush = io.flush if flush then @@ -198,3 +198,25 @@ if flush then local popen = io.popen if popen then function io.popen (...) flush() return popen (...) end end end + +-- new + +FFISUPPORTED = type(ffi) == "table" and ffi.os ~= "" and ffi.arch ~= "" and ffi.load + +if not FFISUPPORTED then + + -- Maybe we should check for LUATEXENGINE but that's also a bti tricky as we still + -- can have a weird ffi library laying around. Checking for presence of 'jit' is + -- also not robust. So for now we hope for the best. + + local okay ; okay, ffi = pcall(require,"ffi") + + FFISUPPORTED = type(ffi) == "table" and ffi.os ~= "" and ffi.arch ~= "" and ffi.load + +end + +if not FFISUPPORTED then + ffi = nil +elseif not ffi.number then + ffi.number = tonumber +end diff --git a/tex/context/base/mkiv/l-md5.lua b/tex/context/base/mkiv/l-md5.lua index 00272c873..6758fa444 100644 --- a/tex/context/base/mkiv/l-md5.lua +++ b/tex/context/base/mkiv/l-md5.lua @@ -48,6 +48,9 @@ do if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end + md5.sumhexa = md5.hex + md5.sumHEXA = md5.HEX + end end diff --git a/tex/context/base/mkiv/l-number.lua b/tex/context/base/mkiv/l-number.lua index 001ca31f7..c6f1e3359 100644 --- a/tex/context/base/mkiv/l-number.lua +++ b/tex/context/base/mkiv/l-number.lua @@ -13,6 +13,7 @@ local tostring, tonumber = tostring, tonumber local format, floor, match, rep = string.format, math.floor, string.match, string.rep local concat, insert = table.concat, table.insert local lpegmatch = lpeg.match +local floor = math.floor number = number or { } local number = number @@ -205,3 +206,25 @@ end function number.bits(n) return { bits(n,1) } end + +function number.bytetodecimal(b) + local d = floor(b * 100 / 255 + 0.5) + if d > 100 then + return 100 + elseif d < -100 then + return -100 + else + return d + end +end + +function number.decimaltobyte(d) + local b = floor(d * 255 / 100 + 0.5) + if b > 255 then + return 255 + elseif b < -255 then + return -255 + else + return b + end +end diff --git a/tex/context/base/mkiv/l-os.lua b/tex/context/base/mkiv/l-os.lua index 0a86ea6d6..9b54c9840 100644 --- a/tex/context/base/mkiv/l-os.lua +++ b/tex/context/base/mkiv/l-os.lua @@ -119,7 +119,7 @@ end local execute = os.execute local iopopen = io.popen -function os.resultof(command) +local function resultof(command) local handle = iopopen(command,"r") -- already has flush if handle then local result = handle:read("*all") or "" @@ -130,9 +130,15 @@ function os.resultof(command) end end +os.resultof = resultof + +function os.pipeto(command) + return iopopen(command,"w") -- already has flush +end + if not io.fileseparator then if find(os.getenv("PATH"),";",1,true) then - io.fileseparator, io.pathseparator, os.type = "\\", ";", os.type or "mswin" + io.fileseparator, io.pathseparator, os.type = "\\", ";", os.type or "windows" else io.fileseparator, io.pathseparator, os.type = "/" , ":", os.type or "unix" end @@ -203,17 +209,17 @@ end }) local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" -local function guess() - local architecture = os.resultof("uname -m") or "" - if architecture ~= "" then - return architecture - end - architecture = os.getenv("HOSTTYPE") or "" - if architecture ~= "" then - return architecture - end - return os.resultof("echo $HOSTTYPE") or "" -end +-- local function guess() +-- local architecture = resultof("uname -m") or "" +-- if architecture ~= "" then +-- return architecture +-- end +-- architecture = os.getenv("HOSTTYPE") or "" +-- if architecture ~= "" then +-- return architecture +-- end +-- return resultof("echo $HOSTTYPE") or "" +-- end -- os.bits = 32 | 64 @@ -245,7 +251,7 @@ elseif name == "linux" then function resolvers.platform(t,k) -- we sometimes have HOSTTYPE set so let's check that first - local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" + local platform, architecture = "", os.getenv("HOSTTYPE") or resultof("uname -m") or "" if find(architecture,"x86_64",1,true) then platform = "linux-64" elseif find(architecture,"ppc",1,true) then @@ -273,9 +279,9 @@ elseif name == "macosx" then function resolvers.platform(t,k) -- local platform, architecture = "", os.getenv("HOSTTYPE") or "" -- if architecture == "" then - -- architecture = os.resultof("echo $HOSTTYPE") or "" + -- architecture = resultof("echo $HOSTTYPE") or "" -- end - local platform, architecture = "", os.resultof("echo $HOSTTYPE") or "" + local platform, architecture = "", resultof("echo $HOSTTYPE") or "" if architecture == "" then -- print("\nI have no clue what kind of OSX you're running so let's assume an 32 bit intel.\n") platform = "osx-intel" @@ -294,7 +300,7 @@ elseif name == "macosx" then elseif name == "sunos" then function resolvers.platform(t,k) - local platform, architecture = "", os.resultof("uname -m") or "" + local platform, architecture = "", resultof("uname -m") or "" if find(architecture,"sparc",1,true) then platform = "solaris-sparc" else -- if architecture == 'i86pc' @@ -308,7 +314,7 @@ elseif name == "sunos" then elseif name == "freebsd" then function resolvers.platform(t,k) - local platform, architecture = "", os.resultof("uname -m") or "" + local platform, architecture = "", resultof("uname -m") or "" if find(architecture,"amd64",1,true) then platform = "freebsd-amd64" else @@ -323,7 +329,7 @@ elseif name == "kfreebsd" then function resolvers.platform(t,k) -- we sometimes have HOSTTYPE set so let's check that first - local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" + local platform, architecture = "", os.getenv("HOSTTYPE") or resultof("uname -m") or "" if find(architecture,"x86_64",1,true) then platform = "kfreebsd-amd64" else @@ -502,8 +508,10 @@ end -- These are moved from core-con.lua (as I needed them elsewhere). -local function isleapyear(year) - return (year % 400 == 0) or ((year % 100 ~= 0) and (year % 4 == 0)) +local function isleapyear(year) -- timed for bram's cs practicum + -- return (year % 400 == 0) or (year % 100 ~= 0 and year % 4 == 0) -- 3:4:1600:1900 = 9.9 : 8.2 : 5.0 : 6.8 (29.9) + return (year % 4 == 0) and (year % 100 ~= 0 or year % 400 == 0) -- 3:4:1600:1900 = 5.1 : 6.5 : 8.1 : 10.2 (29.9) + -- return (year % 4 == 0) and (year % 400 == 0 or year % 100 ~= 0) -- 3:4:1600:1900 = 5.2 : 8.5 : 6.8 : 10.1 (30.6) end os.isleapyear = isleapyear diff --git a/tex/context/base/mkiv/l-pdfview.lua b/tex/context/base/mkiv/l-pdfview.lua index 6302fd6f6..d2add9188 100644 --- a/tex/context/base/mkiv/l-pdfview.lua +++ b/tex/context/base/mkiv/l-pdfview.lua @@ -44,7 +44,7 @@ if os.type == "windows" then ['okular'] = [[start "test" okular.exe --unique "%filename%"]], ['pdfxcview'] = [[start "test" pdfxcview.exe /A "nolock=yes=OpenParameters" "%filename%"]], ['sumatra'] = [[start "test" sumatrapdf.exe -reuse-instance -bg-color 0xCCCCCC "%filename%"]], - ['auto'] = [[start "%filename%"]], + ['auto'] = [[start "" "%filename%"]], } closecalls= { ['default'] = [[pdfclose --file "%filename%"]], @@ -91,7 +91,7 @@ else ['okular'] = [[okular --unique "%filename%"]], ['sumatra'] = [[wine "sumatrapdf.exe" -reuse-instance -bg-color 0xCCCCCC "%filename%"]], ['pdfxcview'] = [[wine "pdfxcview.exe" /A "nolock=yes=OpenParameters" "%filename%"]], - ['auto'] = [[open "%filename%"]], + ['auto'] = [[open "%filename%"]], -- linux: xdg-open } closecalls= { ['default'] = [[pdfclose --file "%filename%"]], diff --git a/tex/context/base/mkiv/l-sandbox.lua b/tex/context/base/mkiv/l-sandbox.lua index f7901379c..7a89aa8cd 100644 --- a/tex/context/base/mkiv/l-sandbox.lua +++ b/tex/context/base/mkiv/l-sandbox.lua @@ -8,8 +8,8 @@ if not modules then modules = { } end modules ['l-sandbox'] = { -- We use string instead of function variables, so 'io.open' instead of io.open. That -- way we can still intercept repetetive overloads. One complication is that when we use --- sandboxed function sin helpers in the sanbox checkers, we can get a recursion loop --- so for that vreason we need to keep originals around till we enable the sandbox. +-- sandboxed functions in helpers in the sanbox checkers, we can get a recursion loop +-- so for that reason we need to keep originals around till we enable the sandbox. -- if sandbox then return end @@ -23,6 +23,8 @@ local format = string.format -- no formatters yet local concat = table.concat local sort = table.sort local gmatch = string.gmatch +local gsub = string.gsub +local requiem = require sandbox = { } local sandboxed = false @@ -34,6 +36,7 @@ local originals = { } local comments = { } local trace = false local logger = false +local blocked = { } -- this comes real early, so that we can still alias @@ -139,29 +142,59 @@ function sandbox.overload(func,overload,comment) return func end -function sandbox.initializer(f) - if not sandboxed then - initializers[#initializers+1] = f +local function whatever(specification,what,target) + if type(specification) ~= "table" then + report("%s needs a specification",what) + elseif type(specification.category) ~= "string" or type(specification.action) ~= "function" then + report("%s needs a category and action",what) + elseif not sandboxed then + target[#target+1] = specification elseif trace then - report("already enabled, discarding initializer") + report("already enabled, discarding %s",what) end end -function sandbox.finalizer(f) - if not sandboxed then - finalizers[#finalizers+1] = f - elseif trace then - report("already enabled, discarding finalizer") +function sandbox.initializer(specification) + whatever(specification,"initializer",initializers) +end + +function sandbox.finalizer(specification) + whatever(specification,"finalizer",finalizers) +end + +function require(name) + local n = gsub(name,"^.*[\\/]","") + local n = gsub(n,"[%.].*$","") + local b = blocked[n] + if b == false then + return nil -- e.g. ffi + elseif b then + if trace then + report("using blocked: %s",n) + end + return b + else + if trace then + report("requiring: %s",name) + end + return requiem(name) + end +end + +function blockrequire(name,lib) + if trace then + report("preventing reload of: %s",name) end + blocked[name] = lib or _G[name] or false end function sandbox.enable() if not sandboxed then for i=1,#initializers do - initializers[i]() + initializers[i].action() end for i=1,#finalizers do - finalizers[i]() + finalizers[i].action() end local nnot = 0 local nyes = 0 @@ -189,22 +222,23 @@ function sandbox.enable() end if #cyes > 0 then sort(cyes) - report(" overloaded known : %s",concat(cyes," | ")) + report("overloaded known: %s",concat(cyes," | ")) end if nyes > 0 then - report(" overloaded unknown : %s",nyes) + report("overloaded unknown: %s",nyes) end if #cnot > 0 then sort(cnot) - report("not overloaded known : %s",concat(cnot," | ")) + report("not overloaded known: %s",concat(cnot," | ")) end if nnot > 0 then - report("not overloaded unknown : %s",nnot) + report("not overloaded unknown: %s",nnot) end if #skip > 0 then sort(skip) - report("not overloaded redefined : %s",concat(skip," | ")) + report("not overloaded redefined: %s",concat(skip," | ")) end + -- initializers = nil finalizers = nil originals = nil @@ -212,6 +246,13 @@ function sandbox.enable() end end +blockrequire("lfs",lfs) +blockrequire("io",io) +blockrequire("os",os) +blockrequire("ffi",ffi) + +-- require = register(require,"require") + -- we sandbox some of the built-in functions now: -- todo: require diff --git a/tex/context/base/mkiv/l-string.lua b/tex/context/base/mkiv/l-string.lua index e9dc2bbbc..e0fb28445 100644 --- a/tex/context/base/mkiv/l-string.lua +++ b/tex/context/base/mkiv/l-string.lua @@ -72,22 +72,27 @@ end local stripper = patterns.stripper local fullstripper = patterns.fullstripper local collapser = patterns.collapser +local nospacer = patterns.nospacer local longtostring = patterns.longtostring function string.strip(str) - return lpegmatch(stripper,str) or "" + return str and lpegmatch(stripper,str) or "" end function string.fullstrip(str) - return lpegmatch(fullstripper,str) or "" + return str and lpegmatch(fullstripper,str) or "" end function string.collapsespaces(str) - return lpegmatch(collapser,str) or "" + return str and lpegmatch(collapser,str) or "" +end + +function string.nospaces(str) + return str and lpegmatch(nospacer,str) or "" end function string.longtostring(str) - return lpegmatch(longtostring,str) or "" + return str and lpegmatch(longtostring,str) or "" end -- function string.is_empty(str) @@ -99,7 +104,7 @@ local pattern = P(" ")^0 * P(-1) -- maybe also newlines -- patterns.onlyspaces = pattern function string.is_empty(str) - if str == "" then + if not str or str == "" then return true else return lpegmatch(pattern,str) and true or false @@ -163,7 +168,7 @@ function string.escapedpattern(str,simple) end function string.topattern(str,lowercase,strict) - if str=="" or type(str) ~= "string" then + if str == "" or type(str) ~= "string" then return ".*" elseif strict then str = lpegmatch(pattern_c,str) @@ -177,6 +182,7 @@ function string.topattern(str,lowercase,strict) end end +-- print(string.escapedpattern("abc*234",true)) -- print(string.escapedpattern("12+34*.tex",false)) -- print(string.escapedpattern("12+34*.tex",true)) -- print(string.topattern ("12+34*.tex",false,false)) @@ -211,3 +217,24 @@ end string.quote = string.quoted string.unquote = string.unquoted + +-- new + +if not string.bytetable then + + local limit = 5000 -- we can go to 8000 in luajit and much higher in lua if needed + + function string.bytetable(str) + local n = #str + if n > limit then + local t = { byte(str,1,limit) } + for i=limit+1,n do + t[i] = byte(str,i) + end + return t + else + return { byte(str,1,n) } + end + end + +end diff --git a/tex/context/base/mkiv/l-table.lua b/tex/context/base/mkiv/l-table.lua index 552097e1c..3c1ce6daf 100644 --- a/tex/context/base/mkiv/l-table.lua +++ b/tex/context/base/mkiv/l-table.lua @@ -478,7 +478,7 @@ function table.fromhash(t) return hsh end -local noquotes, hexify, handle, compact, inline, functions +local noquotes, hexify, handle, compact, inline, functions, metacheck local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key 'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'if', @@ -486,7 +486,7 @@ local reserved = table.tohash { -- intercept a language inconvenience: no reserv 'NaN', 'goto', } --- local function simple_table(t) +-- local function is_simple_table(t) -- if #t > 0 then -- local n = 0 -- for _,v in next, t do @@ -520,29 +520,67 @@ local reserved = table.tohash { -- intercept a language inconvenience: no reserv -- return nil -- end -local function simple_table(t) +-- local function is_simple_table(t) +-- local nt = #t +-- if nt > 0 then +-- local n = 0 +-- for _,v in next, t do +-- n = n + 1 +-- -- if type(v) == "table" then +-- -- return nil +-- -- end +-- end +-- if n == nt then +-- local tt = { } +-- for i=1,nt do +-- local v = t[i] +-- local tv = type(v) +-- if tv == "number" then +-- if hexify then +-- tt[i] = format("0x%X",v) +-- else +-- tt[i] = tostring(v) -- tostring not needed +-- end +-- elseif tv == "string" then +-- tt[i] = format("%q",v) +-- elseif tv == "boolean" then +-- tt[i] = v and "true" or "false" +-- else +-- return nil +-- end +-- end +-- return tt +-- end +-- end +-- return nil +-- end + +local function is_simple_table(t,hexify) -- also used in util-tab so maybe public local nt = #t if nt > 0 then local n = 0 - for _,v in next, t do + for _, v in next, t do n = n + 1 - -- if type(v) == "table" then - -- return nil - -- end + if type(v) == "table" then + return nil + end end + -- local haszero = t[0] + local haszero = rawget(t,0) -- don't trigger meta if n == nt then local tt = { } for i=1,nt do local v = t[i] local tv = type(v) if tv == "number" then + -- tt[i] = v -- not needed tostring(v) if hexify then tt[i] = format("0x%X",v) else - tt[i] = tostring(v) -- tostring not needed + tt[i] = v -- not needed tostring(v) end elseif tv == "string" then - tt[i] = format("%q",v) + tt[i] = format("%q",v) -- f_string(v) elseif tv == "boolean" then tt[i] = v and "true" or "false" else @@ -550,11 +588,35 @@ local function simple_table(t) end end return tt + elseif haszero and (n == nt + 1) then + local tt = { } + for i=0,nt do + local v = t[i] + local tv = type(v) + if tv == "number" then + -- tt[i+1] = v -- not needed tostring(v) + if hexify then + tt[i+1] = format("0x%X",v) + else + tt[i+1] = v -- not needed tostring(v) + end + elseif tv == "string" then + tt[i+1] = format("%q",v) -- f_string(v) + elseif tv == "boolean" then + tt[i+1] = v and "true" or "false" + else + return nil + end + end + tt[1] = "[0] = " .. tt[1] + return tt end end return nil end +table.is_simple_table = is_simple_table + -- Because this is a core function of mkiv I moved some function calls -- inline. -- @@ -608,7 +670,8 @@ local function do_serialize(root,name,depth,level,indexed) if compact then last = #root for k=1,last do - if root[k] == nil then + -- if root[k] == nil then + if rawget(root,k) == nil then last = k - 1 break end @@ -636,7 +699,7 @@ local function do_serialize(root,name,depth,level,indexed) if next(v) == nil then handle(format("%s {},",depth)) elseif inline then -- and #t > 0 - local st = simple_table(v) + local st = is_simple_table(v,hexify) if st then handle(format("%s { %s },",depth,concat(st,", "))) else @@ -673,6 +736,8 @@ local function do_serialize(root,name,depth,level,indexed) else handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) -- %.99g end + elseif tk ~= "string" then + -- ignore elseif noquotes and not reserved[k] and lpegmatch(propername,k) then if hexify then handle(format("%s %s=0x%X,",depth,k,v)) @@ -695,6 +760,8 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tk == "boolean" then handle(format("%s [%s]=%q,",depth,k and "true" or "false",v)) + elseif tk ~= "string" then + -- ignore elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=%q,",depth,k,v)) else @@ -710,13 +777,15 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tk == "boolean" then handle(format("%s [%s]={},",depth,k and "true" or "false")) + elseif tk ~= "string" then + -- ignore elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s={},",depth,k)) else handle(format("%s [%q]={},",depth,k)) end elseif inline then - local st = simple_table(v) + local st = is_simple_table(v,hexify) if st then if tk == "number" then if hexify then @@ -726,6 +795,8 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tk == "boolean" then handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", "))) + elseif tk ~= "string" then + -- ignore elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s={ %s },",depth,k,concat(st,", "))) else @@ -746,6 +817,8 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tk == "boolean" then handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false")) + elseif tk ~= "string" then + -- ignore elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=%s,",depth,k,v and "true" or "false")) else @@ -763,6 +836,8 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tk == "boolean" then handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f)) + elseif tk ~= "string" then + -- ignore elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=load(%q),",depth,k,f)) else @@ -778,6 +853,8 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tk == "boolean" then handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v))) + elseif tk ~= "string" then + -- ignore elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=%q,",depth,k,tostring(v))) else @@ -803,6 +880,7 @@ local function serialize(_handle,root,name,specification) -- handle wins functions = specification.functions compact = specification.compact inline = specification.inline and compact + metacheck = specification.metacheck if functions == nil then functions = true end @@ -812,6 +890,9 @@ local function serialize(_handle,root,name,specification) -- handle wins if inline == nil then inline = compact end + if metacheck == nil then + metacheck = true + end else noquotes = false hexify = false @@ -819,6 +900,7 @@ local function serialize(_handle,root,name,specification) -- handle wins compact = true inline = true functions = true + metacheck = true end if tname == "string" then if name == "return" then @@ -843,8 +925,9 @@ local function serialize(_handle,root,name,specification) -- handle wins end if root then -- The dummy access will initialize a table that has a delayed initialization - -- using a metatable. (maybe explicitly test for metatable) - if getmetatable(root) then -- todo: make this an option, maybe even per subtable + -- using a metatable. (maybe explicitly test for metatable). This can crash on + -- metatables that check the index against a number. + if metacheck and getmetatable(root) then local dummy = root._w_h_a_t_e_v_e_r_ root._w_h_a_t_e_v_e_r_ = nil end @@ -950,6 +1033,41 @@ end table.flattened = flattened +local function collapsed(t,f,h) + if f == nil then + f = { } + h = { } + end + for k=1,#t do + local v = t[k] + if type(v) == "table" then + collapsed(v,f,h) + elseif not h[v] then + f[#f+1] = v + h[v] = true + end + end + return f +end + +local function collapsedhash(t,h) + if h == nil then + h = { } + end + for k=1,#t do + local v = t[k] + if type(v) == "table" then + collapsedhash(v,h) + else + h[v] = true + end + end + return h +end + +table.collapsed = collapsed -- 20% faster than unique(collapsed(t)) +table.collapsedhash = collapsedhash + local function unnest(t,f) -- only used in mk, for old times sake if not f then -- and only relevant for token lists f = { } -- this one can become obsolete @@ -1056,7 +1174,7 @@ function table.count(t) return n end -function table.swapped(t,s) -- hash +function table.swapped(t,s) -- hash, we need to make sure we don't mess up next local n = { } if s then for k, v in next, s do @@ -1069,7 +1187,14 @@ function table.swapped(t,s) -- hash return n end -function table.mirrored(t) -- hash +function table.hashed(t) -- list, add hash to index (save because we are not yet mixed + for i=1,#t do + t[t[i]] = i + end + return t +end + +function table.mirrored(t) -- hash, we need to make sure we don't mess up next local n = { } for k, v in next, t do n[v] = k @@ -1165,7 +1290,7 @@ function table.has_one_entry(t) return t and next(t,next(t)) == nil end --- new +-- new (rather basic, not indexed and nested) function table.loweredkeys(t) -- maybe utf local l = { } diff --git a/tex/context/base/mkiv/l-unicode.lua b/tex/context/base/mkiv/l-unicode.lua index 3dec80013..b913d0cfc 100644 --- a/tex/context/base/mkiv/l-unicode.lua +++ b/tex/context/base/mkiv/l-unicode.lua @@ -1270,3 +1270,35 @@ function utf.chrlen(u) -- u is number (u < 0xFC and 5) or (u < 0xFE and 6) or 0 end + +-- hashing saves a little but not that much in practice +-- +-- local utf32 = table.setmetatableindex(function(t,k) local v = toutf32(k) t[k] = v return v end) + +local extract = bit32.extract +local char = string.char + +function unicode.toutf32string(n) + if n <= 0xFF then + return + char(n) .. + "\000\000\000" + elseif n <= 0xFFFF then + return + char(extract(n, 0,8)) .. + char(extract(n, 8,8)) .. + "\000\000" + elseif n <= 0xFFFFFF then + return + char(extract(n, 0,8)) .. + char(extract(n, 8,8)) .. + char(extract(n,16,8)) .. + "\000" + else + return + char(extract(n, 0,8)) .. + char(extract(n, 8,8)) .. + char(extract(n,16,8)) .. + char(extract(n,24,8)) + end +end diff --git a/tex/context/base/mkiv/lang-cnt.lua b/tex/context/base/mkiv/lang-cnt.lua new file mode 100644 index 000000000..21de6c2d1 --- /dev/null +++ b/tex/context/base/mkiv/lang-cnt.lua @@ -0,0 +1,164 @@ +if not modules then modules = { } end modules ['lang-cnt'] = { + version = 1.001, + comment = "companion to lang-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is generated with help from ctx-checkedcombined.lua (an ugly local +-- helper script). + +-- We don't really need this as we compose and decompose already. The only +-- exception are the ae etc but these can best be entered in their unicode +-- form anyway. So, even if we can support hjcodes with counts is is not +-- needed in practice. It's anyway debatable if æ should be seen as one +-- character or two. And ffi and ij and such are not used in patterns anyway. + +languages = languages or { } + +languages.hjcounts = { -- used: used in registered unicode characters + -- + [0x000C6] = { category = "letter", count = 2 }, -- Æ + [0x000E6] = { category = "letter", count = 2 }, -- æ + -- + [0x01E9E] = { category = "letter", count = 2 }, -- ẞ + [0x000DF] = { category = "letter", count = 2 }, -- ß + -- + [0x00132] = { category = "dubious", count = 2 }, -- IJ + [0x00133] = { category = "dubious", count = 2 }, -- ij + -- + [0x00152] = { category = "dubious", count = 2 }, -- Œ + [0x00153] = { category = "dubious", count = 2 }, -- œ + -- + [0x001C7] = { category = "letter", count = 2 }, -- LJ + [0x001C8] = { category = "letter", count = 2 }, -- Lj + [0x001C9] = { category = "letter", count = 2 }, -- lj + -- + [0x001CA] = { category = "letter", count = 2 }, -- NJ + [0x001CC] = { category = "letter", count = 2 }, -- nj + -- not in patterns + [0x0FB01] = { category = "ligature", count = 2 }, -- fi + [0x0FB02] = { category = "ligature", count = 2 }, -- fl + [0x0FB03] = { category = "ligature", count = 3 }, -- ffi + [0x0FB04] = { category = "ligature", count = 3 }, -- ffl + [0x0FB06] = { category = "ligature", count = 2 }, -- st + -- + [0x00300] = { category = "combining", count = 0, used = true }, -- ̀ + [0x00301] = { category = "combining", count = 0, used = true }, -- ́ + [0x00302] = { category = "combining", count = 0, used = true }, -- ̂ + [0x00303] = { category = "combining", count = 0, used = true }, -- ̃ + [0x00304] = { category = "combining", count = 0, used = true }, -- ̄ + [0x00305] = { category = "combining", count = 0, used = false }, -- ̅ + [0x00306] = { category = "combining", count = 0, used = true }, -- ̆ + [0x00307] = { category = "combining", count = 0, used = true }, -- ̇ + [0x00308] = { category = "combining", count = 0, used = true }, -- ̈ + [0x00309] = { category = "combining", count = 0, used = true }, -- ̉ + [0x0030A] = { category = "combining", count = 0, used = true }, -- ̊ + [0x0030B] = { category = "combining", count = 0, used = true }, -- ̋ + [0x0030C] = { category = "combining", count = 0, used = true }, -- ̌ + [0x0030D] = { category = "combining", count = 0, used = false }, -- ̍ + [0x0030E] = { category = "combining", count = 0, used = false }, -- ̎ + [0x0030F] = { category = "combining", count = 0, used = true }, -- ̏ + [0x00310] = { category = "combining", count = 0, used = false }, -- ̐ + [0x00311] = { category = "combining", count = 0, used = true }, -- ̑ + [0x00312] = { category = "combining", count = 0, used = false }, -- ̒ + [0x00313] = { category = "combining", count = 0, used = true }, -- ̓ + [0x00314] = { category = "combining", count = 0, used = true }, -- ̔ + [0x00315] = { category = "combining", count = 0, used = false }, -- ̕ + [0x00316] = { category = "combining", count = 0, used = false }, -- ̖ + [0x00317] = { category = "combining", count = 0, used = false }, -- ̗ + [0x00318] = { category = "combining", count = 0, used = false }, -- ̘ + [0x00319] = { category = "combining", count = 0, used = false }, -- ̙ + [0x0031A] = { category = "combining", count = 0, used = false }, -- ̚ + [0x0031B] = { category = "combining", count = 0, used = true }, -- ̛ + [0x0031C] = { category = "combining", count = 0, used = false }, -- ̜ + [0x0031D] = { category = "combining", count = 0, used = false }, -- ̝ + [0x0031E] = { category = "combining", count = 0, used = false }, -- ̞ + [0x0031F] = { category = "combining", count = 0, used = false }, -- ̟ + [0x00320] = { category = "combining", count = 0, used = false }, -- ̠ + [0x00321] = { category = "combining", count = 0, used = false }, -- ̡ + [0x00322] = { category = "combining", count = 0, used = false }, -- ̢ + [0x00323] = { category = "combining", count = 0, used = true }, -- ̣ + [0x00324] = { category = "combining", count = 0, used = true }, -- ̤ + [0x00325] = { category = "combining", count = 0, used = true }, -- ̥ + [0x00326] = { category = "combining", count = 0, used = true }, -- ̦ + [0x00327] = { category = "combining", count = 0, used = true }, -- ̧ + [0x00328] = { category = "combining", count = 0, used = true }, -- ̨ + [0x00329] = { category = "combining", count = 0, used = false }, -- ̩ + [0x0032A] = { category = "combining", count = 0, used = false }, -- ̪ + [0x0032B] = { category = "combining", count = 0, used = false }, -- ̫ + [0x0032C] = { category = "combining", count = 0, used = false }, -- ̬ + [0x0032D] = { category = "combining", count = 0, used = true }, -- ̭ + [0x0032E] = { category = "combining", count = 0, used = true }, -- ̮ + [0x0032F] = { category = "combining", count = 0, used = false }, -- ̯ + [0x00330] = { category = "combining", count = 0, used = true }, -- ̰ + [0x00331] = { category = "combining", count = 0, used = true }, -- ̱ + [0x00332] = { category = "combining", count = 0, used = false }, -- ̲ + [0x00333] = { category = "combining", count = 0, used = false }, -- ̳ + [0x00334] = { category = "combining", count = 0, used = false }, -- ̴ + [0x00335] = { category = "combining", count = 0, used = false }, -- ̵ + [0x00336] = { category = "combining", count = 0, used = false }, -- ̶ + [0x00337] = { category = "combining", count = 0, used = false }, -- ̷ + [0x00338] = { category = "combining", count = 0, used = false }, -- ̸ + [0x00339] = { category = "combining", count = 0, used = false }, -- ̹ + [0x0033A] = { category = "combining", count = 0, used = false }, -- ̺ + [0x0033B] = { category = "combining", count = 0, used = false }, -- ̻ + [0x0033C] = { category = "combining", count = 0, used = false }, -- ̼ + [0x0033D] = { category = "combining", count = 0, used = false }, -- ̽ + [0x0033E] = { category = "combining", count = 0, used = false }, -- ̾ + [0x0033F] = { category = "combining", count = 0, used = false }, -- ̿ + [0x00340] = { category = "combining", count = 0, used = false }, -- ̀ + [0x00341] = { category = "combining", count = 0, used = false }, -- ́ + [0x00342] = { category = "combining", count = 0, used = true }, -- ͂ + [0x00343] = { category = "combining", count = 0, used = false }, -- ̓ + [0x00344] = { category = "combining", count = 0, used = false }, -- ̈́ + [0x00345] = { category = "combining", count = 0, used = true }, -- ͅ + [0x00346] = { category = "combining", count = 0, used = false }, -- ͆ + [0x00347] = { category = "combining", count = 0, used = false }, -- ͇ + [0x00348] = { category = "combining", count = 0, used = false }, -- ͈ + [0x00349] = { category = "combining", count = 0, used = false }, -- ͉ + [0x0034A] = { category = "combining", count = 0, used = false }, -- ͊ + [0x0034B] = { category = "combining", count = 0, used = false }, -- ͋ + [0x0034C] = { category = "combining", count = 0, used = false }, -- ͌ + [0x0034D] = { category = "combining", count = 0, used = false }, -- ͍ + [0x0034E] = { category = "combining", count = 0, used = false }, -- ͎ + [0x0034F] = { category = "combining", count = 0, used = false }, -- ͏ + [0x00350] = { category = "combining", count = 0, used = false }, -- ͐ + [0x00351] = { category = "combining", count = 0, used = false }, -- ͑ + [0x00352] = { category = "combining", count = 0, used = false }, -- ͒ + [0x00353] = { category = "combining", count = 0, used = false }, -- ͓ + [0x00354] = { category = "combining", count = 0, used = false }, -- ͔ + [0x00355] = { category = "combining", count = 0, used = false }, -- ͕ + [0x00356] = { category = "combining", count = 0, used = false }, -- ͖ + [0x00357] = { category = "combining", count = 0, used = false }, -- ͗ + [0x00358] = { category = "combining", count = 0, used = false }, -- ͘ + [0x00359] = { category = "combining", count = 0, used = false }, -- ͙ + [0x0035A] = { category = "combining", count = 0, used = false }, -- ͚ + [0x0035B] = { category = "combining", count = 0, used = false }, -- ͛ + [0x0035C] = { category = "combining", count = 0, used = false }, -- ͜ + [0x0035D] = { category = "combining", count = 0, used = false }, -- ͝ + [0x0035E] = { category = "combining", count = 0, used = false }, -- ͞ + [0x0035F] = { category = "combining", count = 0, used = false }, -- ͟ + [0x00360] = { category = "combining", count = 0, used = false }, -- ͠ + [0x00361] = { category = "combining", count = 0, used = false }, -- ͡ + [0x00362] = { category = "combining", count = 0, used = false }, -- ͢ + [0x00363] = { category = "combining", count = 0, used = false }, -- ͣ + [0x00364] = { category = "combining", count = 0, used = false }, -- ͤ + [0x00365] = { category = "combining", count = 0, used = false }, -- ͥ + [0x00366] = { category = "combining", count = 0, used = false }, -- ͦ + [0x00367] = { category = "combining", count = 0, used = false }, -- ͧ + [0x00368] = { category = "combining", count = 0, used = false }, -- ͨ + [0x00369] = { category = "combining", count = 0, used = false }, -- ͩ + [0x0036A] = { category = "combining", count = 0, used = false }, -- ͪ + [0x0036B] = { category = "combining", count = 0, used = false }, -- ͫ + [0x0036C] = { category = "combining", count = 0, used = false }, -- ͬ + [0x0036D] = { category = "combining", count = 0, used = false }, -- ͭ + [0x0036E] = { category = "combining", count = 0, used = false }, -- ͮ + [0x0036F] = { category = "combining", count = 0, used = false }, -- ͯ + [0x00483] = { category = "combining", count = 0, used = false }, -- ҃ + [0x00484] = { category = "combining", count = 0, used = false }, -- ҄ + [0x00485] = { category = "combining", count = 0, used = false }, -- ҅ + [0x00486] = { category = "combining", count = 0, used = false }, -- ҆ + [0x00487] = { category = "combining", count = 0, used = false }, -- ҇ +} diff --git a/tex/context/base/mkiv/lang-def.mkiv b/tex/context/base/mkiv/lang-def.mkiv index 5e40a33b0..96bb88767 100644 --- a/tex/context/base/mkiv/lang-def.mkiv +++ b/tex/context/base/mkiv/lang-def.mkiv @@ -134,7 +134,6 @@ \c!rightquotation=\rightguillemot, \c!date={\v!day,{.},\space,\v!month,\space,\v!year}] - \installlanguage [\s!no] [\s!nb] \installlanguage [\s!norwegian] [\s!nb] \installlanguage [\s!bokmal] [\s!nb] @@ -399,6 +398,23 @@ \installlanguage [\s!arabic] [\s!ar] +\installlanguage + [\s!pe] + [\c!spacing=\v!broad, + \c!leftsentence=\emdash, + \c!rightsentence=\emdash, + \c!leftsubsentence=\emdash, + \c!rightsubsentence=\emdash, + \c!leftquote=\leftguillemot, + \c!rightquote=\rightguillemot, + \c!leftquotation=\leftguillemot, + \c!rightquotation=\rightguillemot, + \c!date={\v!day,\space,\v!month,\space,\v!year}] + +\installlanguage [\s!persian] [\s!pe] +\installlanguage [\s!fa] [\s!pe] % these two are redundant but sometimes might +\installlanguage [\s!farsi] [\s!fa] % sound more natural .. best set labels to 'pe' + % Just aliases to "ar" for now \installlanguage[\s!ar-ae][\c!default=\s!ar] % U.A.E. @@ -414,6 +430,12 @@ \installlanguage[\s!ar-tn][\c!default=\s!ar] % Tunisia \installlanguage[\s!ar-ye][\c!default=\s!ar] % Yemen +% Farsi (Persian) + +\installlanguage[\s!ar-ir][\c!default=\s!pe] +%installlanguage[\s!pe-ir][\c!default=\s!pe] +%installlanguage[\s!fa-ir][\c!default=\s!fa] + % Syriac months \installlanguage[\s!ar-sy][\c!default=\s!ar] % Syria @@ -450,6 +472,8 @@ % Celtic: Breton, Welsh, Irish, Manx, Scottish Gaelic +% CJK: Chinese, Japanese, Korean + \installlanguage [\s!cn] [\c!leftsentence=——, @@ -487,6 +511,10 @@ % \c!date={서기,\space,\v!year,\labeltext{\v!year},\space,\v!month,\labeltext{\v!month},\space,\v!day,\labeltext{\v!day}}] \c!date={\v!year,\labeltext{\v!year},\space,\v!month,\labeltext{\v!month},\space,\v!day,\labeltext{\v!day}}] +\installlanguage [\s!chinese] [\s!cn] +\installlanguage [\s!japanese] [\s!ja] +\installlanguage [\s!korean] [\s!kr] + % Greek \installlanguage @@ -496,10 +524,10 @@ \c!rightsentence=\emdash, \c!leftsubsentence=\emdash, \c!rightsubsentence=\emdash, - \c!leftquote=\greekleftquot, - \c!rightquote=\greekrightquot, - \c!leftquotation=\greekleftquot, - \c!rightquotation=\greekrightquot, + \c!leftquote=“, + \c!rightquote=”, + \c!leftquotation=«, + \c!rightquotation=», \c!date={\v!day\space\v!month\space\v!year}, \s!patterns=\s!agr] % ok? diff --git a/tex/context/base/mkiv/lang-dis.lua b/tex/context/base/mkiv/lang-dis.lua index 84d9b2d5b..e2c0d220e 100644 --- a/tex/context/base/mkiv/lang-dis.lua +++ b/tex/context/base/mkiv/lang-dis.lua @@ -12,7 +12,9 @@ local nodes = nodes local tasks = nodes.tasks local nuts = nodes.nuts -local nodepool = nuts.pool + +local enableaction = tasks.enableaction +local setaction = tasks.setaction local tonode = nuts.tonode local tonut = nuts.tonut @@ -27,22 +29,31 @@ local getattr = nuts.getattr local getsubtype = nuts.getsubtype local setsubtype = nuts.setsubtype local getchar = nuts.getchar +local setchar = nuts.setchar local getdisc = nuts.getdisc local setdisc = nuts.setdisc +local getlang = nuts.setlang +local getboth = nuts.getboth +local setlist = nuts.setlist +local setlink = nuts.setlink local isglyph = nuts.isglyph local copy_node = nuts.copy -local free_node = nuts.free local remove_node = nuts.remove local traverse_id = nuts.traverse_id -local traverse_nodes = nuts.traverse +local flush_list = nuts.flush_list +local flush_node = nuts.flush_node local nodecodes = nodes.nodecodes local disccodes = nodes.disccodes local disc_code = nodecodes.disc local glyph_code = nodecodes.glyph + local discretionary_code = disccodes.discretionary +local explicit_code = disccodes.explicit +local automatic_code = disccodes.automatic +local regular_code = disccodes.regular local a_visualize = attributes.private("visualizediscretionary") local setattribute = tex.setattribute @@ -51,135 +62,158 @@ local getlanguagedata = languages.getdata local check_regular = true -local expanders = { - [disccodes.discretionary] = function(d,template) - -- \discretionary - return template - end, - [disccodes.explicit] = function(d,template) - -- \- - local pre, post, replace = getdisc(d) - local done = false - if pre then - local char = isglyph(pre) - if char and char <= 0 then - done = true - pre = nil +local expanders -- this will go away + +-- the penalty has been determined by the mode (currently we force 1): +-- +-- 0 : exhyphenpenalty +-- 1 : hyphenpenalty +-- 2 : automatichyphenpenalty +-- +-- following a - : the pre and post chars are already appended and set +-- so we have pre=preex and post=postex .. however, the previous +-- hyphen is already injected ... downside: the font handler sees this +-- so this is another argument for doing a hyphenation pass in context + +if LUATEXVERSION < 1.005 then + + expanders = { + [discretionary_code] = function(d,template) + -- \discretionary + return template + end, + [explicit_code] = function(d,template) + -- \- + local pre, post, replace = getdisc(d) + local done = false + if pre then + local char = isglyph(pre) + if char and char <= 0 then + done = true + flush_list(pre) + pre = nil + end end - end - if post then - local char = isglyph(post) - if char and char <= 0 then - done = true - post = nil + if post then + local char = isglyph(post) + if char and char <= 0 then + done = true + flush_list(post) + post = nil + end end - end - if done then - setdisc(d,pre,post,replace,discretionary_code,tex.exhyphenpenalty) - end - return template - end, - [disccodes.automatic] = function(d,template) - -- following a - : the pre and post chars are already appended and set - -- so we have pre=preex and post=postex .. however, the previous - -- hyphen is already injected ... downside: the font handler sees this - -- so this is another argument for doing a hyphenation pass in context - local pre, post, replace = getdisc(d) - if pre then - -- we have a preex characters and want that one to replace the - -- character in front which is the trigger - if not template then - -- can there be font kerns already? - template = getprev(d) - if template and getid(template) ~= glyph_code then - template = getnext(d) + if done then + -- todo: take existing penalty + setdisc(d,pre,post,replace,explicit_code,tex.exhyphenpenalty) + else + setsubtype(d,explicit_code) + end + return template + end, + [automatic_code] = function(d,template) + local pre, post, replace = getdisc(d) + if pre then + -- we have a preex characters and want that one to replace the + -- character in front which is the trigger + if not template then + -- can there be font kerns already? + template = getprev(d) if template and getid(template) ~= glyph_code then - template = nil + template = getnext(d) + if template and getid(template) ~= glyph_code then + template = nil + end end end - end - if template then - local pseudohead = getprev(template) - if pseudohead then - while template ~= d do - pseudohead, template, removed = remove_node(pseudohead,template) - -- free old replace ? - replace = removed - -- break ? + if template then + local pseudohead = getprev(template) + if pseudohead then + while template ~= d do + pseudohead, template, removed = remove_node(pseudohead,template) + -- free old replace ? + replace = removed + -- break ? + end + else + -- can't happen end + setdisc(d,pre,post,replace,automatic_code,tex.hyphenpenalty) else - -- can't happen + -- print("lone regular discretionary ignored") end - setdisc(d,pre,post,replace,discretionary_code,tex.hyphenpenalty) else - -- print("lone regular discretionary ignored") + setdisc(d,pre,post,replace,automatic_code,tex.hyphenpenalty) end - else - setdisc(d,pre,post,replace,discretionary_code,tex.hyphenpenalty) - end - return template - end, - [disccodes.regular] = function(d,template) - if check_regular then - -- simple - if not template then - -- can there be font kerns already? - template = getprev(d) - if template and getid(template) ~= glyph_code then - template = getnext(d) + return template + end, + [regular_code] = function(d,template) + if check_regular then + -- simple + if not template then + -- can there be font kerns already? + template = getprev(d) if template and getid(template) ~= glyph_code then - template = nil + template = getnext(d) + if template and getid(template) ~= glyph_code then + template = nil + end end end - end - if template then - local language = template and getfield(template,"lang") - local data = getlanguagedata(language) - local prechar = data.prehyphenchar - local postchar = data.posthyphenchar - local pre, post, replace = getdisc(d) -- pre can be set - local done = false - if prechar and prechar > 0 then - done = true - pre = copy_node(template) - setchar(pre,prechar) - end - if postchar and postchar > 0 then - done = true - post = copy_node(template) - setchar(post,postchar) - end - if done then - setdisc(d,pre,post,replace,discretionary_code,tex.hyphenpenalty) + if template then + local language = template and getlang(template) + local data = getlanguagedata(language) + local prechar = data.prehyphenchar + local postchar = data.posthyphenchar + local pre, post, replace = getdisc(d) -- pre can be set + local done = false + if prechar and prechar > 0 then + done = true + pre = copy_node(template) + setchar(pre,prechar) + end + if postchar and postchar > 0 then + done = true + post = copy_node(template) + setchar(post,postchar) + end + if done then + setdisc(d,pre,post,replace,regular_code,tex.hyphenpenalty) + end + else + -- print("lone regular discretionary ignored") end - else - -- print("lone regular discretionary ignored") + return template end - return template - else - -- maybe also set penalty here - setsubtype(d,discretionary_code) + end, + [disccodes.first] = function() + -- forget about them + end, + [disccodes.second] = function() + -- forget about them + end, + } + + function languages.expand(d,template,subtype) + if not subtype then + subtype = getsubtype(d) end - end, - [disccodes.first] = function() - -- forget about them - end, - [disccodes.second] = function() - -- forget about them - end, -} + if subtype ~= discretionary_code then + return expanders[subtype](d,template) + end + end -languages.expanders = expanders +else -function languages.expand(d,template,subtype) - if not subtype then - subtype = getsubtype(d) - end - if subtype ~= discretionary_code then - return expanders[subtype](d,template) + function languages.expand() + -- nothing to be fixed end + end +languages.expanders = expanders + +-- -- -- -- -- + local setlistcolor = nodes.tracers.colors.setlist function languages.visualizediscretionaries(head) @@ -206,7 +240,7 @@ function languages.showdiscretionaries(v) setattribute(a_visualize,unsetvalue) else -- also nil if not enabled then - nodes.tasks.enableaction("processors","languages.visualizediscretionaries") + enableaction("processors","languages.visualizediscretionaries") enabled = true end setattribute(a_visualize,1) @@ -229,3 +263,65 @@ function languages.serializediscretionary(d) -- will move to tracer ) end +-- -- + +local wiped = 0 + +local function wipe(head,delayed) + local p, n = getboth(delayed) + local _, _, h, _, _, t = getdisc(delayed,true) + if p or n then + if h then + setlink(p,h) + setlink(t,n) + setfield(delayed,"replace") + else + setlink(p,n) + end + end + if head == delayed then + head = h + end + wiped = wiped + 1 + flush_node(delayed) + return head +end + +function languages.flatten(head) + local nuthead = tonut(head) + local delayed = nil + for d in traverse_id(disc_code,nuthead) do + if delayed then + nuthead = wipe(nuthead,delayed) + end + delayed = d + end + if delayed then + return tonode(wipe(nuthead,delayed)), true + else + return head, false + end +end + +function languages.nofflattened() + return wiped -- handy for testing +end + +-- experiment + +local flatten = languages.flatten +local getlist = nodes.getlist + +nodes.handlers.flattenline = flatten + +function nodes.handlers.flatten(head,where) + if head and (where == "box" or where == "adjusted_hbox") then + return flatten(head) + end + return true +end + +directives.register("hyphenator.flatten",function(v) + setaction("processors","nodes.handlers.flatten",v) + setaction("contributers","nodes.handlers.flattenline",v) +end) diff --git a/tex/context/base/mkiv/lang-frq-pt.lua b/tex/context/base/mkiv/lang-frq-pt.lua new file mode 100644 index 000000000..ce4e7aa26 --- /dev/null +++ b/tex/context/base/mkiv/lang-frq-pt.lua @@ -0,0 +1,12 @@ +return { + language = "pt", + source = "https://pt.wikipedia.org/wiki/Frequência_de_letras", + frequencies = { + [0x61] = 14.63, [0x62] = 1.04, [0x63] = 3.88, [0x64] = 4.99, [0x65] = 12.57, + [0x66] = 1.02, [0x67] = 1.30, [0x68] = 1.28, [0x69] = 6.18, [0x6A] = 0.40, + [0x6B] = 0.02, [0x6C] = 2.78, [0x6D] = 4.74, [0x6E] = 5.05, [0x6F] = 10.73, + [0x70] = 2.52, [0x71] = 1.20, [0x72] = 6.53, [0x73] = 7.81, [0x74] = 4.74, + [0x75] = 4.63, [0x76] = 1.67, [0x77] = 0.01, [0x78] = 0.21, [0x79] = 0.01, + [0x7A] = 0.47, + } +} diff --git a/tex/context/base/mkiv/lang-hyp.lua b/tex/context/base/mkiv/lang-hyp.lua index 146aea4a8..b85295f19 100644 --- a/tex/context/base/mkiv/lang-hyp.lua +++ b/tex/context/base/mkiv/lang-hyp.lua @@ -6,14 +6,6 @@ if not modules then modules = { } end modules ['lang-hyp'] = { license = "see context related readme files" } --- todo: hyphenate over range if needed --- todo: check boundary nodes - --- setattr: helper for full attr - --- to be considered: reset dictionary.hyphenated when a pattern is added --- or maybe an explicit reset of the cache - -- In an automated workflow hypenation of long titles can be somewhat problematic -- especially when demands conflict. For that reason I played a bit with a Lua based -- variant of the traditional hyphenation machinery. This mechanism has been extended @@ -24,7 +16,11 @@ if not modules then modules = { } end modules ['lang-hyp'] = { -- Being the result of two days experimenting the following implementation is probably -- not completely okay yet. If there is demand I might add some more features and plugs. -- The performance is quite okay but can probably improved a bit, although this is not --- the most critital code. +-- the most critital code. For instance, on a metafun manual run the overhead is about +-- 0.3 seconds on 19 seconds which is not that bad. +-- +-- In the procecess of wrapping up (for the ctx conference proceedings) I cleaned up +-- and extended the code a bit. It can be used in production. -- -- . a l g o r i t h m . -- 4l1g4 @@ -45,8 +41,38 @@ if not modules then modules = { } end modules ['lang-hyp'] = { -- -- ab1cd/ef=gh,2,2 : acd - efd (pattern/replacement,start,length -- --- In the procecess of wrapping up (for the ctx conference proceedings) I cleaned up --- and extended the code a bit. +-- todo : support hjcodes (<32 == length) like luatex does now (no need/demand so far) +-- maybe : support hyphenation over range (can alsready be done using attributes/language) +-- maybe : reset dictionary.hyphenated when a pattern is added and/or forced reset option +-- todo : check subtypes (because they have subtle meanings in the line breaking) +-- +-- word start (in tex engine): +-- +-- boundary : yes when wordboundary +-- hlist : when hyphenationbounds 1 or 3 +-- vlist : when hyphenationbounds 1 or 3 +-- rule : when hyphenationbounds 1 or 3 +-- dir : when hyphenationbounds 1 or 3 +-- whatsit : when hyphenationbounds 1 or 3 +-- glue : yes +-- math : skipped +-- glyph : exhyphenchar (one only) : yes (so no -- ---) +-- otherwise : yes +-- +-- word end (in tex engine): +-- +-- boundary : yes +-- glyph : yes when different language +-- glue : yes +-- penalty : yes +-- kern : yes when not italic (for some historic reason) +-- hlist : when hyphenationbounds 2 or 3 +-- vlist : when hyphenationbounds 2 or 3 +-- rule : when hyphenationbounds 2 or 3 +-- dir : when hyphenationbounds 2 or 3 +-- whatsit : when hyphenationbounds 2 or 3 +-- ins : when hyphenationbounds 2 or 3 +-- adjust : when hyphenationbounds 2 or 3 local type, rawset, tonumber, next = type, rawset, tonumber, next @@ -286,15 +312,14 @@ function traditional.lasttrace() return steps end --- We could reuse the w table but as we cache the resolved words --- there is not much gain in that complication. +-- We could reuse the w table but as we cache the resolved words there is not much gain in +-- that complication. -- --- Beware: word can be a table and when n is passed to we can --- assume reuse so we need to honor that n then. - --- todo: a fast variant for tex ... less lookups (we could check is --- dictionary has changed) ... although due to caching the already --- done words, we don't do much here +-- Beware: word can be a table and when n is passed to we can assume reuse so we need to +-- honor that n then. +-- +-- todo: a fast variant for tex ... less lookups (we could check is dictionary has changed) +-- ... although due to caching the already done words, we don't do much here local function hyphenate(dictionary,word,n) -- odd is okay nofwords = nofwords + 1 @@ -331,11 +356,11 @@ local function hyphenate(dictionary,word,n) -- odd is okay end local l = 1 local w = { "." } - -- local d = dictionary.codehash or lcchars[c] + -- local d = dictionary.codehash for i=1,n do local c = word[i] + -- l = l + (d[c] or 1) l = l + 1 - -- w[l] = d[c] or c -- needs testing w[l] = lcchars[c] or c end l = l + 1 @@ -367,7 +392,6 @@ local function hyphenate(dictionary,word,n) -- odd is okay local specials = dictionary.specials local patterns = dictionary.patterns -- --- inspect(specials) local spec for i=1,l do for j=i,l do @@ -378,15 +402,14 @@ local function hyphenate(dictionary,word,n) -- odd is okay if not done then done = { } spec = nil - -- the string that we resolve has explicit fences (.) so - -- done starts at the first fence and runs upto the last - -- one so we need one slot less + -- the string that we resolve has explicit fences (.) so done starts at + -- the first fence and runs upto the last one so we need one slot less for i=1,l do done[i] = 0 end end - -- we run over the pattern that always has a (zero) value for - -- each character plus one more as we look at both sides + -- we run over the pattern that always has a (zero) value for each character + -- plus one more as we look at both sides for k=1,#m do local new = m[k] if not new then @@ -492,8 +515,8 @@ function traditional.injecthyphens(dictionary,word,specification) return word end - -- the following code is similar to code later on but here we have - -- strings while there we have hyphen specs + -- the following code is similar to code later on but here we have strings while there + -- we have hyphen specs local word = lpegmatch(p_split,word) local size = #word @@ -603,8 +626,8 @@ if context then local discretionary_code = disccodes.discretionary local explicit_code = disccodes.explicit - local regular_code = disccodes.regular local automatic_code = disccodes.automatic + local regular_code = disccodes.regular local nuts = nodes.nuts local tonut = nodes.tonut @@ -612,7 +635,6 @@ if context then local nodepool = nuts.pool local new_disc = nodepool.disc - local new_glyph = nodepool.glyph local new_penalty = nodepool.penalty local getfield = nuts.getfield @@ -623,15 +645,22 @@ if context then local getprev = nuts.getprev local getsubtype = nuts.getsubtype local getlist = nuts.getlist + local getlang = nuts.getlang + local getattrlist = nuts.getattrlist + local setattrlist = nuts.setattrlist local isglyph = nuts.isglyph + local ischar = nuts.ischar - local setfield = nuts.setfield local setchar = nuts.setchar local setdisc = nuts.setdisc + local setlink = nuts.setlink + local setprev = nuts.setprev + local setnext = nuts.setnext local insert_before = nuts.insert_before local insert_after = nuts.insert_after local copy_node = nuts.copy + local copy_list = nuts.copy_list local remove_node = nuts.remove local end_of_math = nuts.end_of_math local node_tail = nuts.tail @@ -657,17 +686,22 @@ if context then local a_hyphenation = attributes.private("hyphenation") + local expanders = languages.expanders -- gone in 1.005 + local expand_explicit = expanders and expanders[explicit_code] + local expand_automatic = expanders and expanders[automatic_code] + local interwordpenalty = 5000 function traditional.loadpatterns(language) return dictionaries[language] end - setmetatableindex(dictionaries,function(t,k) -- for the moment we use an independent data structure + -- for the moment we use an independent data structure + + setmetatableindex(dictionaries,function(t,k) if type(k) == "string" then - -- this will force a load if not yet loaded (we need a nicer way) - -- for the moment that will do (nneeded for examples that register - -- a pattern specification + -- this will force a load if not yet loaded (we need a nicer way) for the moment + -- that will do (nneeded for examples that register a pattern specification languages.getnumber(k) end local specification = languages.getdata(k) @@ -742,11 +776,10 @@ if context then -- with less characters than either of them! This could be an option but such a narrow -- hsize doesn't make sense anyway. - -- We assume that featuresets are defined global ... local definitions - -- (also mid paragraph) make not much sense anyway. For the moment we - -- assume no predefined sets so we don't need to store them. Nor do we - -- need to hash them in order to save space ... no sane user will define - -- many of them. + -- We assume that featuresets are defined global ... local definitions (also mid paragraph) + -- make not much sense anyway. For the moment we assume no predefined sets so we don't need + -- to store them. Nor do we need to hash them in order to save space ... no sane user will + -- define many of them. local featuresets = hyphenators.featuresets or { } hyphenators.featuresets = featuresets @@ -768,7 +801,8 @@ if context then return noffeaturesets end - local function makeset(...) -- a bit overkill, supporting variants but who cares + local function makeset(...) + -- a bit overkill, supporting variants but who cares local set = { } for i=1,select("#",...) do local list = select(i,...) @@ -808,9 +842,34 @@ if context then return set end + -- category pd (tex also sees --- and -- as hyphens but do we really want that + local defaulthyphens = { - [0x2D] = true, -- hyphen - [0xAD] = true, -- soft hyphen + [0x002D] = true, -- HYPHEN-MINUS + [0x00AD] = 0x002D, -- SOFT HYPHEN (active in ConTeXt) + -- [0x058A] = true, -- ARMENIAN HYPHEN + -- [0x1400] = true, -- CANADIAN SYLLABICS HYPHEN + -- [0x1806] = true, -- MONGOLIAN TODO SOFT HYPHEN + [0x2010] = true, -- HYPHEN + -- [0x2011] = true, -- NON-BREAKING HYPHEN + -- [0x2012] = true, -- FIGURE DASH + [0x2013] = true, -- EN DASH + [0x2014] = true, -- EM DASH + -- [0x2015] = true, -- HORIZONTAL BAR + -- [0x2027] = true, -- HYPHENATION POINT + -- [0x2E17] = true, -- DOUBLE OBLIQUE HYPHEN + -- [0x2E1A] = true, -- HYPHEN WITH DIAERESIS + -- [0x2E3A] = true, -- TWO-EM DASH + -- [0x2E3B] = true, -- THREE-EM DASH + -- [0x2E40] = true, -- DOUBLE HYPHEN + -- [0x301C] = true, -- WAVE DASH + -- [0x3030] = true, -- WAVY DASH + -- [0x30A0] = true, -- KATAKANA-HIRAGANA DOUBLE HYPHEN + -- [0xFE31] = true, -- PRESENTATION FORM FOR VERTICAL EM DASH + -- [0xFE32] = true, -- PRESENTATION FORM FOR VERTICAL EN DASH + -- [0xFE58] = true, -- SMALL EM DASH + -- [0xFE63] = true, -- SMALL HYPHEN-MINUS + -- [0xFF0D] = true, -- FULLWIDTH HYPHEN-MINUS } local defaultjoiners = { @@ -832,13 +891,15 @@ if context then local charmin = tonumber(featureset.charmin) -- luatex now also has hyphenationmin local leftcharmin = tonumber(featureset.leftcharmin) local rightcharmin = tonumber(featureset.rightcharmin) - local rightedge = featureset.rightedge local leftchar = somehyphenchar(featureset.leftchar) local rightchar = somehyphenchar(featureset.rightchar) local rightchars = featureset.rightchars +local rightedge = featureset.rightedge +local autohyphen = v_yes -- featureset.autohyphen -- insert disc +local hyphenonly = v_yes -- featureset.hyphenonly -- don't hyphenate around rightchars = rightchars == v_word and true or tonumber(rightchars) - joinerchars = joinerchars == v_yes and defaultjoiners or joinerchars - hyphenchars = hyphenchars == v_yes and defaulthyphens or hyphenchars + joinerchars = joinerchars == v_yes and defaultjoiners or joinerchars -- table + hyphenchars = hyphenchars == v_yes and defaulthyphens or hyphenchars -- table -- not yet ok: extrachars have to be ignored so it cannot be all) featureset.extrachars = makeset(joinerchars or "",extrachars or "") featureset.hyphenchars = makeset(hyphenchars or "") @@ -850,8 +911,9 @@ if context then featureset.rightchars = rightchars featureset.leftchar = leftchar featureset.rightchar = rightchar - featureset.strict = rightedge == 'tex' - -- + -- featureset.strict = rightedge == "tex" +featureset.autohyphen = autohyphen == v_yes +featureset.hyphenonly = hyphenonly == v_yes return register(name,featureset) end @@ -923,10 +985,9 @@ if context then arguments = { "string", "string" } } - -- This is a relative large function with local variables and local - -- functions. A previous implementation had the functions outside but - -- this is cleaner and as efficient. The test runs 100 times over - -- tufte.tex, knuth.tex, zapf.tex, ward.tex and darwin.tex in lower + -- This is a relative large function with local variables and local functions. A previous + -- implementation had the functions outside but this is cleaner and as efficient. The test + -- runs 100 times over tufte.tex, knuth.tex, zapf.tex, ward.tex and darwin.tex in lower -- and uppercase with a 1mm hsize. -- -- language=0 language>0 4 | 3 * slower @@ -934,77 +995,89 @@ if context then -- tex 2.34 | 1.30 2.55 | 1.45 0.21 | 0.15 -- lua 2.42 | 1.38 3.30 | 1.84 0.88 | 0.46 -- - -- Of course we have extra overhead (virtual Lua machine) but also we - -- check attributes and support specific local options). The test puts - -- the typeset text in boxes and discards it. If we also flush the - -- runtime is 4.31|2.56 and 4.99|2.94 seconds so the relative difference - -- is (somehow) smaller. The test has 536 pages. There is a little bit - -- of extra overhead because we store the patterns in a different way. + -- Of course we have extra overhead (virtual Lua machine) but also we check attributes and + -- support specific local options). The test puts the typeset text in boxes and discards + -- it. If we also flush the runtime is 4.31|2.56 and 4.99|2.94 seconds so the relative + -- difference is (somehow) smaller. The test has 536 pages. There is a little bit of extra + -- overhead because we store the patterns in a different way. -- - -- As usual I will look for speedups. Some 0.01 seconds could be gained - -- by sharing patterns which is not impressive but it does save some - -- 3M memory on this test. (Some optimizations already brought the 3.30 - -- seconds down to 3.14 but it all depends on aggressive caching.) + -- As usual I will look for speedups. Some 0.01 seconds could be gained by sharing patterns + -- which is not impressive but it does save some 3M memory on this test. (Some optimizations + -- already brought the 3.30 seconds down to 3.14 but it all depends on aggressive caching.) - -- As we kick in the hyphenator before fonts get handled, we don't look - -- at implicit (font) kerns or ligatures. + -- As we kick in the hyphenator before fonts get handled, we don't look at implicit (font) + -- kerns or ligatures. local starttiming = statistics.starttiming local stoptiming = statistics.stoptiming - local strictids = { - [nodecodes.hlist] = true, - [nodecodes.vlist] = true, - [nodecodes.rule] = true, - [nodecodes.disc] = true, - [nodecodes.accent] = true, - [nodecodes.math] = true, - } + -- local strictids = { + -- [nodecodes.hlist] = true, + -- [nodecodes.vlist] = true, + -- [nodecodes.rule] = true, + -- [nodecodes.dir] = true, + -- [nodecodes.whatsit] = true, + -- [nodecodes.ins] = true, + -- [nodecodes.adjust] = true, + -- + -- [nodecodes.math] = true, + -- [nodecodes.disc] = true, + -- + -- [nodecodes.accent] = true, -- never used in context + -- } + + -- a lot of overhead when only one char function traditional.hyphenate(head) - local first = tonut(head) - local tail = nil - local last = nil - local current = first - local dictionary = nil - local instance = nil - local characters = nil - local unicodes = nil - local exhyphenchar = tex.exhyphenchar - local extrachars = nil - local hyphenchars = nil - local language = nil - local start = nil - local stop = nil - local word = { } -- we reuse this table - local size = 0 - local leftchar = false - local rightchar = false -- utfbyte("-") - local leftexchar = false - local rightexchar = false -- utfbyte("-") - local leftmin = 0 - local rightmin = 0 - local charmin = 1 - local leftcharmin = nil - local rightcharmin = nil - ----- leftwordmin = nil - local rightwordmin = nil - local rightchars = nil - local leftchar = nil - local rightchar = nil - local attr = nil - local lastwordlast = nil - local hyphenated = hyphenate - local strict = nil - local hyphenpenalty = tex.hyphenpenalty + local first = tonut(head) + + + local tail = nil + local last = nil + local current = first + local dictionary = nil + local instance = nil + local characters = nil + local unicodes = nil + local exhyphenchar = tex.exhyphenchar + local extrachars = nil + local hyphenchars = nil + local language = nil + local start = nil + local stop = nil + local word = { } -- we reuse this table + local size = 0 + local leftchar = false + local rightchar = false -- utfbyte("-") + local leftexchar = false + local rightexchar = false -- utfbyte("-") + local leftmin = 0 + local rightmin = 0 + local charmin = 1 + local leftcharmin = nil + local rightcharmin = nil + ----- leftwordmin = nil + local rightwordmin = nil + local rightchars = nil + local leftchar = nil + local rightchar = nil + local attr = nil + local lastwordlast = nil + local hyphenated = hyphenate + ----- strict = nil + local exhyphenpenalty = tex.exhyphenpenalty + local hyphenpenalty = tex.hyphenpenalty + local autohyphen = false + local hyphenonly = false -- We cannot use an 'enabled' boolean (false when no characters or extras) because we -- can have plugins that set a characters metatable and so) ... it doesn't save much -- anyway. Using (unicodes and unicodes[code]) and a nil table when no characters also -- doesn't save much. So there not that much to gain for languages that don't hyphenate. -- - -- enabled = (unicodes and (next(unicodes) or getmetatable(unicodes))) or (extrachars and next(extrachars)) + -- enabled = (unicodes and (next(unicodes) or getmetatable(unicodes))) + -- or (extrachars and next(extrachars)) -- -- This can be used to not add characters i.e. keep size 0 but then we need to check for -- attributes that change it, which costs time too. Not much to gain there. @@ -1013,7 +1086,7 @@ if context then local function insertpenalty() local p = new_penalty(interwordpenalty) - setfield(p,"attr",getfield(last,"attr")) + setattrlist(p,last) if trace_visualize then nuts.setvisual(p,"penalty") end @@ -1033,8 +1106,10 @@ if context then rightcharmin = f.rightcharmin leftchar = f.leftchar rightchar = f.rightchar - strict = f.strict and strictids + -- strict = f.strict and strictids rightchars = f.rightchars + autohyphen = f.autohyphen + hyphenonly = f.hyphenonly if rightwordmin and rightwordmin > 0 and lastwordlast ~= rightwordmin then -- so we can change mid paragraph but it's kind of unpredictable then if not tail then @@ -1079,7 +1154,9 @@ if context then rightcharmin = false leftchar = false rightchar = false - strict = false + -- strict = false + autohyphen = false + hyphenonly = false end return a @@ -1092,12 +1169,11 @@ if context then local rsize = 0 local position = 1 - -- todo: remember last dics and don't go back to before that (plus - -- message) .. for simplicity we also assume that we don't start - -- with a dics node + -- todo: remember last dics and don't go back to before that (plus message) ... + -- for simplicity we also assume that we don't start with a dics node -- - -- there can be a conflict: if we backtrack then we can end up in - -- another disc and get out of sync (dup chars and so) + -- there can be a conflict: if we backtrack then we can end up in another disc + -- and get out of sync (dup chars and so) while position <= size do if position >= leftmin and position <= rightmin then @@ -1199,9 +1275,8 @@ if context then return head end - local current = start - - local attributes = getfield(start,"attr") -- todo: just copy the last disc .. faster + local current = start + local attrnode = start -- will be different, just the first char for i=1,rsize do local r = result[i] @@ -1215,9 +1290,9 @@ if context then if leftchar then post = serialize(true,leftchar) end - setdisc(disc,pre,post,nil,discretionary_code,hyphenpenalty) - if attributes then - setfield(disc,"attr",attributes) + setdisc(disc,pre,post,nil,regular_code,hyphenpenalty) + if attrnode then + setattrlist(disc,attrnode) end -- could be a replace as well insert_before(first,current,disc) @@ -1249,9 +1324,10 @@ if context then replace = nil end end - setdisc(disc,pre,post,replace,discretionary_code,hyphenpenalty) - if attributes then - setfield(disc,"attr",attributes) + -- maybe regular code + setdisc(disc,pre,post,replace,regular_code,hyphenpenalty) + if attrnode then + setattrlist(disc,attrnode) end insert_before(first,current,disc) else @@ -1271,7 +1347,7 @@ if context then end - local function inject(leftchar,rightchar,code,attributes) + local function inject(leftchar,rightchar,code,attrnode) if first ~= current then local disc = new_disc() first, current, glyph = remove_node(first,current) @@ -1280,97 +1356,66 @@ if context then setcolor(glyph,"darkred") -- these get checked setcolor(disc,"darkgreen") -- in the colorizer end - local pre = mil + local pre = nil local post = nil local replace = glyph - if not leftchar then - leftchar = code - end - if rightchar then - pre = copy_node(glyph) - setchar(pre,rightchar) - end - if leftchar then + if leftchar and leftchar > 0 then post = copy_node(glyph) setchar(post,leftchar) end - setdisc(disc,pre,post,replace,discretionary_code,hyphenpenalty) - if attributes then - setfield(disc,"attr",attributes) + pre = copy_node(glyph) + setchar(pre,rightchar and rightchar > 0 and rightchar or code) + setdisc(disc,pre,post,replace,automatic_code,hyphenpenalty) -- ex ? + if attrnode then + setattrlist(disc,attrnode) end end return current end + local function injectseries(current,last,next,attrnode) + local disc = new_disc() + local start = current + first, current = insert_before(first,current,disc) + setprev(start) + setnext(last) + if next then + setlink(current,next) + else + setnext(current) + end + local pre = copy_list(start) + local post = nil + local replace = start + setdisc(disc,pre,post,replace,automatic_code,hyphenpenalty) -- ex ? + if attrnode then + setattrlist(disc,attrnode) + end + return current + end + local a = getattr(first,a_hyphenation) if a ~= attr then attr = synchronizefeatureset(a) end - -- The first attribute in a word determines the way a word gets hyphenated - -- and if relevant, other properties are also set then. We could optimize for - -- silly one-char cases but it has no priority as the code is still not that - -- much slower than the native hyphenator and this variant also provides room - -- for extensions. + -- The first attribute in a word determines the way a word gets hyphenated and if + -- relevant, other properties are also set then. We could optimize for silly one-char + -- cases but it has no priority as the code is still not that much slower than the + -- native hyphenator and this variant also provides room for extensions. + + local skipping = false while current and current ~= last do -- and current local code, id = isglyph(current) if code then - local lang = getfield(current,"lang") - if lang ~= language then - if dictionary and size > charmin and leftmin + rightmin <= size then - if categories[word[1]] == "lu" and getfield(start,"uchyph") < 0 then - -- skip - else - local hyphens = hyphenated(dictionary,word,size) - if hyphens then - flush(hyphens) - end - end - end - language = lang - if language > 0 then - -- - dictionary = dictionaries[language] - instance = dictionary.instance - characters = dictionary.characters - unicodes = dictionary.unicodes - -- - local a = getattr(current,a_hyphenation) - attr = synchronizefeatureset(a) - leftchar = leftchar or (instance and posthyphenchar (instance)) -- we can make this more - rightchar = rightchar or (instance and prehyphenchar (instance)) -- efficient if needed - leftexchar = (instance and preexhyphenchar (instance)) - rightexchar = (instance and postexhyphenchar(instance)) - leftmin = leftcharmin or getfield(current,"left") - rightmin = rightcharmin or getfield(current,"right") - if not leftchar or leftchar < 0 then - leftchar = false - end - if not rightchar or rightchar < 0 then - rightchar = false - end - -- - local char = unicodes[code] or (extrachars and extrachars[code]) - if char then - word[1] = char - size = 1 - start = current - else - size = 0 - end - else - size = 0 - end - elseif language <= 0 then - -- - elseif size > 0 then - local char = unicodes[code] or (extrachars and extrachars[code]) - if char then - size = size + 1 - word[size] = char - elseif dictionary then - if size > charmin and leftmin + rightmin <= size then + if skipping then + current = getnext(current) + else + local lang = getlang(current) + if lang ~= language then + if dictionary and size > charmin and leftmin + rightmin <= size then + -- only german has many words starting with an uppercase character if categories[word[1]] == "lu" and getfield(start,"uchyph") < 0 then -- skip else @@ -1380,71 +1425,151 @@ if context then end end end - size = 0 - -- maybe also a strict mode here: no hyphenation before hyphenchars and skip - -- the next set (but then, strict is an option) - if code == exhyphenchar then - current = inject(leftexchar,rightexchar,code,getfield(current,"attr")) - elseif hyphenchars and hyphenchars[code] then - current = inject(leftchar,rightchar,code,getfield(current,"attr")) + language = lang + if language > 0 then + -- + dictionary = dictionaries[language] + instance = dictionary.instance + characters = dictionary.characters + unicodes = dictionary.unicodes + -- + local a = getattr(current,a_hyphenation) + attr = synchronizefeatureset(a) + leftchar = leftchar or (instance and posthyphenchar (instance)) -- we can make this more + rightchar = rightchar or (instance and prehyphenchar (instance)) -- efficient if needed + leftexchar = (instance and preexhyphenchar (instance)) + rightexchar = (instance and postexhyphenchar(instance)) + leftmin = leftcharmin or getfield(current,"left") + rightmin = rightcharmin or getfield(current,"right") + if not leftchar or leftchar < 0 then + leftchar = false + end + if not rightchar or rightchar < 0 then + rightchar = false + end + -- + local char = unicodes[code] or (extrachars and extrachars[code]) + if char then + word[1] = char + size = 1 + start = current + else + size = 0 + end + else + size = 0 end - end - else - local a = getattr(current,a_hyphenation) - if a ~= attr then - attr = synchronizefeatureset(a) -- influences extrachars - leftchar = leftchar or (instance and posthyphenchar (instance)) -- we can make this more - rightchar = rightchar or (instance and prehyphenchar (instance)) -- efficient if needed - leftexchar = (instance and preexhyphenchar (instance)) - rightexchar = (instance and postexhyphenchar(instance)) - leftmin = leftcharmin or getfield(current,"left") - rightmin = rightcharmin or getfield(current,"right") - if not leftchar or leftchar < 0 then - leftchar = false + elseif language <= 0 then + -- + elseif size > 0 then + local char = unicodes[code] or (extrachars and extrachars[code]) + if char then + size = size + 1 + word[size] = char + elseif dictionary then + if not hyphenonly or code ~= exhyphenchar then + if size > charmin and leftmin + rightmin <= size then + if categories[word[1]] == "lu" and getfield(start,"uchyph") < 0 then + -- skip + else + local hyphens = hyphenated(dictionary,word,size) + if hyphens then + flush(hyphens) + end + end + end + end + size = 0 + if code == exhyphenchar then -- normally the - + local next = getnext(current) + local last = current + local font = getfont(current) + while next and ischar(next,font) == code do + last = next + next = getnext(next) + end + if not autohyphen then + current = last + elseif current == last then + current = inject(leftexchar,rightexchar,code,current) + else + current = injectseries(current,last,next,current) + end + if hyphenonly then + skipping = true + end + elseif hyphenchars then + local char = hyphenchars[code] + if char == true then + char = code + end + if char then + current = inject(leftchar and char or nil,rightchar and char or nil,char,current) + end + end end - if not rightchar or rightchar < 0 then - rightchar = false + else + local a = getattr(current,a_hyphenation) + if a ~= attr then + attr = synchronizefeatureset(a) -- influences extrachars + leftchar = leftchar or (instance and posthyphenchar (instance)) -- we can make this more + rightchar = rightchar or (instance and prehyphenchar (instance)) -- efficient if needed + leftexchar = (instance and preexhyphenchar (instance)) + rightexchar = (instance and postexhyphenchar(instance)) + leftmin = leftcharmin or getfield(current,"left") + rightmin = rightcharmin or getfield(current,"right") + if not leftchar or leftchar < 0 then + leftchar = false + end + if not rightchar or rightchar < 0 then + rightchar = false + end + end + -- + local char = unicodes[code] or (extrachars and extrachars[code]) + if char then + word[1] = char + size = 1 + start = current end end - -- - local char = unicodes[code] or (extrachars and extrachars[code]) - if char then - word[1] = char - size = 1 - start = current - end + stop = current + current = getnext(current) end - stop = current - current = getnext(current) else + if skipping then + skipping = false + end if id == disc_code then - local subtype = getsubtype(current) - if subtype == discretionary_code then -- \discretionary - size = 0 - current = getnext(current) - elseif subtype == explicit_code then -- \- => only here - size = 0 - current = getnext(current) - while current do - local id = getid(current) - if id == glyph_code or id == disc_code then - current = getnext(current) - else - break - end + if expanded then + -- pre 1.005 + local subtype = getsubtype(current) + if subtype == discretionary_code then -- \discretionary + size = 0 + elseif subtype == explicit_code then -- \- => only here + -- automatic (-) : the old parser makes negative char entries + size = 0 + expand_explicit(current) + elseif subtype == automatic_code then -- - => only here + -- automatic (-) : the old hyphenator turns an exhyphen into glyph+disc + size = 0 + expand_automatic(current) + else + -- first : done by the hyphenator + -- second : done by the hyphenator + -- regular : done by the hyphenator + size = 0 end - -- todo: change to discretionary_code else - -- automatic (-) : the hyphenator turns an exhyphen into glyph+disc - -- first : done by the hyphenator - -- second : done by the hyphenator - -- regular : done by the hyphenator size = 0 - current = getnext(current) end - elseif strict and strict[id] then - current = id == math_code and getnext(end_of_math(current)) or getnext(current) - size = 0 + current = getnext(current) + if hyphenonly then + skipping = true + end + -- elseif strict and strict[id] then + -- current = id == math_code and getnext(end_of_math(current)) or getnext(current) + -- size = 0 else current = id == math_code and getnext(end_of_math(current)) or getnext(current) end @@ -1463,8 +1588,8 @@ if context then end end end - -- we can have quit due to last so we need to flush the last seen word, we could move this in - -- the loop and test for current but ... messy + -- we can have quit due to last so we need to flush the last seen word, we could move + -- this in the loop and test for current but ... messy if dictionary and size > charmin and leftmin + rightmin <= size then if categories[word[1]] == "lu" and getfield(start,"uchyph") < 0 then -- skip @@ -1517,28 +1642,39 @@ if context then return head, done end - local function expanded(head) + local expanded = function (head) local done = hyphenate(head) - if done then - for d in traverse_id(disc_code,tonut(head)) do - local s = getsubtype(d) - if s ~= discretionary_code then - expanders[s](d,template) - done = true + return head, done + end + + if LUATEXVERSION< 1.005 then + + expanded = function(head) + local done = hyphenate(head) + if done then + for d in traverse_id(disc_code,tonut(head)) do + local s = getsubtype(d) + if s ~= discretionary_code then + expanders[s](d,template) + done = true + end end end + return head, done end - return head, done + end local getcount = tex.getcount hyphenators.methods = methods - hyphenators.optimize = false + local optimize = false + + directives.register("hyphenator.optimize", function(v) optimize = v end) function hyphenators.handler(head,groupcode) if usedmethod then - if groupcode == "hbox" and hyphenators.optimize then + if optimize and (groupcode == "hbox" or groupcode == "adjusted_hbox") then if getcount("hyphenstate") > 0 then forced = false return usedmethod(head) @@ -1555,7 +1691,7 @@ if context then methods.tex = original methods.original = original - methods.expanded = expanded + methods.expanded = expanded -- obsolete starting with 1.005 methods.traditional = languages.hyphenators.traditional.hyphenate methods.none = false -- function(head) return head, false end @@ -1647,54 +1783,54 @@ if context then else --- traditional.loadpatterns("nl","lang-nl") --- traditional.loadpatterns("de","lang-de") --- traditional.loadpatterns("us","lang-us") - --- traditional.registerpattern("nl","e1ë", { start = 1, length = 2, before = "e", after = "e" } ) --- traditional.registerpattern("nl","oo7ë", { start = 2, length = 3, before = "o", after = "e" } ) --- traditional.registerpattern("de","qqxc9xkqq",{ start = 3, length = 4, before = "ab", after = "cd" } ) - --- local specification = { --- leftcharmin = 2, --- rightcharmin = 2, --- leftchar = "<", --- rightchar = ">", --- } - --- print("reëel", traditional.injecthyphens(dictionaries.nl,"reëel", specification),"r{e>}{<e}{eë}el") --- print("reeëel", traditional.injecthyphens(dictionaries.nl,"reeëel", specification),"re{e>}{<e}{eë}el") --- print("rooëel", traditional.injecthyphens(dictionaries.nl,"rooëel", specification),"r{o>}{<e}{ooë}el") - --- print( "qxcxkq", traditional.injecthyphens(dictionaries.de, "qxcxkq", specification),"") --- print( "qqxcxkqq", traditional.injecthyphens(dictionaries.de, "qqxcxkqq", specification),"") --- print( "qqqxcxkqqq", traditional.injecthyphens(dictionaries.de, "qqqxcxkqqq", specification),"") --- print("qqqqxcxkqqqq",traditional.injecthyphens(dictionaries.de,"qqqqxcxkqqqq",specification),"") - --- print("kunstmatig", traditional.injecthyphens(dictionaries.nl,"kunstmatig", specification),"") --- print("kunststofmatig", traditional.injecthyphens(dictionaries.nl,"kunststofmatig", specification),"") --- print("kunst[stof]matig", traditional.injecthyphens(dictionaries.nl,"kunst[stof]matig", specification),"") - --- traditional.loadpatterns("us","lang-us") - --- local specification = { --- leftcharmin = 2, --- rightcharmin = 2, --- leftchar = false, --- rightchar = false, --- } - --- trace_steps = true - --- print("components", traditional.injecthyphens(dictionaries.us,"components", specification),"") --- print("single", traditional.injecthyphens(dictionaries.us,"single", specification),"sin-gle") --- print("everyday", traditional.injecthyphens(dictionaries.us,"everyday", specification),"every-day") --- print("associate", traditional.injecthyphens(dictionaries.us,"associate", specification),"as-so-ciate") --- print("philanthropic", traditional.injecthyphens(dictionaries.us,"philanthropic", specification),"phil-an-thropic") --- print("projects", traditional.injecthyphens(dictionaries.us,"projects", specification),"projects") --- print("Associate", traditional.injecthyphens(dictionaries.us,"Associate", specification),"As-so-ciate") --- print("Philanthropic", traditional.injecthyphens(dictionaries.us,"Philanthropic", specification),"Phil-an-thropic") --- print("Projects", traditional.injecthyphens(dictionaries.us,"Projects", specification),"Projects") + -- traditional.loadpatterns("nl","lang-nl") + -- traditional.loadpatterns("de","lang-de") + -- traditional.loadpatterns("us","lang-us") + + -- traditional.registerpattern("nl","e1ë", { start = 1, length = 2, before = "e", after = "e" } ) + -- traditional.registerpattern("nl","oo7ë", { start = 2, length = 3, before = "o", after = "e" } ) + -- traditional.registerpattern("de","qqxc9xkqq",{ start = 3, length = 4, before = "ab", after = "cd" } ) + + -- local specification = { + -- leftcharmin = 2, + -- rightcharmin = 2, + -- leftchar = "<", + -- rightchar = ">", + -- } + + -- print("reëel", traditional.injecthyphens(dictionaries.nl,"reëel", specification),"r{e>}{<e}{eë}el") + -- print("reeëel", traditional.injecthyphens(dictionaries.nl,"reeëel", specification),"re{e>}{<e}{eë}el") + -- print("rooëel", traditional.injecthyphens(dictionaries.nl,"rooëel", specification),"r{o>}{<e}{ooë}el") + + -- print( "qxcxkq", traditional.injecthyphens(dictionaries.de, "qxcxkq", specification),"") + -- print( "qqxcxkqq", traditional.injecthyphens(dictionaries.de, "qqxcxkqq", specification),"") + -- print( "qqqxcxkqqq", traditional.injecthyphens(dictionaries.de, "qqqxcxkqqq", specification),"") + -- print("qqqqxcxkqqqq",traditional.injecthyphens(dictionaries.de,"qqqqxcxkqqqq",specification),"") + + -- print("kunstmatig", traditional.injecthyphens(dictionaries.nl,"kunstmatig", specification),"") + -- print("kunststofmatig", traditional.injecthyphens(dictionaries.nl,"kunststofmatig", specification),"") + -- print("kunst[stof]matig", traditional.injecthyphens(dictionaries.nl,"kunst[stof]matig", specification),"") + + -- traditional.loadpatterns("us","lang-us") + + -- local specification = { + -- leftcharmin = 2, + -- rightcharmin = 2, + -- leftchar = false, + -- rightchar = false, + -- } + + -- trace_steps = true + + -- print("components", traditional.injecthyphens(dictionaries.us,"components", specification),"") + -- print("single", traditional.injecthyphens(dictionaries.us,"single", specification),"sin-gle") + -- print("everyday", traditional.injecthyphens(dictionaries.us,"everyday", specification),"every-day") + -- print("associate", traditional.injecthyphens(dictionaries.us,"associate", specification),"as-so-ciate") + -- print("philanthropic", traditional.injecthyphens(dictionaries.us,"philanthropic", specification),"phil-an-thropic") + -- print("projects", traditional.injecthyphens(dictionaries.us,"projects", specification),"projects") + -- print("Associate", traditional.injecthyphens(dictionaries.us,"Associate", specification),"As-so-ciate") + -- print("Philanthropic", traditional.injecthyphens(dictionaries.us,"Philanthropic", specification),"Phil-an-thropic") + -- print("Projects", traditional.injecthyphens(dictionaries.us,"Projects", specification),"Projects") end diff --git a/tex/context/base/mkiv/lang-hyp.mkiv b/tex/context/base/mkiv/lang-hyp.mkiv index ca9113386..c111bc31a 100644 --- a/tex/context/base/mkiv/lang-hyp.mkiv +++ b/tex/context/base/mkiv/lang-hyp.mkiv @@ -37,6 +37,22 @@ \definesystemattribute[hyphenation][public] +%D After a decade of playing with these things in \LUATEX|/|\MKIV\ it's time to +%D finish the way we deal with discretionaries. Apart from the fact that they play a +%D role in hyphenation they also need to be dealt with in fonts. Flattening, cleanup +%D and such are now more or less default in \CONTEXT\ so we can simplify some of the +%D code. We also use the new penalty mechanism. + +\newcount\compoundhyphenpenalty + +\automatichyphenmode \plusone +\hyphenpenaltymode \plusfour + +\hyphenpenalty 50 % hyphenator +\automatichyphenpenalty 50 % - +\explicithyphenpenalty 50 % \- +\compoundhyphenpenalty 50 + %D This command can change! At some point we will keep the setting with the %D paragraph and then the \type {\par} can go. @@ -51,7 +67,6 @@ % \enabledirectives[hyphenators.method]% % \endgroup} - % \exhyphenchar \hyphenasciicode % \preexhyphenchar \lessthanasciicode % \postexhyphenchar\morethanasciicode @@ -123,7 +138,9 @@ leftchar \numexpr\dummyparameter\s!lefthyphenchar\relax rightchar \numexpr\dummyparameter\s!righthyphenchar\relax alternative {\dummyparameter\c!alternative}% - rightedge {\dummyparameter\c!rightedge}% +rightedge {\dummyparameter\c!rightedge}% +% autohyphen {\dummyparameter\c!autohyphen} +% hyphenonly {\dummyparameter\c!hyphenonly} }% \relax \endgroup} diff --git a/tex/context/base/mkiv/lang-ini.lua b/tex/context/base/mkiv/lang-ini.lua index 00fdb3f09..6de951998 100644 --- a/tex/context/base/mkiv/lang-ini.lua +++ b/tex/context/base/mkiv/lang-ini.lua @@ -20,15 +20,16 @@ if not modules then modules = { } end modules ['lang-ini'] = { local type, tonumber = type, tonumber local utfbyte = utf.byte -local format, gsub = string.format, string.gsub -local concat, sortedkeys, sortedpairs = table.concat, table.sortedkeys, table.sortedpairs -local utfbytes, strip = string.utfvalues, string.strip +local format, gsub, gmatch, find = string.format, string.gsub, string.gmatch, string.find +local concat, sortedkeys, sortedpairs, keys, insert = table.concat, table.sortedkeys, table.sortedpairs, table.keys, table.insert +local utfbytes, strip, utfcharacters = string.utfvalues, string.strip, utf.characters local context = context local commands = commands local implement = interfaces.implement local settings_to_array = utilities.parsers.settings_to_array +local settings_to_set = utilities.parsers.settings_to_set local trace_patterns = false trackers.register("languages.patterns", function(v) trace_patterns = v end) @@ -45,6 +46,7 @@ local postexhyphenchar = lang.postexhyphenchar -- global per language local sethjcode = lang.sethjcode local uccodes = characters.uccodes +local lccodes = characters.lccodes lang.exceptions = lang.hyphenation local new_langage = lang.new @@ -71,6 +73,11 @@ storage.register("languages/associated",associated,"languages.associated") storage.register("languages/numbers", numbers, "languages.numbers") storage.register("languages/data", data, "languages.data") +local variables = interfaces.variables + +local v_reset = variables.reset +local v_yes = variables.yes + local nofloaded = 0 local function resolve(tag) @@ -119,7 +126,7 @@ local function validdata(loaded,what,tag) if dataset then local data = dataset.data if not data or data == "" then - return nil + -- nothing elseif dataset.compression == "zlib" then data = zlib.decompress(data) if dataset.length and dataset.length ~= #data then @@ -132,39 +139,158 @@ local function validdata(loaded,what,tag) end end -local function sethjcodes(instance,loaded,what) +-- languages.hjcounts[unicode].count + +-- hjcode: 0 not to be hyphenated +-- 1--31 length +-- 32 zero length +-- > 32 hyphenated with length 1 + +local function sethjcodes(instance,loaded,what,factor) local l = loaded[what] local c = l and l.characters if c then - local h = l.codehash + local hjcounts = factor and languages.hjcounts or false + -- + local h = loaded.codehash if not h then h = { } - l.codehash = h + loaded.codehash = h + end + -- + local function setcode(l) + local u = uccodes[l] + local s = l + if hjcounts then + local c = hjcounts[l] + if c then + c = c.count + if not c then + -- error, keep as 1 + elseif c <= 0 then + -- counts as 0 i.e. ignored + s = 32 + elseif c >= 31 then + -- counts as 31 + s = 31 + else + -- count c times + s = c + end + end + end + sethjcode(instance,l,s) + h[l] = s + if u ~= l and type(u) == "number" then + sethjcode(instance,u,s) + h[u] = lccodes[l] + end end + -- local s = tex.savinghyphcodes tex.savinghyphcodes = 0 - for l in utfbytes(c) do - local u = uccodes[l] - sethjcode(instance,l,l) - h[l] = l - if type(u) == "number" then - -- we don't want ß -> SS - sethjcode(instance,u,l) - h[u] = l + if type(c) == "table" then + for l in next, c do + setcode(utfbyte(l)) + end + else + for l in utfbytes(c) do + setcode(l) end end tex.savinghyphcodes = s end end +-- 2'2 conflicts with 4' ... and luatex barks on it + +local P, R, Cs, Ct, lpegmatch, lpegpatterns = lpeg.P, lpeg.R, lpeg.Cs, lpeg.Ct, lpeg.match, lpeg.patterns + +local utfsplit = utf.split + +local space = lpegpatterns.space +local whitespace = lpegpatterns.whitespace^1 +local nospace = lpegpatterns.utf8char - whitespace +local digit = lpegpatterns.digit +----- endofstring = #whitespace + P(-1) +local endofstring = #whitespace + +local word = (digit/"")^0 * (digit/"" * endofstring + digit/" " + nospace)^1 +local anyword = (1-whitespace)^1 +local analyze = Ct((whitespace + Cs(word))^1) + +local function unique(tag,requested,loaded) + local nofloaded = #loaded + if nofloaded == 0 then + return "" + elseif nofloaded == 1 then + return loaded[1] + else + insert(loaded,1," ") -- no need then for special first word + -- insert(loaded, " ") + loaded = concat(loaded," ") + local t = lpegmatch(analyze,loaded) or { } + local h = { } + local b = { } + for i=1,#t do + local ti = t[i] + local hi = h[ti] + if not hi then + h[ti] = 1 + elseif hi == 1 then + h[ti] = 2 + b[#b+1] = utfsplit(ti," ") + end + end + -- sort + local nofbad = #b + if nofbad > 0 then + local word + for i=1,nofbad do + local bi = b[i] + local p = P(bi[1]) + for i=2,#bi do + p = p * digit * P(bi[i]) + end + if word then + word = word + p + else + word = p + end + report_initialization("language %a, patterns %a, discarding conflict (0-9)%{[0-9]}t(0-9)",tag,requested,bi) + end + t, h, b = nil, nil, nil -- permit gc + local someword = digit^0 * word * digit^0 * endofstring / "" + -- local strip = Cs(someword^-1 * (someword + anyword + whitespace)^1) + local strip = Cs((someword + anyword + whitespace)^1) + return lpegmatch(strip,loaded) or loaded + else + return loaded + end + end +end + local function loaddefinitions(tag,specification) statistics.starttiming(languages) local data, instance = resolve(tag) - local definitions = settings_to_array(specification.patterns or "") + local requested = specification.patterns or "" + local definitions = settings_to_array(requested) if #definitions > 0 then if trace_patterns then report_initialization("pattern specification for language %a: %s",tag,specification.patterns) end + local ploaded = instance:patterns() + local eloaded = instance:hyphenation() + if not ploaded or ploaded == "" then + ploaded = { } + else + ploaded = { ploaded } + end + if not eloaded or eloaded == "" then + eloaded = { } + else + eloaded = { eloaded } + end local dataused = data.used local ok = false local resources = data.resources or { } @@ -173,11 +299,14 @@ local function loaddefinitions(tag,specification) local definition = definitions[i] if definition == "" then -- error - elseif definition == "reset" then -- interfaces.variables.reset + elseif definition == v_reset then if trace_patterns then report_initialization("clearing patterns for language %a",tag) end instance:clear_patterns() + instance:clear_hyphenation() + ploaded = { } + eloaded = { } elseif not dataused[definition] then dataused[definition] = definition local filename = "lang-" .. definition .. ".lua" @@ -193,10 +322,16 @@ local function loaddefinitions(tag,specification) local loaded = table.load(fullname,gzipped and gzip.load) if loaded then -- todo: version test ok, nofloaded = true, nofloaded + 1 - sethjcodes(instance,loaded,"patterns") - sethjcodes(instance,loaded,"exceptions") - instance:patterns (validdata(loaded,"patterns", tag) or "") - instance:hyphenation(validdata(loaded,"exceptions",tag) or "") + sethjcodes(instance,loaded,"patterns",specification.factor) + sethjcodes(instance,loaded,"exceptions",specification.factor) + local p = validdata(loaded,"patterns",tag) + local e = validdata(loaded,"exceptions",tag) + if p and p ~= "" then + ploaded[#ploaded+1] = p + end + if e and e ~= "" then + eloaded[#eloaded+1] = e + end resources[#resources+1] = loaded -- so we can use them otherwise else report_initialization("invalid definition %a for language %a in %a",definition,tag,filename) @@ -208,6 +343,14 @@ local function loaddefinitions(tag,specification) report_initialization("definition %a for language %a already loaded",definition,tag) end end + if #ploaded > 0 then + instance:clear_patterns() + instance:patterns(unique(tag,requested,ploaded)) + end + if #eloaded > 0 then + instance:clear_hyphenation() + instance:hyphenation(concat(eloaded," ")) + end return ok elseif trace_patterns then report_initialization("no definitions for language %a",tag) @@ -259,7 +402,9 @@ function languages.associate(tag,script,language) -- not yet used end function languages.association(tag) -- not yet used - if type(tag) == "number" then + if not tag then + tag = numbers[tex.language] + elseif type(tag) == "number" then tag = numbers[tag] end local lat = tag and associated[tag] @@ -295,10 +440,11 @@ if environment.initex then else - function languages.getnumber(tag,default,patterns) + function languages.getnumber(tag,default,patterns,factor) local l = registered[tag] if l then if l.dirty then + l.factor = factor == v_yes and true or false if trace_patterns then report_initialization("checking patterns for %a with default %a",tag,default) end @@ -353,19 +499,43 @@ function languages.postexhyphenchar(what) return postexhyphenchar(tolang(what)) -- e['user-friendly'] = 'user=friend-ly' -- e['exceptionally-friendly'] = 'excep-tionally=friend-ly' +local invalid = { "{", "}", "-" } + +local function collecthjcodes(data,str) + local found = data.extras and data.extras.characters or { } + for s in utfcharacters(str) do + if not found[s] then + found[s] = true + end + end + for i=1,#invalid do -- less checks this way + local c = invalid[i] + if found[c] then + found[c] = nil + end + end + data.extras = { characters = found } + sethjcodes(data.instance,data,"extras",data.factor) +end + function languages.loadwords(tag,filename) local data, instance = resolve(tag) if data then statistics.starttiming(languages) - instance:hyphenation(io.loaddata(filename) or "") + local str = io.loaddata(filename) or "" + collecthjcodes(data,str) + instance:hyphenation(str) statistics.stoptiming(languages) end end + function languages.setexceptions(tag,str) local data, instance = resolve(tag) if data then - instance:hyphenation(strip(str)) -- we need to strip leading spaces + str = strip(str) -- we need to strip leading spaces + collecthjcodes(data,str) + instance:hyphenation(str) end end @@ -422,7 +592,7 @@ end) implement { name = "languagenumber", actions = { languages.getnumber, context }, - arguments = { "string", "string", "string" } + arguments = { "string", "string", "string", "string" } } implement { @@ -454,7 +624,6 @@ implement { arguments = { "string", "string" } } - implement { name = "currentprehyphenchar", actions = function() diff --git a/tex/context/base/mkiv/lang-ini.mkiv b/tex/context/base/mkiv/lang-ini.mkiv index 214ce8ca3..947422710 100644 --- a/tex/context/base/mkiv/lang-ini.mkiv +++ b/tex/context/base/mkiv/lang-ini.mkiv @@ -24,6 +24,7 @@ \registerctxluafile{lang-ini}{1.001} \registerctxluafile{lang-def}{1.001} +\registerctxluafile{lang-cnt}{1.001} \unprotect @@ -169,9 +170,9 @@ \lastnamedcs \fi\fi\fi} -\unexpanded\def\setlanguageparameter#1% - {\edef\currentusedlanguage{\reallanguagetag{#1\c!language}}% - %\let\setlanguageparameter\gobbleoneargument +\unexpanded\def\setusedlanguage#1% +% {\edef\currentusedlanguage{\reallanguagetag{#1\c!language}}% + {\edef\currentusedlanguage{\reallanguagetag{#1}}% \ifx\currentusedlanguage\empty \let\currentusedlanguage \currentlanguage \let\usedlanguageparameter\languageparameter @@ -458,6 +459,7 @@ {\currentlanguage}% {\defaultlanguage\currentlanguage}% {\languageparameter\s!patterns}% + {\languageparameter\c!factor}% \relax \normallanguage\csname\??languagenumbers\currentlanguage\endcsname} @@ -497,16 +499,6 @@ \fi \lang_basics_synchronize_min_max} -% \unexpanded\def\nohyphens % % % % % not clever, we still hyphenate but supress application -% {\ifx\dohyphens\relax -% \unexpanded\edef\dohyphens -% {\hyphenpenalty \the\hyphenpenalty -% \exhyphenpenalty\the\exhyphenpenalty -% \relax}% -% \fi -% \hyphenpenalty \plustenthousand -% \exhyphenpenalty\plustenthousand} - \unexpanded\def\nohyphens % nicer for url's {\ifx\dohyphens\relax \unexpanded\edef\dohyphens @@ -583,36 +575,26 @@ %D Fast switcher -% \def\lang_basics_switch_asked -% {\ifx\askedlanguage\empty \else -% \ifcsname\??languagelinked\askedlanguage\endcsname -% \edef\askedlanguage{\csname\??languagelinked\askedlanguage\endcsname}% -% \ifx\currentlanguage\askedlanguage \else -% \setcurrentlanguage\currentmainlanguage\askedlanguage -% \lang_basics_synchronize -% \fi -% \fi -% \fi} - \def\lang_basics_switch_asked - {\ifx\askedlanguage\empty \else - \ifcsname\??languagelinked\askedlanguage\endcsname - %\edef\askedlanguage{\csname\??languagelinked\askedlanguage\endcsname}% - \edef\askedlanguage{\lastnamedcs}% - \ifx\currentlanguage\askedlanguage \else - \setcurrentlanguage\currentmainlanguage\askedlanguage - \lang_basics_synchronize - \fi + {\ifcsname\??languagelinked\askedlanguage\endcsname + \edef\askedlanguage{\lastnamedcs}% + \ifx\currentlanguage\askedlanguage \else + \setcurrentlanguage\currentmainlanguage\askedlanguage + \lang_basics_synchronize \fi \fi} \unexpanded\def\uselanguageparameter#1% {\edef\askedlanguage{#1\c!language}% - \lang_basics_switch_asked} + \ifx\askedlanguage\empty\else\lang_basics_switch_asked\fi} + +\unexpanded\def\douselanguageparameter#1% fast setter + {\edef\askedlanguage{#1}% + \ifx\askedlanguage\empty\else\lang_basics_switch_asked\fi} \unexpanded\def\lang_basics_set_current[#1]% {\edef\askedlanguage{#1}% - \lang_basics_switch_asked} + \ifx\askedlanguage\empty\else\lang_basics_switch_asked\fi} \unexpanded\def\language {\doifelsenextoptionalcs\lang_basics_set_current\normallanguage} @@ -809,6 +791,9 @@ \clf_setlanguageexceptions{\askedlanguage}{#2}% \endgroup} +\unexpanded\def\hyphenation + {\clf_setlanguageexceptions{\currentlanguage}} + %D For the moment here: \uchyph 1 % also treat uppercase diff --git a/tex/context/base/mkiv/lang-lab.mkiv b/tex/context/base/mkiv/lang-lab.mkiv index 26c10086f..40845be4a 100644 --- a/tex/context/base/mkiv/lang-lab.mkiv +++ b/tex/context/base/mkiv/lang-lab.mkiv @@ -81,6 +81,8 @@ \expandafter\noexpand\csname #1texts\endcsname \expandafter\noexpand\csname #1text\endcsname}} +% hm, not interfaced + \unexpanded\def\lang_labels_define_class_indeed#1#2#3#4#5#6#7#8#9% {\setuvalue{setup#1text}{\protecttextprefixes#2\def\currenttextprefixclass{#1}\dodoubleempty\lang_labels_text_prefix_setup}% \setuvalue{preset#1text}{\protecttextprefixes1\def\currenttextprefixclass{#1}\dodoubleempty\lang_labels_text_prefix_setup}% diff --git a/tex/context/base/mkiv/lang-rep.lua b/tex/context/base/mkiv/lang-rep.lua index 28f2e5d50..6fde353f7 100644 --- a/tex/context/base/mkiv/lang-rep.lua +++ b/tex/context/base/mkiv/lang-rep.lua @@ -52,11 +52,13 @@ local getchar = nuts.getchar local isglyph = nuts.isglyph local setfield = nuts.setfield +local getfield = nuts.getfield local setattr = nuts.setattr local setlink = nuts.setlink local setnext = nuts.setnext local setprev = nuts.setprev local setchar = nuts.setchar +local setattrlist = nuts.setattrlist local insert_node_before = nuts.insert_before local remove_node = nuts.remove @@ -65,12 +67,13 @@ local flush_list = nuts.flush_list local insert_after = nuts.insert_after local nodepool = nuts.pool -local new_glyph = nodepool.glyph local new_disc = nodepool.disc local texsetattribute = tex.setattribute local unsetvalue = attributes.unsetvalue +local enableaction = nodes.tasks.enableaction + local v_reset = interfaces.variables.reset local implement = interfaces.implement @@ -223,34 +226,35 @@ function replacements.handler(head) local i = 1 while i <= newlength do local codes = newcodes[i] - local new = nil if type(codes) == "table" then local method = codes[1] if method == "discretionary" then local pre, post, replace = codes[2], codes[3], codes[4] - new = new_disc() if pre then - setfield(new,"pre",tonodes(pre,last)) + pre = tonodes(pre,last) end if post then - setfield(new,"post",tonodes(post,last)) + post = tonodes(post,last) end if replace then - setfield(new,"replace",tonodes(replace,last)) + replace = tonodes(replace,last) end + -- todo: also set attr + local new = new_disc(pre,post,replace) + setattrlist(new,last) head, current = insert_after(head,current,new) elseif method == "noligature" then -- not that efficient to copy but ok for testing local list = codes[2] if list then for i=1,#list do - new = copy_node(last) + local new = copy_node(last) setchar(new,list[i]) setattr(new,a_noligature,1) head, current = insert_after(head,current,new) end else - new = copy_node(last) + local new = copy_node(last) setchar(new,zwnj) head, current = insert_after(head,current,new) end @@ -258,7 +262,7 @@ function replacements.handler(head) -- todo end else - new = copy_node(last) + local new = copy_node(last) setchar(new,codes) head, current = insert_after(head,current,new) end @@ -311,7 +315,7 @@ function replacements.set(n) else n = lists[n].attribute if not enabled then - nodes.tasks.enableaction("processors","languages.replacements.handler") + enableaction("processors","languages.replacements.handler") if trace_replacements then report_replacement("enabling replacement handler") end diff --git a/tex/context/base/mkiv/lang-txt.lua b/tex/context/base/mkiv/lang-txt.lua index 2938550ee..b550ac2b4 100644 --- a/tex/context/base/mkiv/lang-txt.lua +++ b/tex/context/base/mkiv/lang-txt.lua @@ -38,6 +38,7 @@ if not modules then modules = { } end modules ['lang-txt'] = { -- nb Norwegian Hans Fredrik Nordhaug, ... -- nn Norwegian Hans Fredrik Nordhaug, ... -- nl Dutch Hans Hagen +-- pe Persian Mohammad Hossein Bateni -- pl Polish Grzegorz Sapijaszko -- pt Portuguese Pedro F. M. Mendonça -- ro Romanian Dan Seracu, ... @@ -63,2738 +64,2947 @@ languages.data = languages.data or utilities.storage.allocate { } local data = languages.data data.labels={ - functions={ - Pr={ - labels={ - cz="P", - en="Pr", - sk="P", - }, - }, - arccos={ - labels={ - cz="arccos", - en="arccos", - es="arc\\sixperemspace cos", - hr="arc\\sixperemspace cos", - pl="arc\\sixperemspace cos", - sk="arccos", - }, - }, - arcctg={ - labels={ - cz="arccotg", - en="arccot", - es="arc\\sixperemspace cot", - hr="arc\\sixperemspace ctg", - pl="arc\\sixperemspace ctg", - sk="arccotg", - }, - }, - arcsin={ - labels={ - cz="arcsin", - en="arcsin", - es="arc\\sixperemspace sen", - hr="arc\\sixperemspace sin", - pl="arc\\sixperemspace sin", - sk="arcsin", - }, - }, - arctan={ - labels={ - cz="arctg", - en="arctan", - es="arc\\sixperemspace tan", - hr="arc\\sixperemspace tg", - pl="arc\\sixperemspace tg", - sk="arctg", - }, - }, - arctg={ - labels={ - cz="arctg", - en="arctan", - es="arc\\sixperemspace tan", - hr="arc\\sixperemspace tg", - pl="arc\\sixperemspace tg", - sk="arctg", - }, - }, - arg={ - labels={ - cz="arg", - en="arg", - es="arg", - sk="arg", - }, - }, - cos={ - labels={ - cz="cos", - en="cos", - es="cos", - sk="cos", - }, - }, - cosh={ - labels={ - cz="cosh", - en="cosh", - es="cosh", - sk="cosh", - }, - }, - cot={ - labels={ - cz="cotg", - en="cot", - es="cot", - hr="ctg", - pl="ctg", - sk="cotg", - }, - }, - coth={ - labels={ - cz="cotgh", - en="coth", - es="coth", - sk="cotgh", - }, - }, - csc={ - labels={ - cz="cosec", - en="csc", - es="csc", - sk="cosec", - }, - }, - ctg={ - labels={ - cz="cotg", - en="cot", - es="cot", - hr="ctg", - pl="ctg", - sk="cotg", - }, - }, - diff={ - labels={ - en="d", - }, - }, - deg={ - labels={ - cz="deg", - en="deg", - es="gr", - sk="deg", - }, - }, - det={ - labels={ - cz="det", - en="det", - es="det", - sk="det", - }, - }, - dim={ - labels={ - cz="dim", - en="dim", - es="dim", - sk="dim", - }, - }, - exp={ - labels={ - cz="exp", - en="exp", - es="exp", - sk="exp", - }, - }, - gcd={ - labels={ - cz="NSD", - en="gcd", - es="mcd", - hr="nzd", - nl="ggd", - sk="NSD", + ["btx"]={ + ["In"]={ + ["labels"]={ + ["en"]="In", + ["es"]="En", + ["fr"]="Dans", + ["pe"]="در", }, }, - hom={ - labels={ - cz="Hom", - en="hom", - es="hom", - sk="Hom", + ["Number"]={ + ["labels"]={ + ["de"]="Numer", + ["en"]="Number", + ["fr"]="Numéro", + ["nl"]="Nummer", + ["pe"]="شماره", }, }, - inf={ - labels={ - cz="inf", - en="inf", - es="inf", - sk="inf", + ["Volume"]={ + ["labels"]={ + ["de"]="Band", + ["en"]="Volume", + ["nl"]="Deel", + ["pe"]="جلد", }, }, - injlim={ - labels={ - cz="inj\\sixperemspace lim", - en="inj\\sixperemspace lim", - es="lím\\sixperemspace iny", - sk="inj\\sixperemspace lim", + ["and"]={ + ["labels"]={ + ["de"]="und", + ["en"]="and", + ["es"]="y", + ["fr"]="et", + ["it"]="e", + ["nl"]="en", + ["pe"]="و", + }, + }, + ["edition"]={ + ["labels"]={ + ["de"]="Auflage", + ["en"]="edition", + ["es"]="edición", + ["fr"]="édition", + ["it"]="edizione", + ["nl"]="editie", + ["pe"]="ویرایش", + }, + }, + ["editor"]={ + ["labels"]={ + ["de"]="Herausgeber", + ["en"]="editor", + ["fr"]="éditeur", + ["it"]="a cura di", + ["pe"]="ویراستار", + }, + }, + ["editors"]={ + ["labels"]={ + ["de"]="Herausgeber", + ["en"]="editors", + ["es"]="editores", + ["fr"]="éditeurs", + ["it"]="a cura di", + }, + }, + ["in"]={ + ["labels"]={ + ["en"]="in", + ["es"]="en", + ["fr"]="dans", + ["pe"]="در", + }, + }, + ["mastersthesis"]={ + ["labels"]={ + ["de"]="Masterarbeit", + ["en"]="Master's thesis", + ["es"]="Tesis de maestría", + ["fr"]="Thèse de master (DEA, DESS, master)", + ["it"]="Tesi di laurea", + ["nl"]="Masterproef", + ["pe"]="پایاننامه کارشناسی ارشد", + }, + }, + ["number"]={ + ["labels"]={ + ["de"]="Numer", + ["en"]="number", + ["fr"]="numéro", + ["nl"]="nummer", + ["pe"]="شماره", + }, + }, + ["of"]={ + ["labels"]={ + ["de"]="von", + ["en"]="of", + ["fr"]="de", + ["nl"]="van", + }, + }, + ["others"]={ + ["labels"]={ + ["en"]="et al.", + }, + }, + ["p"]={ + ["labels"]={ + ["de"]="S.", + ["en"]="p.", + ["pe"]="ص", + }, + }, + ["pages"]={ + ["labels"]={ + ["de"]="Seiten", + ["en"]="pages", + ["nl"]="paginas", + ["pe"]="صفحات", + }, + }, + ["patent"]={ + ["labels"]={ + ["de"]="Patent", + ["en"]="Patent", + ["es"]="Patente", + ["fr"]="Brevet", + ["it"]="Brevetto", + ["nl"]="Octrooi", + }, + }, + ["phdthesis"]={ + ["labels"]={ + ["de"]="Dissertation", + ["en"]="PhD thesis", + ["es"]="Tesis doctoral", + ["fr"]="Thèse de doctorat", + ["it"]="Tesi di dottorato", + ["nl"]="Proefschrift", + ["pe"]="رساله دکتری", + }, + }, + ["pp"]={ + ["labels"]={ + ["de"]="S.", + ["en"]="pp.", + ["pe"]="صص", + }, + }, + ["technicalreport"]={ + ["labels"]={ + ["de"]="Technischer Bericht", + ["en"]="Technical report", + ["es"]="Informe técnico", + ["fr"]="Rapport technique", + ["it"]="Relazione tecnica", + ["nl"]="Technisch rapport", + ["pe"]="گزارش فنی", + }, + }, + ["volume"]={ + ["labels"]={ + ["de"]="Band", + ["en"]="volume", + ["nl"]="deel", + ["pe"]="جلد", + }, + }, + ["with"]={ + ["labels"]={ + ["de"]="mit", + ["en"]="with", + ["es"]="con", + ["fr"]="avec", + ["it"]="con", + ["nl"]="met", }, }, - ker={ - labels={ - cz="ker", - en="ker", - es="Ker", - sk="ker", - }, + }, + ["functions"]={ + ["Pr"]={ + ["labels"]={ + ["cz"]="P", + ["en"]="Pr", + ["sk"]="P", + }, + }, + ["acos"]={ + ["labels"]={ + ["cz"]="arccos", + ["en"]="arccos", + ["es"]="arc\\sixperemspace cos", + ["hr"]="arc\\sixperemspace cos", + ["pl"]="arc\\sixperemspace cos", + ["sk"]="arccos", + }, + }, + ["arccos"]={ + ["labels"]={ + ["cz"]="arccos", + ["en"]="arccos", + ["es"]="arc\\sixperemspace cos", + ["hr"]="arc\\sixperemspace cos", + ["pl"]="arc\\sixperemspace cos", + ["sk"]="arccos", + }, + }, + ["arcctg"]={ + ["labels"]={ + ["cz"]="arccotg", + ["en"]="arccot", + ["es"]="arc\\sixperemspace cot", + ["hr"]="arc\\sixperemspace ctg", + ["pl"]="arc\\sixperemspace ctg", + ["sk"]="arccotg", + }, + }, + ["arcsin"]={ + ["labels"]={ + ["cz"]="arcsin", + ["en"]="arcsin", + ["es"]="arc\\sixperemspace sen", + ["hr"]="arc\\sixperemspace sin", + ["pl"]="arc\\sixperemspace sin", + ["sk"]="arcsin", + }, + }, + ["arctan"]={ + ["labels"]={ + ["cz"]="arctg", + ["en"]="arctan", + ["es"]="arc\\sixperemspace tan", + ["hr"]="arc\\sixperemspace tg", + ["pl"]="arc\\sixperemspace tg", + ["sk"]="arctg", + }, + }, + ["arctg"]={ + ["labels"]={ + ["cz"]="arctg", + ["en"]="arctan", + ["es"]="arc\\sixperemspace tan", + ["hr"]="arc\\sixperemspace tg", + ["pl"]="arc\\sixperemspace tg", + ["sk"]="arctg", + }, + }, + ["arg"]={ + ["labels"]={ + ["cz"]="arg", + ["en"]="arg", + ["es"]="arg", + ["sk"]="arg", + }, + }, + ["asin"]={ + ["labels"]={ + ["cz"]="arcsin", + ["en"]="arcsin", + ["es"]="arc\\sixperemspace sen", + ["hr"]="arc\\sixperemspace sin", + ["pl"]="arc\\sixperemspace sin", + ["sk"]="arcsin", + }, + }, + ["atan"]={ + ["labels"]={ + ["cz"]="arctg", + ["en"]="arctan", + ["es"]="arc\\sixperemspace tan", + ["hr"]="arc\\sixperemspace tg", + ["pl"]="arc\\sixperemspace tg", + ["sk"]="arctg", + }, + }, + ["cos"]={ + ["labels"]={ + ["cz"]="cos", + ["en"]="cos", + ["es"]="cos", + ["sk"]="cos", + }, + }, + ["cosh"]={ + ["labels"]={ + ["cz"]="cosh", + ["en"]="cosh", + ["es"]="cosh", + ["sk"]="cosh", + }, + }, + ["cot"]={ + ["labels"]={ + ["cz"]="cotg", + ["en"]="cot", + ["es"]="cot", + ["hr"]="ctg", + ["pl"]="ctg", + ["sk"]="cotg", + }, + }, + ["coth"]={ + ["labels"]={ + ["cz"]="cotgh", + ["en"]="coth", + ["es"]="coth", + ["sk"]="cotgh", + }, + }, + ["csc"]={ + ["labels"]={ + ["cz"]="cosec", + ["en"]="csc", + ["es"]="csc", + ["sk"]="cosec", + }, + }, + ["ctg"]={ + ["labels"]={ + ["cz"]="cotg", + ["en"]="cot", + ["es"]="cot", + ["hr"]="ctg", + ["pl"]="ctg", + ["sk"]="cotg", + }, + }, + ["deg"]={ + ["labels"]={ + ["cz"]="deg", + ["en"]="deg", + ["es"]="gr", + ["sk"]="deg", + }, + }, + ["det"]={ + ["labels"]={ + ["cz"]="det", + ["en"]="det", + ["es"]="det", + ["sk"]="det", + }, + }, + ["diff"]={ + ["labels"]={ + ["en"]="d", + }, + }, + ["dim"]={ + ["labels"]={ + ["cz"]="dim", + ["en"]="dim", + ["es"]="dim", + ["sk"]="dim", + }, + }, + ["exp"]={ + ["labels"]={ + ["cz"]="exp", + ["en"]="exp", + ["es"]="exp", + ["sk"]="exp", + }, }, - lcm={ - labels={ - cz="NSN", - en="lcm", - es="MCM", - hr="nzv", - nl="kgv", - sk="NSN", + ["gcd"]={ + ["labels"]={ + ["cz"]="NSD", + ["en"]="gcd", + ["es"]="mcd", + ["hr"]="nzd", + ["nl"]="ggd", + ["sk"]="NSD", }, }, - lg={ - labels={ - cz="log", - en="lg", - es="log", - sk="log", + ["hom"]={ + ["labels"]={ + ["cz"]="Hom", + ["en"]="hom", + ["es"]="hom", + ["sk"]="Hom", }, }, - lim={ - labels={ - cz="lim", - en="lim", - es="lím", - sk="lim", + ["inf"]={ + ["labels"]={ + ["cz"]="inf", + ["en"]="inf", + ["es"]="inf", + ["sk"]="inf", }, - }, - liminf={ - labels={ - cz="lim\\sixperemspace inf", - en="lim\\sixperemspace inf", - es="lím\\sixperemspace inf", - sk="lim\\sixperemspace inf", + }, + ["injlim"]={ + ["labels"]={ + ["cz"]="inj\\sixperemspace lim", + ["en"]="inj\\sixperemspace lim", + ["es"]="lím\\sixperemspace iny", + ["sk"]="inj\\sixperemspace lim", }, - }, - limsup={ - labels={ - cz="lim\\sixperemspace sup", - en="lim\\sixperemspace sup", - es="lím\\sixperemspace sup", - sk="lim\\sixperemspace sup", + }, + ["ker"]={ + ["labels"]={ + ["cz"]="ker", + ["en"]="ker", + ["es"]="Ker", + ["sk"]="ker", }, - }, - ln={ - labels={ - cz="ln", - en="ln", - es="ln", - sk="ln", + }, + ["lcm"]={ + ["labels"]={ + ["cz"]="NSN", + ["en"]="lcm", + ["es"]="MCM", + ["hr"]="nzv", + ["nl"]="kgv", + ["sk"]="NSN", }, - }, - log={ - labels={ - cz="log", - en="log", - es="log", - sk="log", - }, - }, - max={ - labels={ - cz="max", - en="max", - es="máx", - sk="max", + }, + ["lg"]={ + ["labels"]={ + ["cz"]="log", + ["en"]="lg", + ["es"]="log", + ["sk"]="log", }, }, - median={ - labels={ - cz="\\tilde", - en="median", - es="Mediana", - sk="\\tilde", + ["lim"]={ + ["labels"]={ + ["cz"]="lim", + ["en"]="lim", + ["es"]="lím", + ["sk"]="lim", }, }, - min={ - labels={ - cz="min", - en="min", - es="mín", - sk="min", + ["liminf"]={ + ["labels"]={ + ["cz"]="lim\\sixperemspace inf", + ["en"]="lim\\sixperemspace inf", + ["es"]="lím\\sixperemspace inf", + ["sk"]="lim\\sixperemspace inf", }, }, - mod={ - labels={ - cz="mod", - en="mod", - es="mod", - sk="mod", + ["limsup"]={ + ["labels"]={ + ["cz"]="lim\\sixperemspace sup", + ["en"]="lim\\sixperemspace sup", + ["es"]="lím\\sixperemspace sup", + ["sk"]="lim\\sixperemspace sup", + }, + }, + ["ln"]={ + ["labels"]={ + ["cz"]="ln", + ["en"]="ln", + ["es"]="ln", + ["sk"]="ln", + }, + }, + ["log"]={ + ["labels"]={ + ["cz"]="log", + ["en"]="log", + ["es"]="log", + ["sk"]="log", + }, + }, + ["max"]={ + ["labels"]={ + ["cz"]="max", + ["en"]="max", + ["es"]="máx", + ["sk"]="max", }, }, - projlim={ - labels={ - cz="proj\\sixperemspace lim", - en="proj\\sixperemspace lim", - es="lím\\sixperemspace proy", - sk="proj\\sixperemspace lim", + ["median"]={ + ["labels"]={ + ["cz"]="\\tilde", + ["en"]="median", + ["es"]="Mediana", + ["sk"]="\\tilde", }, }, - sec={ - labels={ - cz="sec", - en="sec", - es="sec", - sk="sec", + ["min"]={ + ["labels"]={ + ["cz"]="min", + ["en"]="min", + ["es"]="mín", + ["sk"]="min", }, }, - sin={ - labels={ - cz="sin", - en="sin", - es="sen", - sk="sin", + ["mod"]={ + ["labels"]={ + ["cz"]="mod", + ["en"]="mod", + ["es"]="mod", + ["sk"]="mod", }, }, - sinh={ - labels={ - cz="sinh", - en="sinh", - es="senh", - sk="sinh", + ["projlim"]={ + ["labels"]={ + ["cz"]="proj\\sixperemspace lim", + ["en"]="proj\\sixperemspace lim", + ["es"]="lím\\sixperemspace proy", + ["sk"]="proj\\sixperemspace lim", }, }, - sup={ - labels={ - cz="sup", - en="sup", - es="sup", - sk="sup", + ["sec"]={ + ["labels"]={ + ["cz"]="sec", + ["en"]="sec", + ["es"]="sec", + ["sk"]="sec", }, }, - tan={ - labels={ - cz="tg", - en="tan", - es="tan", - hr="tg", - pl="tg", - sk="tg", + ["sin"]={ + ["labels"]={ + ["cz"]="sin", + ["en"]="sin", + ["es"]="sen", + ["sk"]="sin", }, }, - tanh={ - labels={ - cz="tgh", - en="tanh", - es="tanh", - sk="tgh", + ["sinh"]={ + ["labels"]={ + ["cz"]="sinh", + ["en"]="sinh", + ["es"]="senh", + ["sk"]="sinh", }, }, - tg={ - labels={ - cz="tg", - en="tan", - es="tan", - hr="tg", - pl="tg", - sk="tg", + ["sup"]={ + ["labels"]={ + ["cz"]="sup", + ["en"]="sup", + ["es"]="sup", + ["sk"]="sup", }, }, - }, - texts={ - ["year"]={ - labels={ - en="year", - nl="jaar", - kr="년", + ["tan"]={ + ["labels"]={ + ["cz"]="tg", + ["en"]="tan", + ["es"]="tan", + ["hr"]="tg", + ["pl"]="tg", + ["sk"]="tg", }, }, - ["month"]={ - labels={ - en="month", - nl="maand", - kr="월", + ["tanh"]={ + ["labels"]={ + ["cz"]="tgh", + ["en"]="tanh", + ["es"]="tanh", + ["sk"]="tgh", }, }, - ["day"]={ - labels={ - en="day", - nl="dag", - kr="일", + ["tg"]={ + ["labels"]={ + ["cz"]="tg", + ["en"]="tan", + ["es"]="tan", + ["hr"]="tg", + ["pl"]="tg", + ["sk"]="tg", }, }, + }, + ["texts"]={ ["and"]={ - labels={ - af="", - ca="", - cs="a", - da="", - de="und", - en="and", - es="y", - fi="", - fr="", - gr="", - hr="i", - hu="és", - it="", - la="", - lt="", - nb="", - nl="en", - nn="", - pl="i", - pt="", - ro="", - ru="", - sk="a", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - appendix={ - hidden=true, - labels={ - af="Bylae ", - ar="ملحق ", - ca="Apèndix ", - cn="附录", - cs="Příloha ", - da="Bilag ", - de="Anhang ", - en="Appendix ", - es="Apéndice ", - fi="", - fr="Annexe ", - gr="Παράρτημα", - hr="Dodatak ", - hu="Melléklet ", - it="", - ja="付録", - kr="부록", - la="", - lt="", - nb="Tillegg ", - nl="", - nn="Tillegg ", - pl="Dodatek ", - pt="", - ro="", - ru="", - sk="Príloha ", - sl="Dodatek ", - sv="", - tk="Goşmaça", - tr="", - ua="", - vi="", - }, - }, - april={ - labels={ - af="april", - ar="أبريل", + ["labels"]={ + ["af"]="", + ["ca"]="", + ["cs"]="a", + ["da"]="", + ["de"]="und", + ["en"]="and", + ["es"]="y", + ["fi"]="", + ["fr"]="", + ["gr"]="", + ["hr"]="i", + ["hu"]="és", + ["it"]="", + ["la"]="", + ["lt"]="", + ["nb"]="", + ["nl"]="en", + ["nn"]="", + ["pe"]="و", + ["pl"]="i", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="a", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["appendix"]={ + ["hidden"]=true, + ["labels"]={ + ["af"]="Bylae ", + ["ar"]="ملحق ", + ["ca"]="Apèndix ", + ["cn"]="附录", + ["cs"]="Příloha ", + ["da"]="Bilag ", + ["de"]="Anhang ", + ["en"]="Appendix ", + ["es"]="Apéndice ", + ["fi"]="", + ["fr"]="Annexe ", + ["gr"]="Παράρτημα", + ["hr"]="Dodatak ", + ["hu"]="Melléklet ", + ["it"]="", + ["ja"]="付録", + ["kr"]="부록", + ["la"]="", + ["lt"]="", + ["nb"]="Tillegg ", + ["nl"]="", + ["nn"]="Tillegg ", + ["pe"]="پیوست ", + ["pl"]="Dodatek ", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="Príloha ", + ["sl"]="Dodatek ", + ["sv"]="", + ["tk"]="Goşmaça", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["april"]={ + ["labels"]={ + ["af"]="april", + ["ar"]="أبريل", ["ar-dz"]="أفريل", ["ar-sy"]="نيسان", - ca="abril", - cn="四月", - cs="dubna", - da="april", - de="April", - en="April", - es="abril", - fi="huhtikuu", - fr="avril", - gr="Απρίλιος", - hr="travnja", - hu="április", - it="aprile", - ja="4", - kr="4", - la="Aprilis", - lt="balandžio", - nb="april", - nl="april", - nn="april", - pl="kwietnia", - pt="abril", - ro="aprilie", - ru="апреля", - sk="apríla", - sl="april", - sv="april", - tk="aprel", - tr="nisan", - ua="квітня", - vi="tháng tư", + ["ca"]="abril", + ["cn"]="四月", + ["cs"]="dubna", + ["da"]="april", + ["de"]="April", + ["en"]="April", + ["es"]="abril", + ["fi"]="huhtikuu", + ["fr"]="avril", + ["gr"]="Απρίλιος", + ["hr"]="travnja", + ["hu"]="április", + ["it"]="aprile", + ["ja"]="4", + ["kr"]="4", + ["la"]="Aprilis", + ["lt"]="balandžio", + ["nb"]="april", + ["nl"]="april", + ["nn"]="april", + ["pe"]="آوریل", + ["pl"]="kwietnia", + ["pt"]="abril", + ["ro"]="aprilie", + ["ru"]="апреля", + ["sk"]="apríla", + ["sl"]="april", + ["sv"]="april", + ["tk"]="aprel", + ["tr"]="nisan", + ["ua"]="квітня", + ["vi"]="tháng tư", + }, + }, + ["april:jalali"]={ + ["labels"]={ + ["en"]="Tir", + ["fa"]="تیر", }, }, ["april:mnem"]={ - labels={ - af="", - ca="", - cs="dub.", - da="", - de="", - en="apr", - es="abr.", - fi="", - fr="", - gr="", - hr="tra", - hu="ápr.", - it="", - la="", - lt="apr", - nb="april", - nl="", - nn="april", - pl="kwi.", - pt="", - ro="", - ru="", - sk="apr.", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - atpage={ - labels={ - af="", - ar="في صفحة ", - ca="", - cs="na straně ", - da="på side ", - de="auf Seite ", - en="at page ", - es="en la página ", - fi="", - fr="à la page ", - gr="", - hr="na stranici ", - hu="oldal ", - it="a pagina ", - la="", - lt="puslapyje ", - nb="på side ", - nl="op pagina ", - nn="på side ", - pl="na stronie ", - pt="", - ro="", - ru="на странице ", - sk="na strane ", - sl="na strani ", - sv="på sida ", - tk="", - tr="", - ua="на сторінці ", - vi="", - }, - }, - august={ - labels={ - af="augustus", - ar="أغسطس", + ["labels"]={ + ["af"]="", + ["ca"]="", + ["cs"]="dub.", + ["da"]="", + ["de"]="", + ["en"]="apr", + ["es"]="abr.", + ["fi"]="", + ["fr"]="", + ["gr"]="", + ["hr"]="tra", + ["hu"]="ápr.", + ["it"]="", + ["la"]="", + ["lt"]="apr", + ["nb"]="april", + ["nl"]="", + ["nn"]="april", + ["pl"]="kwi.", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="apr.", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["atpage"]={ + ["labels"]={ + ["af"]="", + ["ar"]="في صفحة ", + ["ca"]="", + ["cs"]="na straně ", + ["da"]="på side ", + ["de"]="auf Seite ", + ["en"]="at page ", + ["es"]="en la página ", + ["fi"]="", + ["fr"]="à la page ", + ["gr"]="", + ["hr"]="na stranici ", + ["hu"]="oldal ", + ["it"]="a pagina ", + ["la"]="", + ["lt"]="puslapyje ", + ["nb"]="på side ", + ["nl"]="op pagina ", + ["nn"]="på side ", + ["pe"]="در صفحه ", + ["pl"]="na stronie ", + ["pt"]="", + ["ro"]="", + ["ru"]="на странице ", + ["sk"]="na strane ", + ["sl"]="na strani ", + ["sv"]="på sida ", + ["tk"]="", + ["tr"]="", + ["ua"]="на сторінці ", + ["vi"]="", + }, + }, + ["august"]={ + ["labels"]={ + ["af"]="augustus", + ["ar"]="أغسطس", ["ar-dz"]="أوت", ["ar-ma"]="غشت", ["ar-sy"]="آب", - ca="agost", - cn="八月", - cs="srpna", - da="august", - de="August", - en="August", - es="agosto", - fi="elokuu", - fr="août", - gr="Αύγουστος", - hr="kolovoza", - hu="augusztus", - it="agosto", - ja="8", - kr="8", - la="Augustus", - lt="rugpjūčio", - nb="august", - nl="augustus", - nn="august", - pl="sierpnia", - pt="agosto", - ro="august", - ru="августа", - sk="augusta", - sl="avgust", - sv="augusti", - tk="awgust", - tr="ağustos", - ua="серпня", - vi="tháng tám", + ["ca"]="agost", + ["cn"]="八月", + ["cs"]="srpna", + ["da"]="august", + ["de"]="August", + ["en"]="August", + ["es"]="agosto", + ["fi"]="elokuu", + ["fr"]="août", + ["gr"]="Αύγουστος", + ["hr"]="kolovoza", + ["hu"]="augusztus", + ["it"]="agosto", + ["ja"]="8", + ["kr"]="8", + ["la"]="Augustus", + ["lt"]="rugpjūčio", + ["nb"]="august", + ["nl"]="augustus", + ["nn"]="august", + ["pe"]="اوت", + ["pl"]="sierpnia", + ["pt"]="agosto", + ["ro"]="august", + ["ru"]="августа", + ["sk"]="augusta", + ["sl"]="avgust", + ["sv"]="augusti", + ["tk"]="awgust", + ["tr"]="ağustos", + ["ua"]="серпня", + ["vi"]="tháng tám", + }, + }, + ["august:jalali"]={ + ["labels"]={ + ["en"]="Aban", + ["fa"]="آبان", }, }, ["august:mnem"]={ - labels={ - af="", - ca="", - cs="srp.", - da="", - de="", - en="aug", - es="ago.", - fi="", - fr="", - gr="", - hr="kol", - hu="aug.", - it="", - la="", - lt="aug", - nb="aug.", - nl="", - nn="aug.", - pl="sier.", - pt="", - ro="", - ru="", - sk="aug.", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - chapter={ - hidden=true, - labels={ - af="Hoofstuk ", - ar="باب ", - ca="Capítol ", - cn={"第","章"}, - cs="Kapitola ", - da="", - de="Kapitel ", - en="Chapter ", - es="Capítulo ", - fi="", - fr="Chapitre ", - gr="Κεφάλαιο", - hr="Poglavlje ", - hu={""," fejezet"}, - it="", - ja={"第","章"}, - kr={"제","장"}, - la="", - lt="", - nb="", - nl="", - nn="", - pl="Rozdział ", - pt="", - ro="", - ru="", - sk="Kapitola ", - sl="Poglavje ", - sv="", - tk="Bap", - tr="", - ua="", - vi="Chương ", - }, - }, - continued={ - labels={ - af="", - ca="", - cs=" (pokračování)", - da="", - de="", - en=" (continued)", - es=" (continúa)", - fi="", - fr="", - gr="", - hr=" (nastavak)", - hu=" (folytatás)", - it="", - la="", - lt="", - nb="", - nl=" (vervolgd)", - nn="", - pl="", - pt="", - ro="", - ru="", - sk=" (pokračovanie)", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - december={ - labels={ - af="desember", - ar="ديسمبر", + ["labels"]={ + ["af"]="", + ["ca"]="", + ["cs"]="srp.", + ["da"]="", + ["de"]="", + ["en"]="aug", + ["es"]="ago.", + ["fi"]="", + ["fr"]="", + ["gr"]="", + ["hr"]="kol", + ["hu"]="aug.", + ["it"]="", + ["la"]="", + ["lt"]="aug", + ["nb"]="aug.", + ["nl"]="", + ["nn"]="aug.", + ["pl"]="sier.", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="aug.", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["chapter"]={ + ["hidden"]=true, + ["labels"]={ + ["af"]="Hoofstuk ", + ["ar"]="باب ", + ["ca"]="Capítol ", + ["cn"]={ "第", "章" }, + ["cs"]="Kapitola ", + ["da"]="", + ["de"]="Kapitel ", + ["en"]="Chapter ", + ["es"]="Capítulo ", + ["fi"]="", + ["fr"]="Chapitre ", + ["gr"]="Κεφάλαιο", + ["hr"]="Poglavlje ", + ["hu"]={ "", " fejezet" }, + ["it"]="", + ["ja"]={ "第", "章" }, + ["kr"]={ "제", "장" }, + ["la"]="", + ["lt"]="", + ["nb"]="", + ["nl"]="", + ["nn"]="", + ["pe"]="فصل ", + ["pl"]="Rozdział ", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="Kapitola ", + ["sl"]="Poglavje ", + ["sv"]="", + ["tk"]="Bap", + ["tr"]="", + ["ua"]="", + ["vi"]="Chương ", + }, + }, + ["continued"]={ + ["labels"]={ + ["af"]="", + ["ca"]="", + ["cs"]=" (pokračování)", + ["da"]="", + ["de"]="", + ["en"]=" (continued)", + ["es"]=" (continúa)", + ["fi"]="", + ["fr"]="", + ["gr"]="", + ["hr"]=" (nastavak)", + ["hu"]=" (folytatás)", + ["it"]="", + ["la"]="", + ["lt"]="", + ["nb"]="", + ["nl"]=" (vervolgd)", + ["nn"]="", + ["pe"]="(ادامه دارد)", + ["pl"]="", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]=" (pokračovanie)", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["day"]={ + ["labels"]={ + ["en"]="day", + ["kr"]="일", + ["nl"]="dag", + ["pe"]="روز", + }, + }, + ["december"]={ + ["labels"]={ + ["af"]="desember", + ["ar"]="ديسمبر", ["ar-ma"]="دجنبر", ["ar-sy"]="كانون الأول", - ca="desembre", - cn="十二月", - cs="prosince", - da="december", - de="Dezember", - en="December", - es="diciembre", - fi="joulukuu", - fr="décembre", - gr="Δεκέμβριος", - hr="prosinca", - hu="december", - it="dicembre", - ja="12", - kr="12", - la="December", - lt="gruodžio", - nb="desember", - nl="december", - nn="desember", - pl="grudnia", - pt="dezembro", - ro="decembrie", - ru="декабря", - sk="decembra", - sl="december", - sv="december", - tk="dekabr", - tr="aralık", - ua="грудня", - vi="tháng mười hai", + ["ca"]="desembre", + ["cn"]="十二月", + ["cs"]="prosince", + ["da"]="december", + ["de"]="Dezember", + ["en"]="December", + ["es"]="diciembre", + ["fi"]="joulukuu", + ["fr"]="décembre", + ["gr"]="Δεκέμβριος", + ["hr"]="prosinca", + ["hu"]="december", + ["it"]="dicembre", + ["ja"]="12", + ["kr"]="12", + ["la"]="December", + ["lt"]="gruodžio", + ["nb"]="desember", + ["nl"]="december", + ["nn"]="desember", + ["pe"]="دسامبر", + ["pl"]="grudnia", + ["pt"]="dezembro", + ["ro"]="decembrie", + ["ru"]="декабря", + ["sk"]="decembra", + ["sl"]="december", + ["sv"]="december", + ["tk"]="dekabr", + ["tr"]="aralık", + ["ua"]="грудня", + ["vi"]="tháng mười hai", + }, + }, + ["december:jalali"]={ + ["labels"]={ + ["en"]="Esfand", + ["fa"]="اسفند", }, }, ["december:mnem"]={ - labels={ - af="", - ca="", - cs="pros.", - da="", - de="", - en="dec", - es="dic.", - fi="", - fr="", - gr="", - hr="pro", - hu="dec.", - it="", - la="", - lt="dec", - nb="des.", - nl="", - nn="des.", - pl="gru.", - pt="", - ro="", - ru="", - sk="dec.", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - february={ - labels={ - af="februarie", - ar="فبراير", + ["labels"]={ + ["af"]="", + ["ca"]="", + ["cs"]="pros.", + ["da"]="", + ["de"]="", + ["en"]="dec", + ["es"]="dic.", + ["fi"]="", + ["fr"]="", + ["gr"]="", + ["hr"]="pro", + ["hu"]="dec.", + ["it"]="", + ["la"]="", + ["lt"]="dec", + ["nb"]="des.", + ["nl"]="", + ["nn"]="des.", + ["pl"]="gru.", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="dec.", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["february"]={ + ["labels"]={ + ["af"]="februarie", + ["ar"]="فبراير", ["ar-dz"]="فيفري", ["ar-sy"]="شباط", - ca="febrer", - cn="二月", - cs="února", - da="februar", - de="Februar", - en="February", - es="febrero", - fi="helmikuu", - fr="février", - gr="Φεβρουάριος", - hr="veljače", - hu="február", - it="febbraio", - ja="2", - kr="2", - la="Februarius", - lt="vasario", - nb="februar", - nl="februari", - nn="februar", - pl="lutego", - pt="fevereiro", - ro="februarie", - ru="февраля", - sk="februára", - sl="februar", - sv="februari", - tk="fewral", - tr="Şubat", - ua="лютого", - vi="tháng hai", + ["ca"]="febrer", + ["cn"]="二月", + ["cs"]="února", + ["da"]="februar", + ["de"]="Februar", + ["en"]="February", + ["es"]="febrero", + ["fi"]="helmikuu", + ["fr"]="février", + ["gr"]="Φεβρουάριος", + ["hr"]="veljače", + ["hu"]="február", + ["it"]="febbraio", + ["ja"]="2", + ["kr"]="2", + ["la"]="Februarius", + ["lt"]="vasario", + ["nb"]="februar", + ["nl"]="februari", + ["nn"]="februar", + ["pe"]="فوریه", + ["pl"]="lutego", + ["pt"]="fevereiro", + ["ro"]="februarie", + ["ru"]="февраля", + ["sk"]="februára", + ["sl"]="februar", + ["sv"]="februari", + ["tk"]="fewral", + ["tr"]="Şubat", + ["ua"]="лютого", + ["vi"]="tháng hai", + }, + }, + ["february:jalali"]={ + ["labels"]={ + ["en"]="Ordibehesht", + ["fa"]="اردیبهشت", }, }, ["february:mnem"]={ - labels={ - af="", - ca="", - cs="ún.", - da="", - de="", - en="feb", - es="feb.", - fi="", - fr="", - gr="", - hr="velj", - hu="feb.", - it="", - la="", - lt="feb", - nb="feb.", - nl="", - nn="feb.", - pl="lut.", - pt="", - ro="", - ru="", - sk="feb.", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - figure={ - labels={ - af="Figuur ", - ar="شكل ", - ca="Figura ", - cn="图", - cs="Obrázek ", - da="Figur ", - de="Abbildung ", - en="Figure ", - es="Figura ", - fi="Kuva ", - fr="Figure ", - gr="Σχήμα", - hr="Slika ", - hu={""," ábra"}, - it="Fig. ", - ja="図", - kr="그림 ", - la="Imago ", - lt={""," pav."}, - nb="Figur ", - nl="Figuur ", - nn="Figur ", - pl="Ilustracja ", - pt="Figura ", - ro="Figura ", - ru="Рисунок ", - sk="Obrázok ", - sl="Slika ", - sv="Figur ", - tk="Surat", - tr="Şekil ", - ua="Малюнок ", - vi="Hình ", - }, - }, - friday={ - labels={ - af="vrydag", - ar="الجمعة", - ca="divendres", - cn="星期五", - cs="pátek", - da="fredag", - de="Freitag", - en="Friday", - es="viernes", - fi="perjantai", - fr="vendredi", - gr="Παρασκευή", - hr="petak", - hu="péntek", - it="venerdì", - ja="金曜日", - kr="금요일", - la="Dies Veneris", - lt="penktadienis", - nb="fredag", - nl="vrijdag", - nn="fredag", - pl="piątek", - pt="sexta-feira", - ro="vineri", - ru="пятница", - sk="piatok", - sl="petek", - sv="fredag", - tk="bäşinji gün", - tr="cuma", - ua="п'ятниця", - vi="thứ sáu", - }, - }, - graphic={ - labels={ - af="Grafiek ", - ar="رسم ", - ca="Gràfica ", - cn="插图", - cs="Graf ", - da="Grafik ", - de="Graphik ", - en="Graphic ", - es="Gráfico ", - fi="Grafiikka ", - fr="Illustration ", - gr="Γραφικό", - hr="Slika ", - hu={""," kép"}, - it="Grafico ", - ja="イラスト", - la="Typus ", - lt="Graphic ", - nb="Bilde ", - nl="Grafiek ", - nn="Bilete ", - pl="Grafika ", - pt="Gráfico ", - ro="Graficul ", - ru="График ", - sk="Graf ", - sl="Slika ", - sv="Grafik ", - tk="Grafik", - tr="Grafik", - ua="График ", - vi="Đồ thị", - }, - }, - precedingpage={ - labels={ - en="on a preceding page", - nl="op een voorgaande bladzijde", - }, - }, - followingpage={ - labels={ - en="on a following page", - nl="op een volgende bladzijde", - }, - }, - hencefore={ - labels={ - af="", - ar="كما وضحنا سابقا", - ca="", - cs="viz výše", - da="se foroven", - de="siehe oben", - en="as we show above", - es="como se muestra arriba", - fi="", - fr="ci-dessus", - gr="", - hr="vidi gore", - hu="lásd feljebb", - kr="그러므로", - it="come mostrato sopra", - la="", - lt="kaip parodyta aukščiau", - nb="som vist over", - nl="hierboven", - nn="som vist over", - pl="jak pokazano wyżej", - pt="", - ro="", - ru="см. выше", - sk="pozri hore", - sl="glej zgoraj", - sv="se ovan", - tk="", - tr="", - ua="як показано вище", - vi="", - }, - }, - hereafter={ - labels={ - af="", - ar="كما نوضح لاحقا", - ca="", - cs="viz níže", - da="se forneden", - de="siehe unten", - en="as we show below", - es="como se muestra abajo", - fi="", - fr="ci-dessous", - gr="", - hr="vidi ispod", - hu="lásd lejjebb", - it="come mostrato sotto", - kr="이후로", - la="", - lt="kaip parodyta žemiau", - nb="som vist under", - nl="hieronder", - nn="som vist under", - pl="jak pokazano niżej", - pt="", - ro="", - ru="см. ниже", - sk="pozri ďalej", - sl="glej spodaj", - sv="se nedan", - tk="", - tr="", - ua="як показано нижче", - vi="", - }, - }, - intermezzo={ - labels={ - af="Intermezzo ", - ar="فسحة ", - ca="Intermedi ", - cn="퉣", - cs="Intermezzo ", - da="Intermezzo ", - de="Intermezzo ", - en="Intermezzo ", - es="Intermedio ", - fi="Intermezzo ", - fr="Intermède ", - gr="Παύση", - hr="Intermeco ", - hu={""," intermezzo"}, - it="Intermezzo ", - ja="間奏曲", - kr="간주곡", - la="Intermissum ", - lt="Intermezzo ", - nb="Intermesso ", - nl="Intermezzo ", - nn="Intermesso ", - pl="Intermezzo ", - pt="Intermédio ", - ro="Intermezzo ", - ru="Вставка ", - sk="Intermezzo ", - sl="Intermezzo ", - sv="Intermezzo ", - tk="Arakesme", - tr="", - ua="Вставка ", - vi="intermezzo", - }, - }, - january={ - labels={ - af="januarie", - ar="يناير", + ["labels"]={ + ["af"]="", + ["ca"]="", + ["cs"]="ún.", + ["da"]="", + ["de"]="", + ["en"]="feb", + ["es"]="feb.", + ["fi"]="", + ["fr"]="", + ["gr"]="", + ["hr"]="velj", + ["hu"]="feb.", + ["it"]="", + ["la"]="", + ["lt"]="feb", + ["nb"]="feb.", + ["nl"]="", + ["nn"]="feb.", + ["pl"]="lut.", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="feb.", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["figure"]={ + ["labels"]={ + ["af"]="Figuur ", + ["ar"]="شكل ", + ["ca"]="Figura ", + ["cn"]="图", + ["cs"]="Obrázek ", + ["da"]="Figur ", + ["de"]="Abbildung ", + ["en"]="Figure ", + ["es"]="Figura ", + ["fi"]="Kuva ", + ["fr"]="Figure ", + ["gr"]="Σχήμα", + ["hr"]="Slika ", + ["hu"]={ "", " ábra" }, + ["it"]="Fig. ", + ["ja"]="図", + ["kr"]="그림 ", + ["la"]="Imago ", + ["lt"]={ "", " pav." }, + ["nb"]="Figur ", + ["nl"]="Figuur ", + ["nn"]="Figur ", + ["pe"]="شکل ", + ["pl"]="Ilustracja ", + ["pt"]="Figura ", + ["ro"]="Figura ", + ["ru"]="Рисунок ", + ["sk"]="Obrázok ", + ["sl"]="Slika ", + ["sv"]="Figur ", + ["tk"]="Surat", + ["tr"]="Şekil ", + ["ua"]="Малюнок ", + ["vi"]="Hình ", + }, + }, + ["followingpage"]={ + ["labels"]={ + ["en"]="on a following page", + ["nl"]="op een volgende bladzijde", + ["pe"]="در صفحات آینده", + }, + }, + ["friday"]={ + ["labels"]={ + ["af"]="vrydag", + ["ar"]="الجمعة", + ["ca"]="divendres", + ["cn"]="星期五", + ["cs"]="pátek", + ["da"]="fredag", + ["de"]="Freitag", + ["en"]="Friday", + ["es"]="viernes", + ["fi"]="perjantai", + ["fr"]="vendredi", + ["gr"]="Παρασκευή", + ["hr"]="petak", + ["hu"]="péntek", + ["it"]="venerdì", + ["ja"]="金曜日", + ["kr"]="금요일", + ["la"]="Dies Veneris", + ["lt"]="penktadienis", + ["nb"]="fredag", + ["nl"]="vrijdag", + ["nn"]="fredag", + ["pe"]="جمعه", + ["pl"]="piątek", + ["pt"]="sexta-feira", + ["ro"]="vineri", + ["ru"]="пятница", + ["sk"]="piatok", + ["sl"]="petek", + ["sv"]="fredag", + ["tk"]="bäşinji gün", + ["tr"]="cuma", + ["ua"]="п'ятниця", + ["vi"]="thứ sáu", + }, + }, + ["graphic"]={ + ["labels"]={ + ["af"]="Grafiek ", + ["ar"]="رسم ", + ["ca"]="Gràfica ", + ["cn"]="插图", + ["cs"]="Graf ", + ["da"]="Grafik ", + ["de"]="Graphik ", + ["en"]="Graphic ", + ["es"]="Gráfico ", + ["fi"]="Grafiikka ", + ["fr"]="Illustration ", + ["gr"]="Γραφικό", + ["hr"]="Slika ", + ["hu"]={ "", " kép" }, + ["it"]="Grafico ", + ["ja"]="イラスト", + ["la"]="Typus ", + ["lt"]="Graphic ", + ["nb"]="Bilde ", + ["nl"]="Grafiek ", + ["nn"]="Bilete ", + ["pe"]="طرح ", + ["pl"]="Grafika ", + ["pt"]="Gráfico ", + ["ro"]="Graficul ", + ["ru"]="График ", + ["sk"]="Graf ", + ["sl"]="Slika ", + ["sv"]="Grafik ", + ["tk"]="Grafik", + ["tr"]="Grafik", + ["ua"]="График ", + ["vi"]="Đồ thị", + }, + }, + ["hencefore"]={ + ["labels"]={ + ["af"]="", + ["ar"]="كما وضحنا سابقا", + ["ca"]="", + ["cs"]="viz výše", + ["da"]="se foroven", + ["de"]="siehe oben", + ["en"]="as we show above", + ["es"]="como se muestra arriba", + ["fi"]="", + ["fr"]="ci-dessus", + ["gr"]="", + ["hr"]="vidi gore", + ["hu"]="lásd feljebb", + ["it"]="come mostrato sopra", + ["kr"]="그러므로", + ["la"]="", + ["lt"]="kaip parodyta aukščiau", + ["nb"]="som vist over", + ["nl"]="hierboven", + ["nn"]="som vist over", + ["pe"]="چنانکه شرح دادیم", + ["pl"]="jak pokazano wyżej", + ["pt"]="", + ["ro"]="", + ["ru"]="см. выше", + ["sk"]="pozri hore", + ["sl"]="glej zgoraj", + ["sv"]="se ovan", + ["tk"]="", + ["tr"]="", + ["ua"]="як показано вище", + ["vi"]="", + }, + }, + ["hereafter"]={ + ["labels"]={ + ["af"]="", + ["ar"]="كما نوضح لاحقا", + ["ca"]="", + ["cs"]="viz níže", + ["da"]="se forneden", + ["de"]="siehe unten", + ["en"]="as we show below", + ["es"]="como se muestra abajo", + ["fi"]="", + ["fr"]="ci-dessous", + ["gr"]="", + ["hr"]="vidi ispod", + ["hu"]="lásd lejjebb", + ["it"]="come mostrato sotto", + ["kr"]="이후로", + ["la"]="", + ["lt"]="kaip parodyta žemiau", + ["nb"]="som vist under", + ["nl"]="hieronder", + ["nn"]="som vist under", + ["pe"]="چنانکه شرح خواهیم داد", + ["pl"]="jak pokazano niżej", + ["pt"]="", + ["ro"]="", + ["ru"]="см. ниже", + ["sk"]="pozri ďalej", + ["sl"]="glej spodaj", + ["sv"]="se nedan", + ["tk"]="", + ["tr"]="", + ["ua"]="як показано нижче", + ["vi"]="", + }, + }, + ["intermezzo"]={ + ["labels"]={ + ["af"]="Intermezzo ", + ["ar"]="فسحة ", + ["ca"]="Intermedi ", + ["cn"]="퉣", + ["cs"]="Intermezzo ", + ["da"]="Intermezzo ", + ["de"]="Intermezzo ", + ["en"]="Intermezzo ", + ["es"]="Intermedio ", + ["fi"]="Intermezzo ", + ["fr"]="Intermède ", + ["gr"]="Παύση", + ["hr"]="Intermeco ", + ["hu"]={ "", " intermezzo" }, + ["it"]="Intermezzo ", + ["ja"]="間奏曲", + ["kr"]="간주곡", + ["la"]="Intermissum ", + ["lt"]="Intermezzo ", + ["nb"]="Intermesso ", + ["nl"]="Intermezzo ", + ["nn"]="Intermesso ", + ["pl"]="Intermezzo ", + ["pt"]="Intermédio ", + ["ro"]="Intermezzo ", + ["ru"]="Вставка ", + ["sk"]="Intermezzo ", + ["sl"]="Intermezzo ", + ["sv"]="Intermezzo ", + ["tk"]="Arakesme", + ["tr"]="", + ["ua"]="Вставка ", + ["vi"]="intermezzo", + }, + }, + ["january"]={ + ["labels"]={ + ["af"]="januarie", + ["ar"]="يناير", ["ar-dz"]="جانفي", ["ar-sy"]="كانون الثاني", - ca="gener", - cn="一月", - cs="ledna", - da="januar", - de="Januar", - en="January", - es="enero", - fi="tammikuu", - fr="janvier", - gr="Ιανουάριος", - hr="siječnja", - hu="január", - it="gennaio", - ja="1", - kr="1", - la="Ianuarius", - lt="sausio", - nb="januar", - nl="januari", - nn="januar", - pl="stycznia", - pt="janeiro", - ro="ianuarie", - ru="января", - sk="januára", - sl="januar", - sv="januari", - tk="ýanwar", - tr="ocak", - ua="січня", - vi="tháng giêng", + ["ca"]="gener", + ["cn"]="一月", + ["cs"]="ledna", + ["da"]="januar", + ["de"]="Januar", + ["en"]="January", + ["es"]="enero", + ["fi"]="tammikuu", + ["fr"]="janvier", + ["gr"]="Ιανουάριος", + ["hr"]="siječnja", + ["hu"]="január", + ["it"]="gennaio", + ["ja"]="1", + ["kr"]="1", + ["la"]="Ianuarius", + ["lt"]="sausio", + ["nb"]="januar", + ["nl"]="januari", + ["nn"]="januar", + ["pe"]="ژانویه", + ["pl"]="stycznia", + ["pt"]="janeiro", + ["ro"]="ianuarie", + ["ru"]="января", + ["sk"]="januára", + ["sl"]="januar", + ["sv"]="januari", + ["tk"]="ýanwar", + ["tr"]="ocak", + ["ua"]="січня", + ["vi"]="tháng giêng", + }, + }, + ["january:jalali"]={ + ["labels"]={ + ["en"]="Farvardin", + ["fa"]="فروردین", }, }, ["january:mnem"]={ - labels={ - af="", - ca="", - cs="led.", - da="", - de="", - en="jan", - es="ene.", - fi="", - fr="", - gr="", - hr="sij", - hu="jan.", - it="", - la="", - lt="jan", - nb="jan.", - nl="", - nn="jan.", - pl="sty.", - pt="", - ro="", - ru="", - sk="jan.", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - july={ - labels={ - af="julie", - ar="يوليو", + ["labels"]={ + ["af"]="", + ["ca"]="", + ["cs"]="led.", + ["da"]="", + ["de"]="", + ["en"]="jan", + ["es"]="ene.", + ["fi"]="", + ["fr"]="", + ["gr"]="", + ["hr"]="sij", + ["hu"]="jan.", + ["it"]="", + ["la"]="", + ["lt"]="jan", + ["nb"]="jan.", + ["nl"]="", + ["nn"]="jan.", + ["pl"]="sty.", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="jan.", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["july"]={ + ["labels"]={ + ["af"]="julie", + ["ar"]="يوليو", ["ar-dz"]="جويلة", ["ar-ma"]="يوليوز", ["ar-sy"]="تموز", - ca="juliol", - cn="七月", - cs="července", - da="juli", - de="Juli", - en="July", - es="julio", - fi="heinäkuu", - fr="juillet", - gr="Ιούλιος", - hr="srpnja", - hu="július", - it="luglio", - ja="7", - kr="7", - la="Iulius", - lt="liepos", - nb="juli", - nl="juli", - nn="juli", - pl="lipca", - pt="julho", - ro="iulie", - ru="июля", - sk="júla", - sl="julij", - sv="juli", - tk="iýul", - tr="temmuz", - ua="липня", - vi="tháng bảy", + ["ca"]="juliol", + ["cn"]="七月", + ["cs"]="července", + ["da"]="juli", + ["de"]="Juli", + ["en"]="July", + ["es"]="julio", + ["fi"]="heinäkuu", + ["fr"]="juillet", + ["gr"]="Ιούλιος", + ["hr"]="srpnja", + ["hu"]="július", + ["it"]="luglio", + ["ja"]="7", + ["kr"]="7", + ["la"]="Iulius", + ["lt"]="liepos", + ["nb"]="juli", + ["nl"]="juli", + ["nn"]="juli", + ["pe"]="ژوئیه", + ["pl"]="lipca", + ["pt"]="julho", + ["ro"]="iulie", + ["ru"]="июля", + ["sk"]="júla", + ["sl"]="julij", + ["sv"]="juli", + ["tk"]="iýul", + ["tr"]="temmuz", + ["ua"]="липня", + ["vi"]="tháng bảy", + }, + }, + ["july:jalali"]={ + ["labels"]={ + ["en"]="Mehr", + ["fa"]="مهر", }, }, ["july:mnem"]={ - labels={ - af="", - ca="", - cs="čce", - da="", - de="", - en="jul", - es="jul.", - fi="", - fr="", - gr="", - hr="srp", - hu="júl.", - it="", - la="", - lt="jul", - nb="juli", - nl="", - nn="juli", - pl="lip.", - pt="", - ro="", - ru="", - sk="júla", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - june={ - labels={ - af="junie", - ar="يونيو", + ["labels"]={ + ["af"]="", + ["ca"]="", + ["cs"]="čce", + ["da"]="", + ["de"]="", + ["en"]="jul", + ["es"]="jul.", + ["fi"]="", + ["fr"]="", + ["gr"]="", + ["hr"]="srp", + ["hu"]="júl.", + ["it"]="", + ["la"]="", + ["lt"]="jul", + ["nb"]="juli", + ["nl"]="", + ["nn"]="juli", + ["pl"]="lip.", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="júla", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["june"]={ + ["labels"]={ + ["af"]="junie", + ["ar"]="يونيو", ["ar-dz"]="جوان", ["ar-sy"]="حزيران", - ca="juny", - cn="六月", - cs="června", - da="juni", - de="Juni", - en="June", - es="junio", - fi="kesäkuu", - fr="juin", - gr="Ιούνιος", - hr="lipnja", - hu="június", - it="giugno", - ja="6", - kr="6", - la="Iunius", - lt="birželio", - nb="juni", - nl="juni", - nn="juni", - pl="czerwca", - pt="junho", - ro="iunie", - ru="июня", - sk="júna", - sl="junij", - sv="juni", - tk="iýun", - tr="haziran", - ua="червня", - vi="tháng sáu", + ["ca"]="juny", + ["cn"]="六月", + ["cs"]="června", + ["da"]="juni", + ["de"]="Juni", + ["en"]="June", + ["es"]="junio", + ["fi"]="kesäkuu", + ["fr"]="juin", + ["gr"]="Ιούνιος", + ["hr"]="lipnja", + ["hu"]="június", + ["it"]="giugno", + ["ja"]="6", + ["kr"]="6", + ["la"]="Iunius", + ["lt"]="birželio", + ["nb"]="juni", + ["nl"]="juni", + ["nn"]="juni", + ["pe"]="ژوئن", + ["pl"]="czerwca", + ["pt"]="junho", + ["ro"]="iunie", + ["ru"]="июня", + ["sk"]="júna", + ["sl"]="junij", + ["sv"]="juni", + ["tk"]="iýun", + ["tr"]="haziran", + ["ua"]="червня", + ["vi"]="tháng sáu", + }, + }, + ["june:jalali"]={ + ["labels"]={ + ["en"]="Shahrivar", + ["fa"]="شهریور", }, }, ["june:mnem"]={ - labels={ - af="", - ca="", - cs="čer.", - da="", - de="", - en="jun", - es="jun.", - fi="", - fr="", - gr="", - hr="lip", - hu="jún.", - it="", - la="", - lt="jun", - nb="juni", - nl="", - nn="juni", - pl="czerw.", - pt="", - ro="", - ru="", - sk="júna", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - line={ - labels={ - af="reël ", - ar="سطر ", - ca="línia ", - cn="行", - cs="řádek ", - da="linie ", - de="Zeile ", - en="line ", - es="línea ", - fi="rivi ", - fr="ligne ", - gr="Γραμμή", - hr="redak ", - hu={""," sor"}, - it="riga ", - ja="線", - kr="행", - la="versus ", - lt="line ", - nb="linje ", - nl="regel ", - nn="linje ", - pl="wiersz ", - pt="linha ", - ro="linia ", - ru="строка ", - sk="riadok ", - sl="vrstica ", - sv="rad ", - tk="setir", - tr="satır ", - ua="рядок ", - vi="dòng ", - }, - }, - lines={ - labels={ - af="reëls ", - ar="السطور ", - ca="línies ", - cn="行", - cs="řádky ", - da="linier ", - de="Zeilen ", - en="lines ", - es="líneas ", - fi="rivie ", - fr="lignes ", - gr="Γραμμές", - hr="retci ", - hu="sorok ", - it="righe ", - ja="線", - kr="행", - la="versus ", - lt="lines ", - nb="linjer ", - nl="regels ", - nn="linjer ", - pl="wiersze ", - pt="linhas ", - ro="liniile ", - ru="строки ", - sk="riadky ", - sl="vrstice ", - sv="rader ", - tk="setirler", - tr="satırlar ", - ua="рядки ", - vi="dòng ", - }, - }, - march={ - labels={ - af="maart", - ar="مارس", + ["labels"]={ + ["af"]="", + ["ca"]="", + ["cs"]="čer.", + ["da"]="", + ["de"]="", + ["en"]="jun", + ["es"]="jun.", + ["fi"]="", + ["fr"]="", + ["gr"]="", + ["hr"]="lip", + ["hu"]="jún.", + ["it"]="", + ["la"]="", + ["lt"]="jun", + ["nb"]="juni", + ["nl"]="", + ["nn"]="juni", + ["pl"]="czerw.", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="júna", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["line"]={ + ["labels"]={ + ["af"]="reël ", + ["ar"]="سطر ", + ["ca"]="línia ", + ["cn"]="行", + ["cs"]="řádek ", + ["da"]="linie ", + ["de"]="Zeile ", + ["en"]="line ", + ["es"]="línea ", + ["fi"]="rivi ", + ["fr"]="ligne ", + ["gr"]="Γραμμή", + ["hr"]="redak ", + ["hu"]={ "", " sor" }, + ["it"]="riga ", + ["ja"]="線", + ["kr"]="행", + ["la"]="versus ", + ["lt"]="line ", + ["nb"]="linje ", + ["nl"]="regel ", + ["nn"]="linje ", + ["pe"]="سطر ", + ["pl"]="wiersz ", + ["pt"]="linha ", + ["ro"]="linia ", + ["ru"]="строка ", + ["sk"]="riadok ", + ["sl"]="vrstica ", + ["sv"]="rad ", + ["tk"]="setir", + ["tr"]="satır ", + ["ua"]="рядок ", + ["vi"]="dòng ", + }, + }, + ["lines"]={ + ["labels"]={ + ["af"]="reëls ", + ["ar"]="السطور ", + ["ca"]="línies ", + ["cn"]="行", + ["cs"]="řádky ", + ["da"]="linier ", + ["de"]="Zeilen ", + ["en"]="lines ", + ["es"]="líneas ", + ["fi"]="rivie ", + ["fr"]="lignes ", + ["gr"]="Γραμμές", + ["hr"]="retci ", + ["hu"]="sorok ", + ["it"]="righe ", + ["ja"]="線", + ["kr"]="행", + ["la"]="versus ", + ["lt"]="lines ", + ["nb"]="linjer ", + ["nl"]="regels ", + ["nn"]="linjer ", + ["pe"]="سطرهای ", + ["pl"]="wiersze ", + ["pt"]="linhas ", + ["ro"]="liniile ", + ["ru"]="строки ", + ["sk"]="riadky ", + ["sl"]="vrstice ", + ["sv"]="rader ", + ["tk"]="setirler", + ["tr"]="satırlar ", + ["ua"]="рядки ", + ["vi"]="dòng ", + }, + }, + ["march"]={ + ["labels"]={ + ["af"]="maart", + ["ar"]="مارس", ["ar-sy"]="آذار", - ca="març", - cn="三月", - cs="března", - da="marts", - de="März", - en="March", - es="marzo", - fi="maaliskuu", - fr="mars", - gr="Μάρτιος", - hr="ožujka", - hu="március", - it="marzo", - ja="3", - kr="3", - la="Martius", - lt="kovo", - nb="mars", - nl="maart", - nn="mars", - pl="marca", - pt="março", - ro="martie", - ru="марта", - sk="marca", - sl="marec", - sv="mars", - tk="mart", - tr="mart", - ua="березня", - vi="tháng ba", + ["ca"]="març", + ["cn"]="三月", + ["cs"]="března", + ["da"]="marts", + ["de"]="März", + ["en"]="March", + ["es"]="marzo", + ["fi"]="maaliskuu", + ["fr"]="mars", + ["gr"]="Μάρτιος", + ["hr"]="ožujka", + ["hu"]="március", + ["it"]="marzo", + ["ja"]="3", + ["kr"]="3", + ["la"]="Martius", + ["lt"]="kovo", + ["nb"]="mars", + ["nl"]="maart", + ["nn"]="mars", + ["pe"]="مارس", + ["pl"]="marca", + ["pt"]="março", + ["ro"]="martie", + ["ru"]="марта", + ["sk"]="marca", + ["sl"]="marec", + ["sv"]="mars", + ["tk"]="mart", + ["tr"]="mart", + ["ua"]="березня", + ["vi"]="tháng ba", + }, + }, + ["march:jalali"]={ + ["labels"]={ + ["en"]="Khordad", + ["fa"]="خرداد", }, }, ["march:mnem"]={ - labels={ - af="", - ca="", - cs="břez.", - da="", - de="", - en="mar", - es="mar.", - fi="", - fr="", - gr="", - hr="ožu", - hu="már.", - it="", - la="", - lt="mar", - nb="mars", - nl="", - nn="mars", - pl="mar.", - pt="", - ro="", - ru="", - sk="mar.", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - may={ - labels={ - af="mei", - ar="مايو", + ["labels"]={ + ["af"]="", + ["ca"]="", + ["cs"]="břez.", + ["da"]="", + ["de"]="", + ["en"]="mar", + ["es"]="mar.", + ["fi"]="", + ["fr"]="", + ["gr"]="", + ["hr"]="ožu", + ["hu"]="már.", + ["it"]="", + ["la"]="", + ["lt"]="mar", + ["nb"]="mars", + ["nl"]="", + ["nn"]="mars", + ["pl"]="mar.", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="mar.", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["may"]={ + ["labels"]={ + ["af"]="mei", + ["ar"]="مايو", ["ar-dz"]="ماي", ["ar-ma"]="ماي", ["ar-sy"]="أيار", - ca="maig", - cn="五月", - cs="května", - da="maj", - de="Mai", - en="May", - es="mayo", - fi="toukokuu", - fr="mai", - gr="Μάιος", - hr="svibnja", - hu="május", - it="maggio", - ja="5", - kr="5", - la="Maius", - lt="gegužės", - nb="mai", - nl="mei", - nn="mai", - pl="maja", - pt="maio", - ro="mai", - ru="мая", - sk="mája", - sl="maj", - sv="maj", - tk="maý", - tr="mayıs", - ua="травня", - vi="tháng năm", + ["ca"]="maig", + ["cn"]="五月", + ["cs"]="května", + ["da"]="maj", + ["de"]="Mai", + ["en"]="May", + ["es"]="mayo", + ["fi"]="toukokuu", + ["fr"]="mai", + ["gr"]="Μάιος", + ["hr"]="svibnja", + ["hu"]="május", + ["it"]="maggio", + ["ja"]="5", + ["kr"]="5", + ["la"]="Maius", + ["lt"]="gegužės", + ["nb"]="mai", + ["nl"]="mei", + ["nn"]="mai", + ["pe"]="مه", + ["pl"]="maja", + ["pt"]="maio", + ["ro"]="mai", + ["ru"]="мая", + ["sk"]="mája", + ["sl"]="maj", + ["sv"]="maj", + ["tk"]="maý", + ["tr"]="mayıs", + ["ua"]="травня", + ["vi"]="tháng năm", + }, + }, + ["may:jalali"]={ + ["labels"]={ + ["en"]="Mordad", + ["fa"]="مرداد", }, }, ["may:mnem"]={ - labels={ - af="", - ca="", - cs="květ.", - da="", - de="", - en="may", - es="may.", - fi="", - fr="", - gr="", - hr="svi", - hu="máj.", - it="", - la="", - lt="may", - nb="mai", - nl="", - nn="mai", - pl="maja", - pt="", - ro="", - ru="", - sk="mája", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - monday={ - labels={ - af="maandag", - ar="الاثنين", - ca="dilluns", - cn="星期一", - cs="pondělí", - da="mandag", - de="Montag", - en="Monday", - es="lunes", - fi="maanantai", - fr="lundi", - gr="Δευτέρα", - hr="ponedjeljak", - hu="hétfő", - it="lunedì", - ja="月曜日", - kr="월요일", - la="Dies Lunae", - lt="pirmadienis", - nb="mandag", - nl="maandag", - nn="måndag", - pl="poniedziałek", - pt="segunda-feira", - ro="luni", - ru="понедельник", - sk="pondelok", - sl="ponedeljek", - sv="måndag", - tk="birinji gün", - tr="pazartesi", - ua="понеділок", - vi="thứ hai", - }, - }, - november={ - labels={ - af="november", - ar="نوفمبر", + ["labels"]={ + ["af"]="", + ["ca"]="", + ["cs"]="květ.", + ["da"]="", + ["de"]="", + ["en"]="may", + ["es"]="may.", + ["fi"]="", + ["fr"]="", + ["gr"]="", + ["hr"]="svi", + ["hu"]="máj.", + ["it"]="", + ["la"]="", + ["lt"]="may", + ["nb"]="mai", + ["nl"]="", + ["nn"]="mai", + ["pl"]="maja", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="mája", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["monday"]={ + ["labels"]={ + ["af"]="maandag", + ["ar"]="الاثنين", + ["ca"]="dilluns", + ["cn"]="星期一", + ["cs"]="pondělí", + ["da"]="mandag", + ["de"]="Montag", + ["en"]="Monday", + ["es"]="lunes", + ["fi"]="maanantai", + ["fr"]="lundi", + ["gr"]="Δευτέρα", + ["hr"]="ponedjeljak", + ["hu"]="hétfő", + ["it"]="lunedì", + ["ja"]="月曜日", + ["kr"]="월요일", + ["la"]="Dies Lunae", + ["lt"]="pirmadienis", + ["nb"]="mandag", + ["nl"]="maandag", + ["nn"]="måndag", + ["pe"]="دوشنبه", + ["pl"]="poniedziałek", + ["pt"]="segunda-feira", + ["ro"]="luni", + ["ru"]="понедельник", + ["sk"]="pondelok", + ["sl"]="ponedeljek", + ["sv"]="måndag", + ["tk"]="birinji gün", + ["tr"]="pazartesi", + ["ua"]="понеділок", + ["vi"]="thứ hai", + }, + }, + ["month"]={ + ["labels"]={ + ["en"]="month", + ["kr"]="월", + ["nl"]="maand", + ["pe"]="ماه", + }, + }, + ["november"]={ + ["labels"]={ + ["af"]="november", + ["ar"]="نوفمبر", ["ar-ma"]="نونبر", ["ar-sy"]="تشرين الثاني", - ca="novembre", - cn="十一月", - cs="listopadu", - da="november", - de="November", - en="November", - es="noviembre", - fi="marraskuu", - fr="novembre", - gr="Νοέμβριος", - hr="studenog", - hu="november", - it="novembre", - ja="11", - kr="11", - la="November", - lt="lapkričio", - nb="november", - nl="november", - nn="november", - pl="listopada", - pt="novembro", - ro="noiembrie", - ru="ноября", - sk="novembra", - sl="november", - sv="november", - tk="noýabr", - tr="kasım", - ua="листопада", - vi="tháng mười một", + ["ca"]="novembre", + ["cn"]="十一月", + ["cs"]="listopadu", + ["da"]="november", + ["de"]="November", + ["en"]="November", + ["es"]="noviembre", + ["fi"]="marraskuu", + ["fr"]="novembre", + ["gr"]="Νοέμβριος", + ["hr"]="studenog", + ["hu"]="november", + ["it"]="novembre", + ["ja"]="11", + ["kr"]="11", + ["la"]="November", + ["lt"]="lapkričio", + ["nb"]="november", + ["nl"]="november", + ["nn"]="november", + ["pe"]="نوامبر", + ["pl"]="listopada", + ["pt"]="novembro", + ["ro"]="noiembrie", + ["ru"]="ноября", + ["sk"]="novembra", + ["sl"]="november", + ["sv"]="november", + ["tk"]="noýabr", + ["tr"]="kasım", + ["ua"]="листопада", + ["vi"]="tháng mười một", + }, + }, + ["november:jalali"]={ + ["labels"]={ + ["en"]="Bahman", + ["fa"]="بهمن", }, }, ["november:mnem"]={ - labels={ - af="", - ca="", - cs="list.", - da="", - de="", - en="nov", - es="nov.", - fi="", - fr="", - gr="", - hr="stu", - hu="nov.", - it="", - la="", - lt="nov", - nb="nov.", - nl="", - nn="nov.", - pl="lis.", - pt="", - ro="", - ru="", - sk="nov.", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - october={ - labels={ - af="oktober", - ar="أكتوبر", + ["labels"]={ + ["af"]="", + ["ca"]="", + ["cs"]="list.", + ["da"]="", + ["de"]="", + ["en"]="nov", + ["es"]="nov.", + ["fi"]="", + ["fr"]="", + ["gr"]="", + ["hr"]="stu", + ["hu"]="nov.", + ["it"]="", + ["la"]="", + ["lt"]="nov", + ["nb"]="nov.", + ["nl"]="", + ["nn"]="nov.", + ["pl"]="lis.", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="nov.", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["october"]={ + ["labels"]={ + ["af"]="oktober", + ["ar"]="أكتوبر", ["ar-sy"]="تشرين الأول", - ca="octubre", - cn="十月", - cs="října", - da="oktober", - de="Oktober", - en="October", - es="octubre", - fi="lokakuu", - fr="octobre", - gr="Οκτώβριος", - hr="listopada", - hu="október", - it="ottobre", - ja="10", - kr="10", - la="October", - lt="spalio", - nb="oktober", - nl="oktober", - nn="oktober", - pl="października", - pt="outubro", - ro="octombrie", - ru="октября", - sk="októbra", - sl="oktober", - sv="oktober", - tk="oktýabr", - tr="ekim", - ua="жовтня", - vi="tháng mười", + ["ca"]="octubre", + ["cn"]="十月", + ["cs"]="října", + ["da"]="oktober", + ["de"]="Oktober", + ["en"]="October", + ["es"]="octubre", + ["fi"]="lokakuu", + ["fr"]="octobre", + ["gr"]="Οκτώβριος", + ["hr"]="listopada", + ["hu"]="október", + ["it"]="ottobre", + ["ja"]="10", + ["kr"]="10", + ["la"]="October", + ["lt"]="spalio", + ["nb"]="oktober", + ["nl"]="oktober", + ["nn"]="oktober", + ["pe"]="اکتبر", + ["pl"]="października", + ["pt"]="outubro", + ["ro"]="octombrie", + ["ru"]="октября", + ["sk"]="októbra", + ["sl"]="oktober", + ["sv"]="oktober", + ["tk"]="oktýabr", + ["tr"]="ekim", + ["ua"]="жовтня", + ["vi"]="tháng mười", + }, + }, + ["october:jalali"]={ + ["labels"]={ + ["en"]="Dey", + ["fa"]="دی", }, }, ["october:mnem"]={ - labels={ - af="", - ca="", - cs="říj.", - da="", - de="", - en="oct", - es="oct.", - fi="", - fr="", - gr="", - hr="lis", - hu="okt.", - it="", - la="", - lt="oct", - nb="okt.", - nl="", - nn="okt.", - pl="paź.", - pt="", - ro="", - ru="", - sk="okt.", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - page={ - labels={ - af="", - ar="صفحة ", - ca="", - cs="strana ", - da="Side ", - de="Seite ", - en="page ", - es="página ", - fi="", - fr="page ", - gr="", - hr="stranica ", - hu="oldal ", - it="pagina ", - kr="쪽", - la="", - lt="puslapis ", - nb="side ", - nl="pagina ", - nn="side ", - pl="strona ", - pt="", - ro="", - ru="страница ", - sk="strana ", - sl="stran ", - sv="Sida ", - tk="", - tr="", - ua="сторінка ", - vi="", - }, - }, - part={ - labels={ - af="Deel ", - ar="جزء ", - ca="Part ", - cn={"第","部分"}, - cs="Část ", - da="Del ", - de="Teil ", - en="Part ", - es="Parte ", - fi="Osa ", - fr="Partie ", - gr="Μέρος", - hr="Dio ", - hu={""," rész"}, - it="Parte ", - ja={"第","パート"}, - kr={"제","부"}, - la="Pars ", - lt={""," dalis"}, - nb="Del", - nl="Deel ", - nn="Del", - pl="Część ", - pt="Parte ", - ro="Partea ", - ru="Часть ", - sk="Časť ", - sl="Del ", - sv="Del ", - tk="Bölüm", - tr="Cilt ", - ua="Частина ", - vi="Phần ", - }, - }, - saturday={ - labels={ - af="saterdag", - ar="السبت", - ca="dissabte", - cn="星期六", - cs="sobota", - da="lørdag", - de="Samstag", - en="Saturday", - es="sábado", - fi="lauantai", - fr="samedi", - gr="Σάββατο", - hr="subota", - hu="szombat", - it="sabato", - ja="土曜日", - kr="토요일", - la="Dies Saturni", - lt="šeštadienis", - nb="lørdag", - nl="zaterdag", - nn="laurdag", - pl="sobota", - pt="sábado", - ro="sâmbătă", - ru="суббота", - sk="sobota", - sl="sobota", - sv="lördag", - tk="altynjy gün", - tr="cumartesi", - ua="субота", - vi="thứ bảy", - }, - }, - section={ - hidden=true, - labels={ - af="Paragraaf ", - ar="فصل ", - ca="Secció ", - cn={"第","节"}, - cs="Sekce ", - da="", - de="", - en="", - es="Sección ", - fi="", - fr="Section ", - gr="Ενότητα", - hr="Odjeljak ", - hu="Fejezet ", - it="", - ja={"第","項"}, - kr={"제","절"}, - la="", - lt="", - nb="", - nl="", - nn="", - pl="Podrozdział ", - pt="", - ro="", - ru="", - sk="Sekcia ", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - see={ - labels={ - af="", - ar="انظر ", - ca="", - cs="viz ", - da="se ", - de="siehe ", - en="see ", - es="ver: ", - fi="", - fr="cf. ", - gr="", - hr="vidi ", - hu="lásd ", - it="cf. ", - kr="", - la="", - lt="žiūrėti ", - nb="se ", - nl="zie ", - nn="sjå ", - pl="patrz ", - pt="", - ro="", - ru="см. ", - sk="pozri ", - sl="glej ", - sv="se ", - tk="", - tr="", - ua="див. ", - vi="", - }, - }, - september={ - labels={ - af="september", - ar="سبتمبر", + ["labels"]={ + ["af"]="", + ["ca"]="", + ["cs"]="říj.", + ["da"]="", + ["de"]="", + ["en"]="oct", + ["es"]="oct.", + ["fi"]="", + ["fr"]="", + ["gr"]="", + ["hr"]="lis", + ["hu"]="okt.", + ["it"]="", + ["la"]="", + ["lt"]="oct", + ["nb"]="okt.", + ["nl"]="", + ["nn"]="okt.", + ["pl"]="paź.", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="okt.", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["page"]={ + ["labels"]={ + ["af"]="", + ["ar"]="صفحة ", + ["ca"]="", + ["cs"]="strana ", + ["da"]="Side ", + ["de"]="Seite ", + ["en"]="page ", + ["es"]="página ", + ["fi"]="", + ["fr"]="page ", + ["gr"]="", + ["hr"]="stranica ", + ["hu"]="oldal ", + ["it"]="pagina ", + ["kr"]="쪽", + ["la"]="", + ["lt"]="puslapis ", + ["nb"]="side ", + ["nl"]="pagina ", + ["nn"]="side ", + ["pe"]="صفحه ", + ["pl"]="strona ", + ["pt"]="", + ["ro"]="", + ["ru"]="страница ", + ["sk"]="strana ", + ["sl"]="stran ", + ["sv"]="Sida ", + ["tk"]="", + ["tr"]="", + ["ua"]="сторінка ", + ["vi"]="", + }, + }, + ["part"]={ + ["labels"]={ + ["af"]="Deel ", + ["ar"]="جزء ", + ["ca"]="Part ", + ["cn"]={ "第", "部分" }, + ["cs"]="Část ", + ["da"]="Del ", + ["de"]="Teil ", + ["en"]="Part ", + ["es"]="Parte ", + ["fi"]="Osa ", + ["fr"]="Partie ", + ["gr"]="Μέρος", + ["hr"]="Dio ", + ["hu"]={ "", " rész" }, + ["it"]="Parte ", + ["ja"]={ "第", "パート" }, + ["kr"]={ "제", "부" }, + ["la"]="Pars ", + ["lt"]={ "", " dalis" }, + ["nb"]="Del", + ["nl"]="Deel ", + ["nn"]="Del", + ["pe"]="قسمت ", + ["pl"]="Część ", + ["pt"]="Parte ", + ["ro"]="Partea ", + ["ru"]="Часть ", + ["sk"]="Časť ", + ["sl"]="Del ", + ["sv"]="Del ", + ["tk"]="Bölüm", + ["tr"]="Cilt ", + ["ua"]="Частина ", + ["vi"]="Phần ", + }, + }, + ["precedingpage"]={ + ["labels"]={ + ["en"]="on a preceding page", + ["nl"]="op een voorgaande bladzijde", + ["pe"]="در صفحات گذشته", + }, + }, + ["saturday"]={ + ["labels"]={ + ["af"]="saterdag", + ["ar"]="السبت", + ["ca"]="dissabte", + ["cn"]="星期六", + ["cs"]="sobota", + ["da"]="lørdag", + ["de"]="Samstag", + ["en"]="Saturday", + ["es"]="sábado", + ["fi"]="lauantai", + ["fr"]="samedi", + ["gr"]="Σάββατο", + ["hr"]="subota", + ["hu"]="szombat", + ["it"]="sabato", + ["ja"]="土曜日", + ["kr"]="토요일", + ["la"]="Dies Saturni", + ["lt"]="šeštadienis", + ["nb"]="lørdag", + ["nl"]="zaterdag", + ["nn"]="laurdag", + ["pe"]="شنبه", + ["pl"]="sobota", + ["pt"]="sábado", + ["ro"]="sâmbătă", + ["ru"]="суббота", + ["sk"]="sobota", + ["sl"]="sobota", + ["sv"]="lördag", + ["tk"]="altynjy gün", + ["tr"]="cumartesi", + ["ua"]="субота", + ["vi"]="thứ bảy", + }, + }, + ["section"]={ + ["hidden"]=true, + ["labels"]={ + ["af"]="Paragraaf ", + ["ar"]="فصل ", + ["ca"]="Secció ", + ["cn"]={ "第", "节" }, + ["cs"]="Sekce ", + ["da"]="", + ["de"]="", + ["en"]="", + ["es"]="Sección ", + ["fi"]="", + ["fr"]="Section ", + ["gr"]="Ενότητα", + ["hr"]="Odjeljak ", + ["hu"]="Fejezet ", + ["it"]="", + ["ja"]={ "第", "項" }, + ["kr"]={ "제", "절" }, + ["la"]="", + ["lt"]="", + ["nb"]="", + ["nl"]="", + ["nn"]="", + ["pe"]="بخش ", + ["pl"]="Podrozdział ", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="Sekcia ", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["see"]={ + ["labels"]={ + ["af"]="", + ["ar"]="انظر ", + ["ca"]="", + ["cs"]="viz ", + ["da"]="se ", + ["de"]="siehe ", + ["en"]="see ", + ["es"]="ver: ", + ["fi"]="", + ["fr"]="cf. ", + ["gr"]="", + ["hr"]="vidi ", + ["hu"]="lásd ", + ["it"]="cf. ", + ["kr"]="", + ["la"]="", + ["lt"]="žiūrėti ", + ["nb"]="se ", + ["nl"]="zie ", + ["nn"]="sjå ", + ["pe"]="نگاه کنید به ", + ["pl"]="patrz ", + ["pt"]="", + ["ro"]="", + ["ru"]="см. ", + ["sk"]="pozri ", + ["sl"]="glej ", + ["sv"]="se ", + ["tk"]="", + ["tr"]="", + ["ua"]="див. ", + ["vi"]="", + }, + }, + ["september"]={ + ["labels"]={ + ["af"]="september", + ["ar"]="سبتمبر", ["ar-ma"]="شتنبر", ["ar-sy"]="أيلول", - ca="setembre", - cn="九月", - cs="září", - da="september", - de="September", - en="September", - es="septiembre", - fi="syyskuu", - fr="septembre", - gr="Σεπτέμβριος", - hr="rujna", - hu="szeptember", - it="settembre", - ja="9", - kr="9", - la="September", - lt="rugsėjo", - nb="september", - nl="september", - nn="september", - pl="września", - pt="setembro", - ro="septembrie", - ru="сентября", - sk="septembra", - sl="september", - sv="september", - tk="sentýabr", - tr="eylül", - ua="вересня", - vi="tháng chín", + ["ca"]="setembre", + ["cn"]="九月", + ["cs"]="září", + ["da"]="september", + ["de"]="September", + ["en"]="September", + ["es"]="septiembre", + ["fi"]="syyskuu", + ["fr"]="septembre", + ["gr"]="Σεπτέμβριος", + ["hr"]="rujna", + ["hu"]="szeptember", + ["it"]="settembre", + ["ja"]="9", + ["kr"]="9", + ["la"]="September", + ["lt"]="rugsėjo", + ["nb"]="september", + ["nl"]="september", + ["nn"]="september", + ["pe"]="سپتامبر", + ["pl"]="września", + ["pt"]="setembro", + ["ro"]="septembrie", + ["ru"]="сентября", + ["sk"]="septembra", + ["sl"]="september", + ["sv"]="september", + ["tk"]="sentýabr", + ["tr"]="eylül", + ["ua"]="вересня", + ["vi"]="tháng chín", + }, + }, + ["september:jalali"]={ + ["labels"]={ + ["en"]="Azar", + ["fa"]="آذر", }, }, ["september:mnem"]={ - labels={ - af="", - ca="", - cs="září", - da="", - de="", - en="sep", - es="sep.", - fi="", - fr="", - gr="", - hr="ruj", - hu="szep.", - it="", - la="", - lt="sep", - nb="sep.", - nl="", - nn="sep.", - pl="wrz.", - pt="", - ro="", - ru="", - sk="sept.", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - subsection={ - hidden=true, - labels={ - af="", - ar="فصل أدنى ", - ca="Subsecció ", - cn="", - cs="Podsekce ", - da="", - de="", - en="", - es="Subsección ", - fi="", - fr="Soussection ", - gr="Υπόενότητα", - hr="Pododjeljak ", - hu="Alfejezet ", - it="", - ja="", - la="", - lt="", - nb="", - nl="", - nn="", - pl="Podpodrozdział ", - pt="", - ro="", - ru="", - sk="Podsekcia ", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - subsubsection={ - hidden=true, - labels={ - af="", - ar="فصل أ دنى أدنى ", - ca="Subsubsecció ", - cn="", - cs="Podpodsekce ", - da="", - de="", - en="", - es="Subsubsección ", - fi="", - fr="Soussoussection ", - gr="", - hr="Podpododjeljak ", - hu="Al-alfejezet ", - it="", - ja="", - la="", - lt="", - nb="", - nl="", - nn="", - pl="", - pt="", - ro="", - ru="", - sk="Podpodsekcia ", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - subsubsubsection={ - hidden=true, - labels={ - af="", - ar="فصل أدنى أدنى أدنى ", - ca="Subsubsubsecció ", - cn="", - cs="Podpodpodsekce ", - da="", - de="", - en="", - es="Subsubsubsección ", - fi="", - fr="Soussoussoussection ", - gr="", - hr="Podpodpododjeljak ", - hu="Al-al-alfejezet ", - it="", - ja="", - la="", - lt="", - nb="", - nl="", - nn="", - pl="", -- not used in Polish - pt="", - ro="", - ru="", - sk="Podpodpodsekcia ", - sl="", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - sunday={ - labels={ - af="sondag", - ar="الأحد", - ca="diumenge", - cn="星期日", - cs="neděle", - da="søndag", - de="Sonntag", - en="Sunday", - es="domingo", - fi="sunnuntai", - fr="dimanche", - gr="Κυριακή", - hr="nedjelja", - hu="vasárnap", - it="domenica", - ja="日曜日", - kr="일요일", - la="Dies Solis", - lt="sekmadienis", - nb="søndag", - nl="zondag", - nn="sundag", - pl="niedziela", - pt="domingo", - ro="duminică", - ru="воскресенье", - sk="nedeľa", - sl="nedelja", - sv="söndag", - tk="dynç gün", - tr="pazar", - ua="неділя", - vi="chủ nhật", - }, - }, - table={ - labels={ - af="Tabel", - ar="جدول ", - ca="Taula ", - cn="表", - cs="Tabulka ", - da="Tabel ", - de="Tabelle ", - en="Table ", - es="Tabla ", - fi="Taulukko ", - fr="Tableau ", - gr="Πίνακας", - hr="Tablica ", - hu={""," táblázat"}, - it="Tabella ", - ja="表", - kr="표 ", - la="Tabula ", - lt={""," lentelė."}, - nb="Tabell ", - nl="Tabel ", - nn="Tabell ", - pl="Tabela ", - pt="Tabela ", - ro="Tabelul ", - ru="Таблица ", - sk="Tabuľka ", - sl="Tabela ", - sv="Tabell ", - tk="Tablisa", - tr="Tablo ", - ua="Таблиця ", - vi="Bảng ", - }, - }, - thursday={ - labels={ - af="donderdag", - ar="الخميس", - ca="dijous", - cn="星期四", - cs="čtvrtek", - da="torsdag", - de="Donnerstag", - en="Thursday", - es="jueves", - fi="torstai", - fr="jeudi", - gr="Πέμπτη", - hr="četvrtak", - hu="csütörtök", - it="giovedì", - ja="木曜日", - kr="목요일", - la="Dies Iovis", - lt="ketvirtadienis", - nb="torsdag", - nl="donderdag", - nn="torsdag", - pl="czwartek", - pt="quinta-feira", - ro="joi", - ru="четверг", - sk="štvrtok", - sl="četrtek", - sv="torsdag", - tk="dördünji gün", - tr="perşembe", - ua="четвер", - vi="thứ năm", - }, - }, - tuesday={ - labels={ - af="dinsdag", - ar="الثلاثاء", - ca="dimarts", - cn="星期二", - cs="úterý", - da="tirsdag", - de="Dienstag", - en="Tuesday", - es="martes", - fi="tiistai", - fr="mardi", - gr="Τρίτη", - hr="utorak", - hu="kedd", - it="martedì", - ja="火曜日", - kr="화요일", - la="Dies Martis", - lt="antradienis", - nb="tirsdag", - nl="dinsdag", - nn="tysdag", - pl="wtorek", - pt="terça-feira", - ro="marți", - ru="вторник", - sk="utorok", - sl="torek", - sv="tisdag", - tk="ikinji gün", - tr="salı", - ua="вівторок", - vi="thứ ba", - }, - }, - wednesday={ - labels={ - af="woensdag", - ar="الأربعاء", - ca="dimecres", - cn="星期三", - cs="středa", - da="onsdag", - de="Mittwoch", - en="Wednesday", - es="miércoles", - fi="keskiviikko", - fr="mercredi", - gr="Τετάρτη", - hr="srijeda", - hu="szerda", - it="mercoledì", - ja="水曜日", - kr="수요일", - la="Dies Mercuri", - lt="trečiadienis", - nb="onsdag", - nl="woensdag", - nn="onsdag", - pl="środa", - pt="quarta-feira", - ro="miercuri", - ru="среда", - sk="streda", - sl="sreda", - sv="onsdag", - tk="üçünji", - tr="çarşamba", - ua="середа", - vi="thứ tư", + ["labels"]={ + ["af"]="", + ["ca"]="", + ["cs"]="září", + ["da"]="", + ["de"]="", + ["en"]="sep", + ["es"]="sep.", + ["fi"]="", + ["fr"]="", + ["gr"]="", + ["hr"]="ruj", + ["hu"]="szep.", + ["it"]="", + ["la"]="", + ["lt"]="sep", + ["nb"]="sep.", + ["nl"]="", + ["nn"]="sep.", + ["pl"]="wrz.", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="sept.", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["subsection"]={ + ["hidden"]=true, + ["labels"]={ + ["af"]="", + ["ar"]="فصل أدنى ", + ["ca"]="Subsecció ", + ["cn"]="", + ["cs"]="Podsekce ", + ["da"]="", + ["de"]="", + ["en"]="", + ["es"]="Subsección ", + ["fi"]="", + ["fr"]="Soussection ", + ["gr"]="Υπόενότητα", + ["hr"]="Pododjeljak ", + ["hu"]="Alfejezet ", + ["it"]="", + ["ja"]="", + ["la"]="", + ["lt"]="", + ["nb"]="", + ["nl"]="", + ["nn"]="", + ["pe"]="زیربخش ", + ["pl"]="Podpodrozdział ", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="Podsekcia ", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["subsubsection"]={ + ["hidden"]=true, + ["labels"]={ + ["af"]="", + ["ar"]="فصل أدنى أدنى ", + ["ca"]="Subsubsecció ", + ["cn"]="", + ["cs"]="Podpodsekce ", + ["da"]="", + ["de"]="", + ["en"]="", + ["es"]="Subsubsección ", + ["fi"]="", + ["fr"]="Soussoussection ", + ["gr"]="", + ["hr"]="Podpododjeljak ", + ["hu"]="Al-alfejezet ", + ["it"]="", + ["ja"]="", + ["la"]="", + ["lt"]="", + ["nb"]="", + ["nl"]="", + ["nn"]="", + ["pe"]="زیرزیربخش ", + ["pl"]="", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="Podpodsekcia ", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["subsubsubsection"]={ + ["hidden"]=true, + ["labels"]={ + ["af"]="", + ["ar"]="فصل أدنى أدنى أدنى ", + ["ca"]="Subsubsubsecció ", + ["cn"]="", + ["cs"]="Podpodpodsekce ", + ["da"]="", + ["de"]="", + ["en"]="", + ["es"]="Subsubsubsección ", + ["fi"]="", + ["fr"]="Soussoussoussection ", + ["gr"]="", + ["hr"]="Podpodpododjeljak ", + ["hu"]="Al-al-alfejezet ", + ["it"]="", + ["ja"]="", + ["la"]="", + ["lt"]="", + ["nb"]="", + ["nl"]="", + ["nn"]="", + ["pe"]="زیرزیرزیربخش ", + ["pl"]="", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="Podpodpodsekcia ", + ["sl"]="", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["sunday"]={ + ["labels"]={ + ["af"]="sondag", + ["ar"]="الأحد", + ["ca"]="diumenge", + ["cn"]="星期日", + ["cs"]="neděle", + ["da"]="søndag", + ["de"]="Sonntag", + ["en"]="Sunday", + ["es"]="domingo", + ["fi"]="sunnuntai", + ["fr"]="dimanche", + ["gr"]="Κυριακή", + ["hr"]="nedjelja", + ["hu"]="vasárnap", + ["it"]="domenica", + ["ja"]="日曜日", + ["kr"]="일요일", + ["la"]="Dies Solis", + ["lt"]="sekmadienis", + ["nb"]="søndag", + ["nl"]="zondag", + ["nn"]="sundag", + ["pe"]="یکشنبه", + ["pl"]="niedziela", + ["pt"]="domingo", + ["ro"]="duminică", + ["ru"]="воскресенье", + ["sk"]="nedeľa", + ["sl"]="nedelja", + ["sv"]="söndag", + ["tk"]="dynç gün", + ["tr"]="pazar", + ["ua"]="неділя", + ["vi"]="chủ nhật", + }, + }, + ["table"]={ + ["labels"]={ + ["af"]="Tabel", + ["ar"]="جدول ", + ["ca"]="Taula ", + ["cn"]="表", + ["cs"]="Tabulka ", + ["da"]="Tabel ", + ["de"]="Tabelle ", + ["en"]="Table ", + ["es"]="Tabla ", + ["fi"]="Taulukko ", + ["fr"]="Tableau ", + ["gr"]="Πίνακας", + ["hr"]="Tablica ", + ["hu"]={ "", " táblázat" }, + ["it"]="Tabella ", + ["ja"]="表", + ["kr"]="표 ", + ["la"]="Tabula ", + ["lt"]={ "", " lentelė." }, + ["nb"]="Tabell ", + ["nl"]="Tabel ", + ["nn"]="Tabell ", + ["pe"]="جدول ", + ["pl"]="Tabela ", + ["pt"]="Tabela ", + ["ro"]="Tabelul ", + ["ru"]="Таблица ", + ["sk"]="Tabuľka ", + ["sl"]="Tabela ", + ["sv"]="Tabell ", + ["tk"]="Tablisa", + ["tr"]="Tablo ", + ["ua"]="Таблиця ", + ["vi"]="Bảng ", + }, + }, + ["thursday"]={ + ["labels"]={ + ["af"]="donderdag", + ["ar"]="الخميس", + ["ca"]="dijous", + ["cn"]="星期四", + ["cs"]="čtvrtek", + ["da"]="torsdag", + ["de"]="Donnerstag", + ["en"]="Thursday", + ["es"]="jueves", + ["fi"]="torstai", + ["fr"]="jeudi", + ["gr"]="Πέμπτη", + ["hr"]="četvrtak", + ["hu"]="csütörtök", + ["it"]="giovedì", + ["ja"]="木曜日", + ["kr"]="목요일", + ["la"]="Dies Iovis", + ["lt"]="ketvirtadienis", + ["nb"]="torsdag", + ["nl"]="donderdag", + ["nn"]="torsdag", + ["pe"]="پنجشنبه", + ["pl"]="czwartek", + ["pt"]="quinta-feira", + ["ro"]="joi", + ["ru"]="четверг", + ["sk"]="štvrtok", + ["sl"]="četrtek", + ["sv"]="torsdag", + ["tk"]="dördünji gün", + ["tr"]="perşembe", + ["ua"]="четвер", + ["vi"]="thứ năm", + }, + }, + ["tuesday"]={ + ["labels"]={ + ["af"]="dinsdag", + ["ar"]="الثلاثاء", + ["ca"]="dimarts", + ["cn"]="星期二", + ["cs"]="úterý", + ["da"]="tirsdag", + ["de"]="Dienstag", + ["en"]="Tuesday", + ["es"]="martes", + ["fi"]="tiistai", + ["fr"]="mardi", + ["gr"]="Τρίτη", + ["hr"]="utorak", + ["hu"]="kedd", + ["it"]="martedì", + ["ja"]="火曜日", + ["kr"]="화요일", + ["la"]="Dies Martis", + ["lt"]="antradienis", + ["nb"]="tirsdag", + ["nl"]="dinsdag", + ["nn"]="tysdag", + ["pe"]="سهشنبه", + ["pl"]="wtorek", + ["pt"]="terça-feira", + ["ro"]="marți", + ["ru"]="вторник", + ["sk"]="utorok", + ["sl"]="torek", + ["sv"]="tisdag", + ["tk"]="ikinji gün", + ["tr"]="salı", + ["ua"]="вівторок", + ["vi"]="thứ ba", + }, + }, + ["wednesday"]={ + ["labels"]={ + ["af"]="woensdag", + ["ar"]="الأربعاء", + ["ca"]="dimecres", + ["cn"]="星期三", + ["cs"]="středa", + ["da"]="onsdag", + ["de"]="Mittwoch", + ["en"]="Wednesday", + ["es"]="miércoles", + ["fi"]="keskiviikko", + ["fr"]="mercredi", + ["gr"]="Τετάρτη", + ["hr"]="srijeda", + ["hu"]="szerda", + ["it"]="mercoledì", + ["ja"]="水曜日", + ["kr"]="수요일", + ["la"]="Dies Mercuri", + ["lt"]="trečiadienis", + ["nb"]="onsdag", + ["nl"]="woensdag", + ["nn"]="onsdag", + ["pe"]="چهارشنبه", + ["pl"]="środa", + ["pt"]="quarta-feira", + ["ro"]="miercuri", + ["ru"]="среда", + ["sk"]="streda", + ["sl"]="sreda", + ["sv"]="onsdag", + ["tk"]="üçünji", + ["tr"]="çarşamba", + ["ua"]="середа", + ["vi"]="thứ tư", }, }, - }, - titles={ - abbreviations={ - labels={ - af="Afkortings", - ar="الاختصارات", - ca="Abreviacions", - cn="缩略语", - cs="Zkratky", - da="Forkortelser", - de="Abkürzungen", - en="Abbreviations", - es="Abreviaturas", - fi="Lyhennyksi", - fr="Abréviations", - gr="Συντομογραφίες", - hr="Kratice", - hu="Rövidítések", - it="Abbreviazioni", - ja="略語", - kr="약어", - la="Notae", - lt="Santrumpos", - nb="Forkortelser", - nl="Afkortingen", - nn="Forkortingar", - pl="Wykaz skrótów", - pt="Abreviaturas", - ro="Abrevieri", - ru="Список сокращений", - sk="Skratky", - sl="Kratice", - sv="Förkortningar", - tk="Gysgaltmalar", - tr="Kısaltmalar", - ua="Перелік скорочень", - vi="Chữ viết tắt", - }, - }, - content={ - labels={ - af="Inhoud", - ar="المحتويات", - ca="Índex de continguts", - cn="目录", - cs="Obsah", - da="Indhold", - de="Inhalt", - en="Contents", - es="Contenido", - fi="Sisällys", - fr="Table des matières", - gr="Περιεχόμενα", - hr="Sadržaj", - hu="Tartalom", - it="Indice", - ja="目次", - kr="목차", - la="Quod in libro continetur", - lt="Turinys", - nb="Innhold", - nl="Inhoud", - nn="Innhald", - pl="Spis treści", - pt="Conteúdo", - ro="Cuprins", - ru="Содержание", - sk="Obsah", - sl="Kazalo", - sv="Innehåll", - tk="Mazmuny", - tr="Fihrist", - ua="Зміст", - vi="Mục lục", - }, - }, - figures={ - labels={ - af="Figure", - ar="الأشكال", - ca="Figures", - cn="图形", - cs="Seznam obrázků", - da="Figurer", - de="Abbildungen", - en="Figures", - es="Figuras", - fi="Kuvi", - fr="Figures", - gr="Σχήματα", - hr="Slike", - hu="Ábrák", - it="Figure", - ja="図", - kr="그림 ", - la="Imagines", - lt="Iliustracijos", - nb="Figurer", - nl="Figuren", - nn="Figurar", - pl="Ilustracje", - pt="Figuras", - ro="Figuri", - ru="Список иллюстраций", - sk="Zoznam obrázkov", - sl="Slike", - sv="Figurer", - tk="Suratlar", - tr="Şekiller", - ua="Перелік ілюстрацій", - vi="Danh sách hình vẽ", - }, - }, - graphics={ - labels={ - af="Grafieke", - ar="الرسوم", - ca="Gràfiques", - cn="图", - cs="Seznam grafů", - da="Grafik", - de="Graphiken", - en="Graphics", - es="Gráficos", - fi="Grafiikkaoi", - fr="Graphiques", - gr="Γραφικά", - hr="Slike", - hu="Grafikák", - it="Grafici", - ja="グラフ", - kr="그래픽 ", - la="Typi", - lt="Graphics", - nb="Bilde", - nl="Grafieken", - nn="Bilete", - pl="Grafiki", - pt="Gráficos", - ro="Grafice", - ru="Список графиков", - sk="Zoznam grafov", - sl="Slike", - sv="Grafik", - tk="Grafikler", - tr="Grafikler", - ua="Перелік графіков", - vi="Đồ thị", - }, - }, - index={ - labels={ - af="Indeks", - ar="الفهرس", - ca="Índex alfabètic", - cn="索引", - cs="Rejstřík", - da="Indeks", - de="Index", - en="Index", - es="Índice", - fi="Indeksiluku", - fr="Index", - gr="Ευρετήριο", - hr="Indeks", - hu="Index", - it="Indice", - ja="目次", - kr="찾아보기", - la="Indices", - lt="Rodyklė", - nb="Register", - nl="Index", - nn="Register", - pl="Indeks", - pt="Índice", - ro="Index", - ru="Алфавитный указатель", - sk="Zoznam", - sl="Stvarno kazalo", - sv="Sakregister", - tk="Indeks", - tr="İndex", - ua="Покажчик", - vi="Chỉ số", - }, - }, - intermezzi={ - labels={ - af="Intermezzos", - ar="فسح", - ca="Intermedis", - cn="퉣", - cs="Intermezza", - da="Intermezzoer", - de="Intermezzi", - en="Intermezzos", - es="Intermedios", - fi="Intermezzos", - fr="Intermèdes", - gr="Παύσεις", - hr="Intermeci", - hu="Intermezzok", - it="Intermezzi", - ja="間奏曲", - kr="간주곡", - la="Intermissa", - lt="Intermezzos", - nb="Intermesso", - nl="Intermezzo's", - nn="Intermesso", - pl="Intermezza", - pt="Intermédios", - ro="Intermzzo", - ru="Список вставок", - sk="Intermezzá", - sl="Intermezzi", - sv="Intermezzon", - tk="Arakesmeler", - tr="", - ua="Перелік вставок", - vi="Intermezzos", - }, - }, - logos={ - labels={ - af="Logos", - ar="الشعارات", - ca="Logotips", - cn="徽贬", - cs="Loga", - da="Logoer", - de="Logos", - en="Logos", - es="Logotipos", - fi="Vertauskuva", - fr="Logos", - gr="Λογότυπα", - hr="Logotipi", - hu="Fejlécek", - it="Logotipi", - ja="理性", - kr="이성", - la="Typi negotiales", - lt="Logos", - nb="Logoer", - nl="Logo's", - nn="Logoar", - pl="Znaki", - pt="Logotipos", - ro="Logo-uri", - ru="Логотипы", - sk="Logá", - sl="Logotipi", - sv="Loggor", - tk="Logolar", - tr="Logolar", - ua="Логотипи", - vi="Biểu tượng", - }, - }, - pubs={ - labels={ - af="", - ca="Referències", - cs="Literatura", - da="", - de="Literatur", - en="References", - es="Bibliografía", - fi="", - fr="Bibliographie", - gr="", - hr="Literatura", - hu="Bibliográfia", - it="Bibliografia", - kr="참고문헌", - la="", - lt="Literatūra", - nb="", - nl="Literatuur", - nn="", - pl="Bibliografia", - pt="", - ro="", - ru="", - sk="Literatúra", - sl="Literatura", - sv="", - tk="", - tr="", - ua="", - vi="", - }, - }, - tables={ - labels={ - af="Tabelle", - ar="الجداول", - ca="Taules", - cn="表格", - cs="Seznam tabulek", - da="Tabeller", - de="Tabellen", - en="Tables", - es="Tablas", - fi="Taulukkoj", - fr="Tableaux", - gr="Πίνακες", - hr="Tablice", - hu="Táblázatok", - it="Tabelle", - ja="机", - kr="표 ", - la="Tabulae", - lt="Lentelės", - nb="Tabeller", - nl="Tabellen", - nn="Tabellar", - pl="Tabele", - pt="Tabelas", - ro="Tabele", - ru="Список таблиц", - sk="Zoznam tabuliek", - sl="Tabele", - sv="Tabeller", - tk="Tablisalar", - tr="Tablolar", - ua="Перелік таблиць", - vi="Danh sách bảng", - }, - }, - units={ - labels={ - af="Eenhede", - ar="الوحدات", - ca="Unitats", - cn="计量单位", - cs="Jednotky", - da="Enheder", - de="Einheiten", - en="Units", - es="Unidades", - fi="Yksiköt", - fr="Unités", - gr="Μονάδες", - hr="Jedinice", - hu="Mértékegységek", - it="Unità", - ja="ユニッツ", - kr="측정단위", - la="Modi", - lt="Units", - nb="Enheter", - nl="Eenheden", - nn="Einingar", - pl="Jednostki", - pt="Unidades", - ro="Unități", - ru="Единицы измерения", - sk="Jednotky", - sl="Enote", - sv="Enheter", - tk="Birlikler", - tr="Birimler", - ua="Одиниці виміру", - vi="Đơn vị", + ["year"]={ + ["labels"]={ + ["en"]="year", + ["kr"]="년", + ["nl"]="jaar", + ["pe"]="سال", }, }, }, - btx = { - ["mastersthesis"] = { - labels = { - en = "Master's thesis", - fr = "Thèse de master (DEA, DESS, master)", - de = "Masterarbeit", - }, - }, - ["phdthesis"] = { - labels = { - en = "PhD thesis", - fr = "Thèse de doctorat", - de = "Dissertation", - }, - }, - ["technicalreport"] = { - labels = { - en = "Technical report", - fr = "Rapport technique", - de = "Technischer Bericht", + ["titles"]={ + ["abbreviations"]={ + ["labels"]={ + ["af"]="Afkortings", + ["ar"]="الاختصارات", + ["ca"]="Abreviacions", + ["cn"]="缩略语", + ["cs"]="Zkratky", + ["da"]="Forkortelser", + ["de"]="Abkürzungen", + ["en"]="Abbreviations", + ["es"]="Abreviaturas", + ["fi"]="Lyhennyksi", + ["fr"]="Abréviations", + ["gr"]="Συντομογραφίες", + ["hr"]="Kratice", + ["hu"]="Rövidítések", + ["it"]="Abbreviazioni", + ["ja"]="略語", + ["kr"]="약어", + ["la"]="Notae", + ["lt"]="Santrumpos", + ["nb"]="Forkortelser", + ["nl"]="Afkortingen", + ["nn"]="Forkortingar", + ["pe"]="نشانههای اختصاری", + ["pl"]="Wykaz skrótów", + ["pt"]="Abreviaturas", + ["ro"]="Abrevieri", + ["ru"]="Список сокращений", + ["sk"]="Skratky", + ["sl"]="Kratice", + ["sv"]="Förkortningar", + ["tk"]="Gysgaltmalar", + ["tr"]="Kısaltmalar", + ["ua"]="Перелік скорочень", + ["vi"]="Chữ viết tắt", + }, + }, + ["content"]={ + ["labels"]={ + ["af"]="Inhoud", + ["ar"]="المحتويات", + ["ca"]="Índex de continguts", + ["cn"]="目录", + ["cs"]="Obsah", + ["da"]="Indhold", + ["de"]="Inhalt", + ["en"]="Contents", + ["es"]="Contenido", + ["fi"]="Sisällys", + ["fr"]="Table des matières", + ["gr"]="Περιεχόμενα", + ["hr"]="Sadržaj", + ["hu"]="Tartalom", + ["it"]="Indice", + ["ja"]="目次", + ["kr"]="목차", + ["la"]="Quod in libro continetur", + ["lt"]="Turinys", + ["nb"]="Innhold", + ["nl"]="Inhoud", + ["nn"]="Innhald", + ["pe"]="فهرست مطالب", + ["pl"]="Spis treści", + ["pt"]="Conteúdo", + ["ro"]="Cuprins", + ["ru"]="Содержание", + ["sk"]="Obsah", + ["sl"]="Kazalo", + ["sv"]="Innehåll", + ["tk"]="Mazmuny", + ["tr"]="Fihrist", + ["ua"]="Зміст", + ["vi"]="Mục lục", + }, + }, + ["figures"]={ + ["labels"]={ + ["af"]="Figure", + ["ar"]="الأشكال", + ["ca"]="Figures", + ["cn"]="图形", + ["cs"]="Seznam obrázků", + ["da"]="Figurer", + ["de"]="Abbildungen", + ["en"]="Figures", + ["es"]="Figuras", + ["fi"]="Kuvi", + ["fr"]="Figures", + ["gr"]="Σχήματα", + ["hr"]="Slike", + ["hu"]="Ábrák", + ["it"]="Figure", + ["ja"]="図", + ["kr"]="그림 ", + ["la"]="Imagines", + ["lt"]="Iliustracijos", + ["nb"]="Figurer", + ["nl"]="Figuren", + ["nn"]="Figurar", + ["pe"]="فهرست اشکال", + ["pl"]="Ilustracje", + ["pt"]="Figuras", + ["ro"]="Figuri", + ["ru"]="Список иллюстраций", + ["sk"]="Zoznam obrázkov", + ["sl"]="Slike", + ["sv"]="Figurer", + ["tk"]="Suratlar", + ["tr"]="Şekiller", + ["ua"]="Перелік ілюстрацій", + ["vi"]="Danh sách hình vẽ", + }, + }, + ["graphics"]={ + ["labels"]={ + ["af"]="Grafieke", + ["ar"]="الرسوم", + ["ca"]="Gràfiques", + ["cn"]="图", + ["cs"]="Seznam grafů", + ["da"]="Grafik", + ["de"]="Graphiken", + ["en"]="Graphics", + ["es"]="Gráficos", + ["fi"]="Grafiikkaoi", + ["fr"]="Graphiques", + ["gr"]="Γραφικά", + ["hr"]="Slike", + ["hu"]="Grafikák", + ["it"]="Grafici", + ["ja"]="グラフ", + ["kr"]="그래픽 ", + ["la"]="Typi", + ["lt"]="Graphics", + ["nb"]="Bilde", + ["nl"]="Grafieken", + ["nn"]="Bilete", + ["pe"]="فهرست طرحها", + ["pl"]="Grafiki", + ["pt"]="Gráficos", + ["ro"]="Grafice", + ["ru"]="Список графиков", + ["sk"]="Zoznam grafov", + ["sl"]="Slike", + ["sv"]="Grafik", + ["tk"]="Grafikler", + ["tr"]="Grafikler", + ["ua"]="Перелік графіков", + ["vi"]="Đồ thị", + }, + }, + ["index"]={ + ["labels"]={ + ["af"]="Indeks", + ["ar"]="الفهرس", + ["ca"]="Índex alfabètic", + ["cn"]="索引", + ["cs"]="Rejstřík", + ["da"]="Indeks", + ["de"]="Index", + ["en"]="Index", + ["es"]="Índice", + ["fi"]="Indeksiluku", + ["fr"]="Index", + ["gr"]="Ευρετήριο", + ["hr"]="Indeks", + ["hu"]="Index", + ["it"]="Indice", + ["ja"]="目次", + ["kr"]="찾아보기", + ["la"]="Indices", + ["lt"]="Rodyklė", + ["nb"]="Register", + ["nl"]="Index", + ["nn"]="Register", + ["pe"]="نمایه", + ["pl"]="Indeks", + ["pt"]="Índice", + ["ro"]="Index", + ["ru"]="Алфавитный указатель", + ["sk"]="Zoznam", + ["sl"]="Stvarno kazalo", + ["sv"]="Sakregister", + ["tk"]="Indeks", + ["tr"]="İndex", + ["ua"]="Покажчик", + ["vi"]="Chỉ số", + }, + }, + ["intermezzi"]={ + ["labels"]={ + ["af"]="Intermezzos", + ["ar"]="فسح", + ["ca"]="Intermedis", + ["cn"]="퉣", + ["cs"]="Intermezza", + ["da"]="Intermezzoer", + ["de"]="Intermezzi", + ["en"]="Intermezzos", + ["es"]="Intermedios", + ["fi"]="Intermezzos", + ["fr"]="Intermèdes", + ["gr"]="Παύσεις", + ["hr"]="Intermeci", + ["hu"]="Intermezzok", + ["it"]="Intermezzi", + ["ja"]="間奏曲", + ["kr"]="간주곡", + ["la"]="Intermissa", + ["lt"]="Intermezzos", + ["nb"]="Intermesso", + ["nl"]="Intermezzo's", + ["nn"]="Intermesso", + ["pl"]="Intermezza", + ["pt"]="Intermédios", + ["ro"]="Intermzzo", + ["ru"]="Список вставок", + ["sk"]="Intermezzá", + ["sl"]="Intermezzi", + ["sv"]="Intermezzon", + ["tk"]="Arakesmeler", + ["tr"]="", + ["ua"]="Перелік вставок", + ["vi"]="Intermezzos", + }, + }, + ["logos"]={ + ["labels"]={ + ["af"]="Logos", + ["ar"]="الشعارات", + ["ca"]="Logotips", + ["cn"]="徽贬", + ["cs"]="Loga", + ["da"]="Logoer", + ["de"]="Logos", + ["en"]="Logos", + ["es"]="Logotipos", + ["fi"]="Vertauskuva", + ["fr"]="Logos", + ["gr"]="Λογότυπα", + ["hr"]="Logotipi", + ["hu"]="Fejlécek", + ["it"]="Logotipi", + ["ja"]="理性", + ["kr"]="이성", + ["la"]="Typi negotiales", + ["lt"]="Logos", + ["nb"]="Logoer", + ["nl"]="Logo's", + ["nn"]="Logoar", + ["pe"]="فهرست لوگوها", + ["pl"]="Znaki", + ["pt"]="Logotipos", + ["ro"]="Logo-uri", + ["ru"]="Логотипы", + ["sk"]="Logá", + ["sl"]="Logotipi", + ["sv"]="Loggor", + ["tk"]="Logolar", + ["tr"]="Logolar", + ["ua"]="Логотипи", + ["vi"]="Biểu tượng", + }, + }, + ["pubs"]={ + ["labels"]={ + ["af"]="", + ["ca"]="Referències", + ["cs"]="Literatura", + ["da"]="", + ["de"]="Literatur", + ["en"]="References", + ["es"]="Bibliografía", + ["fi"]="", + ["fr"]="Bibliographie", + ["gr"]="", + ["hr"]="Literatura", + ["hu"]="Bibliográfia", + ["it"]="Bibliografia", + ["kr"]="참고문헌", + ["la"]="", + ["lt"]="Literatūra", + ["nb"]="", + ["nl"]="Literatuur", + ["nn"]="", + ["pe"]="کتابنامه", + ["pl"]="Bibliografia", + ["pt"]="", + ["ro"]="", + ["ru"]="", + ["sk"]="Literatúra", + ["sl"]="Literatura", + ["sv"]="", + ["tk"]="", + ["tr"]="", + ["ua"]="", + ["vi"]="", + }, + }, + ["tables"]={ + ["labels"]={ + ["af"]="Tabelle", + ["ar"]="الجداول", + ["ca"]="Taules", + ["cn"]="表格", + ["cs"]="Seznam tabulek", + ["da"]="Tabeller", + ["de"]="Tabellen", + ["en"]="Tables", + ["es"]="Tablas", + ["fi"]="Taulukkoj", + ["fr"]="Tableaux", + ["gr"]="Πίνακες", + ["hr"]="Tablice", + ["hu"]="Táblázatok", + ["it"]="Tabelle", + ["ja"]="机", + ["kr"]="표 ", + ["la"]="Tabulae", + ["lt"]="Lentelės", + ["nb"]="Tabeller", + ["nl"]="Tabellen", + ["nn"]="Tabellar", + ["pe"]="فهرست جداول", + ["pl"]="Tabele", + ["pt"]="Tabelas", + ["ro"]="Tabele", + ["ru"]="Список таблиц", + ["sk"]="Zoznam tabuliek", + ["sl"]="Tabele", + ["sv"]="Tabeller", + ["tk"]="Tablisalar", + ["tr"]="Tablolar", + ["ua"]="Перелік таблиць", + ["vi"]="Danh sách bảng", + }, + }, + ["units"]={ + ["labels"]={ + ["af"]="Eenhede", + ["ar"]="الوحدات", + ["ca"]="Unitats", + ["cn"]="计量单位", + ["cs"]="Jednotky", + ["da"]="Enheder", + ["de"]="Einheiten", + ["en"]="Units", + ["es"]="Unidades", + ["fi"]="Yksiköt", + ["fr"]="Unités", + ["gr"]="Μονάδες", + ["hr"]="Jedinice", + ["hu"]="Mértékegységek", + ["it"]="Unità", + ["ja"]="ユニッツ", + ["kr"]="측정단위", + ["la"]="Modi", + ["lt"]="Units", + ["nb"]="Enheter", + ["nl"]="Eenheden", + ["nn"]="Einingar", + ["pe"]="واحدها", + ["pl"]="Jednostki", + ["pt"]="Unidades", + ["ro"]="Unități", + ["ru"]="Единицы измерения", + ["sk"]="Jednotky", + ["sl"]="Enote", + ["sv"]="Enheter", + ["tk"]="Birlikler", + ["tr"]="Birimler", + ["ua"]="Одиниці виміру", + ["vi"]="Đơn vị", }, }, - -- - ["editor"] = { - labels = { - en = "editor", - fr = "éditeur", - de = "Herausgeber", - }, - }, - ["editors"] = { - labels = { - en = "editors", - fr = "éditeurs", - de = "Herausgeber", - }, - }, - ["edition"] = { - labels = { - en = "edition", - fr = "édition", - de = "Auflage", - }, - }, - -- - ["volume"] = { - labels = { - en = "volume", - de = "Band", - }, - }, - ["Volume"] = { - labels = { - en = "Volume", - de = "Band", - }, - }, - ["number"] = { - labels = { - en = "number", - fr = "numéro", - de = "Numer", - }, - }, - ["Number"] = { - labels = { - en = "Number", - fr = "Numéro", - de = "Numer", - }, - }, - ["in"] = { - labels = { - en = "in", - fr = "dans", - de = "in", - }, - }, - ["of"] = { - labels = { - en = "of", - fr = "de", - de = "von", - }, - }, - -- - ["In"] = { - labels = { - en = "In", - fr = "Dans", - de = "In", - }, - }, - -- - ["p"] = { - labels = { - en = "p", - de = "S", - }, - }, - ["pp"] = { - labels = { - en = "pp", - de = "S", - }, - }, - ["pages"] = { - labels = { - en = "pages", - de = "Seiten", - }, - }, - -- - ["and"] = { - labels = { - en = "and", - de = "und", - }, - }, - ["others"] = { - labels = { - en = "et al.", - }, - }, - } + }, } local functions = data.labels.functions @@ -2802,3 +3012,5 @@ local functions = data.labels.functions functions.asin = functions.arcsin functions.acos = functions.arccos functions.atan = functions.arctan + +table.save("e:/tmp/x.lua",data.labels) diff --git a/tex/context/base/mkiv/lang-wrd.lua b/tex/context/base/mkiv/lang-wrd.lua index 38e6187af..8b6e48401 100644 --- a/tex/context/base/mkiv/lang-wrd.lua +++ b/tex/context/base/mkiv/lang-wrd.lua @@ -38,6 +38,7 @@ local getid = nuts.getid local getsubtype = nuts.getsubtype local getchar = nuts.getchar local setattr = nuts.setattr +local getlang = nuts.getlang local isglyph = nuts.isglyph local traverse_nodes = nuts.traverse @@ -45,7 +46,7 @@ local traverse_ids = nuts.traverse_id local wordsdata = words.data local chardata = characters.data -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction local unsetvalue = attributes.unsetvalue @@ -161,7 +162,7 @@ local function mark_words(head,whenfound) -- can be optimized and shared while current do local code, id = isglyph(current) if code then - local a = getfield(current,"lang") + local a = getlang(current) if a then if a ~= language then if s > 0 then @@ -234,7 +235,7 @@ function words.enable(settings) if e then e(settings) end - tasks.enableaction("processors","languages.words.check") + enableaction("processors","languages.words.check") enabled = true end diff --git a/tex/context/base/mkiv/layo-ini.lua b/tex/context/base/mkiv/layo-ini.lua index d35d7ef69..bfe33595d 100644 --- a/tex/context/base/mkiv/layo-ini.lua +++ b/tex/context/base/mkiv/layo-ini.lua @@ -18,7 +18,7 @@ layouts = { local status = layouts.status -function status.leftorrightpagection(left,right) +function status.leftorrightpageaction(left,right) if left == nil then left, right = false, true end @@ -41,14 +41,14 @@ function status.leftorrightpagection(left,right) end end -function status.isleftpage() +function status.isleftpage(r) if not conditionals.layoutisdoublesided then return false elseif conditionals.layoutissinglesided then return false elseif texgetcount("pagenoshift") % 2 == 0 then - return texgetcount("realpageno") % 2 == 0 + return (r or texgetcount("realpageno")) % 2 == 0 else - return not texgetcount("realpageno") % 2 == 0 + return not (r or texgetcount("realpageno")) % 2 == 0 end end diff --git a/tex/context/base/mkiv/lpdf-ano.lua b/tex/context/base/mkiv/lpdf-ano.lua index 72800bc64..e89bda12b 100644 --- a/tex/context/base/mkiv/lpdf-ano.lua +++ b/tex/context/base/mkiv/lpdf-ano.lua @@ -25,7 +25,8 @@ local trace_references = false trackers.register("references.references" local trace_destinations = false trackers.register("references.destinations", function(v) trace_destinations = v end) local trace_bookmarks = false trackers.register("references.bookmarks", function(v) trace_bookmarks = v end) -local log_destinations = false directives.register("destinations.log", function(v) log_destinations = v end) +local log_destinations = false directives.register("destinations.log", function(v) log_destinations = v end) +local untex_urls = true directives.register("references.untexurls", function(v) untex_urls = v end) local report_reference = logs.reporter("backend","references") local report_destination = logs.reporter("backend","destinations") @@ -69,8 +70,7 @@ local nodepool = nodes.pool ----- pdfannotation_node = nodepool.pdfannotation ----- pdfdestination_node = nodepool.pdfdestination ------ latelua_node = nodepool.latelua -local latelua_function_node = nodepool.lateluafunction -- still node ... todo +local new_latelua = nodepool.latelua local texgetcount = tex.getcount @@ -229,7 +229,6 @@ luatex.registerstopactions(function() end end) - local function pdfnametree(destinations) local slices = { } local sorted = table.sortedkeys(destinations) @@ -503,7 +502,7 @@ function nodeinjections.destination(width,height,depth,names,view) end end if doview then - return latelua_function_node(function() flushdestination(width,height,depth,names,view) end) + return new_latelua(function() flushdestination(width,height,depth,names,view) end) end end @@ -579,10 +578,15 @@ local function pdffilelink(filename,destination,page,actions) } end +local untex = references.urls.untex + local function pdfurllink(url,destination,page) if not url or url == "" then return false end + if untex_urls then + url = untex(url) -- last minute cleanup of \* and spaces + end if destination and destination ~= "" then url = url .. "#" .. destination end @@ -726,7 +730,7 @@ function nodeinjections.reference(width,height,depth,prerolled) if trace_references then report_reference("link: width %p, height %p, depth %p, prerolled %a",width,height,depth,prerolled) end - return latelua_function_node(function() finishreference(width,height,depth,prerolled) end) + return new_latelua(function() finishreference(width,height,depth,prerolled) end) end end @@ -735,7 +739,7 @@ function nodeinjections.annotation(width,height,depth,prerolled,r) if trace_references then report_reference("special: width %p, height %p, depth %p, prerolled %a",width,height,depth,prerolled) end - return latelua_function_node(function() finishannotation(width,height,depth,prerolled,r or false) end) + return new_latelua(function() finishannotation(width,height,depth,prerolled,r or false) end) end end diff --git a/tex/context/base/mkiv/lpdf-col.lua b/tex/context/base/mkiv/lpdf-col.lua index 877c01a1c..b5973ba88 100644 --- a/tex/context/base/mkiv/lpdf-col.lua +++ b/tex/context/base/mkiv/lpdf-col.lua @@ -8,6 +8,7 @@ if not modules then modules = { } end modules ['lpdf-col'] = { local type, next, tostring, tonumber = type, next, tostring, tonumber local char, byte, format, gsub, rep, gmatch = string.char, string.byte, string.format, string.gsub, string.rep, string.gmatch +local settings_to_array, settings_to_numbers = utilities.parsers.settings_to_array, utilities.parsers.settings_to_numbers local concat = table.concat local round = math.round local formatters = string.formatters @@ -26,7 +27,6 @@ local register = nodepool.register local pdfliteral = nodepool.pdfliteral local pdfconstant = lpdf.constant -local pdfstring = lpdf.string local pdfdictionary = lpdf.dictionary local pdfarray = lpdf.array local pdfreference = lpdf.reference @@ -167,9 +167,9 @@ local pdf_device_cmyk = pdfconstant("DeviceCMYK") local pdf_device_gray = pdfconstant("DeviceGray") local pdf_extgstate = pdfconstant("ExtGState") -local pdf_rbg_range = pdfarray { 0, 1, 0, 1, 0, 1 } -local pdf_cmyk_range = pdfarray { 0, 1, 0, 1, 0, 1, 0, 1 } -local pdf_gray_range = pdfarray { 0, 1 } +local pdf_rgb_range = pdfarray { 0, 1, 0, 1, 0, 1 } +local pdf_cmyk_range = pdfarray { 0, 1, 0, 1, 0, 1, 0, 1 } +local pdf_gray_range = pdfarray { 0, 1 } local f_rgb_function = formatters["dup %s mul exch dup %s mul exch %s mul"] local f_cmyk_function = formatters["dup %s mul exch dup %s mul exch dup %s mul exch %s mul"] @@ -305,13 +305,15 @@ local function registersomeindexcolor(name,noffractions,names,p,colorspace,range noffractions = tonumber(noffractions) or 1 -- to be checked local cnames = pdfarray() local domain = pdfarray() - if names == "" then - names = name .. ",None" - else - names = names .. ",None" - end - for n in gmatch(names,"[^,]+") do - cnames[#cnames+1] = pdfconstant(spotcolornames[n] or n) + local names = settings_to_array(#names == 0 and name or names) + local values = settings_to_numbers(p) + names [#names +1] = "None" + values[#values+1] = 1 + -- check for #names == #values + for i=1,#names do + local name = names[i] + local spot = spotcolornames[name] + cnames[#cnames+1] = pdfconstant(spot ~= "" and spot or name) domain[#domain+1] = 0 domain[#domain+1] = 1 end @@ -327,19 +329,10 @@ local function registersomeindexcolor(name,noffractions,names,p,colorspace,range colorspace, pdfreference(n), } - if p == "" then - p = "1" - else - p = p .. ",1" - end - local pi = { } - for pp in gmatch(p,"[^,]+") do - pi[#pi+1] = tonumber(pp) - end - local vector, set, n = { }, { }, #pi + local vector, set, n = { }, { }, #values for i=255,0,-1 do for j=1,n do - set[j] = format("%02X",round(pi[j]*i)) + set[j] = format("%02X",round(values[j]*i)) end vector[#vector+1] = concat(set) end @@ -357,21 +350,24 @@ local function delayindexcolor(name,names,func) end local function indexcolorref(name) -- actually, names (parent) is the hash - if not indexcolorhash[name] then - local delayedindexcolor = delayedindexcolors[name] + local parent = colors.spotcolorparent(name) + local data = indexcolorhash[name] + if data == nil then + local delayedindexcolor = delayedindexcolors[parent] if type(delayedindexcolor) == "function" then - indexcolorhash[name] = delayedindexcolor() - delayedindexcolors[name] = true + data = delayedindexcolor() + delayedindexcolors[parent] = true end + indexcolorhash[parent] = data or false end - return indexcolorhash[name] + return data end function registrations.rgbspotcolor(name,noffractions,names,p,r,g,b) if noffractions == 1 then - registersomespotcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rbg_range,f_rgb_function(r,g,b)) + registersomespotcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rgb_range,f_rgb_function(r,g,b)) else - registersomespotcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rbg_range,f_num_3(r,g,b)) + registersomespotcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rgb_range,f_num_3(r,g,b)) end delayindexcolor(name,names,function() return registersomeindexcolor(name,noffractions,names,p,pdf_device_rgb,pdf_rgb_range,f_rgb_function(r,g,b)) @@ -414,7 +410,7 @@ end function codeinjections.setfigurecolorspace(data,figure) local color = data.request.color - if color then + if color then -- != v_default local ref = indexcolorref(color) if ref then figure.colorspace = ref @@ -425,7 +421,7 @@ end -- transparency -local transparencies = { [0] = +local pdftransparencies = { [0] = pdfconstant("Normal"), pdfconstant("Normal"), pdfconstant("Multiply"), @@ -457,7 +453,7 @@ function registrations.transparency(n,a,t) Type = pdf_extgstate, ca = 1, CA = 1, - BM = transparencies[1], + BM = pdftransparencies[1], AIS = false, } local m = pdfflushobject(d) @@ -472,7 +468,7 @@ function registrations.transparency(n,a,t) Type = pdf_extgstate, ca = tonumber(t), CA = tonumber(t), - BM = transparencies[tonumber(a)] or transparencies[0], + BM = pdftransparencies[tonumber(a)] or pdftransparencies[0], AIS = false, } local m = pdfflushobject(d) diff --git a/tex/context/base/mkiv/lpdf-fld.lua b/tex/context/base/mkiv/lpdf-fld.lua index 75d0ba98e..bbafb299b 100644 --- a/tex/context/base/mkiv/lpdf-fld.lua +++ b/tex/context/base/mkiv/lpdf-fld.lua @@ -58,9 +58,8 @@ if not modules then modules = { } end modules ['lpdf-fld'] = { local tostring, next = tostring, next local gmatch, lower, format, formatters = string.gmatch, string.lower, string.format, string.formatters local lpegmatch = lpeg.match -local utfchar = utf.char local bpfactor, todimen = number.dimenfactors.bp, string.todimen - +local sortedhash = table.sortedhash local trace_fields = false trackers.register("backends.fields", function(v) trace_fields = v end) local report_fields = logs.reporter("backend","fields") @@ -88,7 +87,6 @@ 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 pdfshareobjectreference = lpdf.shareobjectreference local pdfshareobject = lpdf.shareobject @@ -249,7 +247,7 @@ local mapping = { local function fieldactions(specification) -- share actions local d = nil - for key, target in next, mapping do + for key, target in sortedhash(mapping) do -- sort so that we can compare pdf local code = specification[key] if code and code ~= "" then -- local a = checked(code) @@ -367,7 +365,8 @@ local function registerfonts() checkpdfdocencoding() -- already done local d = pdfdictionary() local pdffonttype, pdffontsubtype = pdfconstant("Font"), pdfconstant("Type1") - for tag, name in next, usedfonts do + -- for tag, name in next, usedfonts do + for tag, name in sortedhash(usedfonts) do local f = pdfdictionary { Type = pdffonttype, Subtype = pdffontsubtype, @@ -655,7 +654,7 @@ local xfdftemplate = [[ function codeinjections.exportformdata(name) local result = { } - for k, v in table.sortedhash(fields) do + for k, v in sortedhash(fields) do result[#result+1] = formatters[" <field name='%s'><value>%s</value></field>"](v.name or k,v.default or "") end local base = file.basename(tex.jobname) @@ -880,7 +879,7 @@ local forceencoding = false local function finishfields() local sometext = forceencoding - for name, field in next, fields do + for name, field in sortedhash(fields) do local kids = field.kids if kids then pdfflushobject(field.kidsnum,kids) @@ -894,7 +893,7 @@ local function finishfields() sometext = true end end - for name, field in next, radios do + for name, field in sortedhash(radios) do local kids = field.kids if kids then pdfflushobject(field.kidsnum,kids) diff --git a/tex/context/base/mkiv/lpdf-fmt.lua b/tex/context/base/mkiv/lpdf-fmt.lua index b1d9a4b0c..8bbd3374f 100644 --- a/tex/context/base/mkiv/lpdf-fmt.lua +++ b/tex/context/base/mkiv/lpdf-fmt.lua @@ -11,7 +11,7 @@ if not modules then modules = { } end modules ['lpdf-fmt'] = { -- context --directives="backend.format=PDF/X-1a:2001" --trackers=backend.format yourfile local lower, gmatch, format, find = string.lower, string.gmatch, string.format, string.find -local concat, serialize = table.concat, table.serialize +local concat, serialize, sortedhash = table.concat, table.serialize, table.sortedhash local trace_format = false trackers.register("backend.format", function(v) trace_format = v end) local trace_variables = false trackers.register("backend.variables", function(v) trace_variables = v end) @@ -85,7 +85,7 @@ local formatspecification, formatname = nil, nil -- * correspondent document wide flags (write once) needed for permission tests local formats = utilities.storage.allocate { - ["version"] = { + version = { external_icc_profiles = 1.4, -- 'p' in name; URL reference of output intent jbig2_compression = 1.4, jpeg2000_compression = 1.5, -- not supported yet @@ -95,7 +95,7 @@ local formats = utilities.storage.allocate { transparency = 1.4, object_compression = 1.5, }, - ["default"] = { + default = { pdf_version = 1.7, -- todo: block tex primitive format_name = "default", xmp_file = "lpdf-pdx.xml", @@ -114,298 +114,315 @@ local formats = utilities.storage.allocate { transparency = true, -- todo: block at lua level jbig2_compression = true, -- todo: block at lua level jpeg2000_compression = true, -- todo: block at lua level + include_cidsets = true, inject_metadata = function() -- nothing end }, - ["pdf/x-1a:2001"] = { - pdf_version = 1.3, - format_name = "PDF/X-1a:2001", - xmp_file = "lpdf-pdx.xml", - gts_flag = "GTS_PDFX", - gray_scale = true, - cmyk_colors = true, - spot_colors = true, - internal_icc_profiles = true, - inject_metadata = function() - addtoinfo("GTS_PDFXVersion","PDF/X-1a:2001") - injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-1a:2001</pdfxid:GTS_PDFXVersion></rdf:Description>",false) - end - }, - ["pdf/x-1a:2003"] = { - pdf_version = 1.4, - format_name = "PDF/X-1a:2003", - xmp_file = "lpdf-pdx.xml", - gts_flag = "GTS_PDFX", - gray_scale = true, - cmyk_colors = true, - spot_colors = true, - internal_icc_profiles = true, - inject_metadata = function() - addtoinfo("GTS_PDFXVersion","PDF/X-1a:2003") - injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-1a:2003</pdfxid:GTS_PDFXVersion></rdf:Description>",false) - end - }, - ["pdf/x-3:2002"] = { - pdf_version = 1.3, - format_name = "PDF/X-3:2002", - xmp_file = "lpdf-pdx.xml", - gts_flag = "GTS_PDFX", - gray_scale = true, - cmyk_colors = true, - rgb_colors = true, - calibrated_rgb_colors = true, - spot_colors = true, - cielab_colors = true, - internal_icc_profiles = true, - include_intents = true, - inject_metadata = function() - addtoinfo("GTS_PDFXVersion","PDF/X-3:2002") - end - }, - ["pdf/x-3:2003"] = { - pdf_version = 1.4, - format_name = "PDF/X-3:2003", - xmp_file = "lpdf-pdx.xml", - gts_flag = "GTS_PDFX", - gray_scale = true, - cmyk_colors = true, - rgb_colors = true, - calibrated_rgb_colors = true, - spot_colors = true, - cielab_colors = true, - internal_icc_profiles = true, - include_intents = true, - jbig2_compression = true, - inject_metadata = function() - addtoinfo("GTS_PDFXVersion","PDF/X-3:2003") - end - }, - ["pdf/x-4"] = { - pdf_version = 1.6, - format_name = "PDF/X-4", - xmp_file = "lpdf-pdx.xml", - gts_flag = "GTS_PDFX", - gray_scale = true, - cmyk_colors = true, - rgb_colors = true, - calibrated_rgb_colors = true, - spot_colors = true, - cielab_colors = true, - internal_icc_profiles = true, - include_intents = true, - optional_content = true, - transparency = true, - jbig2_compression = true, - jpeg2000_compression = true, - object_compression = true, - inject_metadata = function() - injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-4</pdfxid:GTS_PDFXVersion></rdf:Description>",false) - insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:VersionID>1</xmpMM:VersionID>",false) - insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:RenditionClass>default</xmpMM:RenditionClass>",false) - end - }, - ["pdf/x-4p"] = { - pdf_version = 1.6, - format_name = "PDF/X-4p", - xmp_file = "lpdf-pdx.xml", - gts_flag = "GTS_PDFX", - gray_scale = true, - cmyk_colors = true, - rgb_colors = true, - calibrated_rgb_colors = true, - spot_colors = true, - cielab_colors = true, - internal_icc_profiles = true, - external_icc_profiles = true, - include_intents = true, - optional_content = true, - transparency = true, - jbig2_compression = true, - jpeg2000_compression = true, - object_compression = true, - inject_metadata = function() - injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-4p</pdfxid:GTS_PDFXVersion></rdf:Description>",false) - insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:VersionID>1</xmpMM:VersionID>",false) - insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:RenditionClass>default</xmpMM:RenditionClass>",false) - end - }, - ["pdf/x-5g"] = { - pdf_version = 1.6, - format_name = "PDF/X-5g", - xmp_file = "lpdf-pdx.xml", - gts_flag = "GTS_PDFX", - gray_scale = true, - cmyk_colors = true, - rgb_colors = true, - calibrated_rgb_colors = true, - spot_colors = true, - cielab_colors = true, - internal_icc_profiles = true, - include_intents = true, - open_prepress_interface = true, - optional_content = true, - transparency = true, - jbig2_compression = true, - jpeg2000_compression = true, - object_compression = true, - inject_metadata = function() - -- todo - end - }, - ["pdf/x-5pg"] = { - pdf_version = 1.6, - format_name = "PDF/X-5pg", - xmp_file = "lpdf-pdx.xml", - gts_flag = "GTS_PDFX", - gray_scale = true, - cmyk_colors = true, - rgb_colors = true, - calibrated_rgb_colors = true, - spot_colors = true, - cielab_colors = true, - internal_icc_profiles = true, - external_icc_profiles = true, - include_intents = true, - open_prepress_interface = true, - optional_content = true, - transparency = true, - jbig2_compression = true, - jpeg2000_compression = true, - object_compression = true, - inject_metadata = function() - -- todo - end - }, - ["pdf/x-5n"] = { - pdf_version = 1.6, - format_name = "PDF/X-5n", - xmp_file = "lpdf-pdx.xml", - gts_flag = "GTS_PDFX", - gray_scale = true, - cmyk_colors = true, - rgb_colors = true, - calibrated_rgb_colors = true, - spot_colors = true, - cielab_colors = true, - internal_icc_profiles = true, - include_intents = true, - optional_content = true, - transparency = true, - jbig2_compression = true, - jpeg2000_compression = true, - nchannel_colorspace = true, - object_compression = true, - inject_metadata = function() - -- todo - end - }, - ["pdf/a-1a:2005"] = { - pdf_version = 1.4, - format_name = "pdf/a-1a:2005", - xmp_file = "lpdf-pda.xml", - gts_flag = "GTS_PDFA1", - gray_scale = true, - cmyk_colors = true, - rgb_colors = true, - spot_colors = true, - calibrated_rgb_colors = true, -- unknown - cielab_colors = true, -- unknown - include_intents = true, - forms = true, -- NEW; forms are allowed (with limitations); no JS, other restrictions are unknown (TODO) - tagging = true, -- NEW; the only difference to PDF/A-1b - internal_icc_profiles = true, - inject_metadata = function() - injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/'><pdfaid:part>1</pdfaid:part><pdfaid:conformance>A</pdfaid:conformance></rdf:Description>",false) - end - }, - ["pdf/a-1b:2005"] = { - pdf_version = 1.4, - format_name = "pdf/a-1b:2005", - xmp_file = "lpdf-pda.xml", - gts_flag = "GTS_PDFA1", - gray_scale = true, - cmyk_colors = true, - rgb_colors = true, - spot_colors = true, - calibrated_rgb_colors = true, -- unknown - cielab_colors = true, -- unknown - include_intents = true, - forms = true, - internal_icc_profiles = true, - inject_metadata = function() - injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/'><pdfaid:part>1</pdfaid:part><pdfaid:conformance>B</pdfaid:conformance></rdf:Description>",false) - end - }, - ["pdf/a-2a"] = { -- untested; only PDF/A Attachments are allowed - pdf_version = 1.7, - format_name = "pdf/a-2a", - xmp_file = "lpdf-pda.xml", - gts_flag = "GTS_PDFA2", - gray_scale = true, - cmyk_colors = true, - rgb_colors = true, - spot_colors = true, - calibrated_rgb_colors = true, -- unknown - cielab_colors = true, -- unknown - include_intents = true, - forms = true, - tagging = true, - internal_icc_profiles = true, - transparency = true, -- NEW - jbig2_compression = true, - jpeg2000_compression = true, -- NEW - object_compression = true, - inject_metadata = function() - injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/'><pdfaid:part>2</pdfaid:part><pdfaid:conformance>A</pdfaid:conformance></rdf:Description>",false) - end - }, - ["pdf/a-3a"] = { -- untested; NEW: any type of attachment is allowed - pdf_version = 1.7, - format_name = "pdf/a-3a", - xmp_file = "lpdf-pda.xml", - gts_flag = "GTS_PDFA3", - gray_scale = true, - cmyk_colors = true, - rgb_colors = true, - spot_colors = true, - calibrated_rgb_colors = true, -- unknown - cielab_colors = true, -- unknown - include_intents = true, - forms = true, - tagging = true, - internal_icc_profiles = true, - transparency = true, - jbig2_compression = true, - jpeg2000_compression = true, - object_compression = true, - inject_metadata = function() - injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/'><pdfaid:part>3</pdfaid:part><pdfaid:conformance>A</pdfaid:conformance></rdf:Description>",false) - end - }, - ["pdf/ua-1"] = { -- based on PDF/A-3a, but no 'gts_flag' - pdf_version = 1.7, - format_name = "pdf/ua-1", - xmp_file = "lpdf-pua.xml", - gray_scale = true, - cmyk_colors = true, - rgb_colors = true, - spot_colors = true, - calibrated_rgb_colors = true, -- unknown - cielab_colors = true, -- unknown - include_intents = true, - forms = true, - tagging = true, - internal_icc_profiles = true, - transparency = true, - jbig2_compression = true, - jpeg2000_compression = true, - object_compression = true, - inject_metadata = function() - injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/'><pdfaid:part>3</pdfaid:part><pdfaid:conformance>A</pdfaid:conformance></rdf:Description>",false) - injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfuaid='http://www.aiim.org/pdfua/ns/id/'><pdfuaid:part>1</pdfuaid:part></rdf:Description>",false) - end - }, + data = { + ["pdf/x-1a:2001"] = { + pdf_version = 1.3, + format_name = "PDF/X-1a:2001", + xmp_file = "lpdf-pdx.xml", + gts_flag = "GTS_PDFX", + gray_scale = true, + cmyk_colors = true, + spot_colors = true, + internal_icc_profiles = true, + include_cidsets = true, + inject_metadata = function() + addtoinfo("GTS_PDFXVersion","PDF/X-1a:2001") + injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-1a:2001</pdfxid:GTS_PDFXVersion></rdf:Description>",false) + end + }, + ["pdf/x-1a:2003"] = { + pdf_version = 1.4, + format_name = "PDF/X-1a:2003", + xmp_file = "lpdf-pdx.xml", + gts_flag = "GTS_PDFX", + gray_scale = true, + cmyk_colors = true, + spot_colors = true, + internal_icc_profiles = true, + include_cidsets = true, + inject_metadata = function() + addtoinfo("GTS_PDFXVersion","PDF/X-1a:2003") + injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-1a:2003</pdfxid:GTS_PDFXVersion></rdf:Description>",false) + end + }, + ["pdf/x-3:2002"] = { + pdf_version = 1.3, + format_name = "PDF/X-3:2002", + xmp_file = "lpdf-pdx.xml", + gts_flag = "GTS_PDFX", + gray_scale = true, + cmyk_colors = true, + rgb_colors = true, + calibrated_rgb_colors = true, + spot_colors = true, + cielab_colors = true, + internal_icc_profiles = true, + include_intents = true, + include_cidsets = true, + inject_metadata = function() + addtoinfo("GTS_PDFXVersion","PDF/X-3:2002") + end + }, + ["pdf/x-3:2003"] = { + pdf_version = 1.4, + format_name = "PDF/X-3:2003", + xmp_file = "lpdf-pdx.xml", + gts_flag = "GTS_PDFX", + gray_scale = true, + cmyk_colors = true, + rgb_colors = true, + calibrated_rgb_colors = true, + spot_colors = true, + cielab_colors = true, + internal_icc_profiles = true, + include_intents = true, + jbig2_compression = true, + include_cidsets = true, + inject_metadata = function() + addtoinfo("GTS_PDFXVersion","PDF/X-3:2003") + end + }, + ["pdf/x-4"] = { + pdf_version = 1.6, + format_name = "PDF/X-4", + xmp_file = "lpdf-pdx.xml", + gts_flag = "GTS_PDFX", + gray_scale = true, + cmyk_colors = true, + rgb_colors = true, + calibrated_rgb_colors = true, + spot_colors = true, + cielab_colors = true, + internal_icc_profiles = true, + include_intents = true, + optional_content = true, + transparency = true, + jbig2_compression = true, + jpeg2000_compression = true, + object_compression = true, + include_cidsets = true, + inject_metadata = function() + injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-4</pdfxid:GTS_PDFXVersion></rdf:Description>",false) + insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:VersionID>1</xmpMM:VersionID>",false) + insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:RenditionClass>default</xmpMM:RenditionClass>",false) + end + }, + ["pdf/x-4p"] = { + pdf_version = 1.6, + format_name = "PDF/X-4p", + xmp_file = "lpdf-pdx.xml", + gts_flag = "GTS_PDFX", + gray_scale = true, + cmyk_colors = true, + rgb_colors = true, + calibrated_rgb_colors = true, + spot_colors = true, + cielab_colors = true, + internal_icc_profiles = true, + external_icc_profiles = true, + include_intents = true, + optional_content = true, + transparency = true, + jbig2_compression = true, + jpeg2000_compression = true, + object_compression = true, + include_cidsets = true, + inject_metadata = function() + injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-4p</pdfxid:GTS_PDFXVersion></rdf:Description>",false) + insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:VersionID>1</xmpMM:VersionID>",false) + insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:RenditionClass>default</xmpMM:RenditionClass>",false) + end + }, + ["pdf/x-5g"] = { + pdf_version = 1.6, + format_name = "PDF/X-5g", + xmp_file = "lpdf-pdx.xml", + gts_flag = "GTS_PDFX", + gray_scale = true, + cmyk_colors = true, + rgb_colors = true, + calibrated_rgb_colors = true, + spot_colors = true, + cielab_colors = true, + internal_icc_profiles = true, + include_intents = true, + open_prepress_interface = true, + optional_content = true, + transparency = true, + jbig2_compression = true, + jpeg2000_compression = true, + object_compression = true, + include_cidsets = true, + inject_metadata = function() + -- todo + end + }, + ["pdf/x-5pg"] = { + pdf_version = 1.6, + format_name = "PDF/X-5pg", + xmp_file = "lpdf-pdx.xml", + gts_flag = "GTS_PDFX", + gray_scale = true, + cmyk_colors = true, + rgb_colors = true, + calibrated_rgb_colors = true, + spot_colors = true, + cielab_colors = true, + internal_icc_profiles = true, + external_icc_profiles = true, + include_intents = true, + open_prepress_interface = true, + optional_content = true, + transparency = true, + jbig2_compression = true, + jpeg2000_compression = true, + object_compression = true, + include_cidsets = true, + inject_metadata = function() + -- todo + end + }, + ["pdf/x-5n"] = { + pdf_version = 1.6, + format_name = "PDF/X-5n", + xmp_file = "lpdf-pdx.xml", + gts_flag = "GTS_PDFX", + gray_scale = true, + cmyk_colors = true, + rgb_colors = true, + calibrated_rgb_colors = true, + spot_colors = true, + cielab_colors = true, + internal_icc_profiles = true, + include_intents = true, + optional_content = true, + transparency = true, + jbig2_compression = true, + jpeg2000_compression = true, + nchannel_colorspace = true, + object_compression = true, + include_cidsets = true, + inject_metadata = function() + -- todo + end + }, + ["pdf/a-1a:2005"] = { + pdf_version = 1.4, + format_name = "pdf/a-1a:2005", + xmp_file = "lpdf-pda.xml", + gts_flag = "GTS_PDFA1", + gray_scale = true, + cmyk_colors = true, + rgb_colors = true, + spot_colors = true, + calibrated_rgb_colors = true, -- unknown + cielab_colors = true, -- unknown + include_intents = true, + forms = true, -- NEW; forms are allowed (with limitations); no JS, other restrictions are unknown (TODO) + tagging = true, -- NEW; the only difference to PDF/A-1b + internal_icc_profiles = true, + include_cidsets = true, + inject_metadata = function() + injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/'><pdfaid:part>1</pdfaid:part><pdfaid:conformance>A</pdfaid:conformance></rdf:Description>",false) + end + }, + ["pdf/a-1b:2005"] = { + pdf_version = 1.4, + format_name = "pdf/a-1b:2005", + xmp_file = "lpdf-pda.xml", + gts_flag = "GTS_PDFA1", + gray_scale = true, + cmyk_colors = true, + rgb_colors = true, + spot_colors = true, + calibrated_rgb_colors = true, -- unknown + cielab_colors = true, -- unknown + include_intents = true, + forms = true, + internal_icc_profiles = true, + include_cidsets = true, + inject_metadata = function() + injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/'><pdfaid:part>1</pdfaid:part><pdfaid:conformance>B</pdfaid:conformance></rdf:Description>",false) + end + }, + ["pdf/a-2a"] = { -- untested; only PDF/A Attachments are allowed + pdf_version = 1.7, + format_name = "pdf/a-2a", + xmp_file = "lpdf-pda.xml", + gts_flag = "GTS_PDFA2", + gray_scale = true, + cmyk_colors = true, + rgb_colors = true, + spot_colors = true, + calibrated_rgb_colors = true, -- unknown + cielab_colors = true, -- unknown + include_intents = true, + forms = true, + tagging = true, + internal_icc_profiles = true, + transparency = true, -- NEW + jbig2_compression = true, + jpeg2000_compression = true, -- NEW + object_compression = true, + include_cidsets = false, + inject_metadata = function() + injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/'><pdfaid:part>2</pdfaid:part><pdfaid:conformance>A</pdfaid:conformance></rdf:Description>",false) + end + }, + ["pdf/a-3a"] = { -- untested; NEW: any type of attachment is allowed + pdf_version = 1.7, + format_name = "pdf/a-3a", + xmp_file = "lpdf-pda.xml", + gts_flag = "GTS_PDFA3", + gray_scale = true, + cmyk_colors = true, + rgb_colors = true, + spot_colors = true, + calibrated_rgb_colors = true, -- unknown + cielab_colors = true, -- unknown + include_intents = true, + forms = true, + tagging = true, + internal_icc_profiles = true, + transparency = true, + jbig2_compression = true, + jpeg2000_compression = true, + object_compression = true, + include_cidsets = false, + inject_metadata = function() + injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/'><pdfaid:part>3</pdfaid:part><pdfaid:conformance>A</pdfaid:conformance></rdf:Description>",false) + end + }, + ["pdf/ua-1"] = { -- based on PDF/A-3a, but no 'gts_flag' + pdf_version = 1.7, + format_name = "pdf/ua-1", + xmp_file = "lpdf-pua.xml", + gray_scale = true, + cmyk_colors = true, + rgb_colors = true, + spot_colors = true, + calibrated_rgb_colors = true, -- unknown + cielab_colors = true, -- unknown + include_intents = true, + forms = true, + tagging = true, + internal_icc_profiles = true, + transparency = true, + jbig2_compression = true, + jpeg2000_compression = true, + object_compression = true, + include_cidsets = true, + inject_metadata = function() + injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/'><pdfaid:part>3</pdfaid:part><pdfaid:conformance>A</pdfaid:conformance></rdf:Description>",false) + injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfuaid='http://www.aiim.org/pdfua/ns/id/'><pdfuaid:part>1</pdfuaid:part></rdf:Description>",false) + end + }, + } } lpdf.formats = formats -- it does not hurt to have this one visible @@ -701,7 +718,7 @@ function codeinjections.setformat(s) local option = s.option or "" local filename = s.file or "" if format ~= "" then - local spec = formats[lower(format)] + local spec = formats.data[lower(format)] if spec then formatspecification = spec formatname = spec.format_name @@ -736,6 +753,9 @@ function codeinjections.setformat(s) report_backend("forcing pdf version %s.%s, compression disabled", majorversion,minorversion) end + if pdf.setomitcidset then + pdf.setomitcidset(formatspecification.include_cidsets == false and 1 or 0) + end -- -- context.setupcolors { -- not this way -- cmyk = spec.cmyk_colors and variables.yes or variables.no, @@ -769,7 +789,7 @@ function codeinjections.setformat(s) handleiccprofile("color profile",spec,profile,filename,handledefaultprofile,options,true) handleiccprofile("output intent",spec,intent,filename,handleoutputintent,options,false) if trace_variables then - for k, v in table.sortedhash(formats.default) do + for k, v in sortedhash(formats.default) do local v = formatspecification[k] if type(v) ~= "function" then report_backend("%a = %a",k,v or false) @@ -813,30 +833,28 @@ end function codeinjections.supportedformats() local t = { } - for k, v in table.sortedhash(formats) do - if find(k,"pdf",1,true) then - t[#t+1] = k - end + for k, v in sortedhash(formats.data) do + t[#t+1] = k end return t 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 = handledefaultprofile ---~ ---~ local function flushembeddedprofiles() ---~ for colorspace, filename in next, defaults do ---~ embedprofile(colorspace,filename) ---~ end ---~ end ---~ ---~ local function handledefaultprofile(s) ---~ defaults[lower(s.colorspace)] = s.filename ---~ end ---~ ---~ lpdf.registerdocumentfinalizer(flushembeddedprofiles,1,"embedded color profiles") +-- 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 = handledefaultprofile +-- +-- local function flushembeddedprofiles() +-- for colorspace, filename in next, defaults do +-- embedprofile(colorspace,filename) +-- end +-- end +-- +-- local function handledefaultprofile(s) +-- defaults[lower(s.colorspace)] = s.filename +-- end +-- +-- lpdf.registerdocumentfinalizer(flushembeddedprofiles,1,"embedded color profiles") diff --git a/tex/context/base/mkiv/lpdf-grp.lua b/tex/context/base/mkiv/lpdf-grp.lua index 0eac52dfb..1ebc9b23d 100644 --- a/tex/context/base/mkiv/lpdf-grp.lua +++ b/tex/context/base/mkiv/lpdf-grp.lua @@ -16,8 +16,7 @@ local backends, lpdf = backends, lpdf local nodeinjections = backends.pdf.nodeinjections local colors = attributes.colors -local basepoints = number.dimenfactors["bp"] -local inches = number.dimenfactors["in"] +local basepoints = number.dimenfactors.bp local nodeinjections = backends.pdf.nodeinjections local codeinjections = backends.pdf.codeinjections @@ -36,46 +35,31 @@ local pdfflushobject = lpdf.flushobject -- 22 : << /Bounds [ ] /Domain [ 0.0 1.0 ] /Encode [ 0.0 1.0 ] /FunctionType 3 /Functions [ 31 0 R ] >> -- 31 : << /C0 [ 1.0 0.0 ] /C1 [ 0.0 1.0 ] /Domain [ 0.0 1.0 ] /FunctionType 2 /N 1.0 >> -local function shade(stype,name,domain,color_a,color_b,n,colorspace,coordinates,separation,steps) - if steps then - color_a = color_a[1] - color_b = color_b[1] - end - local f = pdfdictionary { - FunctionType = 2, - Domain = pdfarray(domain), -- domain is actually a string - C0 = pdfarray(color_a), - C1 = pdfarray(color_b), - N = tonumber(n), - } - separation = separation and registrations.getspotcolorreference(separation) - local s = pdfdictionary { - ShadingType = stype, - ColorSpace = separation and pdfreference(separation) or pdfconstant(colorspace), - Function = pdfreference(pdfflushobject(f)), - Coords = pdfarray(coordinates), - Extend = pdfarray { true, true }, - AntiAlias = pdfboolean(true), - } - lpdf.adddocumentshade(name,pdfreference(pdfflushobject(s))) -end - local function shade(stype,name,domain,color_a,color_b,n,colorspace,coordinates,separation,steps,fractions) local func = nil + -- + -- domain has to be consistently added in all dictionaries here otherwise + -- acrobat fails with a drawing error + -- + domain = pdfarray(domain) + n = tonumber(n) + -- if steps then local list = pdfarray() local bounds = pdfarray() local encode = pdfarray() for i=1,steps do - bounds[i] = fractions[i] or 1 + if i < steps then + bounds[i] = fractions[i] or 1 + end encode[2*i-1] = 0 encode[2*i] = 1 list [i] = pdfdictionary { FunctionType = 2, - Domain = pdfarray(domain), -- domain is actually a string + Domain = domain, C0 = pdfarray(color_a[i]), C1 = pdfarray(color_b[i]), - N = tonumber(n), + N = n, } end func = pdfdictionary { @@ -83,21 +67,22 @@ local function shade(stype,name,domain,color_a,color_b,n,colorspace,coordinates, Bounds = bounds, Encode = encode, Functions = list, - Domain = pdfarray(domain), -- domain is actually a string + Domain = domain, } else func = pdfdictionary { FunctionType = 2, - Domain = pdfarray(domain), -- domain is actually a string + Domain = domain, C0 = pdfarray(color_a), C1 = pdfarray(color_b), - N = tonumber(n), + N = n, } end separation = separation and registrations.getspotcolorreference(separation) local s = pdfdictionary { ShadingType = stype, ColorSpace = separation and pdfreference(separation) or pdfconstant(colorspace), + Domain = domain, Function = pdfreference(pdfflushobject(func)), Coords = pdfarray(coordinates), Extend = pdfarray { true, true }, @@ -267,8 +252,6 @@ end -- temp hack -local factor = number.dimenfactors.bp - function img.package(image) -- see lpdf-u3d ** local boundingbox = image.bbox local imagetag = "Im" .. image.index @@ -288,8 +271,42 @@ function img.package(image) -- see lpdf-u3d ** local xform = img.scan { attr = resources(), stream = formatters["%F 0 0 %F 0 0 cm /%s Do"](width,height,imagetag), - bbox = { 0, 0, width/factor, height/factor }, + bbox = { 0, 0, width/basepoints, height/basepoints }, } img.immediatewrite(xform) return xform end + +-- experimental + +local nofpatterns = 0 +local f_pattern = formatters["q /Pattern cs /%s scn 0 0 %F %F re f Q"] -- q Q is not really needed + +local texsavebox = tex.saveboxresource + +function lpdf.registerpattern(specification) + nofpatterns = nofpatterns + 1 + local d = pdfdictionary { + Type = pdfconstant("Pattern"), + PatternType = 1, + PaintType = 1, + TilingType = 2, + XStep = (specification.width or 10) * basepoints, + YStep = (specification.height or 10) * basepoints, + Matrix = { + 1, 0, 0, 1, + (specification.hoffset or 0) * basepoints, + (specification.voffset or 0) * basepoints, + }, + } + local resources = lpdf.collectedresources{ patterns = false } + local attributes = d() + local onlybounds = 1 + local patternobj = texsavebox(specification.number,attributes,resources,true,onlybounds) + lpdf.adddocumentpattern("Pt" .. nofpatterns,lpdf.reference(patternobj )) + return nofpatterns +end + +function lpdf.patternstream(n,width,height) + return f_pattern("Pt" .. n,width*basepoints,height*basepoints) +end diff --git a/tex/context/base/mkiv/lpdf-ini.lua b/tex/context/base/mkiv/lpdf-ini.lua index f0b919d4e..1b24269a6 100644 --- a/tex/context/base/mkiv/lpdf-ini.lua +++ b/tex/context/base/mkiv/lpdf-ini.lua @@ -78,8 +78,8 @@ end local pdfsetinfo = pdf.setinfo local pdfsetcatalog = pdf.setcatalog -local pdfsetnames = pdf.setnames -local pdfsettrailer = pdf.settrailer +----- pdfsetnames = pdf.setnames +----- pdfsettrailer = pdf.settrailer local pdfsetpageresources = pdf.setpageresources local pdfsetpageattributes = pdf.setpageattributes @@ -312,59 +312,8 @@ local f_array = formatters["[ % t ]"] local f_key_number = formatters["/%s %F"] local f_tonumber = formatters["%F"] --- local f_key_value = formatters["/%s %s"] --- local f_key_dictionary = formatters["/%s <<% t>>"] --- local f_dictionary = formatters["<<% t>>"] --- local f_key_array = formatters["/%s [% t]"] --- local f_array = formatters["[% t]"] - local tostring_a, tostring_d --- tostring_d = function(t,contentonly,key) --- if next(t) then --- local r, rn = { }, 0 --- for k, v in next, t do --- -- for k, v in sortedhash(t) do -- can be an option --- rn = rn + 1 --- local tv = type(v) --- if tv == "string" then --- r[rn] = f_key_value(k,toeight(v)) --- elseif tv == "number" then --- r[rn] = f_key_number(k,v) --- -- elseif tv == "unicode" then -- can't happen --- -- r[rn] = f_key_value(k,tosixteen(v)) --- elseif tv == "table" then --- local mv = getmetatable(v) --- if mv and mv.__lpdftype then --- -- if v == t then --- -- report_objects("ignoring circular reference in dirctionary") --- -- r[rn] = f_key_null(k) --- -- else --- r[rn] = f_key_value(k,tostring(v)) --- -- end --- elseif v[1] then --- r[rn] = f_key_value(k,tostring_a(v)) --- else --- r[rn] = f_key_value(k,tostring_d(v)) --- end --- else --- r[rn] = f_key_value(k,tostring(v)) --- end --- end --- if contentonly then --- return concat(r," ") --- elseif key then --- return f_key_dictionary(key,r) --- else --- return f_dictionary(r) --- end --- elseif contentonly then --- return "" --- else --- return "<< >>" --- end --- end - tostring_d = function(t,contentonly,key) if next(t) then local r, n = { }, 0 @@ -514,8 +463,15 @@ local mt_v = { __lpdftype = "verbose", __tostring = tostring_v, __call = valu local function pdfstream(t) -- we need to add attributes if t then - for i=1,#t do - t[i] = tostring(t[i]) + local tt = type(t) + if tt == "table" then + for i=1,#t do + t[i] = tostring(t[i]) + end + elseif tt == "string" then + t= { t } + else + t= { tostring(t) } end end return setmetatable(t or { },mt_x) @@ -1002,11 +958,20 @@ do 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 - function lpdf.collectedresources() + -- patterns are special as they need resources to so we can get recursive references and in that case + -- acrobat doesn't show anything (other viewers handle it well) + -- + -- todo: share them + -- todo: force when not yet set + + function lpdf.collectedresources(options) local ExtGState = next(d_extgstates ) and p_extgstates local ColorSpace = next(d_colorspaces) and p_colorspaces local Pattern = next(d_patterns ) and p_patterns local Shading = next(d_shades ) and p_shades + if options and options.patterns == false then + Pattern = nil + end if ExtGState or ColorSpace or Pattern or Shading then local collected = pdfdictionary { ExtGState = ExtGState, @@ -1053,7 +1018,7 @@ end do - local timestamp = os.date("%Y-%m-%dT%X") .. os.timezone(true) + local timestamp = backends.timestamp() function lpdf.timestamp() return timestamp @@ -1064,7 +1029,7 @@ do n = converters.totime(n) if n then converters.settime(n) - timestamp = os.date("%Y-%m-%dT%X",os.time(n)) .. os.timezone(true) + timestamp = backends.timestamp() end end return timestamp @@ -1223,12 +1188,17 @@ end do - local f_actual_text_one = formatters["BT /Span << /ActualText <feff%04x> >> BDC [<feff>] TJ %s EMC ET"] - local f_actual_text_one_b = formatters["BT /Span << /ActualText <feff%04x> >> BDC [<feff>] TJ "] - local f_actual_text_two = formatters["BT /Span << /ActualText <feff%04x%04x> >> BDC [<feff>] TJ %s EMC ET"] - local f_actual_text_two_b = formatters["BT /Span << /ActualText <feff%04x%04x> >> BDC [<feff>] TJ "] - local s_actual_text_e = " EMC ET" - local f_actual_text = formatters["/Span <</ActualText %s >> BDC"] + local f_actual_text_one = formatters["BT /Span << /ActualText <feff%04x> >> BDC %s EMC ET"] + local f_actual_text_two = formatters["BT /Span << /ActualText <feff%04x%04x> >> BDC %s EMC ET"] + local f_actual_text_one_b = formatters["BT /Span << /ActualText <feff%04x> >> BDC"] + local f_actual_text_two_b = formatters["BT /Span << /ActualText <feff%04x%04x> >> BDC"] + local f_actual_text_b = formatters["BT /Span << /ActualText <feff%s> >> BDC"] + local s_actual_text_e = "EMC ET" + local f_actual_text_b_not = formatters["/Span << /ActualText <feff%s> >> BDC"] + local f_actual_text_one_b_not = formatters["/Span << /ActualText <feff%04x> >> BDC"] + local f_actual_text_two_b_not = formatters["/Span << /ActualText <feff%04x%04x> >> BDC"] + local s_actual_text_e_not = "EMC" + local f_actual_text = formatters["/Span <</ActualText %s >> BDC"] local context = context local pdfdirect = nodes.pool.pdfdirect @@ -1244,7 +1214,9 @@ do end function codeinjections.startunicodetoactualtext(unicode) - if unicode < 0x10000 then + if type(unicode) == "string" then + return f_actual_text_b(unicode) + elseif unicode < 0x10000 then return f_actual_text_one_b(unicode) else return f_actual_text_two_b(unicode/1024+0xD800,unicode%1024+0xDC00) @@ -1255,6 +1227,20 @@ do return s_actual_text_e end + function codeinjections.startunicodetoactualtextdirect(unicode) + if type(unicode) == "string" then + return f_actual_text_b_not(unicode) + elseif unicode < 0x10000 then + return f_actual_text_one_b_not(unicode) + else + return f_actual_text_two_b_not(unicode/1024+0xD800,unicode%1024+0xDC00) + end + end + + function codeinjections.stopunicodetoactualtextdirect() + return s_actual_text_e_not + end + implement { name = "startactualtext", arguments = "string", diff --git a/tex/context/base/mkiv/lpdf-mis.lua b/tex/context/base/mkiv/lpdf-mis.lua index 62713727d..dc3f8560a 100644 --- a/tex/context/base/mkiv/lpdf-mis.lua +++ b/tex/context/base/mkiv/lpdf-mis.lua @@ -33,7 +33,6 @@ local register = nodepool.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 @@ -51,7 +50,21 @@ local addtopageattributes = lpdf.addtopageattributes local addtonames = lpdf.addtonames local variables = interfaces.variables + local v_stop = variables.stop +local v_none = variables.none +local v_max = variables.max +local v_bookmark = variables.bookmark +local v_fit = variables.fit +local v_doublesided = variables.doublesided +local v_singlesided = variables.singlesided +local v_default = variables.default +local v_auto = variables.auto +local v_fixed = variables.fixed +local v_landscape = variables.landscape +local v_portrait = variables.portrait +local v_page = variables.page +local v_paper = variables.paper local positive = register(pdfliteral("/GSpositive gs")) local negative = register(pdfliteral("/GSnegative gs")) @@ -184,7 +197,8 @@ local function setupidentity() if author ~= "" then addtoinfo("Author", pdfunicode(author), author) -- '/Author' in /Info, 'Creator' in XMP end - local creator = identity.creator or "" + -- local creator = identity.creator or "" + local creator = "LuaTeX + ConTeXt MkIV" -- has to be the same in CreatorTool if creator ~= "" then addtoinfo("Creator", pdfunicode(creator), creator) -- '/Creator' in /Info, 'CreatorTool' in XMP end @@ -248,23 +262,99 @@ lpdf.registerdocumentfinalizer(flushjavascripts,"javascripts") -- -- -- local pagespecs = { - [variables.max] = { mode = "FullScreen", layout = false, fit = false, fixed = false, duplex = false }, - [variables.bookmark] = { mode = "UseOutlines", layout = false, fit = false, fixed = false, duplex = false }, - [variables.fit] = { mode = "UseNone", layout = false, fit = true, fixed = false, duplex = false }, - [variables.doublesided] = { mode = "UseNone", layout = "TwoColumnRight", fit = true, fixed = false, duplex = false }, - [variables.singlesided] = { mode = "UseNone", layout = false, fit = false, fixed = false, duplex = false }, - [variables.default] = { mode = "UseNone", layout = "auto", fit = false, fixed = false, duplex = false }, - [variables.auto] = { mode = "UseNone", layout = "auto", fit = false, fixed = false, duplex = false }, - [variables.none] = { mode = false, layout = false, fit = false, fixed = false, duplex = false }, - -- new - [variables.fixed] = { mode = "UseNone", layout = "auto", fit = false, fixed = true, duplex = false }, -- noscale - [variables.landscape] = { mode = "UseNone", layout = "auto", fit = false, fixed = true, duplex = "DuplexFlipShortEdge" }, - [variables.portrait] = { mode = "UseNone", layout = "auto", fit = false, fixed = true, duplex = "DuplexFlipLongEdge" }, - [variables.page] = { mode = "UseNone", layout = "auto", fit = false, fixed = true, duplex = "Simplex" }, + [v_none] = { + }, + [v_max] = { + mode = "FullScreen", + }, + [v_bookmark] = { + mode = "UseOutlines", + }, + [v_fit] = { + mode = "UseNone", + fit = true, + }, + [v_doublesided] = { + mode = "UseNone", + layout = "TwoColumnRight", + fit = true, + }, + [v_singlesided] = { + mode = "UseNone" + }, + [v_default] = { + mode = "UseNone", + layout = "auto", + }, + [v_auto] = { + mode = "UseNone", + layout = "auto", + }, + [v_fixed] = { + mode = "UseNone", + layout = "auto", + fixed = true, -- noscale + }, + [v_landscape] = { + mode = "UseNone", + layout = "auto", + fixed = true, + duplex = "DuplexFlipShortEdge", + }, + [v_portrait] = { + mode = "UseNone", + layout = "auto", + fixed = true, + duplex = "DuplexFlipLongEdge", + }, + [v_page] = { + mode = "UseNone", + layout = "auto", + fixed = true, + duplex = "Simplex", + }, + [v_paper] = { + mode = "UseNone", + layout = "auto", + fixed = true, + duplex = "Simplex", + paper = true, + }, +} + +local plusspecs = { + [v_max] = { + mode = "FullScreen", + }, + [v_bookmark] = { + mode = "UseOutlines", + }, + [v_fit] = { + fit = true, + }, + [v_doublesided] = { + layout = "TwoColumnRight", + }, + [v_fixed] = { + fixed = true, + }, + [v_landscape] = { + duplex = "DuplexFlipShortEdge", + }, + [v_portrait] = { + duplex = "DuplexFlipLongEdge", + }, + [v_page] = { + duplex = "Simplex" , + }, + [v_paper] = { + paper = true, + }, } local pagespec, topoffset, leftoffset, height, width, doublesided = "default", 0, 0, 0, 0, false local cropoffset, bleedoffset, trimoffset, artoffset = 0, 0, 0, 0 +local copies = false function codeinjections.setupcanvas(specification) local paperheight = specification.paperheight @@ -276,11 +366,16 @@ function codeinjections.setupcanvas(specification) if paperwidth then texset('global','pagewidth',paperwidth) end - pagespec = specification.mode or pagespec - topoffset = specification.topoffset or 0 - leftoffset = specification.leftoffset or 0 - height = specification.height or texget("pageheight") - width = specification.width or texget("pagewidth") + pagespec = specification.mode or pagespec + topoffset = specification.topoffset or 0 + leftoffset = specification.leftoffset or 0 + height = specification.height or texget("pageheight") + width = specification.width or texget("pagewidth") + -- + copies = specification.copies + if copies and copies < 2 then + copies = false + end -- cropoffset = specification.cropoffset or 0 trimoffset = cropoffset - (specification.trimoffset or 0) @@ -294,22 +389,17 @@ end local function documentspecification() if not pagespec or pagespec == "" then - pagespec = variables.default + pagespec = v_default end - -- local settings = utilities.parsers.settings_to_array(pagespec) - -- local spec = pagespecs[variables.default] - -- for i=1,#settings do - -- local s = pagespecs[settings[i]] - -- if s then - -- for k, v in next, s do - -- spec[k] = v - -- end - -- end - -- end - local spec = pagespecs[pagespec] or pagespecs[variables.default] + local settings = utilities.parsers.settings_to_array(pagespec) + -- so the first one detemines the defaults + local first = settings[1] + local defaults = pagespecs[first] + local spec = defaults or pagespecs[v_default] + -- successive keys can modify this if spec.layout == "auto" then if doublesided then - local s = pagespecs[variables.doublesided] -- to be checked voor interfaces + local s = pagespecs[v_doublesided] -- to be checked voor interfaces for k, v in next, s do spec[k] = v end @@ -317,32 +407,45 @@ local function documentspecification() spec.layout = false end end + -- we start at 2 when we have a valid first default set + for i=defaults and 2 or 1,#settings do + local s = plusspecs[settings[i]] + if s then + for k, v in next, s do + spec[k] = v + end + end + end + -- local layout = spec.layout local mode = spec.mode local fit = spec.fit local fixed = spec.fixed local duplex = spec.duplex + local paper = spec.paper if layout then addtocatalog("PageLayout",pdfconstant(layout)) end if mode then addtocatalog("PageMode",pdfconstant(mode)) end - if fit or fixed or duplex then + if fit or fixed or duplex or copies or paper then addtocatalog("ViewerPreferences",pdfdictionary { - FitWindow = fit and true or nil, - PrintScaling = fixed and pdfconstant("None") or nil, - Duplex = duplex and pdfconstant(duplex) or nil, + FitWindow = fit and true or nil, + PrintScaling = fixed and pdfconstant("None") or nil, + Duplex = duplex and pdfconstant(duplex) or nil, + NumCopies = copies and copies or nil, + PickTrayByPDFSize = paper and true or nil, }) end addtoinfo ("Trapped", pdfconstant("False")) -- '/Trapped' in /Info, 'Trapped' in XMP addtocatalog("Version", pdfconstant(format("1.%s",pdf.getminorversion()))) end --- temp hack: the mediabox is not under our control and has a precision of 4 digits +-- temp hack: the mediabox is not under our control and has a precision of 5 digits local factor = number.dimenfactors.bp -local f_value = formatters["%0.4F"] +local f_value = formatters["%0.5F"] local function boxvalue(n) -- we could share them return pdfverbose(f_value(factor * n)) diff --git a/tex/context/base/mkiv/lpdf-nod.lua b/tex/context/base/mkiv/lpdf-nod.lua index 3dd5a6648..985d05a82 100644 --- a/tex/context/base/mkiv/lpdf-nod.lua +++ b/tex/context/base/mkiv/lpdf-nod.lua @@ -8,30 +8,34 @@ if not modules then modules = { } end modules ['lpdf-nod'] = { local type = type -local formatters = string.formatters +local formatters = string.formatters -local whatsitcodes = nodes.whatsitcodes -local nodeinjections = backends.nodeinjections +local whatsitcodes = nodes.whatsitcodes +local nodeinjections = backends.nodeinjections -local nuts = nodes.nuts -local tonut = nuts.tonut +local nuts = nodes.nuts +local tonut = nuts.tonut -local setfield = nuts.setfield +local setfield = nuts.setfield -local copy_node = nuts.copy -local new_node = nuts.new +local copy_node = nuts.copy +local new_node = nuts.new -local nodepool = nuts.pool -local register = nodepool.register +local nodepool = nuts.pool +local register = nodepool.register -local pdfliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfliteral,"mode",1) -local pdfsave = register(new_node("whatsit", whatsitcodes.pdfsave)) -local pdfrestore = register(new_node("whatsit", whatsitcodes.pdfrestore)) -local pdfsetmatrix = register(new_node("whatsit", whatsitcodes.pdfsetmatrix)) ------ pdfdest = register(new_node("whatsit", whatsitcodes.pdfdest)) setfield(pdfdest,"named_id",1) -- xyz_zoom untouched ------ pdfannot = register(new_node("whatsit", whatsitcodes.pdfannot)) +local pdforiginliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdforiginliteral,"mode",0) -- set_origin_code +local pdfpageliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfpageliteral, "mode",1) -- page_code +local pdfdirectliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfdirectliteral,"mode",2) -- direct_code +local pdfrawliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfrawliteral, "mode",3) -- raw_code -local variables = interfaces.variables +local pdfsave = register(new_node("whatsit", whatsitcodes.pdfsave)) +local pdfrestore = register(new_node("whatsit", whatsitcodes.pdfrestore)) +local pdfsetmatrix = register(new_node("whatsit", whatsitcodes.pdfsetmatrix)) +----- pdfdest = register(new_node("whatsit", whatsitcodes.pdfdest)) setfield(pdfdest,"named_id",1) -- xyz_zoom untouched +----- pdfannot = register(new_node("whatsit", whatsitcodes.pdfannot)) + +local variables = interfaces.variables local views = { -- beware, we do support the pdf keys but this is *not* official xyz = 0, [variables.standard] = 0, @@ -44,18 +48,12 @@ local views = { -- beware, we do support the pdf keys but this is *not* official fitr = 7, } -function nodepool.pdfliteral(str) - local t = copy_node(pdfliteral) - setfield(t,"data",str) - return t -end +function nodepool.pdforiginliteral(str) local t = copy_node(pdforiginliteral) setfield(t,"data",str) return t end +function nodepool.pdfpageliteral (str) local t = copy_node(pdfpageliteral ) setfield(t,"data",str) return t end +function nodepool.pdfdirectliteral(str) local t = copy_node(pdfdirectliteral) setfield(t,"data",str) return t end +function nodepool.pdfrawliteral (str) local t = copy_node(pdfrawliteral ) setfield(t,"data",str) return t end -function nodepool.pdfdirect(str) - local t = copy_node(pdfliteral) - setfield(t,"data",str) - setfield(t,"mode",1) - return t -end +nodepool.pdfliteral = nodepool.pdfpageliteral function nodepool.pdfsave() return copy_node(pdfsave) diff --git a/tex/context/base/mkiv/lpdf-pda.xml b/tex/context/base/mkiv/lpdf-pda.xml index 3f6b969c0..78ad47f21 100644 --- a/tex/context/base/mkiv/lpdf-pda.xml +++ b/tex/context/base/mkiv/lpdf-pda.xml @@ -50,127 +50,142 @@ xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/" xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#" xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#"> - <pdfaExtension:schemas> - <rdf:Bag> - <rdf:li rdf:parseType="Resource"> - <pdfaSchema:namespaceURI>http://ns.adobe.com/pdf/1.3/</pdfaSchema:namespaceURI> - <pdfaSchema:prefix>pdf</pdfaSchema:prefix> - <pdfaSchema:schema>Adobe PDF Schema</pdfaSchema:schema> - <pdfaSchema:property> - <rdf:Seq> - <rdf:li rdf:parseType="Resource"> - <pdfaProperty:category>internal</pdfaProperty:category> - <pdfaProperty:description>A name object indicating whether the document has been modified to include trapping information</pdfaProperty:description> - <pdfaProperty:name>Trapped</pdfaProperty:name> - <pdfaProperty:valueType>Text</pdfaProperty:valueType> - </rdf:li> - </rdf:Seq> - </pdfaSchema:property> - </rdf:li> - <rdf:li rdf:parseType="Resource"> - <pdfaSchema:namespaceURI>http://purl.org/dc/elements/1.1/</pdfaSchema:namespaceURI> - <pdfaSchema:prefix>pdf</pdfaSchema:prefix> - <pdfaSchema:schema>Dubline Core Schema</pdfaSchema:schema> - <pdfaSchema:property> - <rdf:Seq> - <rdf:li rdf:parseType="Resource"> - <pdfaProperty:category>internal</pdfaProperty:category> - <pdfaProperty:description>Subject in Document Properties</pdfaProperty:description> - <pdfaProperty:name>description</pdfaProperty:name> - <pdfaProperty:valueType>Text</pdfaProperty:valueType> - </rdf:li> - </rdf:Seq> - </pdfaSchema:property> - </rdf:li> - <rdf:li rdf:parseType="Resource"> - <pdfaSchema:namespaceURI>http://ns.adobe.com/pdfx/1.3/</pdfaSchema:namespaceURI> - <pdfaSchema:prefix>pdfx</pdfaSchema:prefix> - <pdfaSchema:schema>PDF/X ID Schema</pdfaSchema:schema> - <pdfaSchema:property> - <rdf:Seq> - <rdf:li rdf:parseType="Resource"> - <pdfaProperty:category>external</pdfaProperty:category> - <pdfaProperty:description>Name of the ConTeXt job</pdfaProperty:description> - <pdfaProperty:name>ConTeXt.Jobname</pdfaProperty:name> - <pdfaProperty:valueType>Text</pdfaProperty:valueType> - </rdf:li> - <rdf:li rdf:parseType="Resource"> - <pdfaProperty:category>external</pdfaProperty:category> - <pdfaProperty:description>Time stamp of ConTeXt version</pdfaProperty:description> - <pdfaProperty:name>ConTeXt.Time</pdfaProperty:name> - <pdfaProperty:valueType>Text</pdfaProperty:valueType> - </rdf:li> - <rdf:li rdf:parseType="Resource"> - <pdfaProperty:category>external</pdfaProperty:category> - <pdfaProperty:description>ConTeXt website</pdfaProperty:description> - <pdfaProperty:name>ConTeXt.Url</pdfaProperty:name> - <pdfaProperty:valueType>Text</pdfaProperty:valueType> - </rdf:li> - <rdf:li rdf:parseType="Resource"> - <pdfaProperty:category>external</pdfaProperty:category> - <pdfaProperty:description>ConTeXt version</pdfaProperty:description> - <pdfaProperty:name>ConTeXt.Version</pdfaProperty:name> - <pdfaProperty:valueType>Text</pdfaProperty:valueType> - </rdf:li> - <rdf:li rdf:parseType="Resource"> - <pdfaProperty:category>external</pdfaProperty:category> - <pdfaProperty:description>Banner of pdftex or one of its successors</pdfaProperty:description> - <pdfaProperty:name>PTEX.Fullbanner</pdfaProperty:name> - <pdfaProperty:valueType>Text</pdfaProperty:valueType> - </rdf:li> - <rdf:li rdf:parseType="Resource"> - <pdfaProperty:category>external</pdfaProperty:category> - <pdfaProperty:description>Document identifier</pdfaProperty:description> - <pdfaProperty:name>ID</pdfaProperty:name> - <pdfaProperty:valueType>Text</pdfaProperty:valueType> - </rdf:li> - </rdf:Seq> - </pdfaSchema:property> - </rdf:li> - <rdf:li rdf:parseType="Resource"> - <pdfaSchema:namespaceURI>http://ns.adobe.com/xap/1.0/mm/</pdfaSchema:namespaceURI> - <pdfaSchema:prefix>xmpMM</pdfaSchema:prefix> - <pdfaSchema:schema>XMP Media Management Schema</pdfaSchema:schema> - <pdfaSchema:property> - <rdf:Seq> - <rdf:li rdf:parseType="Resource"> - <pdfaProperty:category>internal</pdfaProperty:category> - <pdfaProperty:description>UUID based identifier for specific incarnation of a document</pdfaProperty:description> - <pdfaProperty:name>InstanceID</pdfaProperty:name> - <pdfaProperty:valueType>URI</pdfaProperty:valueType> - </rdf:li> - </rdf:Seq> - </pdfaSchema:property> - </rdf:li> - <rdf:li rdf:parseType="Resource"> - <pdfaSchema:namespaceURI>http://www.aiim.org/pdfa/ns/id/</pdfaSchema:namespaceURI> - <pdfaSchema:prefix>pdfaid</pdfaSchema:prefix> - <pdfaSchema:schema>PDF/A ID Schema</pdfaSchema:schema> - <pdfaSchema:property> - <rdf:Seq> - <rdf:li rdf:parseType="Resource"> - <pdfaProperty:category>internal</pdfaProperty:category> - <pdfaProperty:description>Part of PDF/A standard</pdfaProperty:description> - <pdfaProperty:name>part</pdfaProperty:name> - <pdfaProperty:valueType>Integer</pdfaProperty:valueType> - </rdf:li> - <rdf:li rdf:parseType="Resource"> - <pdfaProperty:category>internal</pdfaProperty:category> - <pdfaProperty:description>Amendment of PDF/A standard</pdfaProperty:description> - <pdfaProperty:name>amd</pdfaProperty:name> - <pdfaProperty:valueType>Text</pdfaProperty:valueType> - </rdf:li> - <rdf:li rdf:parseType="Resource"> - <pdfaProperty:category>internal</pdfaProperty:category> - <pdfaProperty:description>Conformance level of PDF/A standard</pdfaProperty:description> - <pdfaProperty:name>conformance</pdfaProperty:name> - <pdfaProperty:valueType>Text</pdfaProperty:valueType> - </rdf:li> - </rdf:Seq> - </pdfaSchema:property> - </rdf:li> - </rdf:Bag> - </pdfaExtension:schemas> - </rdf:Description> + <pdfaExtension:schemas> + <rdf:Bag> + <rdf:li rdf:parseType="Resource"> + <pdfaSchema:namespaceURI>http://ns.adobe.com/pdf/1.3/</pdfaSchema:namespaceURI> + <pdfaSchema:prefix>pdf</pdfaSchema:prefix> + <pdfaSchema:schema>Adobe PDF Schema</pdfaSchema:schema> + <pdfaSchema:property> + <rdf:Seq> + <rdf:li rdf:parseType="Resource"> + <pdfaProperty:category>internal</pdfaProperty:category> + <pdfaProperty:description>A name object indicating whether the document has been modified to include trapping information</pdfaProperty:description> + <pdfaProperty:name>Trapped</pdfaProperty:name> + <pdfaProperty:valueType>Text</pdfaProperty:valueType> + </rdf:li> + </rdf:Seq> + </pdfaSchema:property> + <pdfaSchema:valueType> + <rdf:Seq/> + </pdfaSchema:valueType> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <pdfaSchema:namespaceURI>http://purl.org/dc/elements/1.1/</pdfaSchema:namespaceURI> + <pdfaSchema:prefix>pdf</pdfaSchema:prefix> + <pdfaSchema:schema>Dubline Core Schema</pdfaSchema:schema> + <pdfaSchema:property> + <rdf:Seq> + <rdf:li rdf:parseType="Resource"> + <pdfaProperty:category>internal</pdfaProperty:category> + <pdfaProperty:description>Subject in Document Properties</pdfaProperty:description> + <pdfaProperty:name>description</pdfaProperty:name> + <pdfaProperty:valueType>Text</pdfaProperty:valueType> + </rdf:li> + </rdf:Seq> + </pdfaSchema:property> + <pdfaSchema:valueType> + <rdf:Seq/> + </pdfaSchema:valueType> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <pdfaSchema:namespaceURI>http://ns.adobe.com/pdfx/1.3/</pdfaSchema:namespaceURI> + <pdfaSchema:prefix>pdfx</pdfaSchema:prefix> + <pdfaSchema:schema>PDF/X ID Schema</pdfaSchema:schema> + <pdfaSchema:property> + <rdf:Seq> + <rdf:li rdf:parseType="Resource"> + <pdfaProperty:category>external</pdfaProperty:category> + <pdfaProperty:description>Name of the ConTeXt job</pdfaProperty:description> + <pdfaProperty:name>ConTeXt.Jobname</pdfaProperty:name> + <pdfaProperty:valueType>Text</pdfaProperty:valueType> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <pdfaProperty:category>external</pdfaProperty:category> + <pdfaProperty:description>Time stamp of ConTeXt version</pdfaProperty:description> + <pdfaProperty:name>ConTeXt.Time</pdfaProperty:name> + <pdfaProperty:valueType>Text</pdfaProperty:valueType> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <pdfaProperty:category>external</pdfaProperty:category> + <pdfaProperty:description>ConTeXt website</pdfaProperty:description> + <pdfaProperty:name>ConTeXt.Url</pdfaProperty:name> + <pdfaProperty:valueType>Text</pdfaProperty:valueType> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <pdfaProperty:category>external</pdfaProperty:category> + <pdfaProperty:description>ConTeXt version</pdfaProperty:description> + <pdfaProperty:name>ConTeXt.Version</pdfaProperty:name> + <pdfaProperty:valueType>Text</pdfaProperty:valueType> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <pdfaProperty:category>external</pdfaProperty:category> + <pdfaProperty:description>Banner of pdftex or one of its successors</pdfaProperty:description> + <pdfaProperty:name>PTEX.Fullbanner</pdfaProperty:name> + <pdfaProperty:valueType>Text</pdfaProperty:valueType> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <pdfaProperty:category>external</pdfaProperty:category> + <pdfaProperty:description>Document identifier</pdfaProperty:description> + <pdfaProperty:name>ID</pdfaProperty:name> + <pdfaProperty:valueType>Text</pdfaProperty:valueType> + </rdf:li> + </rdf:Seq> + </pdfaSchema:property> + <pdfaSchema:valueType> + <rdf:Seq/> + </pdfaSchema:valueType> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <pdfaSchema:namespaceURI>http://ns.adobe.com/xap/1.0/mm/</pdfaSchema:namespaceURI> + <pdfaSchema:prefix>xmpMM</pdfaSchema:prefix> + <pdfaSchema:schema>XMP Media Management Schema</pdfaSchema:schema> + <pdfaSchema:property> + <rdf:Seq> + <rdf:li rdf:parseType="Resource"> + <pdfaProperty:category>internal</pdfaProperty:category> + <pdfaProperty:description>UUID based identifier for specific incarnation of a document</pdfaProperty:description> + <pdfaProperty:name>InstanceID</pdfaProperty:name> + <pdfaProperty:valueType>URI</pdfaProperty:valueType> + </rdf:li> + </rdf:Seq> + </pdfaSchema:property> + <pdfaSchema:valueType> + <rdf:Seq/> + </pdfaSchema:valueType> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <pdfaSchema:namespaceURI>http://www.aiim.org/pdfa/ns/id/</pdfaSchema:namespaceURI> + <pdfaSchema:prefix>pdfaid</pdfaSchema:prefix> + <pdfaSchema:schema>PDF/A ID Schema</pdfaSchema:schema> + <pdfaSchema:property> + <rdf:Seq> + <rdf:li rdf:parseType="Resource"> + <pdfaProperty:category>internal</pdfaProperty:category> + <pdfaProperty:description>Part of PDF/A standard</pdfaProperty:description> + <pdfaProperty:name>part</pdfaProperty:name> + <pdfaProperty:valueType>Integer</pdfaProperty:valueType> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <pdfaProperty:category>internal</pdfaProperty:category> + <pdfaProperty:description>Amendment of PDF/A standard</pdfaProperty:description> + <pdfaProperty:name>amd</pdfaProperty:name> + <pdfaProperty:valueType>Text</pdfaProperty:valueType> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <pdfaProperty:category>internal</pdfaProperty:category> + <pdfaProperty:description>Conformance level of PDF/A standard</pdfaProperty:description> + <pdfaProperty:name>conformance</pdfaProperty:name> + <pdfaProperty:valueType>Text</pdfaProperty:valueType> + </rdf:li> + </rdf:Seq> + </pdfaSchema:property> + <pdfaSchema:valueType> + <rdf:Seq/> + </pdfaSchema:valueType> + </rdf:li> + </rdf:Bag> + </pdfaExtension:schemas> + </rdf:Description> </rdf:RDF> </x:xmpmeta> diff --git a/tex/context/base/mkiv/lpdf-ren.lua b/tex/context/base/mkiv/lpdf-ren.lua index 81b9e9f20..47075ee08 100644 --- a/tex/context/base/mkiv/lpdf-ren.lua +++ b/tex/context/base/mkiv/lpdf-ren.lua @@ -12,6 +12,7 @@ local tostring, tonumber, next = tostring, tonumber, next local format, rep = string.format, string.rep local concat = table.concat local settings_to_array = utilities.parsers.settings_to_array +local getrandom = utilities.randomizer.get local backends, lpdf, nodes, node = backends, lpdf, nodes, node @@ -363,7 +364,7 @@ function codeinjections.setpagetransition(specification) last = 0 return elseif n == v_random then - n = math.random(1,#pagetransitions) + n = getrandom("transition",1,#pagetransitions) else n = tonumber(n) end diff --git a/tex/context/base/mkiv/lpdf-res.lua b/tex/context/base/mkiv/lpdf-res.lua index ca092c772..ac9478488 100644 --- a/tex/context/base/mkiv/lpdf-res.lua +++ b/tex/context/base/mkiv/lpdf-res.lua @@ -12,7 +12,7 @@ local implement = interfaces.implement local nuts = nodes.nuts local tonut = nodes.tonut -local setfield = nuts.setfield +local setwhd = nuts.setwhd local setlist = nuts.setlist local new_hlist = nuts.pool.hlist @@ -29,9 +29,7 @@ function codeinjections.restoreboxresource(index) local hbox = new_hlist() local list, wd, ht, dp = useboxresource(index) setlist(hbox,tonut(list)) - setfield(hbox,"width", wd) - setfield(hbox,"height", ht) - setfield(hbox,"depth", dp) + setwhd(hbox,wd,ht,dp) return hbox -- so we return a nut ! end diff --git a/tex/context/base/mkiv/lpdf-swf.lua b/tex/context/base/mkiv/lpdf-swf.lua index 88cdcc4ec..e40dc6378 100644 --- a/tex/context/base/mkiv/lpdf-swf.lua +++ b/tex/context/base/mkiv/lpdf-swf.lua @@ -13,20 +13,17 @@ local format, gsub = string.format, string.gsub local backends, lpdf = backends, lpdf -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 pdfflushobject = lpdf.flushobject - -local checkedkey = lpdf.checkedkey - -local codeinjections = backends.pdf.codeinjections -local nodeinjections = backends.pdf.nodeinjections +local pdfconstant = lpdf.constant +local pdfstring = lpdf.string +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfreference = lpdf.reference +local pdfflushobject = lpdf.flushobject + +local checkedkey = lpdf.checkedkey + +local codeinjections = backends.pdf.codeinjections +local nodeinjections = backends.pdf.nodeinjections local trace_swf = false trackers.register("backend.swf", function(v) trace_swf = v end) diff --git a/tex/context/base/mkiv/lpdf-tag.lua b/tex/context/base/mkiv/lpdf-tag.lua index 79b8ac368..e33c8a811 100644 --- a/tex/context/base/mkiv/lpdf-tag.lua +++ b/tex/context/base/mkiv/lpdf-tag.lua @@ -9,8 +9,8 @@ if not modules then modules = { } end modules ['lpdf-tag'] = { local next = next local format, match, concat = string.format, string.match, table.concat local lpegmatch, P, S, C = lpeg.match, lpeg.P, lpeg.S, lpeg.C -local utfchar = utf.char local settings_to_hash = utilities.parsers.settings_to_hash +local sortedhash = table.sortedhash local formatters = string.formatters local trace_tags = false trackers.register("structures.tags", function(v) trace_tags = v end) @@ -24,7 +24,7 @@ local nodes = nodes local nodeinjections = backends.pdf.nodeinjections local codeinjections = backends.pdf.codeinjections -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction local pdfdictionary = lpdf.dictionary local pdfarray = lpdf.array @@ -32,7 +32,6 @@ 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 @@ -70,7 +69,6 @@ local setlist = nuts.setlist local traverse_nodes = nuts.traverse local tosequence = nuts.tosequence -local slide_nodelist = nuts.slide local insert_before = nuts.insert_before local insert_after = nuts.insert_after @@ -88,7 +86,6 @@ local taglist = structurestags.taglist local specifications = structurestags.specifications local usedlabels = structurestags.labels local properties = structurestags.properties -local lasttaginchain = structurestags.lastinchain local usewithcare = structurestags.usewithcare local usedmapping = { } @@ -148,7 +145,7 @@ local function finishstructure() K = pdfreference(pdfflushobject(structure_kids)), ParentTree = pdfreference(pdfflushobject(parent_ref,parenttree)), IDTree = #names > 0 and pdfreference(pdfflushobject(idtree)) or nil, - RoleMap = rolemap, + RoleMap = rolemap, -- sorted ? } pdfflushobject(structure_ref,structuretree) addtocatalog("StructTreeRoot",pdfreference(structure_ref)) @@ -161,7 +158,7 @@ local function finishstructure() } addtocatalog("MarkInfo",pdfreference(pdfflushobject(markinfo))) -- - for fulltag, element in next, elements do + for fulltag, element in sortedhash(elements) do -- sorting is easier on comparing pdf pdfflushobject(element.knum,element.kids) end end @@ -194,7 +191,7 @@ local pdf_userproperties = pdfconstant("UserProperties") local function makeattribute(t) if t and next(t) then local properties = pdfarray() - for k, v in next, t do + for k, v in sortedhash(t) do -- easier on comparing pdf properties[#properties+1] = pdfdictionary { N = pdfunicode(k), V = pdfunicode(v), @@ -348,7 +345,6 @@ function nodeinjections.addtags(head) last = nil else local nl = getlist(n) - -- slide_nodelist(nl) -- temporary hack till math gets slided (tracker item) collectranges(nl,n) end end @@ -482,7 +478,6 @@ end -- last = nil -- else -- local nl = getlist(n) --- -- slide_nodelist(nl) -- temporary hack till math gets slided (tracker item) -- collectranges(nl,n) -- end -- end @@ -607,9 +602,9 @@ end function codeinjections.enabletags(tg,lb) structures.tags.handler = nodeinjections.addtags - tasks.enableaction("shipouts","structures.tags.handler") - tasks.enableaction("shipouts","nodes.handlers.accessibility") - tasks.enableaction("math","noads.handlers.tags") + enableaction("shipouts","structures.tags.handler") + enableaction("shipouts","nodes.handlers.accessibility") + enableaction("math","noads.handlers.tags") -- maybe also textblock if trace_tags then report_tags("enabling structure tags") diff --git a/tex/context/base/mkiv/lpdf-wid.lua b/tex/context/base/mkiv/lpdf-wid.lua index 73a56caa3..fceae49cb 100644 --- a/tex/context/base/mkiv/lpdf-wid.lua +++ b/tex/context/base/mkiv/lpdf-wid.lua @@ -10,6 +10,7 @@ local gmatch, gsub, find, lower, format = string.gmatch, string.gsub, string.fin local stripstring = string.strip local settings_to_array = utilities.parsers.settings_to_array local settings_to_hash = utilities.parsers.settings_to_hash +local sortedhash = table.sortedhash local report_media = logs.reporter("backend","media") local report_attachment = logs.reporter("backend","attachment") @@ -29,11 +30,10 @@ local executers = structures.references.executers local variables = interfaces.variables local v_hidden = variables.hidden -local v_normal = variables.normal local v_auto = variables.auto local v_embed = variables.embed -local v_unknown = variables.unknown local v_max = variables.max +local v_yes = variables.yes local pdfconstant = lpdf.constant local pdfdictionary = lpdf.dictionary @@ -42,7 +42,6 @@ local pdfreference = lpdf.reference local pdfunicode = lpdf.unicode local pdfstring = lpdf.string local pdfboolean = lpdf.boolean -local pdfcolorspec = lpdf.colorspec local pdfflushobject = lpdf.flushobject local pdfflushstreamobject = lpdf.flushstreamobject local pdfflushstreamfileobject = lpdf.flushstreamfileobject @@ -203,7 +202,7 @@ job.register('job.fileobjreferences.collected', tobesavedobjrefs, initializer) local function flushembeddedfiles() if next(filestreams) then local e = pdfarray() - for tag, reference in next, filestreams do + for tag, reference in sortedhash(filestreams) do if not reference then report_attachment("unreferenced file, tag %a",tag) elseif referenced[tag] == "hidden" then @@ -383,7 +382,7 @@ function codeinjections.attachmentid(filename) -- not used in context return filestreams[filename] end -local nofcomments, usepopupcomments, stripleading = 0, false, true +local nofcomments, usepopupcomments = 0, false local defaultattributes = { ["xmlns"] = "http://www.w3.org/1999/xhtml", @@ -417,10 +416,12 @@ end function nodeinjections.comment(specification) -- brrr: seems to be done twice nofcomments = nofcomments + 1 - local text = stripstring(specification.data or "") - if stripleading then + local text = specification.data or "" + if specification.space ~= v_yes then + text = stripstring(text) text = gsub(text,"[\n\r] *","\n") end + text = gsub(text,"\r","\n") local name, appearance = analyzesymbol(specification.symbol,comment_symbols) local tag = specification.tag or "" -- this is somewhat messy as recent local title = specification.title or "" -- versions of acrobat see the title diff --git a/tex/context/base/mkiv/lpdf-xmp.lua b/tex/context/base/mkiv/lpdf-xmp.lua index c8b86d384..6153b198f 100644 --- a/tex/context/base/mkiv/lpdf-xmp.lua +++ b/tex/context/base/mkiv/lpdf-xmp.lua @@ -8,7 +8,8 @@ if not modules then modules = { } end modules ['lpdf-xmp'] = { } local tostring, type = tostring, type -local format, random, char, gsub, concat = string.format, math.random, string.char, string.gsub, table.concat +local format, gsub = string.format, string.gsub +local utfchar = utf.char local xmlfillin = xml.fillin local trace_xmp = false trackers.register("backend.xmp", function(v) trace_xmp = v end) @@ -26,14 +27,15 @@ local pdfconstant = lpdf.constant local pdfreference = lpdf.reference local pdfflushstreamobject = lpdf.flushstreamobject --- I wonder why this begin end is empty / w (no time now to look into it) / begin can also be "?" +-- The XMP packet wrapper is kind of fixed, see page 10 of XMPSpecificationsPart1.pdf from +-- XMP-Toolkit-SDK-CC201607.zip. So we hardcode the id. -local xpacket = [[ -<?xpacket begin="" id="%s"?> +local xpacket = format ( [[ +<?xpacket begin="%s" id="W5M0MpCehiHzreSzNTczkc9d"?> -%s +%%s -<?xpacket end="w"?>]] +<?xpacket end="w"?>]], utfchar(0xFEFF) ) local mapping = { -- user defined keys (pdfx:) @@ -94,16 +96,7 @@ pdf.setsuppressoptionalinfo( -- + 512 -- pdfnoid ) -local included = table.setmetatableindex( { - context = true, - id = true, - metadata = true, - date = true, - id = true, - pdf = true, -}, function(t,k) - return true -end) +local included = backends.included function lpdf.settrailerid(v) if v then @@ -248,32 +241,23 @@ end -- flushing -local function randomstring(n) - local t = { } - for i=1,n do - t[i] = char(96 + random(26)) - end - return concat(t) -end - -randomstring(26) -- kind of initializes and kicks off random - local function flushxmpinfo() commands.pushrandomseed() commands.setrandomseed(os.time()) - local packetid = "no unique packet id here" -- 24 chars + local version = status.luatex_version + local revision = status.luatex_revision + local documentid = "no unique document id here" local instanceid = "no unique instance id here" - local producer = format("LuaTeX-%0.2f.%s",status.luatex_version/100,status.luatex_revision) + local producer = format("LuaTeX-%i.%i.%s",math.div(version,100),math.mod(version,100),revision) local creator = "LuaTeX + ConTeXt MkIV" local time = lpdf.timestamp() local fullbanner = status.banner if included.id ~= "fake" then - packetid = randomstring(24) - documentid = "uuid:%s" .. os.uuid() - instanceid = "uuid:%s" .. os.uuid() + documentid = "uuid:" .. os.uuid() + instanceid = "uuid:" .. os.uuid() end pdfaddxmpinfo("DocumentID", documentid) @@ -306,7 +290,7 @@ local function flushxmpinfo() report_xmp("stop xmp blob") logs.poptarget() end - blob = format(xpacket,packetid,blob) + blob = format(xpacket,blob) if not verbose and pdf.getcompresslevel() > 0 then blob = gsub(blob,">%s+<","><") end diff --git a/tex/context/base/mkiv/luat-cbk.lua b/tex/context/base/mkiv/luat-cbk.lua index 2c3bede72..6fcfdc7f2 100644 --- a/tex/context/base/mkiv/luat-cbk.lua +++ b/tex/context/base/mkiv/luat-cbk.lua @@ -70,19 +70,26 @@ directives.register("system.callbacks.permitoverloads", function(v) end end) -sandbox.initializer(function() - block_overloads = true -end) +sandbox.initializer { + category = "functions", + action = function() + block_overloads = true + end +} if not list then -- otherwise counters get reset list = utilities.storage.allocate(list_callbacks()) + local supported = { } + for k in next, list do - list[k] = 0 + list[k] = 0 + supported[k] = true end - callbacks.list = list + callbacks.list = list + callbacks.supported = supported end diff --git a/tex/context/base/mkiv/luat-cnf.lua b/tex/context/base/mkiv/luat-cnf.lua index 9d37df7bb..4f2c6569e 100644 --- a/tex/context/base/mkiv/luat-cnf.lua +++ b/tex/context/base/mkiv/luat-cnf.lua @@ -64,15 +64,14 @@ function texconfig.init() "callback", "font", "img", "lang", "lua", "node", "pdf", "status", "tex", "texconfig", "texio", "token", }, extralua = { - "gzip", "zip", "zlib", "lfs", "ltn12", "mime", "socket", "md5", "profiler", "unicode", "utf", + "gzip", "zip", "zlib", "lfs", "ltn12", "mime", "socket", "md5", "fio", "unicode", "utf", }, extratex = { "epdf", "fontloader", "kpse", "mplib", }, obsolete = { - "fontforge", -- can be filled by luat-log + "fontloader", -- can be filled by luat-log "kpse", - "token", }, functions = { "assert", "pcall", "xpcall", "error", "collectgarbage", diff --git a/tex/context/base/mkiv/luat-cod.lua b/tex/context/base/mkiv/luat-cod.lua index f62396a8e..31860db78 100644 --- a/tex/context/base/mkiv/luat-cod.lua +++ b/tex/context/base/mkiv/luat-cod.lua @@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['luat-cod'] = { license = "see context related readme files" } -local type, loadfile = type, loadfile +local type, loadfile, tonumber = type, loadfile, tonumber local match, gsub, find, format = string.match, string.gsub, string.find, string.format local texconfig, lua = texconfig, lua @@ -96,7 +96,29 @@ local targetpath = "." -- environment.jobname = tex.jobname -- environment.version = tostring(tex.toks.contextversiontoks) -environment.initex = tex.formatname == "" +if LUATEXVERION == nil then + LUATEXVERSION = status.luatex_version/100 + + tonumber(status.luatex_revision)/1000 +end + +if LUATEXENGINE == nil then + LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine) + or (find(status.banner,"LuajitTeX") and "luajittex" or "luatex") +end + +if JITSUPPORTED == nil then + JITSUPPORTED = LUATEXENGINE == "luajittex" or jit +end + +if INITEXMODE == nil then + INITEXMODE = status.ini_version +end + +environment.initex = INITEXMODE +environment.initexmode = INITEXMODE +environment.luatexversion = LUATEXVERSION +environment.luatexengine = LUATEXENGINE +environment.jitsupported = JITSUPPORTED if not environment.luafilechunk then diff --git a/tex/context/base/mkiv/luat-exe.lua b/tex/context/base/mkiv/luat-exe.lua index d8d954a30..db06c63cb 100644 --- a/tex/context/base/mkiv/luat-exe.lua +++ b/tex/context/base/mkiv/luat-exe.lua @@ -8,66 +8,115 @@ if not modules then modules = { } end modules ['luat-exe'] = { if not sandbox then require("l-sandbox") require("util-sbx") end -- for testing +-- Ok, as usual, after finishing some code, I rewarded myself with searching youtube for +-- new music ... this time I ran into the swedisch group 'wintergatan' (search for: marble +-- machine) ... mechanical computers are so much more fun than the ones needed for running +-- the code below. Nice videos (and shows) too ... + local type = type -local executers = resolvers.executers or { } -resolvers.executers = executers +local executers = resolvers.executers or { } +resolvers.executers = executers -local disablerunners = sandbox.disablerunners -local registerbinary = sandbox.registerbinary -local registerroot = sandbox.registerroot +local disablerunners = sandbox.disablerunners +local disablelibraries = sandbox.disablelibraries +local registerbinary = sandbox.registerbinary +local registerlibrary = sandbox.registerlibrary +local registerroot = sandbox.registerroot -local lpegmatch = lpeg.match +local lpegmatch = lpeg.match -local sc_splitter = lpeg.tsplitat(";") -local cm_splitter = lpeg.tsplitat(",") +local sc_splitter = lpeg.tsplitat(";") +local cm_splitter = lpeg.tsplitat(",") local execution_mode directives.register("system.executionmode", function(v) execution_mode = v end) local execution_list directives.register("system.executionlist", function(v) execution_list = v end) local root_list directives.register("system.rootlist", function(v) root_list = v end) +local library_mode directives.register("system.librarymode", function(v) library_mode = v end) +local library_list directives.register("system.librarylist", function(v) library_list = v end) -sandbox.initializer(function() - if execution_mode == "none" then - -- will be done later - elseif execution_mode == "list" then - if type(execution_list) == "string" then - execution_list = lpegmatch(cm_splitter,execution_list) - end - if type(execution_list) == "table" then - for i=1,#execution_list do - registerbinary(execution_list[i]) +sandbox.initializer { + category = "binaries", + action = function() + if execution_mode == "none" then + -- will be done later + elseif execution_mode == "list" then + if type(execution_list) == "string" then + execution_list = lpegmatch(cm_splitter,execution_list) + end + if type(execution_list) == "table" then + for i=1,#execution_list do + registerbinary(execution_list[i]) + end end + else + registerbinary(true) -- all end - else - -- whatever else we have configured end -end) +} -sandbox.initializer(function() - if type(root_list) == "string" then - root_list = lpegmatch(sc_splitter,root_list) +sandbox.finalizer { + category = "binaries", + action = function() + if execution_mode == "none" then + disablerunners() + end end - if type(root_list) == "table" then - for i=1,#root_list do - local entry = root_list[i] - if entry ~= "" then - registerroot(entry) +} + +sandbox.initializer { + category = "libraries", + action = function() + if library_mode == "none" then + -- will be done later + elseif library_mode == "list" then + if type(library_list) == "string" then + library_list = lpegmatch(cm_splitter,library_list) + end + if type(library_list) == "table" then + for i=1,#library_list do + registerlibrary(library_list[i]) + end end + else + registerlibrary(true) -- all + end + end +} + +sandbox.finalizer { + category = "libraries", + action = function() + if library_mode == "none" then + disablelibraries() end end -end) +} -sandbox.finalizer(function() - if execution_mode == "none" then - disablerunners() +-- A bit of file system protection. + +sandbox.initializer{ + category = "files", + action = function () + if type(root_list) == "string" then + root_list = lpegmatch(sc_splitter,root_list) + end + if type(root_list) == "table" then + for i=1,#root_list do + registerroot(root_list[i]) + end + end end -end) +} -- Let's prevent abuse of these libraries (built-in support still works). -sandbox.finalizer(function() - mplib = nil - epdf = nil - zip = nil - fontloader = nil -end) +sandbox.finalizer { + category = "functions", + action = function() + mplib = nil + epdf = nil + zip = nil + fontloader = nil + end +} diff --git a/tex/context/base/mkiv/luat-fio.lua b/tex/context/base/mkiv/luat-fio.lua index 2b083b582..302d17a66 100644 --- a/tex/context/base/mkiv/luat-fio.lua +++ b/tex/context/base/mkiv/luat-fio.lua @@ -92,16 +92,16 @@ if not resolvers.instance then register('find_vf_file' , function(name) return findbinfile(name,"vf") end, true) register('find_cidmap_file' , function(name) return findbinfile(name,"cidmap") end, true) - register('read_data_file' , function(file) return loadbinfile(file,"tex") end, true) - register('read_enc_file' , function(file) return loadbinfile(file,"enc") end, true) - register('read_font_file' , function(file) return loadbinfile(file,"tfm") end, true) + register('read_data_file' , function(file) return loadbinfile(file,"tex") end, true) + register('read_enc_file' , function(file) return loadbinfile(file,"enc") end, true) + register('read_font_file' , function(file) return loadbinfile(file,"tfm") end, true) -- format -- image - register('read_map_file' , function(file) return loadbinfile(file,"map") end, true) + register('read_map_file' , function(file) return loadbinfile(file,"map") end, true) -- output - register('read_pk_file' , function(file) return loadbinfile(file,"pk") end, true) -- 600dpi/manfnt.720pk - register('read_sfd_file' , function(file) return loadbinfile(file,"sfd") end, true) - register('read_vf_file' , function(file) return loadbinfile(file,"vf" ) end, true) + register('read_pk_file' , function(file) return loadbinfile(file,"pk") end, true) -- 600dpi/manfnt.720pk + register('read_sfd_file' , function(file) return loadbinfile(file,"sfd") end, true) + register('read_vf_file' , function(file) return loadbinfile(file,"vf" ) end, true) -- register('find_font_file' , function(name) return findbinfile(name,"ofm") end, true) -- register('find_vf_file' , function(name) return findbinfile(name,"ovf") end, true) diff --git a/tex/context/base/mkiv/luat-fmt.lua b/tex/context/base/mkiv/luat-fmt.lua index 9a86ef50e..f61c659fa 100644 --- a/tex/context/base/mkiv/luat-fmt.lua +++ b/tex/context/base/mkiv/luat-fmt.lua @@ -13,18 +13,37 @@ local luasuffixes = utilities.lua.suffixes local report_format = logs.reporter("resolvers","formats") -local function primaryflags() -- not yet ok - local trackers = environment.argument("trackers") - local directives = environment.argument("directives") - local flags = { } +local function primaryflags() + local arguments = environment.arguments + local flags = { } + if arguments.silent then + flags[#flags+1] = "--interaction=batchmode" + end + if arguments.jit then + flags[#flags+1] = "--jiton" + end + return concat(flags," ") +end + +local function secondaryflags() + local arguments = environment.arguments + local trackers = arguments.trackers + local directives = arguments.directives + local flags = { } if trackers and trackers ~= "" then - flags = { "--trackers=" .. quoted(trackers) } + flags[#flags+1] = "--c:trackers=" .. quoted(trackers) end if directives and directives ~= "" then - flags = { "--directives=" .. quoted(directives) } + flags[#flags+1] = "--c:directives=" .. quoted(directives) end - if environment.argument("jit") then - flags = { "--jiton" } + if arguments.silent then + flags[#flags+1] = "--c:silent" + end + if arguments.jit then + flags[#flags+1] = "--c:jiton" + end + if arguments.ansi then + flags[#flags+1] = "--c:ansi" end return concat(flags," ") end @@ -32,8 +51,37 @@ end -- The silent option is Taco. It's a bit of a hack because we cannot yet mess -- with directives. In fact, I could probably clean up the maker a bit by now. -function environment.make_format(name,silent) +local template = [[--ini %primaryflags% --lua=%luafile% %texfile% %secondaryflags% %dump% %redirect%]] + +local checkers = { + primaryflags = "string", + secondaryflags = "string", + luafile = "readable", -- "cache" + texfile = "readable", -- "cache" + redirect = "string", + dump = "string", +} + +local runners = { + luatex = sandbox.registerrunner { + name = "make luatex format", + program = "luatex", + template = template, + checkers = checkers, + reporter = report_format, + }, + luajittex = sandbox.registerrunner { + name = "make luajittex format", + program = "luajittex", + template = template, + checkers = checkers, + reporter = report_format, + }, +} + +function environment.make_format(name,arguments) local engine = environment.ownmain or "luatex" + local silent = environment.arguments.silent -- change to format path (early as we need expanded paths) local olddir = dir.current() local path = caches.getwritablepath("formats",engine) or "" -- maybe platform @@ -96,11 +144,20 @@ function environment.make_format(name,silent) return end -- generate format - local dump = os.platform=="unix" and "\\\\dump" or "\\dump" - if silent then + local specification = { + primaryflags = primaryflags(), + secondaryflags = secondaryflags(), + luafile = quoted(usedluastub), + texfile = quoted(fulltexsourcename), + dump = os.platform == "unix" and "\\\\dump" or "\\dump", + } + local runner = runners[engine] + if not runner then + report_format("format %a cannot be generated, no runner available for engine %a",name,engine) + elseif silent then statistics.starttiming() - local command = format("%s --ini --interaction=batchmode %s --lua=%s %s %s > temp.log",engine,primaryflags(),quoted(usedluastub),quoted(fulltexsourcename),dump) - local result = os.execute(command) + specification.redirect = "> temp.log" + local result = runner(specification) local runtime = statistics.stoptiming() if result ~= 0 then print(format("%s silent make > fatal error when making format %q",engine,name)) -- we use a basic print @@ -109,9 +166,7 @@ function environment.make_format(name,silent) end os.remove("temp.log") else - local command = format("%s --ini %s --lua=%s %s %sdump",engine,primaryflags(),quoted(usedluastub),quoted(fulltexsourcename),dump) - report_format("running command: %s\n",command) - os.execute(command) + runner(specification) end -- remove related mem files local pattern = file.removesuffix(file.basename(usedluastub)).."-*.mem" @@ -127,6 +182,33 @@ function environment.make_format(name,silent) lfs.chdir(olddir) end +local template = [[%flags% --fmt=%fmtfile% --lua=%luafile% %texfile% %more%]] + +local checkers = { + flags = "string", + more = "string", + fmtfile = "readable", -- "cache" + luafile = "readable", -- "cache" + texfile = "readable", -- "cache" +} + +local runners = { + luatex = sandbox.registerrunner { + name = "run luatex format", + program = "luatex", + template = template, + checkers = checkers, + reporter = report_format, + }, + luajittex = sandbox.registerrunner { + name = "run luajittex format", + program = "luajittex", + template = template, + checkers = checkers, + reporter = report_format, + }, +} + function environment.run_format(name,data,more) if name and name ~= "" then local engine = environment.ownmain or "luatex" @@ -148,9 +230,18 @@ function environment.run_format(name,data,more) report_format("using format name %a",fmtname) report_format("no luc/lua file with name %a",barename) else - local command = format("%s %s --fmt=%s --lua=%s %s %s",engine,primaryflags(),quoted(barename),quoted(luaname),quoted(data),more ~= "" and quoted(more) or "") - report_format("running command: %s",command) - os.execute(command) + local runner = runners[engine] + if not runner then + report_format("format %a cannot be run, no runner available for engine %a",name,engine) + else + runner { + flags = primaryflags(), + fmtfile = quoted(barename), + luafile = quoted(luaname), + texfile = quoted(data), + more = more, + } + end end end end diff --git a/tex/context/base/mkiv/luat-ini.lua b/tex/context/base/mkiv/luat-ini.lua index cd1f45692..3ea8551c8 100644 --- a/tex/context/base/mkiv/luat-ini.lua +++ b/tex/context/base/mkiv/luat-ini.lua @@ -25,4 +25,12 @@ if not global then global = _G end -LUATEXVERSION = status.luatex_version/100 + tonumber(status.luatex_revision)/1000 +LUATEXVERSION = status.luatex_version/100 + + tonumber(status.luatex_revision)/1000 + +LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine) + or (string.find(status.banner,"LuajitTeX") and "luajittex" or "luatex") + +JITSUPPORTED = LUATEXENGINE == "luajittex" or jit + +INITEXMODE = status.ini_version diff --git a/tex/context/base/mkiv/luat-iop.lua b/tex/context/base/mkiv/luat-iop.lua index e1772af4e..34cc74e3e 100644 --- a/tex/context/base/mkiv/luat-iop.lua +++ b/tex/context/base/mkiv/luat-iop.lua @@ -9,16 +9,19 @@ if not modules then modules = { } end modules ['luat-iop'] = { local cleanedpathlist = resolvers.cleanedpathlist local registerroot = sandbox.registerroot -sandbox.initializer(function() - local function register(str,mode) - local trees = cleanedpathlist(str) - for i=1,#trees do - registerroot(trees[i],mode) +sandbox.initializer { + category = "files", + action = function() + local function register(str,mode) + local trees = cleanedpathlist(str) + for i=1,#trees do + registerroot(trees[i],mode) + end end + register("TEXMF","read") + register("TEXINPUTS","read") + register("MPINPUTS","read") + -- register("TEXMFCACHE","write") + registerroot(".","write") end - register("TEXMF","read") - register("TEXINPUTS","read") - register("MPINPUTS","read") - -- register("TEXMFCACHE","write") - registerroot(".","write") -end) +} diff --git a/tex/context/base/mkiv/luat-lib.mkiv b/tex/context/base/mkiv/luat-lib.mkiv index cbe15c8a1..c75b9c6b1 100644 --- a/tex/context/base/mkiv/luat-lib.mkiv +++ b/tex/context/base/mkiv/luat-lib.mkiv @@ -88,4 +88,8 @@ \registerctxluafile{lxml-aux}{1.001} \registerctxluafile{lxml-mis}{1.001} +\normalprotected\def\writestatus#1#2{\ctxlua{logs.status([==[#1]==],[==[#2]==])}} +\normalprotected\def\writestring #1{\ctxlua{logs.writer([==[#1]==],"\string\n")}} +\normalprotected\def\writeline {\ctxlua{logs.newline()}} + \endinput diff --git a/tex/context/base/mkiv/luat-mac.lua b/tex/context/base/mkiv/luat-mac.lua index 4274fe9f9..3f1fe6751 100644 --- a/tex/context/base/mkiv/luat-mac.lua +++ b/tex/context/base/mkiv/luat-mac.lua @@ -145,9 +145,8 @@ local grammar = { "converter", * stopcode * poplocal, texbody = ( -leadingcomment -- new per 2015-03-03 (ugly) -+ - V("definition") + leadingcomment -- new per 2015-03-03 (ugly) + + V("definition") + identifier + V("braced") + (1 - stopcode) diff --git a/tex/context/base/mkiv/luat-run.lua b/tex/context/base/mkiv/luat-run.lua index 7e81350f0..372bbcbfa 100644 --- a/tex/context/base/mkiv/luat-run.lua +++ b/tex/context/base/mkiv/luat-run.lua @@ -23,13 +23,19 @@ local report_tempfiles = logs.reporter("resolvers","tempfiles") luatex = luatex or { } local luatex = luatex +if not luatex.synctex then + luatex.synctex = table.setmetatableindex(function() return function() end end) +end + local startactions = { } local stopactions = { } local dumpactions = { } +local pageactions = { } function luatex.registerstartactions(...) insert(startactions, ...) end function luatex.registerstopactions (...) insert(stopactions, ...) end function luatex.registerdumpactions (...) insert(dumpactions, ...) end +function luatex.registerpageactions (...) insert(pageactions, ...) end local function start_run() if logs.start_run then @@ -63,6 +69,10 @@ end local function stop_shipout_page() logs.stop_page_number() + for i=1,#pageactions do + pageactions[i]() + end + luatex.synctex.flush() end local function report_output_pages() @@ -113,7 +123,11 @@ function luatex.registertempfile(name,extrasuffix,keep) -- namespace might chang name = name .. ".mkiv-tmp" -- maybe just .tmp end if trace_temp_files and not tempfiles[name] then - report_tempfiles("registering temporary file %a",name) + if keep then + report_tempfiles("%s temporary file %a","registering",name) + else + report_tempfiles("%s temporary file %a","unregistering",name) + end end tempfiles[name] = keep or false return name @@ -123,7 +137,7 @@ function luatex.cleanuptempfiles() for name, keep in next, tempfiles do if not keep then if trace_temp_files then - report_tempfiles("removing temporary file %a",name) + report_tempfiles("%s temporary file %a","removing",name) end os.remove(name) end @@ -133,27 +147,6 @@ end luatex.registerstopactions(luatex.cleanuptempfiles) --- for the moment here - -local report_system = logs.reporter("system") -local synctex = 0 - -directives.register("system.synctex", function(v) - synctex = tonumber(v) or (toboolean(v,true) and 1) or (v == "zipped" and 1) or (v == "unzipped" and -1) or 0 - if synctex ~= 0 then - report_system("synctex functionality is enabled (%s), expect runtime overhead!",tostring(synctex)) - else - report_system("synctex functionality is disabled!") - end - tex.normalsynctex = synctex -end) - -statistics.register("synctex tracing",function() - if synctex ~= 0 then - return "synctex has been enabled (extra log file generated)" - end -end) - -- filenames local types = { @@ -175,12 +168,17 @@ local total = 0 local stack = { } local all = false +function luatex.currentfile() + return stack[#stack] or tex.jobname +end + local function report_start(left,name) if not left then -- skip elseif left ~= 1 then if all then - report_load("%s > %s",types[left],name or "?") + -- report_load("%s > %s",types[left],name or "?") + report_load("type %a, name %a",types[left],name or "?") end elseif find(name,"virtual://") then insert(stack,false) @@ -188,7 +186,9 @@ local function report_start(left,name) insert(stack,name) total = total + 1 level = level + 1 - report_open("%i > %i > %s",level,total,name or "?") + -- report_open("%i > %i > %s",level,total,name or "?") + report_open("level %i, order %i, name %a",level,total,name or "?") + luatex.synctex.setfilename(name) end end @@ -196,7 +196,8 @@ local function report_stop(right) if level == 1 or not right or right == 1 then local name = remove(stack) if name then - report_close("%i > %i > %s",level,total,name or "?") + -- report_close("%i > %i > %s",level,total,name or "?") + report_close("level %i, order %i, name %a",level,total,name or "?") level = level - 1 end end diff --git a/tex/context/base/mkiv/luat-usr.lua b/tex/context/base/mkiv/luat-usr.lua index 071e3bf5b..e7406782b 100644 --- a/tex/context/base/mkiv/luat-usr.lua +++ b/tex/context/base/mkiv/luat-usr.lua @@ -148,6 +148,7 @@ local function registername(name,message) documentdata = documentdata, -- always there fast context = context, + -- tostring = tostring, tonumber = tonumber, -- standard lua modules diff --git a/tex/context/base/mkiv/lxml-aux.lua b/tex/context/base/mkiv/lxml-aux.lua index 4112db1e5..ee0909cbf 100644 --- a/tex/context/base/mkiv/lxml-aux.lua +++ b/tex/context/base/mkiv/lxml-aux.lua @@ -19,7 +19,6 @@ local xml = xml local xmlcopy, xmlname = xml.copy, xml.name local xmlinheritedconvert = xml.inheritedconvert local xmlapplylpath = xml.applylpath -local xmlfilter = xml.filter local type, next, setmetatable, getmetatable = type, next, setmetatable, getmetatable local insert, remove, fastcopy, concat = table.insert, table.remove, table.fastcopy, table.concat @@ -258,7 +257,17 @@ function xml.replace(root,pattern,whatever) report('replacing',pattern,c,e) end local d = p.dt - d[e.ni] = copiedelement(element,p) + local n = e.ni + local t = copiedelement(element,p) + if type(t) == "table" then + d[n] = t[1] + for i=2,#t do + n = n + 1 + insert(d,n,t[i]) + end + else + d[n] = t + end redo_ni(d) -- probably not needed end end @@ -753,7 +762,7 @@ local obsolete = xml.obsolete xml.strip_whitespace = xml.strip obsolete.strip_whitespace = xml.strip xml.collect_elements = xml.collect obsolete.collect_elements = xml.collect xml.delete_element = xml.delete obsolete.delete_element = xml.delete -xml.replace_element = xml.replace obsolete.replace_element = xml.replacet +xml.replace_element = xml.replace obsolete.replace_element = xml.replace xml.each_element = xml.each obsolete.each_element = xml.each xml.process_elements = xml.process obsolete.process_elements = xml.process xml.insert_element_after = xml.insertafter obsolete.insert_element_after = xml.insertafter diff --git a/tex/context/base/mkiv/lxml-css.lua b/tex/context/base/mkiv/lxml-css.lua index fa921b24f..b2198f341 100644 --- a/tex/context/base/mkiv/lxml-css.lua +++ b/tex/context/base/mkiv/lxml-css.lua @@ -6,10 +6,12 @@ if not modules then modules = { } end modules ['lxml-css'] = { license = "see context related readme files" } -local tonumber, rawset = tonumber, rawset -local lower, format = string.lower, string.format -local P, S, C, R, Cb, Cg, Carg, Ct, Cc, Cf = lpeg.P, lpeg.S, lpeg.C, lpeg.R, lpeg.Cb, lpeg.Cg, lpeg.Carg, lpeg.Ct, lpeg.Cc, lpeg.Cf +local tonumber, rawset, type = tonumber, rawset, type +local lower, format, find, gmatch = string.lower, string.format, string.find, string.gmatch +local topattern, is_empty = string.topattern, string.is_empty +local P, S, C, R, Cb, Cg, Carg, Ct, Cc, Cf, Cs = lpeg.P, lpeg.S, lpeg.C, lpeg.R, lpeg.Cb, lpeg.Cg, lpeg.Carg, lpeg.Ct, lpeg.Cc, lpeg.Cf, lpeg.Cs local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns +local sort = table.sort xml.css = xml.css or { } local css = xml.css @@ -169,3 +171,716 @@ function css.colorspecification(str) local c = str and attributes.colors.values[tonumber(str)] return c and format("rgb(%s%%,%s%%,%s%%)",c[3]*100,c[4]*100,c[5]*100) end + +-- The following might be handy. It hooks into the normal parser as <selector> +-- and should work ok with the rest. It's sometimes even a bit faster but that might +-- change. It's somewhat optimized but not too aggressively. + +-- element-1 > element-2 : element-2 with parent element-1 + +local function s_element_a(list,collected,c,negate,str,dummy,dummy,n) + local all = str == "*" + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + local ok = all or ll.tg == str + if negate then + ok = not ok + end + if ok then + c = c + 1 + collected[c] = ll + end + if (not n or n > 1) and dt then + c = s_element_a(dt,collected,c,negate,str,dummy,dummy,n and n+1 or 1) + end + end + end + return c +end + +-- element-1 + element-2 : element-2 preceded by element-1 + +local function s_element_b(list,collected,c,negate,str) + local all = str == "*" + for l=1,#list do + local ll = list[l] + local pp = ll.__p__ + if pp then + local dd = pp.dt + if dd then + local ni = ll.ni + local d = dd[ni+1] + local dt = d and d.dt + if not dt then + d = dd[ni+2] + dt = d and d.dt + end + if dt then + local ok = all or d.tg == str + if negate then + ok = not ok + end + if ok then + c = c + 1 + collected[c] = d + end + end + end + end + end + return c +end + +-- element-1 ~ element-2 : element-2 preceded by element-1 -- ? + +local function s_element_c(list,collected,c,negate,str) + local all = str == "*" + for l=1,#list do + local ll = list[l] + local pp = ll.__p__ + if pp then + local dt = pp.dt + if dt then + local ni = ll.ni + for i=ni+1,#dt do + local d = dt[i] + local dt = d.dt + if dt then + local ok = all or d.tg == str + if negate then + ok = not ok + end + if ok then + c = c + 1 + collected[c] = d + end + end + end + end + end + end + return c +end + +-- element +-- element-1 element-2 : element-2 inside element-1 + +local function s_element_d(list,collected,c,negate,str) + if str == "*" then + if not negate then + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + if not ll.special then + c = c + 1 + collected[c] = ll + end + c = s_element_d(dt,collected,c,negate,str) + end + end + end + else + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + if not ll.special then + local ok = ll.tg == str + if negate then + ok = not ok + end + if ok then + c = c + 1 + collected[c] = ll + end + end + c = s_element_d(dt,collected,c,negate,str) + end + end + end + return c +end + +-- [attribute] +-- [attribute=value] equals +-- [attribute~=value] contains word +-- [attribute^="value"] starts with +-- [attribute$="value"] ends with +-- [attribute*="value"] contains + +-- .class (no need to optimize) +-- #id (no need to optimize) + +local function s_attribute(list,collected,c,negate,str,what,value) + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + local at = ll.at + if at then + local v = at[str] + local ok = negate + if v then + if not what then + ok = not negate + elseif what == 1 then + if v == value then + ok = not negate + end + elseif what == 2 then + -- todo: lpeg + if find(v,value) then + ok = not negate + end + elseif what == 3 then + -- todo: lpeg + if find(v," ") then + for s in gmatch(v,"[^ ]+") do + if s == value then + ok = not negate + break + end + end + elseif v == value then + ok = not negate + end + end + end + if ok then + c = c + 1 + collected[c] = ll + end + end + c = s_attribute(dt,collected,c,negate,str,what,value) + end + end + return c +end + +-- :nth-child(n) +-- :nth-last-child(n) +-- :first-child +-- :last-child + +local function filter_down(collected,c,negate,dt,a,b) + local t = { } + local n = 0 + for i=1,#dt do + local d = dt[i] + if type(d) == "table" then + n = n + 1 + t[n] = i + end + end + if n == 0 then + return 0 + end + local m = a + while true do + if m > n then + break + end + if m > 0 then + t[m] = -t[m] -- sign signals match + end + m = m + b + end + if negate then + for i=n,1-1 do + local ti = t[i] + if ti > 0 then + local di = dt[ti] + c = c + 1 + collected[c] = di + end + end + else + for i=n,1,-1 do + local ti = t[i] + if ti < 0 then + ti = - ti + local di = dt[ti] + c = c + 1 + collected[c] = di + end + end + end + return c +end + +local function filter_up(collected,c,negate,dt,a,b) + local t = { } + local n = 0 + for i=1,#dt do + local d = dt[i] + if type(d) == "table" then + n = n + 1 + t[n] = i + end + end + if n == 0 then + return 0 + end + if not b then + b = 0 + end + local m = n - a + while true do + if m < 1 then + break + end + if m < n then + t[m] = -t[m] -- sign signals match + end + m = m - b + end + if negate then + for i=1,n do + local ti = t[i] + if ti > 0 then + local di = dt[ti] + c = c + 1 + collected[c] = di + end + end + else + for i=1,n do + local ti = t[i] + if ti < 0 then + ti = - ti + local di = dt[ti] + c = c + 1 + collected[c] = di + end + end + end + return c +end + +local function just(collected,c,negate,dt,a,start,stop,step) + local m = 0 + for i=start,stop,step do + local d = dt[i] + if type(d) == "table" then + m = m + 1 + if negate then + if a ~= m then + c = c + 1 + collected[c] = d + end + else + if a == m then + c = c + 1 + collected[c] = d + break + end + end + end + end + return c +end + +local function s_nth_child(list,collected,c,negate,a,n,b) + if n == "n" then + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + c = filter_up(collected,c,negate,dt,a,b) + end + end + else + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + c = just(collected,c,negate,dt,a,1,#dt,1) + end + end + end + return c +end + +local function s_nth_last_child(list,collected,c,negate,a,n,b) + if n == "n" then + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + c = filter_down(collected,c,negate,dt,a,b) + end + end + else + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + c = just(collected,c,negate,dt,a,#dt,1,-1) + end + end + end + return c +end + +-- :nth-of-type(n) +-- :nth-last-of-type(n) +-- :first-of-type +-- :last-of-type + +local function s_nth_of_type(list,collected,c,negate,a,n,b) + if n == "n" then + return filter_up(collected,c,negate,list,a,b) + else + return just(collected,c,negate,list,a,1,#list,1) + end +end + +local function s_nth_last_of_type(list,collected,c,negate,a,n,b) + if n == "n" then + return filter_down(collected,c,negate,list,a,b) + else + return just(collected,c,negate,list,a,#list,1,-1) + end +end + +-- :only-of-type + +local function s_only_of_type(list,collected,c,negate) + if negate then + for i=1,#list do + c = c + 1 + collected[c] = list[i] + end + else + if #list == 1 then + c = c + 1 + collected[c] = list[1] + end + end + return c +end + +-- :only-child + +local function s_only_child(list,collected,c,negate) + if negate then + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + for i=1,#dt do + local di = dt[i] + if type(di) == "table" then + c = c + 1 + collected[c] = di + end + end + end + end + else + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt and #dt == 1 then + local di = dt[1] + if type(di) == "table" then + c = c + 1 + collected[c] = di + end + end + end + end + return c +end + +-- :empty + +local function s_empty(list,collected,c,negate) + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + local dn = #dt + local ok = dn == 0 + if not ok and dn == 1 then + local d = dt[1] + if type(d) == "string" and is_empty(d) then + ok = true + end + end + if negate then + ok = not ok + end + if ok then + c = c + 1 + collected[c] = ll + end + end + end + return c +end + +-- :root + +local function s_root(list,collected,c,negate) + for l=1,#list do + local ll = list[l] + if type(ll) == "table" then + local r = xml.root(ll) + if r then + if r.special and r.tg == "@rt@" then + r = r.dt[r.ri] + end + c = c + 1 + collected[c] = r + break + end + end + end + return c +end + +local P, R, S, C, Cs, Ct, Cc, Carg, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.Cc, lpeg.Carg, lpeg.match + +local whitespace = lpegpatterns.whitespace +local p_number = lpegpatterns.integer / tonumber +local p_space = whitespace^0 + +local p_key = C((R("az","AZ","09") + S("_-"))^1) +local p_left = S("#.[],:()") +local p_right = S("#.[],:() ") +local p_tag = C((1-p_left) * (1-p_right)^0) +local p_value = C((1-P("]"))^0) +local p_unquoted = (P('"')/"") * C((1-P('"'))^0) * (P('"')/"") + + (1-P("]"))^1 +local p_element = Ct( ( + P(">") * p_space * Cc(s_element_a) + + P("+") * p_space * Cc(s_element_b) + + P("~") * p_space * Cc(s_element_c) + + Cc(s_element_d) + ) * p_tag ) +local p_attribute = P("[") * Ct(Cc(s_attribute) * p_key * ( + P("=" ) * Cc(1) * Cs( p_unquoted) + + P("^=") * Cc(2) * Cs(Cc("^") * (p_unquoted / topattern)) + + P("$=") * Cc(2) * Cs( p_unquoted / topattern * Cc("$")) + + P("*=") * Cc(2) * Cs( p_unquoted / topattern) + + P("~=") * Cc(3) * Cs( p_unquoted) + )^0 * P("]")) + +local p_separator = p_space * P(",") * p_space + +local p_formula = p_space * P("(") + * p_space + * ( + p_number * p_space * (C("n") * p_space * (p_number + Cc(0)))^-1 + + P("even") * Cc(0) * Cc("n") * Cc(2) + + P("odd") * Cc(-1) * Cc("n") * Cc(2) + ) + * p_space + * P(")") + +local p_step = P(".") * Ct(Cc(s_attribute) * Cc("class") * Cc(3) * p_tag) + + P("#") * Ct(Cc(s_attribute) * Cc("id") * Cc(1) * p_tag) + + p_attribute + + p_element + + P(":nth-child") * Ct(Cc(s_nth_child) * p_formula) + + P(":nth-last-child") * Ct(Cc(s_nth_last_child) * p_formula) + + P(":first-child") * Ct(Cc(s_nth_child) * Cc(1)) + + P(":last-child") * Ct(Cc(s_nth_last_child) * Cc(1)) + + P(":only-child") * Ct(Cc(s_only_child) ) + + P(":nth-of-type") * Ct(Cc(s_nth_of_type) * p_formula) + + P(":nth-last-of-type") * Ct(Cc(s_nth_last_of_type) * p_formula) + + P(":first-of-type") * Ct(Cc(s_nth_of_type) * Cc(1)) + + P(":last-of-type") * Ct(Cc(s_nth_last_of_type) * Cc(1)) + + P(":only-of-type") * Ct(Cc(s_only_of_type) ) + + P(":empty") * Ct(Cc(s_empty) ) + + P(":root") * Ct(Cc(s_root) ) + +local p_not = P(":not") * Cc(true) * p_space * P("(") * p_space * p_step * p_space * P(")") +local p_yes = Cc(false) * p_space * p_step + +local p_stepper = Ct((p_space * (p_not+p_yes))^1) +local p_steps = Ct((p_stepper * p_separator^0)^1) * p_space * (P(-1) + function() print("error") end) + +local cache = table.setmetatableindex(function(t,k) + local v = lpegmatch(p_steps,k) or false + t[k] = v + return v +end) + +local function selector(root,s) + -- local steps = lpegmatch(p_steps,s) + local steps = cache[s] + if steps then + local done = { } + local collected = { } + local nofcollected = 0 + local nofsteps = #steps + for i=1,nofsteps do + local step = steps[i] + local n = #step + if n > 0 then + local r = root + local m = 0 + local c = { } + for i=1,n,2 do + local s = step[i+1] -- function + data + m = s[1](r,c,0,step[i],s[2],s[3],s[4]) + if m == 0 then + break + else + r = c + c = { } + end + end + if m > 0 then + if nofsteps > 1 then + for i=1,m do + local ri = r[i] + if done[ri] then + -- print("duplicate",i) + -- elseif ri.special then + -- done[ri] = true + else + nofcollected = nofcollected + 1 + collected[nofcollected] = ri + done[ri] = true + end + end + else + return r + end + end + end + end + if nofcollected > 1 then + -- local n = 0 + -- local function traverse(e) + -- if done[e] then + -- n = n + 1 + -- done[e] = n + -- end + -- local dt = e.dt + -- if dt then + -- for i=1,#dt do + -- local e = dt[i] + -- if type(e) == "table" then + -- traverse(e) + -- end + -- end + -- end + -- end + -- traverse(root[1]) + -- + local n = 0 + local function traverse(dt) + for i=1,#dt do + local e = dt[i] + if done[e] then + n = n + 1 + done[e] = n + if n == nofcollected then + return + end + end + local d = e.dt + if d then + traverse(d) + if n == nofcollected then + return + end + end + end + end + local r = root[1] + if done[r] then + n = n + 1 + done[r] = n + end + traverse(r.dt) + -- + sort(collected,function(a,b) return done[a] < done[b] end) + end + return collected + else + return { } + end +end + +xml.applyselector= selector + +-- local t = [[ +-- <?xml version="1.0" ?> +-- +-- <a> +-- <b class="one"> </b> +-- <b class="two"> </b> +-- <b class="one"> </b> +-- <b class="three"> </b> +-- <b id="first"> </b> +-- <c> </c> +-- <d> d e </d> +-- <e> d e </e> +-- <e> d e e </e> +-- <d> d f </d> +-- <f foo="bar"> </f> +-- <f bar="foo"> </f> +-- <f bar="foo1"> </f> +-- <f bar="foo2"> </f> +-- <f bar="foo3"> </f> +-- <f bar="foo+4"> </f> +-- <g> </g> +-- <?crap ?> +-- <!-- crap --> +-- <g> <gg> <d> </d> </gg> </g> +-- <g> <gg> <f> </f> </gg> </g> +-- <g> <gg> <f class="one"> g gg f </f> </gg> </g> +-- <g> </g> +-- <g> <gg> <f class="two"> g gg f </f> </gg> </g> +-- <g> <gg> <f class="three"> g gg f </f> </gg> </g> +-- <g> <f class="one"> g f </f> </g> +-- <g> <f class="three"> g f </f> </g> +-- <h whatever="four five six"> </h> +-- </a> +-- ]] +-- +-- local s = [[ .one ]] +-- local s = [[ .one, .two ]] +-- local s = [[ .one, .two, #first ]] +-- local s = [[ .one, .two, #first, c, e, [foo], [bar=foo] ]] +-- local s = [[ .one, .two, #first, c, e, [foo], [bar=foo], [bar~=foo] [bar^="foo"] ]] +-- local s = [[ [bar^="foo"] ]] +-- local s = [[ g f .one, g f .three ]] +-- local s = [[ g > f .one, g > f .three ]] +-- local s = [[ * ]] +-- local s = [[ d + e ]] +-- local s = [[ d ~ e ]] +-- local s = [[ d ~ e, g f .one, g f .three ]] +-- local s = [[ :not(d) ]] +-- local s = [[ [whatever~="five"] ]] +-- local s = [[ :not([whatever~="five"]) ]] +-- local s = [[ e ]] +-- local s = [[ :not ( e ) ]] +-- local s = [[ a:nth-child(3) ]] +-- local s = [[ a:nth-child(3n+1) ]] +-- local s = [[ a:nth-child(2n+8) ]] +-- local s = [[ g:nth-of-type(3) ]] +-- local s = [[ a:first-child ]] +-- local s = [[ a:last-child ]] +-- local s = [[ e:first-of-type ]] +-- local s = [[gg d:only-of-type ]] +-- local s = [[ a:nth-child(even) ]] +-- local s = [[ a:nth-child(odd) ]] +-- local s = [[ g:empty ]] +-- local s = [[ g:root ]] + +function css.applyselector(x,str) + -- the wrapping needs checking so this is a placeholder + return applyselector({ x },str) +end + +-- local c = css.applyselector(xml.convert(t),s) for i=1,#c do print(xml.tostring(c[i])) end + diff --git a/tex/context/base/mkiv/lxml-ent.lua b/tex/context/base/mkiv/lxml-ent.lua index c392713f0..93f48046b 100644 --- a/tex/context/base/mkiv/lxml-ent.lua +++ b/tex/context/base/mkiv/lxml-ent.lua @@ -8,8 +8,6 @@ if not modules then modules = { } end modules ['lxml-ent'] = { local type, next, tonumber = type, next, tonumber local byte, format = string.byte, string.format -local utfchar = utf.char -local lpegmatch = lpeg.match local setmetatableindex = table.setmetatableindex --[[ldx-- diff --git a/tex/context/base/mkiv/lxml-ini.lua b/tex/context/base/mkiv/lxml-ini.lua index 6026b1090..11f634739 100644 --- a/tex/context/base/mkiv/lxml-ini.lua +++ b/tex/context/base/mkiv/lxml-ini.lua @@ -41,6 +41,8 @@ implement { name = "xmldoifelseselfempty", actions = lxml.doifelseempty, arg --------- { name = "xmlflushstripped", actions = lxml.strip, arguments = { "string", true } } implement { name = "xmlall", actions = lxml.all, arguments = { "string", "string" } } implement { name = "xmllastmatch", actions = lxml.lastmatch } +implement { name = "xmlpushmatch", actions = lxml.pushmatch } +implement { name = "xmlpopmatch", actions = lxml.popmatch } implement { name = "xmlatt", actions = lxml.att, arguments = { "string", "string" } } implement { name = "xmllastatt", actions = lxml.lastatt } implement { name = "xmlattdef", actions = lxml.att, arguments = { "string", "string", "string" } } diff --git a/tex/context/base/mkiv/lxml-ini.mkiv b/tex/context/base/mkiv/lxml-ini.mkiv index 6fa14ddfc..6ba6bc8d4 100644 --- a/tex/context/base/mkiv/lxml-ini.mkiv +++ b/tex/context/base/mkiv/lxml-ini.mkiv @@ -82,6 +82,8 @@ \let\xmllast \clf_xmllast \let\xmllastatt \clf_xmllastatt \let\xmllastmatch \clf_xmllastmatch +\let\xmlpushmatch \clf_xmlpushmatch +\let\xmlpopmatch \clf_xmlpopmatch \let\xmlloaddirectives \clf_xmlloaddirectives \let\xmlmain \clf_xmlmain \let\xmlmatch \clf_xmlmatch @@ -310,6 +312,16 @@ \unexpanded\def\xmlinstalldirective#1#2% {\clf_xmlinstalldirective{#1}{\csstring#2}} +% an example: + +% <?context-tex-directive bgroup ?> + +\appendtoks + \xmlinstalldirective{tex}{xmltexcommand}% +\to \everyjob + +\def\xmltexcommand#1{\begincsname#1\endcsname} + % \def\xmlcontextdirective#1% kind class key value % {\executeifdefined{xml#1directive}\gobblethreearguments} diff --git a/tex/context/base/mkiv/lxml-lpt.lua b/tex/context/base/mkiv/lxml-lpt.lua index 7ee1db1d8..bb6fb4568 100644 --- a/tex/context/base/mkiv/lxml-lpt.lua +++ b/tex/context/base/mkiv/lxml-lpt.lua @@ -518,6 +518,15 @@ local function apply_expression(list,expression,order) return collected end +local function apply_selector(list,specification) + if xml.applyselector then + apply_selector = xml.applyselector + return apply_selector(list,specification) + else + return list + end +end + -- this one can be made faster but there are not that many conversions so it doesn't -- really pay of @@ -717,6 +726,10 @@ local function register_nodes(nodetest,nodes) return { kind = "nodes", nodetest = nodetest, nodes = nodes } end +local function register_selector(specification) + return { kind = "selector", specification = specification } +end + local function register_expression(expression) local converted = lpegmatch(converter,expression) local runner = load(format(template_e,converted)) @@ -775,7 +788,7 @@ local pathparser = Ct { "patterns", -- can be made a bit faster by moving some p -- the / is needed for // as descendant or self is somewhat special -- -- step = (V("shortcuts") + V("axis") * spaces * V("nodes")^0 + V("error")) * spaces * V("expressions")^0 * spaces * V("finalizer")^0, - step = ((V("shortcuts") + P("/") + V("axis")) * spaces * V("nodes")^0 + V("error")) * spaces * V("expressions")^0 * spaces * V("finalizer")^0, + step = ((V("shortcuts") + V("selector") + P("/") + V("axis")) * spaces * V("nodes")^0 + V("error")) * spaces * V("expressions")^0 * spaces * V("finalizer")^0, axis = V("last_match") + V("descendant") @@ -807,36 +820,40 @@ local pathparser = Ct { "patterns", -- can be made a bit faster by moving some p + V("s_parent") + V("s_self") + V("s_root") - + V("s_ancestor"), + + V("s_ancestor") + + V("s_lastmatch"), shortcuts = V("shortcuts_a") * (spaces * "/" * spaces * V("shortcuts_a"))^0, s_descendant_or_self = (P("***/") + P("/")) * Cc(register_descendant_or_self), --- *** is a bonus s_descendant = P("**") * Cc(register_descendant), - s_child = P("*") * no_nextcolon * Cc(register_child ), - s_parent = P("..") * Cc(register_parent ), - s_self = P("." ) * Cc(register_self ), - s_root = P("^^") * Cc(register_root ), - s_ancestor = P("^") * Cc(register_ancestor ), + s_child = P("*") * no_nextcolon * Cc(register_child), + s_parent = P("..") * Cc(register_parent), + s_self = P("." ) * Cc(register_self), + s_root = P("^^") * Cc(register_root), + s_ancestor = P("^") * Cc(register_ancestor), + s_lastmatch = P("=") * Cc(register_last_match), -- we can speed this up when needed but we cache anyway so ... - descendant = P("descendant::") * Cc(register_descendant ), - child = P("child::") * Cc(register_child ), - parent = P("parent::") * Cc(register_parent ), - self = P("self::") * Cc(register_self ), - root = P('root::') * Cc(register_root ), - ancestor = P('ancestor::') * Cc(register_ancestor ), - descendant_or_self = P('descendant-or-self::') * Cc(register_descendant_or_self ), - ancestor_or_self = P('ancestor-or-self::') * Cc(register_ancestor_or_self ), - -- attribute = P('attribute::') * Cc(register_attribute ), - -- namespace = P('namespace::') * Cc(register_namespace ), - following = P('following::') * Cc(register_following ), - following_sibling = P('following-sibling::') * Cc(register_following_sibling ), - preceding = P('preceding::') * Cc(register_preceding ), - preceding_sibling = P('preceding-sibling::') * Cc(register_preceding_sibling ), - reverse_sibling = P('reverse-sibling::') * Cc(register_reverse_sibling ), - last_match = P('last-match::') * Cc(register_last_match ), + descendant = P("descendant::") * Cc(register_descendant), + child = P("child::") * Cc(register_child), + parent = P("parent::") * Cc(register_parent), + self = P("self::") * Cc(register_self), + root = P('root::') * Cc(register_root), + ancestor = P('ancestor::') * Cc(register_ancestor), + descendant_or_self = P('descendant-or-self::') * Cc(register_descendant_or_self), + ancestor_or_self = P('ancestor-or-self::') * Cc(register_ancestor_or_self), + -- attribute = P('attribute::') * Cc(register_attribute), + -- namespace = P('namespace::') * Cc(register_namespace), + following = P('following::') * Cc(register_following), + following_sibling = P('following-sibling::') * Cc(register_following_sibling), + preceding = P('preceding::') * Cc(register_preceding), + preceding_sibling = P('preceding-sibling::') * Cc(register_preceding_sibling), + reverse_sibling = P('reverse-sibling::') * Cc(register_reverse_sibling), + last_match = P('last-match::') * Cc(register_last_match), + + selector = P("{") * C((1-P("}"))^1) * P("}") / register_selector, nodes = (V("nodefunction") * spaces * P("(") * V("nodeset") * P(")") + V("nodetest") * V("nodeset")) / register_nodes, @@ -1026,6 +1043,8 @@ do collected = apply_nodes(collected,pi.nodetest,pi.nodes) elseif kind == "expression" then collected = apply_expression(collected,pi.evaluator,order) + elseif kind == "selector" then + collected = apply_selector(collected,pi.specification) elseif kind == "finalizer" then collected = pi.finalizer(collected) -- no check on # here p.matched = p.matched + 1 @@ -1068,6 +1087,9 @@ do elseif kind == "expression" then collected = apply_expression(collected,pi.evaluator,order) report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted) + elseif kind == "selector" then + collected = apply_selector(collected,pi.specification) + report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification) elseif kind == "finalizer" then collected = pi.finalizer(collected) report_lpath("% 10i : fi : %s : %s(%s)",(type(collected) == "table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "") @@ -1100,6 +1122,8 @@ do collected = apply_nodes(collected,pi.nodetest,pi.nodes) elseif kind == "expression" then collected = apply_expression(collected,pi.evaluator,order) + elseif kind == "selector" then + collected = apply_selector(collected,pi.specification) elseif kind == "finalizer" then return pi.finalizer(collected) end @@ -1175,6 +1199,16 @@ do return lastmatch end + local stack = { } + + function xml.pushmatch() + insert(stack,lastmatch) + end + + function xml.popmatch() + lastmatch = remove(stack) + end + end local applylpath = xml.applylpath diff --git a/tex/context/base/mkiv/lxml-tab.lua b/tex/context/base/mkiv/lxml-tab.lua index 60d6262c7..02228c7c5 100644 --- a/tex/context/base/mkiv/lxml-tab.lua +++ b/tex/context/base/mkiv/lxml-tab.lua @@ -34,7 +34,7 @@ local xml = xml --~ local xml = xml local concat, remove, insert = table.concat, table.remove, table.insert -local type, next, setmetatable, getmetatable, tonumber, rawset = type, next, setmetatable, getmetatable, tonumber, rawset +local type, next, setmetatable, getmetatable, tonumber, rawset, select = type, next, setmetatable, getmetatable, tonumber, rawset, select local lower, find, match, gsub = string.lower, string.find, string.match, string.gsub local sort = table.sort local utfchar = utf.char @@ -264,6 +264,7 @@ local function add_empty(spacing, namespace, tag) tg = tag, at = at, dt = { }, + ni = nt, -- set slot, needed for css filtering __p__ = top } dt[nt] = t @@ -285,7 +286,8 @@ local function add_begin(spacing, namespace, tag) rn = resolved, tg = tag, at = at, - dt = {}, + dt = { }, + ni = nil, -- preset slot, needed for css filtering __p__ = stack[level] } setmetatable(top, mt) @@ -314,7 +316,7 @@ local function add_end(spacing, namespace, tag) dt = top.dt nt = #dt + 1 dt[nt] = toclose - -- dt[0] = top -- nasty circular reference when serializing table + toclose.ni = nt -- update slot, needed for css filtering if toclose.at.xmlns then remove(xmlns) end @@ -324,7 +326,7 @@ end -- -- will be an option: dataonly -- --- if #text == 0 or lpegmatch(spaceonly,text) then +-- if #text == 0 or lpegmatch(spaceonly,text) then -- return -- end @@ -370,7 +372,13 @@ local function add_special(what, spacing, text) -- forget it else nt = nt + 1 - dt[nt] = { special=true, ns="", tg=what, dt={ text } } + dt[nt] = { + special = true, + ns = "", + tg = what, + ni = nil, -- preset slot + dt = { text }, + } end end @@ -439,7 +447,6 @@ do local p_rest = (1-P(";"))^0 local p_many = P(1)^0 - local p_char = lpegpatterns.utf8character local parsedentity = P("&#") * (P("x")*(p_rest/fromhex) + (p_rest/fromdec)) * P(";") * P(-1) + @@ -494,15 +501,30 @@ do [ [[~]] ] = "&U+7E;", } + local privates_x = { -- for xml + [ [["]] ] = "&U+22;", + [ [[#]] ] = "&U+23;", + [ [[$]] ] = "&U+24;", + [ [[%]] ] = "&U+25;", + [ [[']] ] = "&U+27;", + [ [[\]] ] = "&U+5C;", + [ [[{]] ] = "&U+7B;", + [ [[|]] ] = "&U+7C;", + [ [[}]] ] = "&U+7D;", + [ [[~]] ] = "&U+7E;", + } + local privates_n = { -- keeps track of defined ones } local escaped = utf.remapper(privates_u,"dynamic") local unprivatized = utf.remapper(privates_p,"dynamic") local unspecialized = utf.remapper(privates_s,"dynamic") + local despecialized = utf.remapper(privates_x,"dynamic") xml.unprivatized = unprivatized xml.unspecialized = unspecialized + xml.despecialized = despecialized xml.escaped = escaped local function unescaped(s) @@ -1050,9 +1072,13 @@ local grammar_unparsed_text = P { "preamble", -- maybe we will add settings to result as well -local function _xmlconvert_(data, settings) +local function _xmlconvert_(data,settings) settings = settings or { } -- no_root strip_cm_and_dt given_entities parent_root error_handler preparexmlstate(settings) + local preprocessor = settings.preprocessor + if data and data ~= "" and type(preprocessor) == "function" then + data = preprocessor(data,settings) or data -- settings.currentresource + end if settings.parent_root then mt = getmetatable(settings.parent_root) else @@ -1240,17 +1266,15 @@ generic table copier. Since we know what we're dealing with we can speed up things a bit. The second argument is not to be used!</p> --ldx]]-- --- local function copy(old,tables) +-- local function copy(old) -- if old then --- if not tables then --- tables = { } --- end -- local new = { } --- if not tables[old] then --- tables[old] = new --- end -- for k,v in next, old do --- new[k] = (type(v) == "table" and (tables[v] or copy(v, tables))) or v +-- if type(v) == "table" then +-- new[k] = table.copy(v) +-- else +-- new[k] = v +-- end -- end -- local mt = getmetatable(old) -- if mt then @@ -1261,15 +1285,27 @@ can speed up things a bit. The second argument is not to be used!</p> -- return { } -- end -- end +-- +-- We need to prevent __p__ recursio, so: -local function copy(old) +local function copy(old,p) if old then local new = { } - for k,v in next, old do - if type(v) == "table" then - new[k] = table.copy(v) - else + for k, v in next, old do + local t = type(v) == "table" + if k == "at" then + local t = { } + for k, v in next, v do + t[k] = v + end + new[k] = t + elseif k == "dt" then + v.__p__ = nil + v = copy(v,new) new[k] = v + v.__p__ = p + else + new[k] = v -- so we also share entities, etc in root end end local mt = getmetatable(old) @@ -1317,7 +1353,9 @@ and then handle the lot.</p> local f_attribute = formatters['%s=%q'] --- we could reuse ats +-- we could reuse ats .. for high performance we could also +-- have a multiple handle calls instead of multiple arguments +-- but it's not that critical local function verbose_element(e,handlers,escape) -- options local handle = handlers.handle @@ -1480,7 +1518,7 @@ local function newhandlers(settings) for k,v in next, settings do if type(v) == "table" then local tk = t[k] if not tk then tk = { } t[k] = tk end - for kk,vv in next, v do + for kk, vv in next, v do tk[kk] = vv end else @@ -1580,19 +1618,43 @@ function xml.save(root,name) serialize(root,xmlfilehandler,name) end -local result +-- local result +-- +-- local xmlstringhandler = newhandlers { +-- name = "string", +-- initialize = function() +-- result = { } +-- return result +-- end, +-- finalize = function() +-- return concat(result) +-- end, +-- handle = function(...) +-- result[#result+1] = concat { ... } +-- end, +-- } + +local result, r, threshold = { }, 0, 512 local xmlstringhandler = newhandlers { name = "string", initialize = function() - result = { } + r = 0 return result end, finalize = function() - return concat(result) + local done = concat(result,"",1,r) + r = 0 + if r > threshold then + result = { } + end + return done end, handle = function(...) - result[#result+1] = concat { ... } + for i=1,select("#",...) do + r = r + 1 + result[r] = select(i,...) + end end, } diff --git a/tex/context/base/mkiv/lxml-tex.lua b/tex/context/base/mkiv/lxml-tex.lua index 3a49ea3d2..582185ba8 100644 --- a/tex/context/base/mkiv/lxml-tex.lua +++ b/tex/context/base/mkiv/lxml-tex.lua @@ -10,7 +10,6 @@ if not modules then modules = { } end modules ['lxml-tex'] = { -- interface and not the context one. If we ever do that there will -- be an cldf-xml helper library. -local utfchar = utf.char local concat, insert, remove, sortedkeys, reversed = table.concat, table.insert, table.remove, table.sortedkeys, table.reverse local format, sub, gsub, find, gmatch, match = string.format, string.sub, string.gsub, string.find, string.gmatch, string.match local type, next, tonumber, tostring, select = type, next, tonumber, tostring, select @@ -46,6 +45,7 @@ local xmltext = xml.text local xmltostring = xml.tostring local xmlapplylpath = xml.applylpath local xmlunspecialized = xml.unspecialized +local xmldespecialized = xml.despecialized -- nicer in expanded xml local xmlprivatetoken = xml.privatetoken local xmlstripelement = xml.stripelement local xmlinclusion = xml.inclusion @@ -53,6 +53,8 @@ local xmlinclusions = xml.inclusions local xmlbadinclusions = xml.badinclusions local xmlcontent = xml.content local xmllastmatch = xml.lastmatch +local xmlpushmatch = xml.pushmatch +local xmlpopmatch = xml.popmatch directives.enable("xml.path.keeplastmatch") @@ -309,14 +311,6 @@ function lxml.stopraw() forceraw = false end -function lxml.startraw() - forceraw = true -end - -function lxml.stopraw() - forceraw = false -end - function lxml.rawroot() return rawroot end @@ -524,6 +518,8 @@ local function entityconverter(id,str,ent) -- todo: disable tex entities when ra return xmlprivatetoken(str) end +lxml.preprocessor = nil + local function lxmlconvert(id,data,compress,currentresource) local settings = { -- we're now roundtrip anyway unify_predefined_entities = false, -- is also default @@ -531,6 +527,7 @@ local function lxmlconvert(id,data,compress,currentresource) resolve_predefined_entities = true, -- is also default resolve_entities = function(str,ent) return entityconverter(id,str,ent) end, currentresource = tostring(currentresource or id), + preprocessor = lxml.preprocessor, } if compress and compress == variables.yes then settings.strip_cm_and_dt = true @@ -909,7 +906,8 @@ local function sprint(root) -- check rawroot usage if forceraw then rawroot = root -- contextsprint(ctxcatcodes,xmltostring(root)) -- goes wrong with % etc - root = xmlunspecialized(xmltostring(root)) + -- root = xmlunspecialized(xmltostring(root)) -- we loose < > & + root = xmldespecialized(xmltostring(root)) lpegmatch(xmltextcapture,root) -- goes to toc else xmlserialize(root,xmltexhandler) @@ -1402,7 +1400,7 @@ local function attribute(collected,a,default) end end -local function chainattribute(collected,arguments) -- todo: optional levels +local function chainattribute(collected,arguments,default) -- todo: optional levels if collected and #collected > 0 then local e = collected[1] while e do @@ -1411,6 +1409,7 @@ local function chainattribute(collected,arguments) -- todo: optional levels local a = at[arguments] if a then contextsprint(notcatcodes,a) + return end else break -- error @@ -1418,6 +1417,9 @@ local function chainattribute(collected,arguments) -- todo: optional levels e = e.__p__ end end + if default then + contextsprint(notcatcodes,default) + end end local function chainpath(collected,nonamespace) @@ -1942,6 +1944,9 @@ function lxml.lastmatch() end end +lxml.pushmatch = xmlpushmatch +lxml.popmatch = xmlpopmatch + function lxml.snippet(id,i) local e = getid(id) if e then @@ -2204,7 +2209,11 @@ local pattern = P("context-") * C((1-patterns.whitespace)^1) * C(P(1)^1) function lxml.applyselectors(id) local root = getid(id) local function filter(e) - local dt = e.dt + local dt = e.dt + if not dt then + report_lxml("error in selector, no data in %a",e.tg or "?") + return + end local ndt = #dt local done = false local i = 1 @@ -2310,7 +2319,7 @@ function lxml.applyselectors(id) end end end - else + elseif dti then filter(dti) end end diff --git a/tex/context/base/mkiv/m-fonts-plugins.mkiv b/tex/context/base/mkiv/m-fonts-plugins.mkiv new file mode 100644 index 000000000..ecb311694 --- /dev/null +++ b/tex/context/base/mkiv/m-fonts-plugins.mkiv @@ -0,0 +1,406 @@ +%D \module +%D [ file=m-fonts-plugins, +%D version=2016.10.10, +%D title=\CONTEXT\ Fonts, +%D subtitle=Font Engine Plugins, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D See source code for comments. I wrote this a follow up on a presentation by +%D Kai Eigner, left it for a while, and sort of finalized it the last quarter of +%D 2016. As I don't use this module, apart from maybe testing something, it is +%D not guaranteed to work. Also, plugins can interfere with other functionality +%D in \CONTEXT\ so don't expect too much support. The two modules mentioned +%D below should work in the generic loader too. It's anyhow an illustration of +%D how \type {ffi} can work be used in a practical application. + +\registerctxluafile{font-txt}{1.001} % generic text handler +\registerctxluafile{font-phb}{1.001} % harfbuzz plugin + +\startluacode + + local function processlist(data) + local list = data.list + local timings = data.results + for i=1,#list do + local name = list[i] + local data = timings[name] + local none = data["context none"] or 0 + local node = data["context node"] or 0 + if node > 0.1 then + context.starttabulate { "|l|c|c|c|c|c|" } + context.NC() context.bold(name) + context.NC() context([[$t$]]) + context.NC() context([[$t - t_{\hbox{\tx none}}$]]) + context.NC() context([[$t - t_{\hbox{\tx node}}$]]) + context.NC() context([[$t / t_{\hbox{\tx node}}$]]) + context.NC() context([[$\frac{t - t_{\hbox{\txx none}}}{t_{\hbox{\txx node}} - t_{\hbox{\txx none}}}$]]) + context.NC() context.NR() + context.TL() + for k, v in table.sortedhash(data) do + context.NC() context(k) + context.NC() context("%0.2f",v) + context.NC() context("%0.2f",v - none) + context.NC() context("%0.2f",v - node) + context.NC() context("%0.2f",v / node) + context.NC() if node ~= none then context("%0.2f",(v-none) / (node-none)) end + context.NC() context.NR() + end + context.stoptabulate() + end + end + end + + moduledata.plugins = { + processlist = processlist, + } + +\stopluacode + +\continueifinputfile{m-fonts-plugins.mkiv} + +\usemodule[art-01] + +\starttext + +\edef\tufte{\cldloadfile{tufte.tex}} +\edef\khatt{\cldloadfile{khatt-ar.tex}} + +\startbuffer[latin-definitions] +\definefont[TestA][Serif*test] +\definefont[TestB][SerifItalic*test] +\definefont[TestC][SerifBold*test] +\stopbuffer + +\startbuffer[latin-text] +\TestA \tufte \par +\TestB \tufte \par +\TestC \tufte \par +\dorecurse {10} {% + \TestA Fluffy Test Font A + \TestB Fluffy Test Font B + \TestC Fluffy Test Font C +}\par +\stopbuffer + +\startbuffer[arabic-definitions] +\definedfont[Arabic*test at 14pt] +\setupinterlinespace[line=18pt] +\setupalign[r2l] +\stopbuffer + +\startbuffer[arabic-text] +\dorecurse {10} { + \khatt\space + \khatt\space + \khatt + \blank +} +\stopbuffer + +\startbuffer[mixed-definitions] +\definefont[TestL][Serif*test] +\definefont[TestA][Arabic*test at 14pt] +\setupinterlinespace[line=18pt] +\setupalign[r2l] +\stopbuffer + +\startbuffer[mixed-text] +\dorecurse {2} { + {\TestA\khatt\space\khatt\space\khatt} + {\TestL\lefttoright\tufte} + \blank + \dorecurse{10}{% + {\TestA وَ قَرْمِطْ بَيْنَ الْحُرُوفِ؛ فَإِنَّ} + {\TestL\lefttoright A snippet text that makes no sense.} + } +} +\stopbuffer + +\definefontfeature + [test-none] + [mode=none] + +\definefontfeature + [test-base] + [mode=base, + liga=yes, + kern=yes] + +\definefontfeature + [test-node] + [mode=node, + script=auto, + autoscript=position, + autolanguage=position, + ccmp=yes, + liga=yes, + % rlig=yes, + % hlig=yes, + % dlig=yes, + clig=yes, + kern=yes, + mark=yes, + mkmk=yes, + curs=yes] + +\definefontfeature + [test-text] + [mode=plug, + features=text] + +\definefontfeature + [test-native] + [mode=plug, + features=harfbuzz, + %liga=yes, + %kern=yes, + shaper=native] + +\definefontfeature + [test-uniscribe] + [mode=plug, + features=harfbuzz, + %liga=yes, + %kern=yes, + shaper=uniscribe] + +\definefontfeature + [test-binary] + [mode=plug, + features=harfbuzz, + %liga=yes, + %kern=yes, + shaper=uniscribe, + method=binary] + +\definefontfeature + [arabic-node] + [arabic] + +\definefontfeature + [arabic-native] + [mode=plug, + features=harfbuzz, + % method=binary, + script=arab,language=dflt, +% ccmp=yes, +% init=yes,medi=yes,fina=yes,isol=yes, +% liga=yes,dlig=yes,rlig=yes,clig=yes,calt=yes, +% mark=yes,mkmk=yes,kern=yes,curs=yes, + shaper=native] + +\definefontfeature + [arabic-uniscribe] + [mode=plug, + features=harfbuzz, + script=arab,language=dflt,ccmp=yes, + init=yes,medi=yes,fina=yes,isol=yes, + liga=yes,dlig=yes,rlig=yes,clig=yes,calt=yes, + mark=yes,mkmk=yes,kern=yes,curs=yes, + shaper=uniscribe] + +\starttexdefinition RunLatinTest #1#2#3#4#5 + \start + \dontcomplain + \definefontfeature[test][test-#4] + \writestatus{warning}{#1 #3 #4 (1 initial run)} + \page + \startluacode + collectgarbage("collect") + \stopluacode + \title{#1 #3 #4} + \start + \getbuffer[#5-definitions] + \showfontkerns + \showmakeup[discretionary] + \enabletrackers[fonts.plugins.hb.colors]% + \testfeatureonce{1}{ + \getbuffer[#5-text] + } + \stop + \page + \startluacode + collectgarbage("collect") + \stopluacode + \ifnum#2>1\relax + \writestatus{warning}{#1 #3 #4 (#2 timing runs)} + \start + \getbuffer[#5-definitions] + \testfeatureonce{#2}{ + \setbox\scratchbox\hbox{\getbuffer[#5-text]} + } + \stop + \writestatus{warning}{done} + \fi + \startluacode + document.collected_timings.timings["#5"].results["#1"]["#3 #4"] = \elapsedtime\space + collectgarbage("collect") + \stopluacode + \stop +\stoptexdefinition + +\starttexdefinition RunArabicTest #1#2#3#4#5 + \start + \dontcomplain + \definefontsynonym[Arabic][#1] + \definefontfeature[test][arabic-#4] + \writestatus{warning}{#1 #3 #4 #5 (1 initial run)} + \page + \startluacode + collectgarbage("collect") + \stopluacode + \title{#1 #3 #4} + \start + \getbuffer[#5-definitions] + \enabletrackers[fonts.plugins.hb.colors]% + \testfeatureonce{1}{ + \setupalign[flushleft] % easier to compare + \getbuffer[#5-text] + } + \par + \stop + \page + \ifnum#2>1\relax + \writestatus{warning}{#1 #3 #4 #5 (#2 timing runs)} + \start + \getbuffer[#5-definitions] + \testfeatureonce{#2}{ + \setbox\scratchbox\hbox{\getbuffer[#5-text]} + } + \stop + \writestatus{warning}{done} + \fi + \startluacode + document.collected_timings.timings["#5"].results["#1"]["#3 #4"] = \elapsedtime\space + collectgarbage("collect") + \stopluacode + \stop +\stoptexdefinition + +\startluacode + local processlist = moduledata.plugins.processlist + + local data = { + timings = { }, + engine = jit and "luajittex" or "luatex", + } + + document.collected_timings = data + + -- LATIN + + local list = { + "modern", + "pagella", + "dejavu", + "cambria", + "ebgaramond", + "lucidaot" + } + + data.timings["latin"] = { + list = list, + results = table.setmetatableindex("table"), + } + + for i=1,#list do + + local name = list[i] + + context.setupbodyfont { name } + context.RunLatinTest (name, 100, "context", "none", "latin") + context.RunLatinTest (name, 100, "context", "base", "latin") + context.RunLatinTest (name, 100, "context", "node", "latin") + context.RunLatinTest (name, 100, "harfbuzz", "native", "latin") + -- context.RunLatinTest (name, 100, "harfbuzz", "uniscribe", "latin") + -- context.RunLatinTest (name, 1, "context", "text", "latin") + -- context.RunLatinTest (name, 1, "harfbuzz", "binary", "latin") + + end + + context(function() + context.page() + context.title((jit and "luajittex" or "luatex") .. " latin") + processlist(data.timings["latin"]) + context.page() + end) + + -- ARABIC + + local list = { + "arabtype" + } + + data.timings["arabic"] = { + list = list, + results = table.setmetatableindex("table") + } + + for i=1,#list do + + local name = list[i] + + context.setupbodyfont { name } + context.RunArabicTest (name, 100, "context", "none", "arabic") + context.RunArabicTest (name, 100, "context", "base", "arabic") + context.RunArabicTest (name, 100, "context", "node", "arabic") + context.RunArabicTest (name, 100, "harfbuzz", "native", "arabic") + -- context.RunArabicTest (name, 100, "harfbuzz", "uniscribe", "arabic") + -- context.RunArabicTest (name, 1, "context", "text", "arabic") + -- context.RunArabicTest (name, 1, "harfbuzz", "binary", "arabic") + + end + + context(function() + context.page() + context.title((jit and "luajittex" or "luatex") .. " arabic") + processlist(data.timings["arabic"]) + context.page() + end) + + -- MIXED + + local list = { + "arabtype" + } + + data.timings["mixed"] = { + list = list, + results = table.setmetatableindex("table") + } + + for i=1,#list do + + local name = list[i] + + context.setupbodyfont { name } + context.RunArabicTest (name, 100, "context", "none", "mixed") + context.RunArabicTest (name, 100, "context", "base", "mixed") + context.RunArabicTest (name, 100, "context", "node", "mixed") + context.RunArabicTest (name, 100, "harfbuzz", "native", "mixed") + -- context.RunArabicTest (name, 100, "harfbuzz", "uniscribe", "mixed") + -- context.RunArabicTest (name, 1, "context", "text", "mixed") + -- context.RunArabicTest (name, 1, "harfbuzz", "binary", "mixed") + + end + + context(function() + context.page() + context.title((jit and "luajittex" or "luatex") .. " mixed") + processlist(data.timings["mixed"]) + context.page() + end) + + context(function() + table.save("m-fonts-plugins-timings-" .. (jit and "luajittex" or "luatex") .. ".lua",data) + end) + +\stopluacode + +\stoptext diff --git a/tex/context/base/mkiv/m-oldotf.mkiv b/tex/context/base/mkiv/m-oldotf.mkiv index 313f9f484..f860df712 100644 --- a/tex/context/base/mkiv/m-oldotf.mkiv +++ b/tex/context/base/mkiv/m-oldotf.mkiv @@ -28,7 +28,6 @@ "font-one", "font-map", "font-fbk", - "font-gds", } local report = logs.reporter("oldotf") local findfile = resolvers.findfile diff --git a/tex/context/base/mkiv/math-acc.mkvi b/tex/context/base/mkiv/math-acc.mkvi index 415f2b91f..c3f8bad40 100644 --- a/tex/context/base/mkiv/math-acc.mkvi +++ b/tex/context/base/mkiv/math-acc.mkvi @@ -178,4 +178,35 @@ \stopusemathstyleparameter \endgroup} +%D Relative new: + +\newconditional\c_math_accents_auto_dotless \settrue\c_math_accents_auto_dotless % cf opentype math + +\let\normalgrave \grave \unexpanded\def\dotlessgrave #1{\normalgrave {\mathdotless#1}} +\let\normalddot \ddot \unexpanded\def\dotlessddot #1{\normalddot {\mathdotless#1}} +\let\normalbar \bar \unexpanded\def\dotlessbar #1{\normalbar {\mathdotless#1}} +\let\normalacute \acute \unexpanded\def\dotlessacute #1{\normalacute {\mathdotless#1}} +\let\normalhat \hat \unexpanded\def\dotlesshat #1{\normalhat {\mathdotless#1}} +\let\normalcheck \check \unexpanded\def\dotlesscheck #1{\normalcheck {\mathdotless#1}} +\let\normalbreve \breve \unexpanded\def\dotlessbreve #1{\normalbreve {\mathdotless#1}} +\let\normaldot \dot \unexpanded\def\dotlessdot #1{\normaldot {\mathdotless#1}} +\let\normalmathring\mathring \unexpanded\def\dotlessmathring#1{\normalmathring{\mathdotless#1}} +\let\normaltilde \tilde \unexpanded\def\dotlesstilde #1{\normaltilde {\mathdotless#1}} +\let\normaldddot \dddot \unexpanded\def\dotlessdddot #1{\normaldddot {\mathdotless#1}} + +\def\math_accents_auto_dotless#1#2% + {\ifconditional\c_math_accents_auto_dotless\expandafter#2\else\expandafter#1\fi} + +\unexpanded\def\grave {\math_accents_auto_dotless\normalgrave \dotlessgrave } +\unexpanded\def\ddot {\math_accents_auto_dotless\normalddot \dotlessddot } +\unexpanded\def\bar {\math_accents_auto_dotless\normalbar \dotlessbar } +\unexpanded\def\acute {\math_accents_auto_dotless\normalacute \dotlessacute } +\unexpanded\def\hat {\math_accents_auto_dotless\normalhat \dotlesshat } +\unexpanded\def\check {\math_accents_auto_dotless\normalcheck \dotlesscheck } +\unexpanded\def\breve {\math_accents_auto_dotless\normalbreve \dotlessbreve } +\unexpanded\def\dot {\math_accents_auto_dotless\normaldot \dotlessdot } +\unexpanded\def\mathring{\math_accents_auto_dotless\normalmathring\dotlessmathring} +\unexpanded\def\tilde {\math_accents_auto_dotless\normaltilde \dotlesstilde } +\unexpanded\def\dddot {\math_accents_auto_dotless\normaldddot \dotlessdddot } + \protect \endinput diff --git a/tex/context/base/mkiv/math-act.lua b/tex/context/base/mkiv/math-act.lua index d0ea78990..ddc7510b1 100644 --- a/tex/context/base/mkiv/math-act.lua +++ b/tex/context/base/mkiv/math-act.lua @@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['math-act'] = { -- Here we tweak some font properties (if needed). local type, next = type, next -local fastcopy = table.fastcopy +local fastcopy, insert, remove = table.fastcopy, table.insert, table.remove local formatters = string.formatters local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end) @@ -28,6 +28,7 @@ local appendgroup = sequencers.appendgroup local appendaction = sequencers.appendaction local fontchars = fonts.hashes.characters +local fontproperties = fonts.hashes.properties local mathfontparameteractions = sequencers.new { name = "mathparameters", @@ -59,7 +60,9 @@ local how = { -- RadicalKernAfterDegree = "horizontal", ScriptPercentScaleDown = "unscaled", ScriptScriptPercentScaleDown = "unscaled", - RadicalDegreeBottomRaisePercent = "unscaled" + RadicalDegreeBottomRaisePercent = "unscaled", + NoLimitSupFactor = "unscaled", + NoLimitSubFactor = "unscaled", } function mathematics.scaleparameters(target,original) @@ -299,7 +302,9 @@ function mathematics.overloaddimensions(target,original,set) end end -sequencers.appendaction("aftercopyingcharacters", "system","mathematics.overloaddimensions") +-- no, it's a feature now (see good-mth): +-- +-- sequencers.appendaction("aftercopyingcharacters", "system","mathematics.overloaddimensions") -- a couple of predefined tweaks: @@ -406,7 +411,6 @@ local setmetatableindex = table.setmetatableindex local family_font = node.family_font local fontcharacters = fonts.hashes.characters -local fontdescriptions = fonts.hashes.descriptions local extensibles = utilities.storage.allocate() fonts.hashes.extensibles = extensibles @@ -418,7 +422,6 @@ local extensibles = mathematics.extensibles local e_left = extensibles.left local e_right = extensibles.right local e_horizontal = extensibles.horizontal -local e_vertical = extensibles.vertical local e_mixed = extensibles.mixed local e_unknown = extensibles.unknown @@ -588,74 +591,179 @@ blocks["uppercasedoublestruck"].gaps = { -- todo: tounicode -function mathematics.injectfallbacks(target,original) - local properties = original.properties - if properties and properties.hasmath then - local specification = target.specification - if specification then - local fallbacks = specification.fallbacks - if fallbacks then - local definitions = fonts.collections.definitions[fallbacks] - if definitions then - if trace_collecting then - report_math("adding fallback characters to font %a",specification.hash) - end - local definedfont = fonts.definers.internal - local copiedglyph = fonts.handlers.vf.math.copy_glyph - local fonts = target.fonts - local size = specification.size -- target.size - local characters = target.characters - if not fonts then - fonts = { } - target.fonts = fonts - target.type = "virtual" - target.properties.virtualized = true - end - if #fonts == 0 then - fonts[1] = { id = 0, size = size } -- sel, will be resolved later - end - local done = { } - for i=1,#definitions do - local definition = definitions[i] - local name = definition.font - local start = definition.start - local stop = definition.stop - local gaps = definition.gaps - local check = definition.check - local force = definition.force - local rscale = definition.rscale or 1 - local offset = definition.offset or start - local id = definedfont { name = name, size = size * rscale } - local index = #fonts + 1 - fonts[index] = { id = id, size = size } - local chars = fontchars[id] - local function remap(unic,unicode,gap) - local unic = unicode + offset - start - if check and not chars[unicode] then - -- not in font - elseif force or (not done[unic] and not characters[unic]) then - if trace_collecting then - report_math("remapping math character, vector %a, font %a, character %C%s%s", - fallbacks,name,unic,check and ", checked",gap and ", gap plugged") - end - characters[unic] = copiedglyph(target,characters,chars,unicode,index) - done[unic] = true - end - end - for unicode = start, stop do - local unic = unicode + offset - start - remap(unic,unicode,false) +-- function mathematics.injectfallbacks(target,original) +-- local properties = original.properties +-- if properties and properties.hasmath then +-- local specification = target.specification +-- if specification then +-- local fallbacks = specification.fallbacks +-- if fallbacks then +-- local definitions = fonts.collections.definitions[fallbacks] +-- if definitions then +-- if trace_collecting then +-- report_math("adding fallback characters to font %a",specification.hash) +-- end +-- local definedfont = fonts.definers.internal +-- local copiedglyph = fonts.handlers.vf.math.copy_glyph +-- local fonts = target.fonts +-- local size = specification.size -- target.size +-- local characters = target.characters +-- if not fonts then +-- fonts = { } +-- target.fonts = fonts +-- target.type = "virtual" +-- target.properties.virtualized = true +-- end +-- if #fonts == 0 then +-- fonts[1] = { id = 0, size = size } -- sel, will be resolved later +-- end +-- local done = { } +-- for i=1,#definitions do +-- local definition = definitions[i] +-- local name = definition.font +-- local start = definition.start +-- local stop = definition.stop +-- local gaps = definition.gaps +-- local check = definition.check +-- local force = definition.force +-- local rscale = definition.rscale or 1 +-- local offset = definition.offset or start +-- local id = definedfont { name = name, size = size * rscale } +-- local index = #fonts + 1 +-- fonts[index] = { id = id, size = size } +-- local chars = fontchars[id] +-- local function remap(unic,unicode,gap) +-- -- local unic = unicode + offset - start +-- if check and not chars[unicode] then +-- -- not in font +-- elseif force or (not done[unic] and not characters[unic]) then +-- if trace_collecting then +-- report_math("remapping math character, vector %a, font %a, character %C%s%s", +-- fallbacks,name,unic,check and ", checked",gap and ", gap plugged") +-- end +-- characters[unic] = copiedglyph(target,characters,chars,unicode,index) +-- done[unic] = true +-- end +-- end +-- for unicode = start, stop do +-- local unic = unicode + offset - start +-- remap(unic,unicode,false) +-- end +-- if gaps then +-- for unic, unicode in next, gaps do +-- remap(unic,unicode,true) +-- end +-- end +-- end +-- end +-- end +-- end +-- end +-- end +-- +-- sequencers.appendaction("aftercopyingcharacters", "system","mathematics.finishfallbacks") + +local stack = { } + +function mathematics.registerfallbackid(n,id,name) + if trace_collecting then + report_math("resolved fallback font %i, name %a, id %a, used %a", + n,name,id,fontproperties[id].fontname) + end + stack[#stack][n] = id +end + +interfaces.implement { -- will be shared with text + name = "registerfontfallbackid", + arguments = { "integer", "integer", "string" }, + actions = mathematics.registerfallbackid, +} + +function mathematics.resolvefallbacks(target,specification,fallbacks) + local definitions = fonts.collections.definitions[fallbacks] + if definitions then + local size = specification.size -- target.size + local list = { } + insert(stack,list) + context.pushcatcodes("prt") -- context.unprotect() + for i=1,#definitions do + local definition = definitions[i] + local name = definition.font + local features = definition.features or "" + local size = size * (definition.rscale or 1) + context.font_fallbacks_register_math(i,name,features,size) + if trace_collecting then + report_math("registering fallback font %i, name %a, size %a, features %a",i,name,size,features) + end + end + context.popcatcodes() + end +end + +function mathematics.finishfallbacks(target,specification,fallbacks) + local list = remove(stack) + if list and #list > 0 then + local definitions = fonts.collections.definitions[fallbacks] + if definitions and #definitions > 0 then + if trace_collecting then + report_math("adding fallback characters to font %a",specification.hash) + end + local definedfont = fonts.definers.internal + local copiedglyph = fonts.handlers.vf.math.copy_glyph + local fonts = target.fonts + local size = specification.size -- target.size + local characters = target.characters + if not fonts then + fonts = { } + target.fonts = fonts + end + target.type = "virtual" + target.properties.virtualized = true + if #fonts == 0 then + fonts[1] = { id = 0, size = size } -- self, will be resolved later + end + local done = { } + for i=1,#definitions do + local definition = definitions[i] + local name = definition.font + local start = definition.start + local stop = definition.stop + local gaps = definition.gaps + local check = definition.check + local force = definition.force + local rscale = definition.rscale or 1 + local offset = definition.offset or start + local id = list[i] + if id then + local index = #fonts + 1 + fonts[index] = { id = id, size = size } + local chars = fontchars[id] + local function remap(unic,unicode,gap) + if check and not chars[unicode] then + return end - if gaps then - for unic, unicode in next, gaps do - remap(unic,unicode,true) + if force or (not done[unic] and not characters[unic]) then + if trace_collecting then + report_math("replacing math character %C by %C using vector %a and font id %a for %a%s%s", + unic,unicode,fallbacks,id,fontproperties[id].fontname,check and ", checked",gap and ", gap plugged") end + characters[unic] = copiedglyph(target,characters,chars,unicode,index) + done[unic] = true + end + end + for unicode = start, stop do + local unic = unicode + offset - start + remap(unic,unicode,false) + end + if gaps then + for unic, unicode in next, gaps do + remap(unic,unicode,true) end end end end + elseif trace_collecting then + report_math("no fallback characters added to font %a",specification.hash) end end end - -sequencers.appendaction("aftercopyingcharacters", "system","mathematics.injectfallbacks") diff --git a/tex/context/base/mkiv/math-ali.mkiv b/tex/context/base/mkiv/math-ali.mkiv index ebb20e33e..49a343ba0 100644 --- a/tex/context/base/mkiv/math-ali.mkiv +++ b/tex/context/base/mkiv/math-ali.mkiv @@ -25,26 +25,28 @@ %D Modules may provide additional alignment features. The following %D mechanisms are provided by the core. +% why all these spans + % n>1 ### needed, strange # interaction in recurse -\newtoks\c_math_align_a -\newtoks\c_math_align_b -\newtoks\c_math_align_c +\newtoks\t_math_align_a +\newtoks\t_math_align_b +\newtoks\t_math_align_c \def\displayopenupvalue{.25\bodyfontsize} \def\math_build_eqalign {\scratchtoks\emptytoks \dorecurse{\mathalignmentparameter\c!m}\math_build_eqalign_step - \normalexpanded{\scratchtoks{\the\scratchtoks\the\c_math_align_c}}} + \normalexpanded{\scratchtoks{\the\scratchtoks\the\t_math_align_c}}} -\def\math_build_eqalign_step +\unexpanded\def\math_build_eqalign_step % make sure no expansion in tracing {\ifnum\recurselevel>\plusone \scratchtoks\expandafter{\the\scratchtoks\tabskip\mathalignmentparameter\c!distance\aligntab\tabskip\zeropoint}% \fi - \normalexpanded{\scratchtoks{\the\scratchtoks\the\c_math_align_a}}% + \normalexpanded{\scratchtoks{\the\scratchtoks\the\t_math_align_a}}% \dorecurse{\numexpr\mathalignmentparameter\c!n-\plusone\relax} - {\normalexpanded{\scratchtoks{\the\scratchtoks\the\c_math_align_b}}}} + {\normalexpanded{\scratchtoks{\the\scratchtoks\the\t_math_align_b}}}} \def\math_math_in_eqalign#1% {\startforceddisplaymath @@ -83,70 +85,141 @@ % use zeroskipplusfill -% i really need to redo this eqno mess ... in lua - \def\math_prepare_r_eqalign_no - {\c_math_align_a{\strut\math_first_in_eqalign\hfil\math_left_of_equalign\span\math_math_in_eqalign{\alignmark\alignmark}\math_right_of_eqalign\tabskip\zeropoint}% - \c_math_align_b{\aligntab\math_next_in_eqalign\math_left_of_equalign\span\math_math_in_eqalign{\alignmark\alignmark}\math_right_of_eqalign\tabskip\zeropoint}% + {\t_math_align_a + {\strut + \tabskip\zeropoint + \alignmark\alignmark % for picking up the number + \aligntab + \math_first_in_eqalign + \hfil + \math_left_of_equalign + \span + \math_math_in_eqalign{\alignmark\alignmark}% + \math_right_of_eqalign + \tabskip\zeropoint}% + \t_math_align_b + {\aligntab + \math_next_in_eqalign + \math_left_of_equalign + \span + \math_math_in_eqalign{\alignmark\alignmark}% + \math_right_of_eqalign + \tabskip\zeropoint}% \ifnum\mathraggedstatus=\plusone - \c_math_align_c{\hfil\aligntab\span\math_text_in_eqalign{\alignmark\alignmark}\tabskip\zeropoint}% + \t_math_align_c + {\hfil + \aligntab + \span + \math_text_in_eqalign{\alignmark\alignmark}% + \tabskip\zeropoint}% \else\ifnum\mathraggedstatus=\plusthree - \c_math_align_c{\hfil\tabskip\zeropoint\s!plus 1\s!fill\aligntab\span\math_text_in_eqalign{\alignmark\alignmark}\tabskip\zeropoint}% + \t_math_align_c + {\hfil + \tabskip\zeropoint\s!plus 1\s!fill + \aligntab + \span + \math_text_in_eqalign{\alignmark\alignmark}% + \tabskip\zeropoint}% \else - \c_math_align_c{\hfil\tabskip\centering\aligntab\llap{\span\math_text_in_eqalign{\alignmark\alignmark}}\tabskip\zeropoint}% + \t_math_align_c + {\hfil + \tabskip\centering + \aligntab + \span + \llap{\math_text_in_eqalign{\alignmark\alignmark}}% + \tabskip\zeropoint}% \fi\fi - \global\mathnumberstatus\zerocount \math_build_eqalign \the\mathdisplayaligntweaks \tabskip\centering} \def\math_prepare_l_eqalign_no % \checkeddisplaymath - {\c_math_align_a{\strut\math_first_in_eqalign\hfil\math_left_of_equalign\span\math_math_in_eqalign{\alignmark\alignmark}\math_right_of_eqalign\tabskip\zeropoint}% - \c_math_align_b{\aligntab\math_next_in_eqalign\math_left_of_equalign\span\math_math_in_eqalign{\alignmark\alignmark}\math_right_of_eqalign\tabskip\zeropoint}% - % problem: number is handled after rest and so ends up in the margin + {\t_math_align_a + {\strut + \tabskip\zeropoint + \alignmark\alignmark % for picking up the number + \aligntab + \math_first_in_eqalign + \hfil + \math_left_of_equalign + \span + \math_math_in_eqalign{\alignmark\alignmark}% + \math_right_of_eqalign + \tabskip\zeropoint}% + \t_math_align_b + {\aligntab + \math_next_in_eqalign + \math_left_of_equalign + \span + \math_math_in_eqalign{\alignmark\alignmark}% + \math_right_of_eqalign + \tabskip\zeropoint}% \ifnum\mathraggedstatus=\plusone - \c_math_align_c{\hfil\aligntab\kern-\displaywidth\rlap{\span\math_text_in_eqalign{\alignmark\alignmark}}\tabskip\displaywidth}% + \t_math_align_c + {\hfil + \aligntab + \kern-\displaywidth + \span + \rlap{\math_text_in_eqalign{\alignmark\alignmark}}% + \tabskip\displaywidth}% \else\ifnum\mathraggedstatus=\plusthree - \c_math_align_c{\hfil\tabskip\zeropoint\s!plus 1\s!fill\aligntab\kern-\displaywidth\span\math_rlap{\span\math_text_in_eqalign{\alignmark\alignmark}}\tabskip\displaywidth}% + \t_math_align_c + {\hfil + \tabskip\zeropoint\s!plus 1\s!fill + \aligntab + \kern-\displaywidth + \span + \math_rlap{\math_text_in_eqalign{\alignmark\alignmark}}% + \tabskip\displaywidth}% \else - \c_math_align_c{\hfil\tabskip\centering\aligntab\kern-\displaywidth\rlap{\span\math_text_in_eqalign{\alignmark\alignmark}}\tabskip\displaywidth}% + \t_math_align_c + {\hfil + \tabskip\centering + \aligntab + \kern-\displaywidth + \span + \rlap{\math_text_in_eqalign{\alignmark\alignmark}}% + \tabskip\displaywidth}% \fi\fi - \global\mathnumberstatus\zerocount \math_build_eqalign \the\mathdisplayaligntweaks \tabskip\centering} +\def\math_halign_checked + {\halign \ifcase\eqalignmode \or to \checkeddisplaywidth \fi} + \def\math_both_eqalign_no_normal#1#2% {\ifmmode - \the\mathdisplayaligntweaks % \let\strc_formulas_place_number\relax % strange hack + \the\mathdisplayaligntweaks \vcenter\bgroup \let\math_finish_eqalign_no\egroup \else \let\math_finish_eqalign_no\relax \fi #1% - \halign \ifcase\eqalignmode \or to \checkeddisplaywidth \fi \expandafter {\the\scratchtoks\crcr#2\crcr}% + \math_halign_checked\expandafter\bgroup\the\scratchtoks\crcr#2\crcr\egroup \math_finish_eqalign_no} \def\math_both_eqalign_no_aligned#1% {\ifmmode - \the\mathdisplayaligntweaks - \global\mathnumberstatus\plusone - \ifcase\mathraggedstatus + \the\mathdisplayaligntweaks + \global\mathnumberstatus\plusone + \ifcase\mathraggedstatus \def\math_finish_eqalign_no{\crcr\egroup}% - \else + \else % we're in a mathbox \vcenter\bgroup \def\math_finish_eqalign_no{\crcr\egroup\egroup}% - \fi + \fi \fi #1% - \halign \ifcase\eqalignmode \or to \checkeddisplaywidth \fi \expandafter \bgroup\the\scratchtoks\crcr} + \math_halign_checked\expandafter\bgroup\the\scratchtoks\crcr} \def\math_rlap#1% {\setbox\scratchbox\hbox{#1}% - \ifdim\wd\scratchbox>\mathnumbercorrection - \xdef\mathnumbercorrection{\the\wd\scratchbox}% + \ifdim\wd\scratchbox>\d_math_number_correction + \global\d_math_number_correction\wd\scratchbox \fi \box\scratchbox \global\mathnumberstatus\plustwo} @@ -157,12 +230,9 @@ \def\math_handle_eqalign_no_l_aligned{\math_both_eqalign_no_aligned\math_prepare_l_eqalign_no} \def\math_finish_eqalign_no {\crcr\egroup} -\let \reqalignno \math_handle_eqalign_no_r_normal -\let \leqalignno \math_handle_eqalign_no_l_normal -\let\alignreqalignno \math_handle_eqalign_no_r_aligned -\let\alignleqalignno \math_handle_eqalign_no_l_aligned -\let \eqalignno \math_handle_eqalign_no_r_normal -\let \aligneqalignno \math_handle_eqalign_no_r_aligned +\let\reqalignno\relax +\let\leqalignno\relax +\let\eqalignno \relax %D Here we implement the user interface part. We start with basic math alignments: @@ -170,26 +240,28 @@ \newtoks \everymathalignment -\def\math_alignment_NR_indeed[#1][#2]% - {\strc_formulas_place_number_nested{#1}{#2}% to be tagged (better an attribute) +\def\math_alignment_NC_first#1\NR + {\glet\math_alignment_NC\math_alignment_NC_rest + \scratchtoks{\math_number_left_of_eqalign\aligntab#1\NR}% \math_number_left_of_eqalign not used yet + \dodoubleempty\math_alignment_NC_first_indeed} + +\def\math_alignment_NC_first_indeed[#1][#2]% + {\strc_formulas_place_number_nested{#1}{#2}\the\scratchtoks} + +\def\math_alignment_NR + {\aligntab + \dostoptagged % finish cell + \math_number_right_of_eqalign \crcr \dostoptagged % finish row \noalign{\glet\math_alignment_NC\math_alignment_NC_first}} % noalign used for change state, conditional does not work here -\def\math_alignment_NC_first - {\glet\math_alignment_NC\math_alignment_NC_rest} - \def\math_alignment_NC_rest {\aligntab} \def\math_alignment_EQ {\NC=} -\def\math_alignment_NR - {\aligntab - \dostoptagged % finish cell - \dodoubleempty\math_alignment_NR_indeed} % use xx from tabulate - \appendtoks \glet\math_alignment_NC\math_alignment_NC_first \unexpanded\def\NC{\math_alignment_NC}% messy, due to lookahead (we cannot use a flag) @@ -227,7 +299,7 @@ \the\everymathalignment \c_math_eqalign_column\zerocount \processcommacommand - [\mathalignmentparameter\c!align] + [\mathalignmentparameter\c!align]% {\advance\c_math_eqalign_column\plusone\math_eqalign_set_column}% takes argument \global\c_math_eqalign_column\plusone \dostarttagged\t!math\empty @@ -311,15 +383,33 @@ \def\math_left_of_equalign {\ifcsname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname - \ifcase\csname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname\or - \relax \or \hfill \or \hfill - \fi + \ifcase\lastnamedcs \or \relax \or \hfill \or \hfill \fi \fi} \def\math_right_of_eqalign {\ifcsname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname - \ifcase\csname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname\or - \hfill \or \relax \or \hfill + \ifcase\lastnamedcs \or \hfill \or \relax \or \hfill \fi + \fi} + +\newconditional\c_math_alignment_local_number % not used but when true puts in front (todo) + +\def\math_number_right_of_eqalign + {\ifcase\wd\b_strc_formulas_number\else + \ifconditional\c_math_alignment_local_number + \ifcase\c_strc_math_number_location\or\or + \box\b_strc_formulas_number + \fi + \else + \box\b_strc_formulas_number + \fi + \fi} + +\def\math_number_left_of_eqalign + {\ifcase\wd\b_strc_formulas_number\else + \ifconditional\c_math_alignment_local_number + \ifcase\c_strc_math_number_location\or + \box\b_strc_formulas_number + \fi \fi \fi} @@ -677,8 +767,10 @@ \def\math_matrix_stop {\crcr - \mathstrut\crcr - \noalign{\kern-\baselineskip}% + % \ifgridsnapping \else + \mathstrut\crcr + \noalign{\vskip-\baselineskip}% + % \fi \egroup \popmacro\math_matrix_NC \egroup @@ -689,19 +781,19 @@ \definemathmatrix[\v!mathmatrix] \def\math_matrix_prepare - {\c_math_align_a{\strut\math_first_in_eqalign\math_left_of_equalign\span + {\t_math_align_a{\strut\math_first_in_eqalign\math_left_of_equalign\span \math_text_in_eqalign{\mathmatrixparameter\c!style\alignmark\alignmark}\math_right_of_eqalign}% - \c_math_align_b{\aligntab\hskip\mathmatrixparameter\c!distance + \t_math_align_b{\aligntab\hskip\mathmatrixparameter\c!distance \math_next_in_eqalign\math_left_of_equalign\span \math_text_in_eqalign{\mathmatrixparameter\c!style\alignmark\alignmark}\math_right_of_eqalign}% - \c_math_align_c{\aligntab\aligntab\hskip\mathmatrixparameter\c!distance + \t_math_align_c{\aligntab\aligntab\hskip\mathmatrixparameter\c!distance \math_left_of_equalign\span \math_text_in_eqalign{\mathmatrixparameter\c!style\alignmark\alignmark}\math_right_of_eqalign}% \scratchtoks\emptytoks - \normalexpanded{\scratchtoks{\the\scratchtoks\the\c_math_align_a}}% + \normalexpanded{\scratchtoks{\the\scratchtoks\the\t_math_align_a}}% \dorecurse{\numexpr\scratchcounter-\plusone\relax} - {\normalexpanded{\scratchtoks{\the\scratchtoks\the\c_math_align_b}}}% - \normalexpanded{\scratchtoks{\the\scratchtoks\the\c_math_align_c}}% + {\normalexpanded{\scratchtoks{\the\scratchtoks\the\t_math_align_b}}}% + \normalexpanded{\scratchtoks{\the\scratchtoks\the\t_math_align_c}}% \halign \expandafter \bgroup\the\scratchtoks \crcr} \unexpanded\def\math_matrix_NC_indeed @@ -1023,9 +1115,8 @@ %D The following code comes from \type {math-str.mkiv}. %D -%D Here we implement a basic math alignment mechanism. Numbers -%D are also handled. The macros \type {\startinnermath} and -%D \type {\stopinnermath} can be overloaded in specialized +%D Here we implement a basic math alignment mechanism. Numbers are also handled. The macros +%D \type {\startinnermath} and \type {\stopinnermath} can be overloaded in specialized %D modules. \installcorenamespace{mathinnerstart} @@ -1052,223 +1143,444 @@ \newconstant\mathraggedstatus % normal left center right \newconstant\mathnumberstatus % nothing normal shift_right -\let\mathnumbercorrection\!!zeropoint - -\let\math_the_r_eq_no\empty -\let\math_the_l_eq_no\empty - -\unexpanded\def\startmathbox#1% - {\hsize\displaywidth % \checkeddisplaymath - \global\mathnumberstatus\plusone - \mathraggedstatus#1\relax - \let\mathnumbercorrection\!!zeropoint - \global\let\math_the_r_eq_no\empty - \global\let\math_the_l_eq_no\empty - \def\reqno{\gdef\math_the_r_eq_no}% - \def\leqno{\gdef\math_the_l_eq_no}% - \let\eqno\reqno - % added - \let\normalreqno\reqno - \let\normalleqno\leqno - \let\normaleqno \eqno - % added - \strc_formulas_place_number - \setbox\scratchbox\math_hbox to \displaywidth\bgroup % \checkeddisplaymath - \mathinnerstrut - \startforceddisplaymath - \ifcase\mathraggedstatus\or\hfill\or\hfill\fi} +\newdimen\d_math_number_correction \def\math_box_llapped_math_no {\ifcase\mathraggedstatus\or - \math_the_r_eq_no + \box\b_strc_formulas_number \or - \llap{\math_the_r_eq_no}% + \llap{\box\b_strc_formulas_number}% \or - \llap{\math_the_r_eq_no}% + \llap{\box\b_strc_formulas_number}% \fi} \def\math_box_rlapped_math_no {\ifcase\mathraggedstatus\or - \rlap{\math_the_l_eq_no}% + \rlap{\box\b_strc_formulas_number}% \or - \rlap{\math_the_l_eq_no}% + \rlap{\box\b_strc_formulas_number}% \or - \math_the_l_eq_no + \box\b_strc_formulas_number + \fi} + +\newconditional\c_strc_math_has_number +\newconditional\c_strc_math_display_overflow +\newconstant \c_strc_math_number_location +\newdimen \d_strc_math_number_width +\newdimen \d_strc_math_display_width +\newbox \b_strc_math_display +\newconstant \c_strc_formulas_frame_mode + +\let\d_strc_math_framed_width\displaywidth + +\setvalue{\??formulaoption\v!frame}% + {\edef\p_frame{\formulaparameter\c!frame}% + \ifx\p_frame\v!number + \c_strc_formulas_frame_mode\plustwo % inside frame + \else + \c_strc_formulas_frame_mode\plusone % outside frame + \fi} + +% mode: 0=no frame | 1=number inside frame | 2=number outside frame + +\def\strc_math_flush_aligned + {\ifcase\mathraggedstatus\or\hfill\or\hfill\fi + \box\b_strc_math_display + \ifcase\mathraggedstatus\or\or\hfill\or\hfill\fi} + +\def\strc_math_flush_box_normal + {\hbox to \displaywidth\bgroup + \strc_math_flush_aligned + \egroup} + +\def\strc_math_flush_box_framed_common + {\setformulaframedparameter\c!align{\formulaparameter\c!align}% + \letformulaframedparameter\c!strut\v!no + \d_framed_formula\ht\b_strc_math_display + \ifcase\mathraggedstatus\or\hfill\or\hfill \fi + \inheritedformulaframedframed{\box\b_strc_math_display}% + \ifcase\mathraggedstatus\or \or\hfill\or\hfill\fi} + +% \def\strc_math_flush_box_framed_inline +% {\letformulaframedparameter\c!location\empty +% \letformulaframedparameter\c!width\displaywidth +% \strc_math_flush_box_framed_common} + +\def\strc_math_flush_box_framed_display + {\let\currentformulaframed\currentformula + \letformulaframedparameter\c!location\v!formula + \setformulaframedparameter\c!width{\d_strc_math_framed_width}% + \strc_math_flush_box_framed_common} + +\def\strc_math_flush_box_framed_fit_inline + {\let\currentformulaframed\currentformula + \letformulaframedparameter\c!location\empty + \letformulaframedparameter\c!width\v!fit + \strc_math_flush_box_framed_common} + +\def\strc_math_flush_box_framed_fit_display + {\let\currentformulaframed\currentformula + \letformulaframedparameter\c!location\v!formula + \letformulaframedparameter\c!width\v!fit + \strc_math_flush_box_framed_common} + +% combiners + +\def\strc_math_flush_box + {\ifcase\c_strc_formulas_frame_mode + \strc_math_flush_box_normal + \else + \strc_math_flush_box_framed_display + \fi} + +\def\strc_math_number_right_normal + {\strc_math_flush_aligned + \hss % hss makes room for number + \math_box_llapped_math_no} + +\def\strc_math_number_left_normal + {\math_box_rlapped_math_no + \strc_math_flush_aligned + \hss} % hss makes room for number + +\def\strc_math_number_right_normal_outside + {\ifconditional\c_strc_formulas_tight + \strc_math_flush_box_framed_fit_display + \else + \strc_math_flush_box_framed_display + \fi + \hss % hss makes room for number + \math_box_llapped_math_no} + +\def\strc_math_number_left_normal_outside + {\math_box_rlapped_math_no + \hss % hss makes room for number + \ifconditional\c_strc_formulas_tight + \strc_math_flush_box_framed_fit_display + \else + \strc_math_flush_box_framed_display + \fi} + +\def\strc_math_number_right_normal_inside + {\setbox\b_strc_math_display\hpack to \dimexpr\displaywidth-\d_framed_locator_lo-\d_framed_locator_ro\relax\bgroup + \strc_math_flush_aligned + \hss + \math_box_llapped_math_no + \egroup + \strc_math_flush_box_framed_fit_inline} + +\def\strc_math_number_left_normal_inside + {\setbox\b_strc_math_display\hpack to \dimexpr\displaywidth-\d_framed_locator_lo-\d_framed_locator_ro\relax\bgroup + \math_box_rlapped_math_no + \hss + \strc_math_flush_aligned + \egroup + \strc_math_flush_box_framed_fit_inline} + +\def\strc_math_number_right_overflow + {\vpack\bgroup + \strc_math_flush_box + \par + \hpack to \displaywidth\bgroup + \hss + \math_box_llapped_math_no + \egroup + \egroup} + +\def\strc_math_number_left_overflow + {\vpack\bgroup + \hpack to \displaywidth\bgroup + \math_box_rlapped_math_no + \hss + \egroup + \strc_math_flush_box + \egroup} + +\def\strc_math_number_right_overflow_outside + {\vpack\bgroup + \strc_math_flush_box_framed_fit_inline +% \hskip\zeropoint % nicely breaks the line without introducing funny vertical spacing ... why o why + \hpack to \displaywidth\bgroup + \hss + \math_box_llapped_math_no + \egroup + \egroup} + +\def\strc_math_number_left_overflow_outside + {\vpack\bgroup + \hpack to \dimexpr\displaywidth-\d_framed_locator_lo\relax\bgroup + \math_box_rlapped_math_no + \hss + \egroup + \hskip\zeropoint % nicely breaks the line without introducing funny vertical spacing ... why o why + \strc_math_flush_box_framed_fit_inline + \egroup} + +\def\strc_math_number_right_overflow_inside + {\setbox\b_strc_math_display\vpack\bgroup + \box\b_strc_math_display + \hpack to \displaywidth\bgroup + \hss + \math_box_llapped_math_no + \hskip\d_framed_locator_ro + \egroup + \egroup + \strc_math_flush_box_framed_fit_inline} + +\def\strc_math_number_left_overflow_inside + {\setbox\b_strc_math_display\vpack\bgroup + \hpack to \displaywidth\bgroup + % \hskip\d_framed_locator_lo + \math_box_rlapped_math_no + \hss + \egroup + \box\b_strc_math_display + \egroup + \strc_math_flush_box_framed_fit_inline} + +% checkers + +\def\strc_math_number_check + {\d_strc_math_display_width\wd\b_strc_math_display + \ifconditional\c_strc_formulas_tight + \ifdim\d_strc_math_display_width>\displaywidth + \settrue\c_strc_math_display_overflow + \else + \displaywidth\d_strc_math_display_width + \setfalse\c_strc_math_display_overflow + \fi + \else + \ifdim\d_strc_math_display_width>\displaywidth + \settrue\c_strc_math_display_overflow + \else + \setfalse\c_strc_math_display_overflow + \fi \fi} -\unexpanded\def\stopmathbox +\def\strc_math_number_check_outside + {\d_strc_math_display_width\naturalwd\b_strc_math_display + \ifdim\dimexpr\d_strc_math_display_width+\d_framed_locator_lo+\d_framed_locator_ro\relax>\displaywidth + \settrue\c_strc_math_display_overflow + \else + \setfalse\c_strc_math_display_overflow + \fi + % still ok? + \ifnum\mathraggedstatus=\plustwo + \edef\d_strc_math_framed_width{\the\dimexpr\displaywidth-2\wd\b_strc_formulas_number\relax}% + \else + \edef\d_strc_math_framed_width{\the\dimexpr\displaywidth-\wd\b_strc_formulas_number\relax}% + \fi} + +\let\strc_math_number_check_inside\strc_math_number_check_outside + +% offsets + +\def\strc_math_number_check_offsets + {\begingroup + \setbox\scratchbox\hbox + {\inheritedformulaframedframed + {\pack_framed_locator_set_lo\pack_framed_locator_set_ro}}% + \endgroup} + +% tracing + +\def\strc_math_traced_state_yes + {\llap{\setbox\scratchbox\hbox{\infofont + \ifcase\mathraggedstatus unset\or right\or middle\or left\fi + \space + \ifcase\c_strc_formulas_frame_mode no\or out\or in\fi + \space + \ifconditional\c_strc_math_display_overflow overflow\else fit\fi + \quad}\ht\scratchbox\zeropoint\dp\scratchbox\zeropoint\box\scratchbox}} + +\let\strc_math_traced_state\relax + +\installtextracker + {formulas.framed} + {\let\strc_math_traced_state\strc_math_traced_state_yes} + {\let\strc_math_traced_state\relax} + +% packaging + +\unexpanded\def\strc_math_box_start#1% + {\hsize\displaywidth % \checkeddisplaymath + \global\mathnumberstatus\plusone + \mathraggedstatus#1\relax + % + \global\d_math_number_correction\zeropoint + % + \edef\p_location{\formulaparameter\c!location}% + \useformulacolorparameter\c!color + \c_strc_math_number_location\ifx\p_location\v!left\plusone\else\ifx\p_location\v!right\plustwo\else\zerocount\fi\fi + % + %\strc_formulas_place_number % not here as we can have inner alignment numbers + \dontcomplain + \setbox\b_strc_math_display\math_hbox\bgroup % \checkeddisplaymath + \mathinnerstrut + \startforceddisplaymath} + +\def\strc_math_flush_number_no + {\ifconditional\c_strc_math_display_overflow + \ifcase\c_strc_formulas_frame_mode + \strc_math_flush_box_normal + \else + \strc_math_flush_box_framed_fit_inline + \fi + \else + \ifcase\c_strc_formulas_frame_mode + %\ifconditional\c_strc_formulas_tight + % \strc_math_flush_box_normal + %\else + \strc_math_flush_box_normal + %\fi + \else + \ifconditional\c_strc_formulas_tight + \strc_math_flush_box_framed_fit_inline + \else + \strc_math_flush_box_framed_display + \fi + \fi + \fi} + +\def\strc_math_flush_number_left + {\ifconditional\c_strc_math_display_overflow + \ifcase\c_strc_formulas_frame_mode + \strc_math_number_left_overflow + \or + \strc_math_number_left_overflow_outside + \or + \strc_math_number_left_overflow_inside + \fi + \else + \ifcase\c_strc_formulas_frame_mode + \strc_math_number_left_normal + \or + \strc_math_number_left_normal_outside + \or + \strc_math_number_left_normal_inside + \fi + \fi} + +\def\strc_math_flush_number_right + {\ifconditional\c_strc_math_display_overflow + \ifcase\c_strc_formulas_frame_mode + \strc_math_number_right_overflow + \or + \strc_math_number_right_overflow_outside + \or + \strc_math_number_right_overflow_inside + \fi + \else + \ifcase\c_strc_formulas_frame_mode + \strc_math_number_right_normal + \or + \strc_math_number_right_normal_outside + \or + \strc_math_number_right_normal_inside + \fi + \fi} + +\unexpanded\def\strc_math_box_stop {\stopforceddisplaymath - \ifcase\mathraggedstatus\or\or\hfill\or\hfill\fi \egroup - \setbox0\hbox{\unhcopy\scratchbox}% - \scratchdimen\wd0 - % to be tested: \scratchdimen\naturalwd\scratchbox - \ifdim\scratchdimen>\displaywidth % \checkeddisplaymath - \donetrue + % % not needed, attribute driven + % \ifgridsnapping + % \snaptogrid[\v!math]\vbox + % \fi + % \bgroup + % check number + \d_strc_math_number_width\wd\b_strc_formulas_number + % + \ifcase\mathnumberstatus + \setfalse\c_strc_math_has_number + \or\ifzeropt\d_strc_math_number_width + \setfalse\c_strc_math_has_number \else - \donefalse + \settrue\c_strc_math_has_number + \fi\fi + % preroll left and right offsets + \ifcase\c_strc_formulas_frame_mode + % no frame + \else + \strc_math_number_check_offsets + \fi + \ifcase\c_strc_formulas_frame_mode + \strc_math_number_check + \or + \strc_math_number_check_outside + \else + \strc_math_number_check_inside \fi - \hbox to \displaywidth\bgroup + \noindent % \noindentation % not \dontleavehmode + \hskip\d_strc_formulas_display_margin_left % was kern but that doesn't indent + \strc_math_traced_state + \hbox to \displaywidth \bgroup \ifcase\mathnumberstatus - \box\scratchbox - \or - \ifx\math_the_l_eq_no\empty - \ifx\math_the_r_eq_no\empty - \box\scratchbox + \strc_math_flush_box + \or % status 1 + \ifcase\c_strc_math_number_location + \strc_math_flush_box + \or % number left + \ifzeropt\wd\b_strc_formulas_number + \strc_math_flush_number_no \else - \ifdone - \vpack{\box\scratchbox\hpack to \displaywidth{\hss\math_box_llapped_math_no}}% \checkeddisplaymath - \else - \hss\box\scratchbox\math_box_llapped_math_no % hss makes room for number - \fi + \strc_math_flush_number_left \fi - \else - \ifdone - \vpack{\hpack to \displaywidth{\math_box_rlapped_math_no\hss}\box\scratchbox}% \checkeddisplaymath + \else % number right + \ifzeropt\wd\b_strc_formulas_number + \strc_math_flush_number_no \else - \math_box_rlapped_math_no\box\scratchbox\hss % hss makes room for number + \strc_math_flush_number_right \fi \fi - \or - \hskip\mathnumbercorrection - \box\scratchbox + \or % status 2 + \hskip\d_math_number_correction % probably no longer used + \strc_math_flush_box \hss \else - \box\scratchbox + \strc_math_flush_box \fi + % \egroup \egroup} -\defineinnermathhandler\v!left {\startmathbox\plusone }{\stopmathbox} -\defineinnermathhandler\v!middle {\startmathbox\plustwo }{\stopmathbox} -\defineinnermathhandler\v!right {\startmathbox\plusthree}{\stopmathbox} -\defineinnermathhandler\v!flushleft {\startmathbox\plusthree}{\stopmathbox} -\defineinnermathhandler\v!center {\startmathbox\plustwo }{\stopmathbox} -\defineinnermathhandler\v!flushright{\startmathbox\plusone }{\stopmathbox} -\defineinnermathhandler\v!normal {} {} +\defineinnermathhandler\v!left {\strc_math_box_start\plusone }{\strc_math_box_stop} +\defineinnermathhandler\v!middle {\strc_math_box_start\plustwo }{\strc_math_box_stop} +\defineinnermathhandler\v!right {\strc_math_box_start\plusthree}{\strc_math_box_stop} +\defineinnermathhandler\v!flushleft {\strc_math_box_start\plusthree}{\strc_math_box_stop} +\defineinnermathhandler\v!center {\strc_math_box_start\plustwo }{\strc_math_box_stop} +\defineinnermathhandler\v!flushright{\strc_math_box_start\plusone }{\strc_math_box_stop} +\defineinnermathhandler\v!normal {\strc_math_box_start\plustwo }{\strc_math_box_stop} -%defineinnermathhandler\v!normal {\startmathbox\plustwo }{\stopmathbox} +%D Some inline math tweak. -%D [The examples below are in english and don't process in the -%D documentation style, which will be english some day.] -%D -%D Normally a formula is centered, but in case you want to -%D align it left or right, you can set up formulas to behave -%D that way. Normally a formula will adapt is left indentation -%D to the environment: -%D -%D \startbuffer -%D \fakewords{20}{40}\epar -%D \startitemize -%D \item \fakewords{20}{40}\epar -%D \placeformula \startformula \fakeformula \stopformula -%D \item \fakewords{20}{40}\epar -%D \stopitemize -%D \fakewords{20}{40}\epar -%D \stopbuffer -%D -%D % \getbuffer -%D -%D In the next examples we explicitly align formulas to the -%D left (\type {\raggedleft}), center and right (\type -%D {\raggedright}): -%D -%D \startbuffer -%D \setupformulas[align=left] -%D \startformula\fakeformula\stopformula -%D \setupformulas[align=middle] -%D \startformula\fakeformula\stopformula -%D \setupformulas[align=right] -%D \startformula\fakeformula\stopformula -%D \stopbuffer -%D -%D \typebuffer -%D -%D Or in print: -%D -%D % {\getbuffer} -%D -%D With formula numbers these formulas look as follows: -%D -%D \startbuffer -%D \setupformulas[align=left] -%D \placeformula \startformula\fakeformula\stopformula -%D \setupformulas[align=middle] -%D \placeformula \startformula\fakeformula\stopformula -%D \setupformulas[align=right] -%D \placeformula \startformula\fakeformula\stopformula -%D \stopbuffer -%D -%D % {\getbuffer} -%D -%D This was keyed in as: -%D -%D \typebuffer -%D -%D When tracing is turned on (\type {\tracemathtrue}) you can -%D visualize the bounding box of the formula, -%D -%D % {\tracemathtrue\getbuffer} -%D -%D As you can see, the dimensions are the natural ones, but if -%D needed you can force a normalized line: -%D -%D \startbuffer -%D \setupformulas[strut=yes] -%D \placeformula \startformula \fakeformula \stopformula -%D \stopbuffer -%D -%D \typebuffer -%D -%D This time we get a more spacy result. -%D -%D % {\tracemathtrue\getbuffer} -%D -%D We will now show a couple of more settings and combinations -%D of settings. In centered formulas, the number takes no space -%D -%D \startbuffer -%D \setupformulas[align=middle] -%D \startformula \fakeformula \stopformula -%D \placeformula \startformula \fakeformula \stopformula -%D \stopbuffer -%D -%D \typebuffer % {\tracemathtrue\getbuffer} -%D -%D You can influence the placement of the whole box with the -%D parameters \type {leftmargin} and \type {rightmargin}. -%D -%D \startbuffer -%D \setupformulas[align=right,leftmargin=3em] -%D \startformula \fakeformula \stopformula -%D \placeformula \startformula \fakeformula \stopformula -%D -%D \setupformulas[align=left,rightmargin=1em] -%D \startformula \fakeformula \stopformula -%D \placeformula \startformula \fakeformula \stopformula -%D \stopbuffer -%D -%D \typebuffer % {\tracemathtrue\getbuffer} -%D -%D You can also inherit the margin from the environment. -%D -%D \startbuffer -%D \setupformulas[align=right,margin=standard] -%D \startformula \fakeformula \stopformula -%D \placeformula \startformula \fakeformula \stopformula -%D \stopbuffer -%D -%D \typebuffer % {\tracemathtrue\getbuffer} -%D -%D The distance between the formula and the number is only -%D applied when the formula is left or right aligned. -%D -%D \startbuffer -%D \setupformulas[align=left,distance=2em] -%D \startformula \fakeformula \stopformula -%D \placeformula \startformula \fakeformula \stopformula -%D \stopbuffer -%D -%D \typebuffer % {\tracemathtrue\getbuffer} +\appendtoks + \ifcase\mathnestinglevel\or + % 4=disable 6=only when no spaces + \mathsurroundskip\mathematicsparameter\c!textdistance\relax + \ifzeropt\mathsurroundskip + \ifdim\gluestretch\mathsurroundskip=\zeropoint + \ifdim\glueshrink\mathsurroundskip=\zeropoint + \mathsurroundmode\plussix + \else + \mathsurroundskip\zeropoint + \mathsurroundmode\plusfour + \fi + \else + \mathsurroundmode\plussix + \fi + \else + \mathsurroundmode\plussix + \fi + \else + \mathsurroundmode\plusfour + \mathsurroundskip\zeropoint + \fi +\to \everymathematics + +\setupmathematics + [\c!textdistance=\zeropoint] + +%D For documentation, see \type {math-mkiv.tex}. \protect \endinput diff --git a/tex/context/base/mkiv/math-del.mkiv b/tex/context/base/mkiv/math-del.mkiv index be78b581f..269b6946a 100644 --- a/tex/context/base/mkiv/math-del.mkiv +++ b/tex/context/base/mkiv/math-del.mkiv @@ -79,6 +79,8 @@ [\c!symbol=0, \c!command=\v!yes, \c!factor=1.5, + \c!axis=\v!yes, + % \c!exact=\v!yes \c!height=\exheight, \c!depth=\exheight] @@ -93,29 +95,78 @@ {\dodoubleempty\math_fenced_extensible_indeed} \unexpanded\def\math_fenced_extensible_indeed[#1][#2]% - {\mathop{% - \edef\currentmathextensible{#1}% - \edef\p_factor{\mathextensibleparameter\c!factor}% - \ifsecondargument - \doifassignmentelse{#2} - {\setupcurrentmathextensible[#2]}% - {\edef\p_factor{#2}}% - \fi - \Uvextensible - axis % can be an option - height \p_factor\dimexpr\mathextensibleparameter\c!height\relax - depth \p_factor\dimexpr\mathextensibleparameter\c!depth\relax - \Udelimiter\zerocount\zerocount\mathextensibleparameter\c!symbol - \relax}% - } + {\mathop + {\edef\currentmathextensible{#1}% + \edef\p_factor{\mathextensibleparameter\c!factor}% + \ifsecondargument + \doifassignmentelse{#2} + {\setupcurrentmathextensible[#2]% + \edef\p_factor{\mathextensibleparameter\c!factor}}% + {\edef\p_factor{#2}}% + \else + \edef\p_factor{\mathextensibleparameter\c!factor}% + \fi + \edef\p_exact{\mathextensibleparameter\c!exact}% + \edef\p_axis {\mathextensibleparameter\c!axis}% + \edef\p_leftoffset{\mathextensibleparameter\c!leftoffset}% + \edef\p_rightoffset{\mathextensibleparameter\c!rightoffset}% + \ifx\p_leftoffset\empty\else + \mskip\p_leftoffset + \fi + \Uvextensible + \ifx\p_exact\v!yes exact \fi + \ifx\p_axis \v!yes axis \fi + height \p_factor\dimexpr\mathextensibleparameter\c!height\relax + depth \p_factor\dimexpr\mathextensibleparameter\c!depth \relax + \Udelimiter\zerocount\zerocount\mathextensibleparameter\c!symbol + \relax + \ifx\p_rightoffset\empty\else + \mskip\p_rightoffset + \fi}} \let\mathextensible\math_fenced_extensible +\definemathextensible[integral][\c!symbol="222B] + +% \setupmathextensible[integral][rightoffset=-3mu,exact=yes,factor=2] +% +% \let\inlineint \int +% \let\displayint\integral +% +% \unexpanded\def\int{\ifmmode\inlineordisplaymath\inlineint\displayint\else\normalint\fi} +% +% \startlines +% \ruledhbox{$\integral f\frac{1}{2}$} +% \ruledhbox{$\integral[factor=1] f\frac{1}{2}$} +% \ruledhbox{$\integral[factor=3] f\frac{1}{2}$} +% \ruledhbox{$\int f\frac{1}{2}$} +% \stoplines + +\unexpanded\def\autointegral#1#2#3% + {\ifmmode + \setbox\nextbox\mathstylehbox{#3}% + \scratchdimen\ifdim\nextboxht>\nextboxdp\nextboxht\else\nextboxdp\fi + \mathlimop{% + \Uvextensible + height \scratchdimen + depth \scratchdimen + exact% + axis% + \Udelimiter \plusfour \zerocount "222B% + }% + \limits % nolimits needs more work: kerning and so + \normalsuperscript{#1}% + \normalsubscript{#2}% + \box\nextbox + \else + \char"222B\relax + \fi} + % \startformula -% \integral[factor=3] \frac{1}{2} -% \integral[5] \frac{1}{2} +% a = +% \autointegral{t}{b}1 + +% \autointegral{t}{b}{\frac{\frac{3}{4}}{\frac{1}{2}}} + +% \autointegral{t}{b}{\frac{\frac{\frac{\frac{1}{2}}{2}}{2}}{2}} % \stopformula -\definemathextensible[integral][\c!symbol="222B] - \protect \endinput diff --git a/tex/context/base/mkiv/math-dim.lua b/tex/context/base/mkiv/math-dim.lua index b5241cb5a..ba0235a5b 100644 --- a/tex/context/base/mkiv/math-dim.lua +++ b/tex/context/base/mkiv/math-dim.lua @@ -99,6 +99,8 @@ local defaults = { radical_degree_before = { default = { "RadicalKernBeforeDegree", "(5/18)*quad" }, }, radical_degree_after = { default = { "RadicalKernAfterDegree", "(-10/18)*quad" }, }, radical_degree_raise = { default = { "RadicalDegreeBottomRaisePercent", "60" }, }, + no_limit_sub_factor = { default = { "NoLimitSubFactor", "0" }, }, + no_limit_sup_factor = { default = { "NoLimitSupFactor", "0" }, }, } local styles = { diff --git a/tex/context/base/mkiv/math-dir.lua b/tex/context/base/mkiv/math-dir.lua index c9c2a38dd..cba991b84 100644 --- a/tex/context/base/mkiv/math-dir.lua +++ b/tex/context/base/mkiv/math-dir.lua @@ -41,7 +41,7 @@ local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after local nodecodes = nodes.nodecodes -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction local glyph_code = nodecodes.glyph local hlist_code = nodecodes.hlist @@ -108,13 +108,13 @@ local function processmath(head) end elseif not start then -- nothing -if id == hlist_code or id == vlist_code then - local list, d = processmath(getlist(current)) - setlist(current,list) - if d then - done = true - end -end + if id == hlist_code or id == vlist_code then + local list, d = processmath(getlist(current)) + setlist(current,list) + if d then + done = true + end + end elseif start == stop then start = nil else @@ -160,7 +160,7 @@ function directions.setmath(n) if trace_directions then report_directions("enabling directions handler") end - tasks.enableaction("math","typesetters.directions.processmath") + enableaction("math","typesetters.directions.processmath") enabled = true end end diff --git a/tex/context/base/mkiv/math-fen.mkiv b/tex/context/base/mkiv/math-fen.mkiv index 81e39723d..320dffeb8 100644 --- a/tex/context/base/mkiv/math-fen.mkiv +++ b/tex/context/base/mkiv/math-fen.mkiv @@ -43,7 +43,8 @@ \c!middle=, \c!mathstyle=, \c!color=, - \c!command=] + \c!command=, + \c!factor=\v!auto] \appendtoks \edef\p_command{\mathfenceparameter\c!command}% @@ -54,20 +55,68 @@ % we need the direct use of \Udelimiter because of { etc -\def\math_fenced_left {\edef\p_left{\mathfenceparameter\c!left}% - \math_fenced_color_push - \normalleft\ifx\p_left\empty.\else\Udelimiter\plusfour\fam\p_left\relax\fi - \math_fenced_color_pop} -\def\math_fenced_middle{\edef\p_middle{\mathfenceparameter\c!middle}% - \mskip\thinmuskip - \math_fenced_color_push - \normalmiddle\ifx\p_middle\empty.\else\Udelimiter\plusfour\fam\p_middle\relax\fi - \math_fenced_color_pop - \mskip\thinmuskip} -\def\math_fenced_right {\edef\p_right{\mathfenceparameter\c!right}% - \math_fenced_color_push - \normalright\ifx\p_right\empty.\else\Udelimiter\plusfive\fam\p_right\relax\fi - \math_fenced_color_pop} +\newconditional\c_math_fenced_mirror \settrue\c_math_fenced_mirror + +\unexpanded\def\math_fenced_inject#1#2#3#4% + {\ifx#1\empty + #2.% + \else + \edef\p_factor{\mathfenceparameter\c!factor}% + \ifx\p_factor\empty + #2% + \else\ifx\p_factor\v!auto + #2% + \else\ifx\p_factor\v!none + #3\s!height\zeropoint\s!depth\zeropoint\s!axis + #2% + \else + \scratchdimen\dimexpr\p_factor\bodyfontsize/2\relax + #3\s!height\scratchdimen\s!depth\scratchdimen\s!axis + \fi\fi\fi + \Udelimiter#4\fam#1\relax + \fi} + +\def\math_fenced_left + {\edef\p_left + {\ifconditional\c_math_fenced_mirror + \ifconditional\c_math_right_to_left + \mathfenceparameter\c!right + \else + \mathfenceparameter\c!left + \fi + \else + \mathfenceparameter\c!left + \fi}% + \math_fenced_color_push + % \normalleft\ifx\p_left\empty.\else\Udelimiter\plusfour\fam\p_left\relax\fi + \math_fenced_inject\p_left\normalleft\Uleft\plusfour + \math_fenced_color_pop} + +\def\math_fenced_middle + {\edef\p_middle + {\mathfenceparameter\c!middle}% + \mskip\thinmuskip + \math_fenced_color_push + % \normalmiddle\ifx\p_middle\empty.\else\Udelimiter\plusfour\fam\p_middle\relax\fi + \math_fenced_inject\p_middle\normalmiddle\Umiddle\plusfour + \math_fenced_color_pop + \mskip\thinmuskip} + +\def\math_fenced_right + {\edef\p_right + {\ifconditional\c_math_fenced_mirror + \ifconditional\c_math_right_to_left + \mathfenceparameter\c!left + \else + \mathfenceparameter\c!right + \fi + \else + \mathfenceparameter\c!right + \fi}% + \math_fenced_color_push + % \normalright \ifx\p_right\empty.\else\Udelimiter\plusfive\fam\p_right\relax\fi + \math_fenced_inject\p_right\normalright\Uright\plusfive + \math_fenced_color_pop} \def\math_fenced_color_do_push{\pushcolor[\p_math_fenced_color]} \let\math_fenced_color_do_pop \popcolor @@ -80,11 +129,8 @@ \newcount\c_math_fenced_nesting -\unexpanded\def\math_fenced_fenced_start#1% - {\advance\c_math_fenced_nesting\plusone - \begingroup - \edef\currentmathfence{#1}% - \startusemathstyleparameter\mathfenceparameter +\unexpanded\def\math_fenced_fenced_common + {\startusemathstyleparameter\mathfenceparameter \let\fence\math_fenced_middle \edef\p_math_fenced_color{\mathfenceparameter\c!color}% \ifx\p_math_fenced_color\empty @@ -93,7 +139,13 @@ \else \let\math_fenced_color_push\math_fenced_color_do_push \let\math_fenced_color_pop \math_fenced_color_do_pop - \fi + \fi} + +\unexpanded\def\math_fenced_fenced_start#1% + {\advance\c_math_fenced_nesting\plusone + \begingroup + \edef\currentmathfence{#1}% + \math_fenced_fenced_common \math_fenced_left} \unexpanded\def\math_fenced_fenced_stop#1% @@ -103,8 +155,16 @@ \endgroup \advance\c_math_fenced_nesting\minusone} -\unexpanded\def\math_fenced_fenced[#1]#2% - {\math_fenced_fenced_start{#1}% +\unexpanded\def\math_fenced_fenced[#1]% + {\advance\c_math_fenced_nesting\plusone + \begingroup + \edef\currentmathfence{#1}% + \dosingleempty\math_fenced_fenced_indeed} + +\unexpanded\def\math_fenced_fenced_indeed[#1]#2% + {\iffirstargument\setupcurrentmathfence[#1]\fi + \math_fenced_fenced_common + \math_fenced_left #2% \math_fenced_right \stopusemathstyleparameter @@ -201,6 +261,21 @@ \unexpanded\def\Lopenbracketmirrored {\math_fenced_fenced_stop {mirroredopenbracket}} \unexpanded\def\Ropenbracketmirrored {\math_fenced_fenced_start{mirroredopenbracket}} \unexpanded\def\Lnothingmirrored {\math_fenced_fenced_stop {mirrorednothing}} \unexpanded\def\Rnothingmirrored {\math_fenced_fenced_start{mirrorednothing}} +\definemathfence [interval] [\c!left="2997,\c!right="2998] +\definemathfence [openinterval] [interval] [\c!left="2998,\c!right="2998] +\definemathfence [leftopeninterval] [interval] [\c!left="2997,\c!right="2997] +\definemathfence [rightopeninterval] [interval] [\c!left="2998,\c!right="2998] + +\unexpanded\def\Linterval {\math_fenced_fenced_start{interval}} +\unexpanded\def\Lointerval {\math_fenced_fenced_start{openinterval}} +\unexpanded\def\Llointerval {\math_fenced_fenced_start{leftopeninterval}} +\unexpanded\def\Lrointerval {\math_fenced_fenced_start{rightopeninterval}} + +\unexpanded\def\Rinterval {\math_fenced_fenced_stop {interval}} +\unexpanded\def\Rointerval {\math_fenced_fenced_stop {openinterval}} +\unexpanded\def\Rlointerval {\math_fenced_fenced_stop {leftopeninterval}} +\unexpanded\def\Rrointerval {\math_fenced_fenced_stop {rightopeninterval}} + % \startformula % \left{ \frac{1}{a} \right} % \left[ \frac{1}{b} \right] @@ -230,40 +305,40 @@ % % \def\math_left % {\settrue\c_math_fenced_done -% \edef\m_math_left{\meaning\nexttoken}% +% \edef\m_math_left{\normalmeaning\nexttoken}% % \csname\??mathleft\ifcsname\??mathleft\m_math_left\endcsname\m_math_left\else\s!unknown\fi\endcsname} % % \def\math_right % {\settrue\c_math_fenced_done -% \edef\m_math_right{\meaning\nexttoken}% +% \edef\m_math_right{\normalmeaning\nexttoken}% % \csname\??mathright\ifcsname\??mathright\m_math_right\endcsname\m_math_right\else\s!unknown\fi\endcsname} % % \def\math_middle % {\settrue\c_math_fenced_done -% \edef\m_math_middle{\meaning\nexttoken}% +% \edef\m_math_middle{\normalmeaning\nexttoken}% % \csname\??mathmiddle\ifcsname\??mathmiddle\m_math_middle\endcsname\m_math_middle\else\s!unknown\fi\endcsname} % % \unexpanded\def\lfence#1% % {\settrue\c_math_fenced_done % \let\nexttoken#1% -% \edef\m_math_left{\meaning#1}% +% \edef\m_math_left{\normalmeaning#1}% % \csname\??mathleft\ifcsname\??mathleft\m_math_left\endcsname\m_math_left\else\s!unknown\fi\endcsname} % % \unexpanded\def\rfence#1% % {\settrue\c_math_fenced_done % \let\nexttoken#1% -% \edef\m_math_right{\meaning#1}% +% \edef\m_math_right{\normalmeaning#1}% % \csname\??mathright\ifcsname\??mathright\m_math_right\endcsname\m_math_right\else\s!unknown\fi\endcsname} % % \unexpanded\def\mfence#1% % {\settrue\c_math_fenced_done % \let\nexttoken#1% -% \edef\m_math_middle{\meaning#1}% +% \edef\m_math_middle{\normalmeaning#1}% % \csname\??mathmiddle\ifcsname\??mathmiddle\m_math_middle\endcsname\m_math_middle\else\s!unknown\fi\endcsname} \unexpanded\def\installmathfencepair#1#2#3#4% - {\expandafter\let\csname\??mathleft \meaning#1\endcsname#2% - \expandafter\let\csname\??mathright\meaning#3\endcsname#4} + {\expandafter\let\csname\??mathleft \normalmeaning#1\endcsname#2% + \expandafter\let\csname\??mathright\normalmeaning#3\endcsname#4} \def\math_unknown_left {\setfalse\c_math_fenced_done\ifconditional\c_math_fenced_unknown\normalleft \nexttoken\fi} \def\math_unknown_right {\setfalse\c_math_fenced_done\ifconditional\c_math_fenced_unknown\normalright \nexttoken\fi} @@ -275,7 +350,7 @@ \def\math_left {\settrue\c_math_fenced_done - \ifcsname\??mathleft\meaning\nexttoken\endcsname + \ifcsname\??mathleft\normalmeaning\nexttoken\endcsname \expandafter\lastnamedcs \else \expandafter\math_unknown_left @@ -283,7 +358,7 @@ \def\math_right {\settrue\c_math_fenced_done - \ifcsname\??mathright\meaning\nexttoken\endcsname + \ifcsname\??mathright\normalmeaning\nexttoken\endcsname \expandafter\lastnamedcs \else \expandafter\math_unknown_right @@ -291,7 +366,7 @@ \def\math_middle {\settrue\c_math_fenced_done - \ifcsname\??mathmiddle\meaning\nexttoken\endcsname + \ifcsname\??mathmiddle\normalmeaning\nexttoken\endcsname \expandafter\lastnamedcs \else \expandafter\math_unknown_middle @@ -300,7 +375,7 @@ \unexpanded\def\lfence#1% {\settrue\c_math_fenced_done \let\nexttoken#1% - \ifcsname\??mathleft\meaning\nexttoken\endcsname + \ifcsname\??mathleft\normalmeaning\nexttoken\endcsname \expandafter\lastnamedcs \else \expandafter\math_unknown_left @@ -309,7 +384,7 @@ \unexpanded\def\rfence#1% {\settrue\c_math_fenced_done \let\nexttoken#1% - \ifcsname\??mathright\meaning\nexttoken\endcsname + \ifcsname\??mathright\normalmeaning\nexttoken\endcsname \expandafter\lastnamedcs \else \expandafter\math_unknown_right @@ -318,7 +393,7 @@ \unexpanded\def\mfence#1% {\settrue\c_math_fenced_done \let\nexttoken#1% - \ifcsname\??mathmiddle\meaning\nexttoken\endcsname + \ifcsname\??mathmiddle\normalmeaning\nexttoken\endcsname \expandafter\lastnamedcs \else \expandafter\math_unknown_middle @@ -370,6 +445,8 @@ % \installmathfencepair { \Lbrace } \Rbrace % \installmathfencepair } \Rbracemirrored { \Lbracemirrored +\installmathfencepair ⦗ \Linterv ⦘ \Rinterv + \appendtoks \ignorediscretionaries % so $\mtext{a|b}$ works, this is ok because it's an \hbox \to \everymathematics @@ -418,6 +495,12 @@ \installmathfencepair \llbracket \Lopenbracket \rrbracket \Ropenbracket \installmathfencepair \lgroup \Lgroup \rgroup \Rgroup +\installmathfencepair \linterval \Linterval \rinterval \Rinterval +%installmathfencepair \linterv \Linterval \rinterv \Rinterval +\installmathfencepair \lointerval \Linterval \rointerval \Rinterval +\installmathfencepair \llointerval \Llointerval \rlointerval \Rlointerval +\installmathfencepair \lrointerval \Lrointerval \rrointerval \Rrointerval + \let\textlbar\lbar \let\mathlbar\Lbar \let\textrbar\lbar \let\mathrbar\Rbar @@ -470,7 +553,7 @@ \installcorenamespace{mathbig} \unexpanded\def\choosemathbig#1#2% so we accept \big{||} as well - {{\hbox\bgroup + {{\naturalhbox\bgroup \startimath \ifcase\bigmathdelimitermethod \math_fenced_step#2\relax diff --git a/tex/context/base/mkiv/math-for.mkiv b/tex/context/base/mkiv/math-for.mkiv index 0c8bd05ae..176552406 100644 --- a/tex/context/base/mkiv/math-for.mkiv +++ b/tex/context/base/mkiv/math-for.mkiv @@ -19,15 +19,29 @@ \unprotect %D \macros -%D {setupformulas,setupsubformulas} +%D {setupformulas,setupsubformulas,setupformulaframed} \installcorenamespace{formula} \installcorenamespace{subformula} +\installcorenamespace{formulaframed} +\installcorenamespace{formulaoption} -\installcommandhandler \??formula {formula} \??formula -\installcommandhandler \??subformula {subformula} \??subformula % maybe just setuphandler (no childs used yet) +\installcommandhandler \??formula {formula} \??formula +\installcommandhandler \??subformula {subformula} \??subformula % maybe just setuphandler (no childs used yet) +\installframedcommandhandler \??formulaframed {formulaframed} \??formulaframed \let\setupformulas \setupformula \let\setupsubformulas\setupsubformula +\appendtoks + \normalexpanded{\defineformulaframed[\currentformula][\currentformulaparent]}% +\to \everydefineformula + +\def\strc_formulas_option#1% + {\ifcsname\??formulaoption#1\endcsname + \lastnamedcs + \else + \font_basics_switchtobodyfont{#1}% for old time sake, might go away, only pt so maybe dimension and small test + \fi} + \protect \endinput diff --git a/tex/context/base/mkiv/math-ini.lua b/tex/context/base/mkiv/math-ini.lua index e6a35c39e..2cb4e2413 100644 --- a/tex/context/base/mkiv/math-ini.lua +++ b/tex/context/base/mkiv/math-ini.lua @@ -24,8 +24,7 @@ local context = context local commands = commands local implement = interfaces.implement -local context_sprint = context.sprint ------ context_fprint = context.fprint -- a bit inefficient +local ctx_sprint = context.sprint local ctx_doifelsesomething = commands.doifelsesomething local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end) @@ -142,49 +141,49 @@ mathematics.families = families -- there will be proper functions soon (and we will move this code in-line) -- no need for " in class and family (saves space) -local function mathchar(class,family,slot) - return formatters['\\Umathchar "%X "%X "%X '](class,family,slot) -end - -local function mathaccent(class,family,slot) - return formatters['\\Umathaccent "%X "%X "%X '](0,family,slot) -- no class -end - -local function delimiter(class,family,slot) - return formatters['\\Udelimiter "%X "%X "%X '](class,family,slot) -end - -local function radical(family,slot) - return formatters['\\Uradical "%X "%X '](family,slot) -end - -local function root(family,slot) - return formatters['\\Uroot "%X "%X '](family,slot) -end - -local function mathchardef(name,class,family,slot) - return formatters['\\Umathchardef\\%s "%X "%X "%X '](name,class,family,slot) -end - -local function mathcode(target,class,family,slot) - return formatters['\\Umathcode%s="%X "%X "%X '](target,class,family,slot) -end - -local function mathtopaccent(class,family,slot) - return formatters['\\Umathaccent "%X "%X "%X '](0,family,slot) -- no class -end - -local function mathbotaccent(class,family,slot) - return formatters['\\Umathaccent bottom "%X "%X "%X '](0,family,slot) -- no class -end - -local function mathtopdelimiter(class,family,slot) - return formatters['\\Udelimiterover "%X "%X '](family,slot) -- no class -end - -local function mathbotdelimiter(class,family,slot) - return formatters['\\Udelimiterunder "%X "%X '](family,slot) -- no class -end +-- local function mathchar(class,family,slot) +-- return formatters['\\Umathchar "%X "%X "%X '](class,family,slot) +-- end +-- +-- local function mathaccent(class,family,slot) +-- return formatters['\\Umathaccent "%X "%X "%X '](0,family,slot) -- no class +-- end +-- +-- local function delimiter(class,family,slot) +-- return formatters['\\Udelimiter "%X "%X "%X '](class,family,slot) +-- end +-- +-- local function radical(family,slot) +-- return formatters['\\Uradical "%X "%X '](family,slot) +-- end +-- +-- local function root(family,slot) +-- return formatters['\\Uroot "%X "%X '](family,slot) +-- end +-- +-- local function mathchardef(name,class,family,slot) +-- return formatters['\\Umathchardef\\%s "%X "%X "%X '](name,class,family,slot) +-- end +-- +-- local function mathcode(target,class,family,slot) +-- return formatters['\\Umathcode%s="%X "%X "%X '](target,class,family,slot) +-- end +-- +-- local function mathtopaccent(class,family,slot) +-- return formatters['\\Umathaccent "%X "%X "%X '](0,family,slot) -- no class +-- end +-- +-- local function mathbotaccent(class,family,slot) +-- return formatters['\\Umathaccent bottom "%X "%X "%X '](0,family,slot) -- no class +-- end +-- +-- local function mathtopdelimiter(class,family,slot) +-- return formatters['\\Udelimiterover "%X "%X '](family,slot) -- no class +-- end +-- +-- local function mathbotdelimiter(class,family,slot) +-- return formatters['\\Udelimiterunder "%X "%X '](family,slot) -- no class +-- end local escapes = characters.filters.utf.private.escapes @@ -192,11 +191,11 @@ local escapes = characters.filters.utf.private.escapes local setmathcharacter = function(class,family,slot,unicode,mset,dset) if mset and codes[class] then -- regular codes < 7 - setmathcode("global",slot,{class,family,unicode}) + setmathcode("global",slot,class,family,unicode) mset = false end if dset and class == open_class or class == close_class or class == middle_class then - setdelcode("global",slot,{family,unicode,0,0}) + setdelcode("global",slot,family,unicode,0,0) dset = false end return mset, dset @@ -216,28 +215,28 @@ local f_char = formatters[ [[\Umathchardef\%s "%X "%X "%X ]] ] local setmathsymbol = function(name,class,family,slot) -- hex is nicer for tracing if class == classes.accent then - context_sprint(f_accent(name,family,slot)) + ctx_sprint(f_accent(name,family,slot)) elseif class == classes.topaccent then - context_sprint(f_topaccent(name,family,slot)) + ctx_sprint(f_topaccent(name,family,slot)) elseif class == classes.botaccent then - context_sprint(f_botaccent(name,family,slot)) + ctx_sprint(f_botaccent(name,family,slot)) elseif class == classes.over then - context_sprint(f_over(name,family,slot)) + ctx_sprint(f_over(name,family,slot)) elseif class == classes.under then - context_sprint(f_under(name,family,slot)) + ctx_sprint(f_under(name,family,slot)) elseif class == open_class or class == close_class or class == middle_class then setdelcode("global",slot,{family,slot,0,0}) - context_sprint(f_fence(name,class,family,slot)) + ctx_sprint(f_fence(name,class,family,slot)) elseif class == classes.delimiter then setdelcode("global",slot,{family,slot,0,0}) - context_sprint(f_delimiter(name,family,slot)) + ctx_sprint(f_delimiter(name,family,slot)) elseif class == classes.radical then - context_sprint(f_radical(name,family,slot)) + ctx_sprint(f_radical(name,family,slot)) elseif class == classes.root then - context_sprint(f_root(name,family,slot)) + ctx_sprint(f_root(name,family,slot)) else -- beware, open/close and other specials should not end up here - context_sprint(f_char(name,class,family,slot)) + ctx_sprint(f_char(name,class,family,slot)) end end @@ -366,6 +365,11 @@ local function utfmathclass(chr, default) return cd and cd.mathclass or default or "unknown" end +local function utfmathlimop(chr) + local cd = somechar[chr] + return cd and cd.mathclass == "limop" or false +end + local function utfmathaccent(chr,default,asked1,asked2) local cd = somechar[chr] if not cd then @@ -514,6 +518,7 @@ implement { actions = { utfmathcommand, context }, arguments = { "string", false, "'botaccent'","'under'" } } + implement { name = "utfmathcommandfiller", actions = { utfmathfiller, context }, @@ -546,6 +551,12 @@ implement { arguments = "string", } +implement { + name = "doifelseutfmathlimop", + actions = { utfmathlimop, ctx_doifelsesomething }, + arguments = "string", +} + -- helpers -- -- 1: step 1 diff --git a/tex/context/base/mkiv/math-ini.mkiv b/tex/context/base/mkiv/math-ini.mkiv index 2e7831d75..8c682bdcb 100644 --- a/tex/context/base/mkiv/math-ini.mkiv +++ b/tex/context/base/mkiv/math-ini.mkiv @@ -19,6 +19,10 @@ % todo: 0x2062 : invisible times % todo: 0x2063 : invisible comma +% a bit tricky way to set ... no (pseudo) registers but math hash values: +% +% \normalexpanded{\Umathlimitabovevgap\displaystyle=40\dimexpr\the\Umathlimitabovevgap\displaystyle\relax} + % Todo in luatex maincontrol.w: also accept a number here: % % case set_math_param_cmd: @@ -73,9 +77,28 @@ \registerctxluafile{math-fbk}{1.001} \registerctxluafile{math-dir}{1.001} +%D A starter: +%D +%D \startbuffer +%D \mathsurround 10pt +%D \mathsurroundskip30pt +%D x $x + \ruledhbox{$x$} + x$ x +%D \stopbuffer +%D +%D \typebuffer +%D +%D \start \blank \getbuffer \blank \stop + +\newcount\mathnestinglevel + +\appendtoks + \advance\mathnestinglevel\plusone +\to \everymathematics + %D A few compatibility helpers: \def\Umathbotaccent{\Umathaccent \s!bottom } +\def\Umathtopaccent{\Umathaccent \s!top } \def\Umathaccents {\Umathaccent \s!both } \ifdefined\Umathcharclass \else @@ -84,7 +107,7 @@ \def\Umathcharslot {\cldcontext{tex.getmathcode(token.scan_int())[3]}} \fi -%D The attributes that we will use: +%D The attributes that we will use (todo: pack some into one but uglier code): \definesystemattribute[mathalphabet] [public] \definesystemattribute[mathsize] [public] @@ -95,6 +118,7 @@ \definesystemattribute[mathcategory] [public] \definesystemattribute[mathmode] [public] \definesystemattribute[mathitalics] [public] +\definesystemattribute[mathkernpairs] [public] \definesystemattribute[mathbidi] [public] \definesystemattribute[mathdomain] [public] @@ -106,9 +130,6 @@ \appendtoks \attribute\mathmodeattribute\plusone -\to \everybeforedisplayformula - -\appendtoksonce \attribute\displaymathattribute\plusone \to \everybeforedisplayformula @@ -139,10 +160,12 @@ \unexpanded\def\startforceddisplaymath {\startimath \displaystyle + \begingroup \settrue\indisplaymath} \unexpanded\def\stopforceddisplaymath - {\stopimath} + {\endgroup + \stopimath} % \unexpanded\def\rawmathcharacter#1% slow but only for tracing % {\begingroup @@ -215,7 +238,9 @@ \def\math_m_yes_text[#1]% {\begingroup - \edef\currentmathematics{#1}% check for valid + \doifassignmentelse{#1}% + {\setupcurrentmathematics[#1]}% + {\edef\currentmathematics{#1}}% check for valid \edef\p_openup{\mathematicsparameter\c!openup}% \ifx\p_openup\v!yes \expandafter\math_m_yes_text_openedup @@ -337,13 +362,13 @@ \unexpanded\def\math_set_font_style #1{\ifmmode\clf_setmathstyle{#1}\fi} \unexpanded\def\math_set_font_alternate#1{\ifmmode\clf_setmathalternate\defaultmathfamily{#1}\fi} -\installcorenamespace{mathstylealternate} % might become a setuphandler +\installcorenamespace{mathstylealternative} % might become a setuphandler \unexpanded\def\math_set_font_style_alternate#1% - {\ifcsname\??mathstylealternate\fontclass:#1\endcsname + {\ifcsname\??mathstylealternative\fontclass:#1\endcsname %\expandafter\math_set_font_alternate\csname\??mathstylealternate\fontclass:#1\endcsname \expandafter\math_set_font_alternate\lastnamedcs - \else\ifcsname\??mathstylealternate#1\endcsname + \else\ifcsname\??mathstylealternative#1\endcsname %\expandafter\math_set_font_alternate\csname\??mathstylealternate#1\endcsname \expandafter\math_set_font_alternate\lastnamedcs \fi\fi} @@ -353,19 +378,30 @@ \def\math_setup_rendering[#1][#2]% {\ifsecondargument - \getparameters[\??mathstylealternate#1:][#2]% + \getparameters[\??mathstylealternative#1:][#2]% \else - \getparameters[\??mathstylealternate][#1]% + \getparameters[\??mathstylealternative][#1]% \fi} +\appendtoks + \edef\p_stylealternative{\mathematicsparameter\c!stylealternative}% + \ifx\p_stylealternative\empty\else + \clf_presetmathalternate\defaultmathfamily{\p_stylealternative}% + \fi +\to \everymathematics + % if there were many features we could have a feature pass over math nodes but it makes no % sense now so we have commands to deal with it -\unexpanded\def\mathaltcal {\math_set_font_alternate{cal}\cal} % set via goody file -%unexpanded\def\mathslashedzero {\math_set_font_alternate{zero}0} % set via goody file or automatic -\unexpanded\def\mathdotless {\math_set_font_alternate{dotless}} % set via goody file or automatic -\unexpanded\def\mathdotlessi {{\mathdotless i}} -\unexpanded\def\mathdotlessj {{\mathdotless j}} +\unexpanded\def\mathaltcalligraphic{\math_set_font_alternate{calligraphic}\cal} % set via goody file +\unexpanded\def\mathaltitalic {\math_set_font_alternate{italic}} % set via goody file +\unexpanded\def\mathslashedzero {\begingroup\math_set_font_alternate{zero}∅\endgroup} % set via goody file or automatic +\unexpanded\def\mathdotless {\math_set_font_alternate{dotless}} % set via goody file or automatic +\unexpanded\def\mathdotlessi {\begingroup\mathdotless i\endgroup} +\unexpanded\def\mathdotlessj {\begingroup\mathdotless j\endgroup} + +\let\mathaltcal\mathaltcalligraphic +\let\mathaltit \mathaltitalic %let\textslashedzero\slashedzero \unexpanded\def\autoslashedzero{\mathortext\mathslashedzero\textslashedzero} \let\textdotlessi \dotlessi \unexpanded\def\autodotlessi {\mathortext\mathdotlessi \textdotlessi} @@ -377,13 +413,15 @@ \let\dotlessj \autodotlessj \to \everymathematics -\let\setmathattribute \math_set_attribute -\let\setmathalphabet \math_set_alphabet -\let\setmathfontstyle \math_set_font_style -\let\setmathfontalternate \math_set_font_alternate -\let\setmathfontstylealternate\math_set_font_style_alternate +\let\setmathattribute \math_set_attribute +\let\setmathalphabet \math_set_alphabet +\let\setmathfontstyle \math_set_font_style +\let\setmathfontalternate \math_set_font_alternate +\let\setmathfontalternative \math_set_font_alternate +\let\setmathfontstylealternate \math_set_font_style_alternate +\let\setmathfontstylealternative\math_set_font_style_alternate -\let\mathalternate \math_set_font_alternate +\let\mathalternate \math_set_font_alternate \unexpanded\def\mathupright {\math_set_attribute\s!regular\s!tf\math_set_font_style_alternate\s!tf} \unexpanded\def\mathitalic {\math_set_attribute\s!regular\s!it\math_set_font_style_alternate\s!it} @@ -445,9 +483,9 @@ \ifdefined\normalbi\else\let\normalbi\bi\fi \unexpanded\def\bi{\ifmmode\mathbi\else\normalbi\fi} \ifdefined\normalbs\else\let\normalbs\bs\fi \unexpanded\def\bs{\ifmmode\mathbs\else\normalbs\fi} -\let\normalrm\rm \unexpanded\def\rm{\ifmmode\mathrm\else\normalrm\fi} -\let\normalss\ss \unexpanded\def\ss{\ifmmode\mathss\else\normalss\fi} -\let\normaltt\tt \unexpanded\def\tt{\ifmmode\mathtt\else\normaltt\fi} +\unexpanded\def\rm{\ifmmode\mathrm\else\normalrm\fi} +\unexpanded\def\ss{\ifmmode\mathss\else\normalss\fi} +\unexpanded\def\tt{\ifmmode\mathtt\else\normaltt\fi} \ifdefined\mr \else \let\mr\relax \fi \ifdefined\mb \else \let\mb\relax \fi @@ -519,11 +557,13 @@ \unexpanded\def\doifelseutfmathabove #1{\clf_doifelseutfmathabove {#1}} \unexpanded\def\doifelseutfmathbelow #1{\clf_doifelseutfmathbelow {#1}} \unexpanded\def\doifelseutfmathfiller#1{\clf_doifelseutfmathfiller{#1}} +\unexpanded\def\doifelseutfmathlimop #1{\clf_doifelseutfmathlimop {#1}} \let\doifutfmathaccentelse \doifelseutfmathaccent \let\doifutfmathaboveelse \doifelseutfmathabove \let\doifutfmathbelowelse \doifelseutfmathbelow \let\doifutfmathfillerelse \doifelseutfmathfiller +\let\doifutfmathlimopelse \doifelseutfmathlimop %D Not used that much: @@ -1322,6 +1362,31 @@ % \csname\??mathitalics\mathematicsparameter\s!italics\endcsname % \to \everyswitchmathematics % only in mathematics +%D Math kerns (experiment) + +\installcorenamespace{mathkernpairs} + +\setnewconstant\c_math_kernpairs_attribute\attributeunsetvalue % no real need for an extra constant + +\def\math_kernpairs_initialize + {\ifnum\c_math_kernpairs_attribute=\attributeunsetvalue \else + \clf_initializemathkernpairs % one time + \global\let\math_kernpairs_initialize\relax + \fi} + +\appendtoks + \edef\p_kernpairs{\mathematicsparameter\s!kernpairs}% + \c_math_kernpairs_attribute\ifx\p_kernpairs\v!yes\plusone\else\attributeunsetvalue\fi\relax +\to \everyswitchmathematics % only in mathematics + +\appendtoks + \math_kernpairs_initialize + \attribute\mathkernpairsattribute\c_math_kernpairs_attribute +\to \everymathematics + +\setupmathematics + [\s!kernpairs=\v!no] + %D \macros %D {enablemathpunctuation,disablemathpunctuation} %D @@ -2084,16 +2149,53 @@ % if needed we can get rid of the normalize (predo in font code) -\def\math_text_choice_font#1% +% \def\math_text_choice_font#1#2#% +% {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}% +% \hbox#2\bgroup +% \font_basics_switchtobodyfont\m_math_text_choice_face +% #1% +% \let\next} + +% \def\math_text_choice_word#1#2#% +% {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}% +% \hbox#2\bgroup +% \font_basics_switchtobodyfont\m_math_text_choice_face +% #1% +% \nospacing % \normalnospaces\plusone +% \let\next} + +%D We accept a low level box specification so that one can make helpers: +%D +%D \startbuffer +%D \startformula +%D \startalign[m=2,align={middle}] +%D \NC \text to 6cm{One\hfill} \NC a = 1 \NR +%D \NC \text to 6cm{One Two\hfill} \NC b = 2 \NR +%D \NC \text to 6cm{One Two Three\hfill} \NC c = 3 \NR +%D \stopalign +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +\def\math_text_choice_font#1#2#% {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}% - \hbox\bgroup + \hbox#2\bgroup + \bgroup + \aftergroup\hss + \aftergroup\egroup + \hss \font_basics_switchtobodyfont\m_math_text_choice_face #1% \let\next} -\def\math_text_choice_word#1% +\def\math_text_choice_word#1#2#% {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}% - \hbox\bgroup + \hbox#2\bgroup + \bgroup + \aftergroup\hss + \aftergroup\egroup + \hss \font_basics_switchtobodyfont\m_math_text_choice_face #1% \nospacing % \normalnospaces\plusone @@ -2155,9 +2257,7 @@ \newtoks\mathdisplayaligntweaks -\appendtoks - \resetdisplaymatheq % moved to here -\to \mathdisplayaligntweaks +% this can become an option: \unexpanded\def\math_display_align_hack % I don't like the global, maybe we should push and pop {\global\let\math_display_align_hack_indeed\math_display_align_hack_remove_skip @@ -2418,6 +2518,21 @@ \setupmathematics [\s!italics=3] % for the moment only this one makes sense .. still experimental +%D For special purposed we set this one: + +\installcorenamespace{mathrules} + +\unexpanded\def\enablemathrules{\global\letvalue{\??mathrules\fontclass}\plusone} + +\appendtoks + \mathrulesmode\ifcsname\??mathrules\fontclass\endcsname + \lastnamedcs + \else + \zerocount + \fi + \mathrulesfam\zerocount +\to \everymathematics + \protect \endinput % % not used (yet) diff --git a/tex/context/base/mkiv/math-map.lua b/tex/context/base/mkiv/math-map.lua index 94dde4110..cf9353e95 100644 --- a/tex/context/base/mkiv/math-map.lua +++ b/tex/context/base/mkiv/math-map.lua @@ -34,12 +34,12 @@ if not modules then modules = { } end modules ['math-map'] = { local type, next = type, next local floor, div = math.floor, math.div -local merged = table.merged +local merged, sortedhash = table.merged, table.sortedhash local extract = bit32.extract local allocate = utilities.storage.allocate -local otffeatures = fonts.constructors.newfeatures("otf") +local otffeatures = fonts.constructors.features.otf local registerotffeature = otffeatures.register local setmetatableindex = table.setmetatableindex @@ -164,6 +164,10 @@ local function toupper (n) local t = { } for i=0,25 do t[0x00041+i] = n+i end re local function tolower (n) local t = { } for i=0,25 do t[0x00061+i] = n+i end return t end local function tovector(t) return t end +-- how about 0x2A (ast) cq. 0x2217 +-- 0x2D (hyphen) cq. 0x2212 +-- 0x3A (colon) cq. 0x2236 + local regular_tf = { digits = todigit(0x00030), ucletters = toupper(0x00041), @@ -553,10 +557,10 @@ mathematics.mapremap = mathremap local boldmap = allocate { } mathematics.boldmap = boldmap --- all math (a bit of redundancy here) +-- all math (a bit of redundancy here) (sorted for tracing) -for alphabet, styles in next, alphabets do -- per 9/6/2011 we also have attr for missing - for style, data in next, styles do +for alphabet, styles in sortedhash(alphabets) do -- per 9/6/2011 we also have attr for missing + for style, data in sortedhash(styles) do -- let's keep the long names (for tracing) local n = #mathremap + 1 local d = { diff --git a/tex/context/base/mkiv/math-noa.lua b/tex/context/base/mkiv/math-noa.lua index 95b5a8ac9..f9e8c9f70 100644 --- a/tex/context/base/mkiv/math-noa.lua +++ b/tex/context/base/mkiv/math-noa.lua @@ -23,11 +23,13 @@ if not modules then modules = { } end modules ['math-noa'] = { -- nota bene: uunderdelimiter uoverdelimiter etc are radicals (we have 5 types) +local next, tonumber = next, tonumber local utfchar, utfbyte = utf.char, utf.byte -local formatters = string.formatters +local formatters, gmatch = string.formatters, string.gmatch local sortedhash = table.sortedhash local insert, remove = table.insert, table.remove local div = math.div +local setbit, hasbit = number.setbit, number.hasbit local fonts = fonts local nodes = nodes @@ -36,13 +38,14 @@ local mathematics = mathematics local context = context local otf = fonts.handlers.otf -local otffeatures = fonts.constructors.newfeatures("otf") +local otffeatures = fonts.constructors.features.otf local registerotffeature = otffeatures.register local privateattribute = attributes.private local registertracker = trackers.register local registerdirective = directives.register local logreporter = logs.reporter +local setmetatableindex = table.setmetatableindex local trace_remapping = false registertracker("math.remapping", function(v) trace_remapping = v end) local trace_processing = false registertracker("math.processing", function(v) trace_processing = v end) @@ -54,6 +57,7 @@ local trace_goodies = false registertracker("math.goodies", function local trace_variants = false registertracker("math.variants", function(v) trace_variants = v end) local trace_alternates = false registertracker("math.alternates", function(v) trace_alternates = v end) local trace_italics = false registertracker("math.italics", function(v) trace_italics = v end) +local trace_kernpairs = false registertracker("math.kernpairs", function(v) trace_kernpairs = v end) local trace_domains = false registertracker("math.domains", function(v) trace_domains = v end) local trace_families = false registertracker("math.families", function(v) trace_families = v end) local trace_fences = false registertracker("math.fences", function(v) trace_fences = v end) @@ -69,6 +73,7 @@ local report_goodies = logreporter("mathematics","goodies") local report_variants = logreporter("mathematics","variants") local report_alternates = logreporter("mathematics","alternates") local report_italics = logreporter("mathematics","italics") +local report_kernpairs = logreporter("mathematics","kernpairs") local report_domains = logreporter("mathematics","domains") local report_families = logreporter("mathematics","families") local report_fences = logreporter("mathematics","fences") @@ -84,6 +89,7 @@ local nutstring = nuts.tostring local setfield = nuts.setfield local setlink = nuts.setlink +local setlist = nuts.setlist local setnext = nuts.setnext local setprev = nuts.setprev local setchar = nuts.setchar @@ -99,8 +105,17 @@ local getsubtype = nuts.getsubtype local getchar = nuts.getchar local getfont = nuts.getfont local getattr = nuts.getattr +local getlist = nuts.getlist -local free_node = nuts.free +local getnucleus = nuts.getnucleus +local getsub = nuts.getsub +local getsup = nuts.getsup + +local setnucleus = nuts.setnucleus +local setsub = nuts.setsub +local setsup = nuts.setsup + +local flush_node = nuts.flush local new_node = nuts.new -- todo: pool: math_noad math_sub local copy_node = nuts.copy local slide_nodes = nuts.slide @@ -111,15 +126,11 @@ local mlist_to_hlist = nodes.mlist_to_hlist local font_of_family = node.family_font local new_kern = nodepool.kern -local new_rule = nodepool.rule local fonthashes = fonts.hashes local fontdata = fonthashes.identifiers local fontcharacters = fonthashes.characters -local fontproperties = fonthashes.properties local fontitalics = fonthashes.italics -local fontemwidths = fonthashes.emwidths -local fontexheights = fonthashes.exheights local variables = interfaces.variables local texsetattribute = tex.setattribute @@ -141,6 +152,8 @@ noads.handlers = noads.handlers or { } local handlers = noads.handlers local tasks = nodes.tasks +local enableaction = tasks.enableaction +local setaction = tasks.setaction local nodecodes = nodes.nodecodes local noadcodes = nodes.noadcodes @@ -166,7 +179,7 @@ local math_sub = nodecodes.submlist -- attr list local math_char = nodecodes.mathchar -- attr fam char local math_textchar = nodecodes.mathtextchar -- attr fam char local math_delim = nodecodes.delim -- attr small_fam small_char large_fam large_char -local math_style = nodecodes.style -- attr style +----- math_style = nodecodes.style -- attr style local math_choice = nodecodes.choice -- attr display text script scriptscript local math_fence = nodecodes.fence -- attr subtype @@ -174,9 +187,19 @@ local left_fence_code = fencecodes.left local middle_fence_code = fencecodes.middle local right_fence_code = fencecodes.right +-- local mathclasses = mathematics.classes +-- local fenceclasses = { +-- [left_fence_code] = mathclasses.open, +-- [middle_fence_code] = mathclasses.middle, +-- [right_fence_code] = mathclasses.close, +-- } + -- this initial stuff is tricky as we can have removed and new nodes with the same address -- the only way out is a free-per-page list of nodes (not bad anyway) +-- local gf = getfield local gt = setmetatableindex("number") getfield = function(n,f) gt[f] = gt[f] + 1 return gf(n,f) end mathematics.GETFIELD = gt +-- local sf = setfield local st = setmetatableindex("number") setfield = function(n,f,v) st[f] = st[f] + 1 sf(n,f,v) end mathematics.SETFIELD = st + local function process(start,what,n,parent) if n then n = n + 1 @@ -225,13 +248,13 @@ local function process(start,what,n,parent) end elseif id == math_noad then -- single characters are like this - local noad = getfield(start,"nucleus") if noad then process(noad,what,n,start) end -- list - noad = getfield(start,"sup") if noad then process(noad,what,n,start) end -- list - noad = getfield(start,"sub") if noad then process(noad,what,n,start) end -- list + local noad = getnucleus(start) if noad then process(noad,what,n,start) end -- list + noad = getsup (start) if noad then process(noad,what,n,start) end -- list + noad = getsub (start) if noad then process(noad,what,n,start) end -- list elseif id == math_char or id == math_textchar or id == math_delim then break elseif id == math_box or id == math_sub then - local noad = getfield(start,"list") if noad then process(noad,what,n,start) end -- list (not getlist !) + local noad = getlist(start) if noad then process(noad,what,n,start) end -- list (not getlist !) elseif id == math_fraction then local noad = getfield(start,"num") if noad then process(noad,what,n,start) end -- list noad = getfield(start,"denom") if noad then process(noad,what,n,start) end -- list @@ -245,15 +268,15 @@ local function process(start,what,n,parent) elseif id == math_fence then local noad = getfield(start,"delim") if noad then process(noad,what,n,start) end -- delimiter elseif id == math_radical then - local noad = getfield(start,"nucleus") if noad then process(noad,what,n,start) end -- list - noad = getfield(start,"sup") if noad then process(noad,what,n,start) end -- list - noad = getfield(start,"sub") if noad then process(noad,what,n,start) end -- list + local noad = getnucleus(start) if noad then process(noad,what,n,start) end -- list + noad = getsup (start) if noad then process(noad,what,n,start) end -- list + noad = getsub (start) if noad then process(noad,what,n,start) end -- list noad = getfield(start,"left") if noad then process(noad,what,n,start) end -- delimiter noad = getfield(start,"degree") if noad then process(noad,what,n,start) end -- list elseif id == math_accent then - local noad = getfield(start,"nucleus") if noad then process(noad,what,n,start) end -- list - noad = getfield(start,"sup") if noad then process(noad,what,n,start) end -- list - noad = getfield(start,"sub") if noad then process(noad,what,n,start) end -- list + local noad = getnucleus(start) if noad then process(noad,what,n,start) end -- list + noad = getsup (start) if noad then process(noad,what,n,start) end -- list + noad = getsub (start) if noad then process(noad,what,n,start) end -- list noad = getfield(start,"accent") if noad then process(noad,what,n,start) end -- list noad = getfield(start,"bot_accent") if noad then process(noad,what,n,start) end -- list -- elseif id == math_style then @@ -272,11 +295,11 @@ local function processnested(current,what,n) local noad = nil local id = getid(current) if id == math_noad then - noad = getfield(current,"nucleus") if noad then process(noad,what,n,current) end -- list - noad = getfield(current,"sup") if noad then process(noad,what,n,current) end -- list - noad = getfield(current,"sub") if noad then process(noad,what,n,current) end -- list + noad = getnucleus(current) if noad then process(noad,what,n,current) end -- list + noad = getsup (current) if noad then process(noad,what,n,current) end -- list + noad = getsub (current) if noad then process(noad,what,n,current) end -- list elseif id == math_box or id == math_sub then - noad = getfield(current,"list") if noad then process(noad,what,n,current) end -- list (not getlist !) + noad = getlist(current) if noad then process(noad,what,n,current) end -- list (not getlist !) elseif id == math_fraction then noad = getfield(current,"num") if noad then process(noad,what,n,current) end -- list noad = getfield(current,"denom") if noad then process(noad,what,n,current) end -- list @@ -290,15 +313,15 @@ local function processnested(current,what,n) elseif id == math_fence then noad = getfield(current,"delim") if noad then process(noad,what,n,current) end -- delimiter elseif id == math_radical then - noad = getfield(current,"nucleus") if noad then process(noad,what,n,current) end -- list - noad = getfield(current,"sup") if noad then process(noad,what,n,current) end -- list - noad = getfield(current,"sub") if noad then process(noad,what,n,current) end -- list + noad = getnucleus(current) if noad then process(noad,what,n,current) end -- list + noad = getsup (current) if noad then process(noad,what,n,current) end -- list + noad = getsub (current) if noad then process(noad,what,n,current) end -- list noad = getfield(current,"left") if noad then process(noad,what,n,current) end -- delimiter noad = getfield(current,"degree") if noad then process(noad,what,n,current) end -- list elseif id == math_accent then - noad = getfield(current,"nucleus") if noad then process(noad,what,n,current) end -- list - noad = getfield(current,"sup") if noad then process(noad,what,n,current) end -- list - noad = getfield(current,"sub") if noad then process(noad,what,n,current) end -- list + noad = getnucleus(current) if noad then process(noad,what,n,current) end -- list + noad = getsup (current) if noad then process(noad,what,n,current) end -- list + noad = getsub (current) if noad then process(noad,what,n,current) end -- list noad = getfield(current,"accent") if noad then process(noad,what,n,current) end -- list noad = getfield(current,"bot_accent") if noad then process(noad,what,n,current) end -- list end @@ -308,11 +331,11 @@ local function processstep(current,process,n,id) local noad = nil local id = id or getid(current) if id == math_noad then - noad = getfield(current,"nucleus") if noad then process(noad,n,current) end -- list - noad = getfield(current,"sup") if noad then process(noad,n,current) end -- list - noad = getfield(current,"sub") if noad then process(noad,n,current) end -- list + noad = getnucleus(current) if noad then process(noad,n,current) end -- list + noad = getsup (current) if noad then process(noad,n,current) end -- list + noad = getsub (current) if noad then process(noad,n,current) end -- list elseif id == math_box or id == math_sub then - noad = getfield(current,"list") if noad then process(noad,n,current) end -- list (not getlist !) + noad = getlist(current) if noad then process(noad,n,current) end -- list (not getlist !) elseif id == math_fraction then noad = getfield(current,"num") if noad then process(noad,n,current) end -- list noad = getfield(current,"denom") if noad then process(noad,n,current) end -- list @@ -326,15 +349,15 @@ local function processstep(current,process,n,id) elseif id == math_fence then noad = getfield(current,"delim") if noad then process(noad,n,current) end -- delimiter elseif id == math_radical then - noad = getfield(current,"nucleus") if noad then process(noad,n,current) end -- list - noad = getfield(current,"sup") if noad then process(noad,n,current) end -- list - noad = getfield(current,"sub") if noad then process(noad,n,current) end -- list + noad = getnucleus(current) if noad then process(noad,n,current) end -- list + noad = getsup (current) if noad then process(noad,n,current) end -- list + noad = getsub (current) if noad then process(noad,n,current) end -- list noad = getfield(current,"left") if noad then process(noad,n,current) end -- delimiter noad = getfield(current,"degree") if noad then process(noad,n,current) end -- list elseif id == math_accent then - noad = getfield(current,"nucleus") if noad then process(noad,n,current) end -- list - noad = getfield(current,"sup") if noad then process(noad,n,current) end -- list - noad = getfield(current,"sub") if noad then process(noad,n,current) end -- list + noad = getnucleus(current) if noad then process(noad,n,current) end -- list + noad = getsup (current) if noad then process(noad,n,current) end -- list + noad = getsub (current) if noad then process(noad,n,current) end -- list noad = getfield(current,"accent") if noad then process(noad,n,current) end -- list noad = getfield(current,"bot_accent") if noad then process(noad,n,current) end -- list end @@ -356,13 +379,12 @@ noads.process = processnoads noads.processnested = processnested noads.processouter = process - -- experiment (when not present fall back to fam 0) -- needs documentation local unknowns = { } local checked = { } -- simple case local tracked = false trackers.register("fonts.missing", function(v) tracked = v end) -local cached = table.setmetatableindex("table") -- complex case +local cached = setmetatableindex("table") -- complex case local function errorchar(font,char) local done = unknowns[char] @@ -519,7 +541,8 @@ do processors.relocate = { } local function report_remap(tag,id,old,new,extra) - report_remapping("remapping %s in font %s from %C to %C%s",tag,id,old,new,extra) + report_remapping("remapping %s in font (%s,%s) from %C to %C%s", + tag,id,fontdata[id].properties.fontname or "",old,new,extra) end local remapalphabets = mathematics.remapalphabets @@ -562,9 +585,10 @@ do end local newchar = remapalphabets(char,a,g) if newchar then - if characters[newchar] then + local newchardata = characters[newchar] + if newchardata then if trace_remapping then - report_remap("char",font,char,newchar) + report_remap("char",font,char,newchar,newchardata.commands and " (virtual)" or "") end if trace_analyzing then setnodecolor(pointer,"font:isol") @@ -595,6 +619,11 @@ do report_remap("char",font,char,newchar," fails (no fallback style)") end end + elseif trace_remapping then + local chardata = characters[char] + if chardata and chardata.commands then + report_remap("char",font,char,char," (virtual)") + end end end if not characters[char] then @@ -696,6 +725,8 @@ function handlers.resize(head,style,penalties) return true end +-- still not perfect: + local a_autofence = privateattribute("mathautofence") local autofences = { } processors.autofences = autofences @@ -705,26 +736,27 @@ local function makefence(what,char) local d = new_node(math_delim) local f = new_node(math_fence) if char then - local sym = getfield(char,"nucleus") - local chr = getfield(sym,"char") + local sym = getnucleus(char) + local chr = getchar(sym) local fam = getfield(sym,"fam") if chr == dummyfencechar then chr = 0 end setfield(d,"small_char",chr) setfield(d,"small_fam", fam) - free_node(sym) + flush_node(sym) end setsubtype(f,what) setfield(f,"delim",d) + setfield(f,"class",-1) -- tex itself does this, so not fenceclasses[what] return f end local function makelist(noad,f_o,o_next,c_prev,f_c,middle) local list = new_node(math_sub) - setfield(list,"head",f_o) + setlist(list,f_o) setsubtype(noad,noad_inner) - setfield(noad,"nucleus",list) + setnucleus(noad,list) setlink(f_o,o_next) setlink(c_prev,f_c) if middle and next(middle) then @@ -735,12 +767,11 @@ local function makelist(noad,f_o,o_next,c_prev,f_c,middle) if m then local next = getnext(current) local fence = makefence(middle_fence_code,current) - setfield(current,"nucleus",nil) - free_node(current) + setnucleus(current) + flush_node(current) middle[current] = nil -- replace_node - setlink(prev,fence) - setlink(fence,next) + setlink(prev,fence,next) prev = fence current = next else @@ -760,8 +791,8 @@ local function convert_both(open,close,middle) local f_o = makefence(left_fence_code,open) local f_c = makefence(right_fence_code,close) makelist(open,f_o,o_next,c_prev,f_c,middle) - setfield(close,"nucleus",nil) - free_node(close) + setnucleus(close) + flush_node(close) if c_next then setprev(c_next,open) end @@ -791,7 +822,7 @@ local function convert_close(close,first,middle) return close end -local stacks = table.setmetatableindex("table") +local stacks = setmetatableindex("table") local function processfences(pointer,n,parent) local current = pointer @@ -817,20 +848,23 @@ local function processfences(pointer,n,parent) local open = remove(stack) if open then if trace_fences then - report_fences("%2i: handling %s, stack depth %i",n,"both",#stack) + report_fences("%2i: handling %s, stack depth %i",n,"both",#stack+1) end current = convert_both(open,current,middle) elseif current == start then -- skip else if trace_fences then - report_fences("%2i: handling %s, stack depth %i",n,"close",#stack) + report_fences("%2i: handling %s, stack depth %i",n,"close",#stack+1) end current = convert_close(current,initial,middle) if not parent then initial = current end end + if trace_fences then + report_fences("%2i: popping close from stack",n) + end elseif a == 3 then if trace_fences then report_fences("%2i: registering middle",n) @@ -879,7 +913,7 @@ implement { name = "enableautofences", onlyonce = true, actions = function() - tasks.enableaction("math","noads.handlers.autofences") + enableaction("math","noads.handlers.autofences") enabled = true end } @@ -906,8 +940,8 @@ local function replace(pointer,what,n,parent) local start_super, stop_super, start_sub, stop_sub local mode = "unset" while next and getid(next) == math_noad do - local nextnucleus = getfield(next,"nucleus") - if nextnucleus and getid(nextnucleus) == math_char and not getfield(next,"sub") and not getfield(next,"sup") then + local nextnucleus = getnucleus(next) + if nextnucleus and getid(nextnucleus) == math_char and not getsub(next) and not getsup(next) then local char = getchar(nextnucleus) local s = superscripts[char] if s then @@ -950,11 +984,11 @@ local function replace(pointer,what,n,parent) end if start_super then if start_super == stop_super then - setfield(pointer,"sup",getfield(start_super,"nucleus")) + setsup(pointer,getnucleus(start_super)) else local list = new_node(math_sub) -- todo attr - setfield(list,"list",start_super) - setfield(pointer,"sup",list) + setlist(list,start_super) + setsup(pointer,list) end if mode == "super" then setnext(pointer,getnext(stop_super)) @@ -963,11 +997,11 @@ local function replace(pointer,what,n,parent) end if start_sub then if start_sub == stop_sub then - setfield(pointer,"sub",getfield(start_sub,"nucleus")) + setsub(pointer,getnucleus(start_sub)) else local list = new_node(math_sub) -- todo attr - setfield(list,"list",start_sub) - setfield(pointer,"sub",list) + setlist(list,start_sub) + setsub(pointer,list) end if mode == "sub" then setnext(pointer,getnext(stop_sub)) @@ -1004,126 +1038,210 @@ statistics.register("unknown math characters", function() return collected(unknowns) end) --- math alternates: (in xits lgf: $ABC$ $\cal ABC$ $\mathalternate{cal}\cal ABC$) --- math alternates: (in lucidanova lgf: $ABC \mathalternate{italic} ABC$) +-- math alternates: (in xits lgf: $ABC$ $\cal ABC$ $\mathalternate{cal}\cal ABC$) +-- math alternates: (in lucidaot lgf: $ABC \mathalternate{italic} ABC$) -- todo: set alternate for specific symbols -- todo: no need to do this when already loaded +-- todo: use a fonts.hashes.mathalternates -local defaults = { - dotless = { feature = 'dtls', value = 1, comment = "Mathematical Dotless Forms" }, - -- zero = { feature = 'zero', value = 1, comment = "Slashed or Dotted Zero" }, -- in no math font (yet) -} +do -local function initializemathalternates(tfmdata) - local goodies = tfmdata.goodies - local autolist = table.copy(defaults) - - local function setthem(alternates) - local resources = tfmdata.resources -- was tfmdata.shared - local lastattribute = 0 - local attributes = { } - for k, v in sortedhash(alternates) do - lastattribute = lastattribute + 1 - v.attribute = lastattribute - attributes[lastattribute] = v - end - resources.mathalternates = alternates -- to be checked if shared is ok here - resources.mathalternatesattributes = attributes -- to be checked if shared is ok here - end + local last = 0 - if goodies then - local done = { } - 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 - if trace_goodies then - report_goodies("loading alternates for font %a",tfmdata.properties.name) + local known = setmetatableindex(function(t,k) + local v = setbit(0,2^last) + t[k] = v + last = last + 1 + return v + end) + + local defaults = { + dotless = { feature = 'dtls', value = 1, comment = "Mathematical Dotless Forms" }, + -- zero = { feature = 'zero', value = 1, comment = "Slashed or Dotted Zero" }, -- in no math font (yet) + } + + local function initializemathalternates(tfmdata) + local goodies = tfmdata.goodies + local autolist = defaults -- table.copy(defaults) + + local function setthem(newalternates) + local resources = tfmdata.resources -- was tfmdata.shared + local mathalternates = resources.mathalternates + local alternates, attributes, registered, presets + if mathalternates then + alternates = mathalternates.alternates + attributes = mathalternates.attributes + registered = mathalternates.registered + else + alternates, attributes, registered = { }, { }, { } + mathalternates = { + attributes = attributes, + alternates = alternates, + registered = registered, + presets = { }, +hashes = setmetatableindex("table") + } + resources.mathalternates = mathalternates + end + -- + for name, data in sortedhash(newalternates) do + if alternates[name] then + -- ignore + else + local attr = known[name] + attributes[attr] = data + alternates[name] = attr + registered[#registered+1] = attr end - for k, v in next, autolist do - if not alternates[k] then - alternates[k] = v + end + end + + if goodies then + local done = { } + 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 + if trace_goodies then + report_goodies("loading alternates for font %a",tfmdata.properties.name) end + for k, v in next, autolist do + if not alternates[k] then + alternates[k] = v + end + end + setthem(alternates) + return end - setthem(alternates) - return end end - end - if trace_goodies then - report_goodies("loading default alternates for font %a",tfmdata.properties.name) - end - setthem(autolist) + if trace_goodies then + report_goodies("loading default alternates for font %a",tfmdata.properties.name) + end + setthem(autolist) -end + end -registerotffeature { - name = "mathalternates", - description = "additional math alternative shapes", - initializers = { - base = initializemathalternates, - node = initializemathalternates, + registerotffeature { + name = "mathalternates", + description = "additional math alternative shapes", + initializers = { + base = initializemathalternates, + node = initializemathalternates, + } } -} --- local getalternate = otf.getalternate (runtime new method so ...) + -- local getalternate = otf.getalternate (runtime new method so ...) + + -- todo: not shared but copies ... one never knows --- todo: not shared but copies ... one never knows + local a_mathalternate = privateattribute("mathalternate") + local alternate = { } -- processors.alternate = alternate + local fontdata = fonts.hashes.identifiers + local fontresources = fonts.hashes.resources + + local function getalternate(fam,tag) + local resources = fontresources[font_of_family(fam)] + local attribute = unsetvalue + if resources then + local mathalternates = resources.mathalternates + if mathalternates then + local presets = mathalternates.presets + if presets then + attribute = presets[tag] + if not attribute then + attribute = 0 + local alternates = mathalternates.alternates + for s in gmatch(tag,"[^, ]+") do + local a = alternates[s] -- or known[s] + if a then + attribute = attribute + a + end + end + if attribute == 0 then + attribute = unsetvalue + end + presets[tag] = attribute + end + end + end + end + return attribute + end -local a_mathalternate = privateattribute("mathalternate") + local function presetalternate(fam,tag) + texsetattribute(a_mathalternate,getalternate(fam,tag)) + end -local alternate = { } -- processors.alternate = alternate + implement { + name = "presetmathalternate", + actions = presetalternate, + arguments = { "integer", "string" } + } -function mathematics.setalternate(fam,tag) - local id = font_of_family(fam) - local tfmdata = fontdata[id] - local resources = tfmdata.resources -- was tfmdata.shared - if resources then - local mathalternates = resources.mathalternates - if mathalternates then - local m = mathalternates[tag] - texsetattribute(a_mathalternate,m and m.attribute or unsetvalue) + local function setalternate(fam,tag) + local a = texgetattribute(a_mathalternate) + local v = getalternate(fam,tag) + if a and a > 0 then + v = a + v end + texsetattribute(a_mathalternate,v) end -end -implement { - name = "setmathalternate", - actions = mathematics.setalternate, - arguments = { "integer", "string" } -} + implement { + name = "setmathalternate", + actions = setalternate, + arguments = { "integer", "string" } + } -alternate[math_char] = function(pointer) - local a = getattr(pointer,a_mathalternate) - if a and a > 0 then - setattr(pointer,a_mathalternate,0) - local tfmdata = fontdata[getfont(pointer)] - local resources = tfmdata.resources -- was tfmdata.shared - if resources then - local mathalternatesattributes = resources.mathalternatesattributes - if mathalternatesattributes then - local what = mathalternatesattributes[a] - local char = getchar(pointer) - local alt = otf.getalternate(tfmdata,char,what.feature,what.value) - if alt ~= char then - if trace_alternates then - report_alternates("alternate %a, value %a, replacing glyph %U by glyph %U", - tostring(what.feature),tostring(what.value),getchar(pointer),alt) + alternate[math_char] = function(pointer) -- slow + local a = getattr(pointer,a_mathalternate) + if a and a > 0 then + setattr(pointer,a_mathalternate,0) + local fontid = getfont(pointer) + local resources = fontresources[fontid] + if resources then + local mathalternates = resources.mathalternates + if mathalternates then + local attributes = mathalternates.attributes + local registered = mathalternates.registered + local hashes = mathalternates.hashes + for i=1,#registered do + local r = registered[i] + if hasbit(a,r) then + local char = getchar(pointer) + local alt = hashes[i][char] + if alt == nil then + local what = attributes[r] + alt = otf.getalternate(fontdata[fontid],char,what.feature,what.value) or false + if alt == char then + alt = false + elseif trace_alternates then + report_alternates("alternate %a, value %a, replacing glyph %U by glyph %U", + tostring(what.feature),tostring(what.value),getchar(pointer),alt) + end + hashes[i][char] = alt + end + if alt then + setchar(pointer,alt) + break + end + end end - setchar(pointer,alt) end end end end -end -function handlers.alternates(head,style,penalties) - processnoads(head,alternate,"alternate") - return true + function handlers.alternates(head,style,penalties) + processnoads(head,alternate,"alternate") + return true + end + end -- italics: we assume that only characters matter @@ -1137,9 +1255,9 @@ end -- and text. Also, for a while in context we had to deal with a mix of virtual math fonts and -- real ones. --- in opentype the italic correction of a limop is added to the width and luatex does some juggling --- that we want to avoid but we need to do something here (in fact, we could better fix the width of --- the character +-- in opentype the italic correction of a limop is added to the width and luatex does +-- some juggling that we want to avoid but we need to do something here (in fact, we could +-- better fix the width of the character local a_mathitalics = privateattribute("mathitalics") @@ -1155,9 +1273,9 @@ local c_negative_d = "trace:dr" local function insert_kern(current,kern) local sub = new_node(math_sub) -- todo: pool local noad = new_node(math_noad) -- todo: pool - setfield(sub,"list",kern) + setlist(sub,kern) setnext(kern,noad) - setfield(noad,"nucleus",current) + setnucleus(noad,current) return sub end @@ -1234,7 +1352,8 @@ italics[math_char] = function(pointer,what,n,parent) if correction and correction ~= 0 then local next_noad = getnext(parent) if not next_noad then - if n == 1 then -- only at the outer level .. will become an option (always,endonly,none) + if n == 1 then + -- only at the outer level .. will become an option (always,endonly,none) if trace_italics then report_italics("method %a, flagging italic correction %p between %C and end math",method,correction,char) end @@ -1259,7 +1378,7 @@ end local enable enable = function() - tasks.enableaction("math", "noads.handlers.italics") + enableaction("math", "noads.handlers.italics") if trace_italics then report_italics("enabling math italics") end @@ -1311,6 +1430,80 @@ implement { actions = mathematics.resetitalics } +do + + -- math kerns (experiment) in goodies: + -- + -- mathematics = { + -- kernpairs = { + -- [0x1D44E] = { + -- [0x1D44F] = 400, -- 𝑎𝑏 + -- } + -- }, + -- } + + local a_kernpairs = privateattribute("mathkernpairs") + local kernpairs = { } + + local function enable() + enableaction("math", "noads.handlers.kernpairs") + if trace_kernpairs then + report_kernpairs("enabling math kern pairs") + end + enable = false + end + + implement { + name = "initializemathkernpairs", + actions = enable, + onlyonce = true, + } + + local hash = setmetatableindex(function(t,font) + local g = fontdata[font].goodies + local m = g and g[1].mathematics + local k = m and m.kernpairs + t[font] = k + return k + end) + + kernpairs[math_char] = function(pointer,what,n,parent) + if getattr(pointer,a_kernpairs) == 1 then + local font = getfont(pointer) + local list = hash[font] + if list then + local first = getchar(pointer) + local found = list[first] + if found then + local next = getnext(parent) + if next and getid(next) == math_noad then + pointer = getnucleus(next) + if pointer then + if getfont(pointer) == font then + local second = getchar(pointer) + local kern = found[second] + if kern then + kern = kern * fonts.hashes.parameters[font].hfactor + if trace_kernpairs then + report_kernpairs("adding %p kerning between %C and %C",kern,first,second) + end + setlink(parent,new_kern(kern),getnext(parent)) + end + end + end + end + end + end + end + end + + function handlers.kernpairs(head,style,penalties) + processnoads(head,kernpairs,"kernpairs") + return true + end + +end + -- primes and such local collapse = { } processors.collapse = collapse @@ -1355,30 +1548,30 @@ local validpair = { local function movesubscript(parent,current_nucleus,current_char) local prev = getprev(parent) if prev and getid(prev) == math_noad then - if not getfield(prev,"sup") and not getfield(prev,"sub") then + if not getsup(prev) and not getsub(prev) then -- {f} {'}_n => f_n^' setchar(current_nucleus,movesub[current_char or getchar(current_nucleus)]) - local nucleus = getfield(parent,"nucleus") - local sub = getfield(parent,"sub") - local sup = getfield(parent,"sup") - setfield(prev,"sup",nucleus) - setfield(prev,"sub",sub) + local nucleus = getnucleus(parent) + local sub = getsub(parent) + local sup = getsup(parent) + setsup(prev,nucleus) + setsub(prev,sub) local dummy = copy_node(nucleus) setchar(dummy,0) - setfield(parent,"nucleus",dummy) - setfield(parent,"sub",nil) + setnucleus(parent,dummy) + setsub(parent) if trace_collapsing then report_collapsing("fixing subscript") end - elseif not getfield(prev,"sup") then + elseif not getsup(prev) then -- {f} {'}_n => f_n^' setchar(current_nucleus,movesub[current_char or getchar(current_nucleus)]) - local nucleus = getfield(parent,"nucleus") - local sup = getfield(parent,"sup") - setfield(prev,"sup",nucleus) + local nucleus = getnucleus(parent) + local sup = getsup(parent) + setsup(prev,nucleus) local dummy = copy_node(nucleus) setchar(dummy,0) - setfield(parent,"nucleus",dummy) + setnucleus(parent,dummy) if trace_collapsing then report_collapsing("fixing subscript") end @@ -1389,16 +1582,16 @@ end local function collapsepair(pointer,what,n,parent,nested) -- todo: switch to turn in on and off if parent then if validpair[getsubtype(parent)] then - local current_nucleus = getfield(parent,"nucleus") + local current_nucleus = getnucleus(parent) if getid(current_nucleus) == math_char then local current_char = getchar(current_nucleus) - if not getfield(parent,"sub") and not getfield(parent,"sup") then + if not getsub(parent) and not getsup(parent) then local mathpair = mathpairs[current_char] if mathpair then local next_noad = getnext(parent) if next_noad and getid(next_noad) == math_noad then if validpair[getsubtype(next_noad)] then - local next_nucleus = getfield(next_noad,"nucleus") + local next_nucleus = getnucleus(next_noad) local next_char = getchar(next_nucleus) if getid(next_nucleus) == math_char then local newchar = mathpair[next_char] @@ -1416,11 +1609,11 @@ local function collapsepair(pointer,what,n,parent,nested) -- todo: switch to tur else setnext(parent) end - setfield(parent,"sup",getfield(next_noad,"sup")) - setfield(parent,"sub",getfield(next_noad,"sub")) - setfield(next_noad,"sup",nil) - setfield(next_noad,"sub",nil) - free_node(next_noad) + setsup(parent,getsup(next_noad)) + setsub(parent,getsub(next_noad)) + setsup(next_noad) + setsub(next_noad) + flush_node(next_noad) collapsepair(pointer,what,n,parent,true) -- if not nested and movesub[current_char] then -- movesubscript(parent,current_nucleus,current_char) @@ -1478,7 +1671,7 @@ variants[math_char] = function(pointer,what,n,parent) -- also set export value if selector then local next = getnext(parent) if next and getid(next) == math_noad then - local nucleus = getfield(next,"nucleus") + local nucleus = getnucleus(next) if nucleus and getid(nucleus) == math_char and getchar(nucleus) == selector then local variant local tfmdata = fontdata[getfont(pointer)] @@ -1502,7 +1695,7 @@ variants[math_char] = function(pointer,what,n,parent) -- also set export value end setprev(next,pointer) setnext(parent,getnext(next)) - free_node(next) + flush_node(next) end end end @@ -1547,7 +1740,9 @@ function handlers.classes(head,style,penalties) return true end -registertracker("math.classes",function(v) tasks.setaction("math","noads.handlers.classes",v) end) +registertracker("math.classes",function(v) + setaction("math","noads.handlers.classes",v) +end) -- experimental @@ -1564,7 +1759,6 @@ do local domains = { } local categories = { } local numbers = { } - local mclasses = mathematics.classes local a_mathdomain = privateattribute("mathdomain") mathematics.domains = categories @@ -1593,7 +1787,7 @@ do local enable enable = function() - tasks.enableaction("math", "noads.handlers.domains") + enableaction("math", "noads.handlers.domains") if trace_domains then report_domains("enabling math domains") end @@ -1709,14 +1903,29 @@ do end - -- just for me function handlers.showtree(head,style,penalties) inspect(nodes.totree(head)) end -registertracker("math.showtree",function(v) tasks.setaction("math","noads.handlers.showtree",v) end) +registertracker("math.showtree",function(v) + setaction("math","noads.handlers.showtree",v) +end) + +-- also for me + +local applyvisuals = nuts.applyvisuals +local visual = false + +function handlers.makeup(head) + applyvisuals(tonut(head),visual) +end + +registertracker("math.makeup",function(v) + visual = v + setaction("math","noads.handlers.makeup",v) +end) -- the normal builder diff --git a/tex/context/base/mkiv/math-pln.mkiv b/tex/context/base/mkiv/math-pln.mkiv index a5ecdd11d..754cb6141 100644 --- a/tex/context/base/mkiv/math-pln.mkiv +++ b/tex/context/base/mkiv/math-pln.mkiv @@ -29,7 +29,7 @@ % will move \def\oalign#1% - {\leavevmode + {\leavevmode % plain tex uses this \vtop {\baselineskip\zeroskip \lineskip.25\exheight diff --git a/tex/context/base/mkiv/math-rad.mkvi b/tex/context/base/mkiv/math-rad.mkvi index 113d4af50..699a1a125 100644 --- a/tex/context/base/mkiv/math-rad.mkvi +++ b/tex/context/base/mkiv/math-rad.mkvi @@ -208,7 +208,7 @@ %D Because I wanted to illustrate some more fun stuff another mechanism %D is provided as well ... let's put some dangerous tools in the hand of -%D math juglers like Aditya. +%D math jugglers like Aditya. \installcorenamespace{mathornament} \installcorenamespace{mathornamentalternative} diff --git a/tex/context/base/mkiv/math-stc.mkvi b/tex/context/base/mkiv/math-stc.mkvi index 96e1738db..208e756f6 100644 --- a/tex/context/base/mkiv/math-stc.mkvi +++ b/tex/context/base/mkiv/math-stc.mkvi @@ -471,10 +471,14 @@ {\math_stackers_triplet\zerocount\currentmathstackers\scratchcounter{#toptext}{#bottomtext}% \endgroup} -%D A few direct accessors: +%D A few direct accessors (in the meantime we redefined \mathextensible so we renamed the +%D following): -\unexpanded\def\mathextensible{\begingroup\dosingleempty\math_stackers_handle_math} -\unexpanded\def\textextensible{\begingroup\dosingleempty\math_stackers_handle_text} +\unexpanded\def\directmathextensible{\begingroup\dosingleempty\math_stackers_handle_math} +\unexpanded\def\directtextextensible{\begingroup\dosingleempty\math_stackers_handle_text} + +\let\mathstacker\directmathextensible +\let\textstacker\directtextextensible \unexpanded\def\math_stackers_handle_math[#category]% {\math_stackers_handle_extensible{\iffirstargument#category\else\v!mathematics\fi}} % will be defined later on diff --git a/tex/context/base/mkiv/math-tag.lua b/tex/context/base/mkiv/math-tag.lua index e83b401fb..13c8fffc7 100644 --- a/tex/context/base/mkiv/math-tag.lua +++ b/tex/context/base/mkiv/math-tag.lua @@ -30,6 +30,8 @@ local getdisc = nuts.getdisc local getsubtype = nuts.getsubtype local getattr = nuts.getattr local setattr = nuts.setattr +local getcomponents = nuts.getcomponents +local getwidth = nuts.getwidth local set_attributes = nuts.setattributes local traverse_nodes = nuts.traverse @@ -70,8 +72,6 @@ local math_code = nodecodes.math local processnoads = noads.process local a_tagged = attributes.private('tagged') -local a_taggedpar = attributes.private('taggedpar') -local a_exportstatus = attributes.private('exportstatus') local a_mathcategory = attributes.private('mathcategory') local a_mathmode = attributes.private('mathmode') local a_fontkern = attributes.private('fontkern') @@ -252,7 +252,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer if tag == "formulacaption" then -- skip elseif tag == "mstacker" then - local list = getfield(start,"list") + local list = getlist(start) if list then process(list) end @@ -262,7 +262,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer end local text = start_tagged(tag) setattr(start,a_tagged,text) - local list = getfield(start,"list") + local list = getlist(start) if not list then -- empty list elseif not attr then @@ -317,7 +317,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer if id == hlist_code or id == vlist_code then runner(getlist(n),depth+1) elseif id == glyph_code then - runner(getfield(n,"components"),depth+1) -- this should not be needed + runner(getcomponents(n),depth+1) -- this should not be needed elseif id == disc_code then local pre, post, replace = getdisc(n) runner(pre,depth+1) -- idem @@ -337,7 +337,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer stop_tagged() end elseif id == math_sub_code then -- normally a hbox - local list = getfield(start,"list") + local list = getlist(start) if list then local attr = getattr(start,a_tagged) local last = attr and taglist[attr] @@ -528,7 +528,7 @@ process = function(start) -- we cannot use the processor as we have no finalizer processsubsup(start) end elseif id == glue_code then - -- setattr(start,a_tagged,start_tagged("mspace",{ width = getfield(start,"width") })) + -- setattr(start,a_tagged,start_tagged("mspace",{ width = getwidth(start) })) setattr(start,a_tagged,start_tagged("mspace")) stop_tagged() else diff --git a/tex/context/base/mkiv/math-vfu.lua b/tex/context/base/mkiv/math-vfu.lua index a683e02cf..a8a789d28 100644 --- a/tex/context/base/mkiv/math-vfu.lua +++ b/tex/context/base/mkiv/math-vfu.lua @@ -25,7 +25,6 @@ if not modules then modules = { } end modules ['math-vfu'] = { local type, next = type, next local max = math.max local format = string.format -local utfchar = utf.char local fastcopy = table.copy local fonts, nodes, mathematics = fonts, nodes, mathematics @@ -564,6 +563,10 @@ function vfmath.addmissing(main,id,size) raise(main,characters,id,size,0x2032,0xFE325,1,id_of_smaller) -- prime raise(main,characters,id,size,0x2033,0xFE325,2,id_of_smaller) -- double prime raise(main,characters,id,size,0x2034,0xFE325,3,id_of_smaller) -- triple prime + -- to satisfy the prime resolver + characters[0xFE932] = characters[0x2032] + characters[0xFE933] = characters[0x2033] + characters[0xFE934] = characters[0x2034] end -- there are more (needs discussion first): @@ -1080,6 +1083,7 @@ function vfmath.define(specification,set,goodies) report_virtual("loading and virtualizing font %a at size %p took %0.3f seconds",name,size,os.clock()-start) end -- + main.oldmath = true return main end diff --git a/tex/context/base/mkiv/meta-imp-mat.mkiv b/tex/context/base/mkiv/meta-imp-mat.mkiv new file mode 100644 index 000000000..8913845fd --- /dev/null +++ b/tex/context/base/mkiv/meta-imp-mat.mkiv @@ -0,0 +1,174 @@ +%D \module +%D [ file=meta-mat, +%D version=2013.07.19, +%D title=\METAPOST\ Graphics, +%D subtitle=Math, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is just an example library not meant for production. + +% A few accents: + +% / for cambria + +\startMPextensions + vardef math_stacker_overbracket_shape = + image ( + draw + (0,OverlayOffset) -- + (0,OverlayHeight-OverlayOffset) -- + (OverlayWidth,OverlayHeight-OverlayOffset) -- + (OverlayWidth,OverlayOffset) + withcolor + OverlayLineColor ; + setbounds currentpicture to boundingbox currentpicture bottomenlarged OverlayOffset ; + ) + enddef ; + vardef math_stacker_underbracket_shape = + math_stacker_overbracket_shape rotated 180 + enddef ; + vardef math_stacker_overparent_shape = + image ( + draw + (0,OverlayOffset) ... + (OverlayWidth/2,OverlayHeight-OverlayOffset) ... + (OverlayWidth,OverlayOffset) + withcolor + OverlayLineColor ; + setbounds currentpicture to boundingbox currentpicture bottomenlarged OverlayOffset ; + ) + enddef ; + vardef math_stacker_underparent_shape = + math_stacker_overparent_shape rotated 180 + enddef ; + vardef math_stacker_overbrace_shape = + image ( + draw + (0,OverlayOffset) ... + (OverlayWidth/4-OverlayOffset,OverlayHeight-OverlayOffset) ... + (OverlayWidth/2-OverlayOffset,OverlayHeight-OverlayOffset) ... + (OverlayWidth/2,OverlayHeight) & + (OverlayWidth/2,OverlayHeight) ... + (OverlayWidth/2+OverlayOffset,OverlayHeight-OverlayOffset) ... + (3OverlayWidth/4+OverlayOffset,OverlayHeight-OverlayOffset) ... + (OverlayWidth,OverlayOffset) + withcolor + OverlayLineColor ; + setbounds currentpicture to boundingbox currentpicture bottomenlarged OverlayOffset ; + ) + enddef ; + vardef math_stacker_underbrace_shape = + math_stacker_overbrace_shape rotated 180 + enddef ; + vardef math_stacker_overbar_shape = + image ( + draw + (0,OverlayOffset) -- (OverlayWidth,OverlayOffset) + withcolor + OverlayLineColor ; + setbounds currentpicture to boundingbox currentpicture bottomenlarged OverlayOffset ; + ) + enddef ; + vardef math_stacker_underbar_shape = + math_stacker_overbar_shape rotated 180 + enddef ; + vardef math_stacker_arrow_shape = + image ( + drawarrow + (OverlayWidth,OverlayOffset) -- (0,OverlayOffset) + withcolor + OverlayLineColor ; + setbounds currentpicture to boundingbox currentpicture bottomenlarged (OverlayOffset/2) topenlarged (OverlayOffset/2) ; + ) + enddef ; + vardef math_stacker_leftarrow_shape = + math_stacker_arrow_shape + enddef ; + vardef math_stacker_rightarrow_shape = + math_stacker_arrow_shape rotated 180 + enddef ; + def math_stacker_draw(expr p) = + draw + p + withpen + pencircle + xscaled (2OverlayLineWidth) + % yscaled (3OverlayLineWidth/4) + yscaled (3OverlayLineWidth) + % rotated 30 ; + rotated 45 ; + enddef ; +\stopMPextensions + +\startuniqueMPgraphic{math:stacker:\number"FE3B4} + math_stacker_draw(math_stacker_overbracket_shape) ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{math:stacker:\number"FE3B5} + math_stacker_draw(math_stacker_underbracket_shape) ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{math:stacker:\number"FE3DC} + math_stacker_draw(math_stacker_overparent_shape) ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{math:stacker:\number"FE3DD} + math_stacker_draw(math_stacker_underparent_shape) ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{math:stacker:\number"FE3DE} + math_stacker_draw(math_stacker_overbrace_shape) ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{math:stacker:\number"FE3DF} + math_stacker_draw(math_stacker_underbrace_shape) ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{math:stacker:\number"FE33E} + math_stacker_draw(math_stacker_overbar_shape) ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{math:stacker:\number"FE33F} + math_stacker_draw(math_stacker_underbar_shape) ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{math:stacker:\number"2190} + math_stacker_draw(math_stacker_leftarrow_shape) ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{math:stacker:\number"2192} + math_stacker_draw(math_stacker_rightarrow_shape) ; +\stopuniqueMPgraphic + +%D Radicals: + +\startMPextensions + vardef math_radical_simple(expr w,h,d,o) = + (-h/2-o,h/2-o) -- + (-h/4-o,-d-o) -- + (-o,h+o) -- + (w+o,h+o) -- + (w+o,h-h/10+o) + enddef ; +\stopMPextensions + +\startuniqueMPgraphic{math:radical:default}%{...} + draw + math_radical_simple(OverlayWidth,OverlayHeight,OverlayDepth,OverlayOffset) + withpen pencircle xscaled (2OverlayLineWidth) yscaled (3OverlayLineWidth/4) rotated 30 + % dashed evenly + withcolor OverlayLineColor ; +\stopuniqueMPgraphic + +% \setupmathstackers +% [vfenced] +% [color=darkred, +% alternative=mp] + +\endinput diff --git a/tex/context/base/mkiv/meta-imp-nodes.mkiv b/tex/context/base/mkiv/meta-imp-nodes.mkiv new file mode 100644 index 000000000..2555fcaa2 --- /dev/null +++ b/tex/context/base/mkiv/meta-imp-nodes.mkiv @@ -0,0 +1,34 @@ +%D \module +%D [ file=meta-imp-nodes, +%D version=2016.11.23, +%D title=\METAPOST\ Graphics, +%D subtitle=Nodes, +%D author=Alan Braslau and Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D We might add more here. Also, the node module might get preloaded in +%D all instances. + +\unprotect + +\defineMPinstance + [nodes] + [\s!format=metafun, + \s!extensions=\v!yes, + \s!initializations=\v!yes, + \c!method=\s!double] + +\defineframed + [node] + [\c!frame=\v!off] + +\startMPdefinitions{nodes} + loadmodule "node" ; +\stopMPdefinitions + +\protect diff --git a/tex/context/base/mkiv/meta-imp-outlines.mkiv b/tex/context/base/mkiv/meta-imp-outlines.mkiv index 7d7495037..7629c0c92 100644 --- a/tex/context/base/mkiv/meta-imp-outlines.mkiv +++ b/tex/context/base/mkiv/meta-imp-outlines.mkiv @@ -18,8 +18,8 @@ local formatters = string.formatters local validstring = string.valid local f_setbounds = formatters["setbounds currentpicture to (%s) enlarged %.4G;"] -local f_index = formatters['draw anchored.bot(textext("\\tttf\\setstrut\\strut index %i") ysized 2bp ,.5[llcorner currentpicture,lrcorner currentpicture] shifted (0,%.4G));'] -local f_unicode = formatters['draw anchored.bot(textext("\\tttf\\setstrut\\strut unicode %05X") ysized 2bp ,.5[llcorner currentpicture,lrcorner currentpicture] shifted (0,%.4G));'] +local f_index = formatters['draw anchored.bot(textext("\\tttf\\setstrut\\strut index %i") ysized 10bp ,.5[llcorner currentpicture,lrcorner currentpicture] shifted (0,%.4G));'] +local f_unicode = formatters['draw anchored.bot(textext("\\tttf\\setstrut\\strut unicode %05X") ysized 10bp ,.5[llcorner currentpicture,lrcorner currentpicture] shifted (0,%.4G));'] local f_in_red = formatters["draw %s withpen pencircle scaled .15 withcolor .5red;"] local f_in_green = formatters["draw %s withpen pencircle scaled .15 withcolor .5green;"] @@ -43,35 +43,42 @@ local v_all = variables.all local v_page = variables.page local v_text = variables.text local v_command = variables.command +local v_box = variables.box +local v_width = variables.width +local v_min = variables.min +local v_max = variables.max +local v_comment = variables.comment +local v_simple = variables.simple function metapost.showglyph(specification) local fontid = font.current() local shapedata = fonts.hashes.shapes[fontid] -- by index local chardata = fonts.hashes.characters[fontid] -- by unicode - local shapeglyphs = shapedata.glyphs + local shapeglyphs = shapedata.glyphs or { } local character = validstring(specification.character) local index = validstring(specification.index) local alternative = validstring(specification.alternative) local command = validstring(specification.command) - + local options = utilities.parsers.settings_to_set(specification.option) + local all = not next(options) and not options[v_simple] or options[v_all] local function shape(index,what,f_comment) if not index then return end local glyph = shapeglyphs[index] if glyph and (glyph.segments or glyph.sequence) then - local units = data.fontheader and data.fontheader.emsize or 1000 + local units = shapedata.units or 1000 local factor = 100/units local paths = metapost.paths(glyph,factor) - if #paths > 0 then + if #paths > 0 and glyph.boundingbox and glyph.width then local graphic = f_glyph(concat{ - f_in_gray(metapost.fill(paths)), - metapost.draw(paths,true), -- true triggers trace - f_in_red(metapost.boundingbox(glyph,factor)), - f_in_green(metapost.widthline(glyph,factor)), - f_in_blue(metapost.zeroline(glyph,factor)), - f_setbounds(metapost.maxbounds(data,index,factor),offset or 1), - f_comment(what,1) + f_in_gray (metapost.fill(paths)), + metapost.draw(paths,true), -- true triggers trace + (all or options[v_box]) and f_in_red (metapost.boundingbox(glyph,factor)) or "", + (all or options[v_width]) and f_in_green (metapost.widthline(glyph,factor)) or "", + (all or options[v_min]) and f_in_blue (metapost.zeroline(glyph,factor)) or "", + (all or options[v_max]) and f_setbounds(metapost.maxbounds(data,index,factor),offset or 1) or "", + (all or options[v_comment]) and f_comment (what,1) or "", }) if alternative == v_page then context.startMPpage() @@ -110,7 +117,7 @@ function metapost.showglyph(specification) end local first, last if type(index) == "string" then - first, last = string.match(index,"^(.-):(.*)$") + first, last = string.split(index,":") if first and last then first = tonumber(first) last = tonumber(last) @@ -137,17 +144,25 @@ end \unprotect +% option: box|width|min|max|comment + \unexpanded\def\showshape {\dosingleargument\meta_shapes_show} \def\meta_shapes_show[#1]% {\begingroup - \getdummyparameters[\c!alternative=\v!text,#1]% + \letdummyparameter\c!index\empty + \letdummyparameter\c!character\empty + \letdummyparameter\c!alternative\v!text + \letdummyparameter\c!command\empty + \letdummyparameter\c!option\v!all + \getdummyparameters[#1]% \ctxlua{fonts.metapost.showglyph{ character = "\dummyparameter\c!character", index = "\dummyparameter\c!index", alternative = "\dummyparameter\c!alternative", command = "\dummyparameter\c!command", + option = "\dummyparameter\c!option", }}% \endgroup} @@ -164,8 +179,21 @@ end % \setupbodyfont[pagella] % \showshape[character=all,alternative=page] -\setupbodyfont[dejavu] -\showshape[character=P,alternative=text] +\usemodule[art-01] + +% \definedfont[lt55476.afm] + +\startcombination[3*1] + {\ruledhbox{\startMPcode draw textext("\showshape[character=a]") ; \stopMPcode}} {} + {\ruledhbox{\startMPcode draw textext("\showshape[character=x]") ; \stopMPcode}} {} + {\ruledhbox{\showshape[character=P,alternative=text]}} {} +\stopcombination + +\startcombination[3*1] + {\ruledhbox{\startMPcode draw textext("\showshape[character=a,option={simple}]") ; \stopMPcode}} {} + {\ruledhbox{\startMPcode draw textext("\showshape[character=x,option={simple}]") ; \stopMPcode}} {} + {\ruledhbox{\showshape[character=P,alternative=text,option=simple]}} {} +\stopcombination % \definedfont[almfixed] % \showshape[character=all,alternative=page] diff --git a/tex/context/base/mkiv/meta-imp-txt.mkiv b/tex/context/base/mkiv/meta-imp-txt.mkiv index 7069d21a4..b2a6d6d1d 100644 --- a/tex/context/base/mkiv/meta-imp-txt.mkiv +++ b/tex/context/base/mkiv/meta-imp-txt.mkiv @@ -31,7 +31,7 @@ \definesystemvariable {sh} % ShapedText .. todo: commandhandler \startMPextensions - if unknown context_text: input "mp-text.mpiv" ; fi; + loadmodule "text" ; \stopMPextensions %%%%%%% @@ -130,6 +130,7 @@ \unexpanded\def\getshapetext % option: unvbox {\vbox\bgroup \forgetall + \dontcomplain \setbox\scratchbox\vbox to \parheight {\expanded{\switchtobodyfont[\@@shbodyfont]}% evt strutheight en \splittopskip\strutheight % lineheight opslaan @@ -150,84 +151,242 @@ \setupshapetexts [\c!bodyfont=] -%%%%%%% rotfont nog definieren - \doifundefined{RotFont}{\definefont[RotFont][RegularBold*default]} -\unexpanded\def\processfollowingtoken#1% strut toegevoegd - {\appendtoks#1\to\MPtoks - \setbox\MPbox=\hbox{\RotFont\setstrut\strut\the\MPtoks}% - \startMPdrawing - n := n + 1 ; len[n] := \the\wd\MPbox ; - \stopMPdrawing - \startMPdrawing[-] - % pic[n] := textext{\RotFont\setstrut\strut#1} ; % btex \RotFont\setstrut\strut#1 etex ; - pic[n] := btex \RotFont\setstrut\strut#1 etex ; - pic[n] := pic[n] shifted - llcorner pic[n] ; - \stopMPdrawing} - -\startuseMPgraphic{followtokens} - % we default to nothing -\stopuseMPgraphic +% \startuseMPgraphic{followtokens} +% % we default to nothing +% \stopuseMPgraphic + +% \unexpanded\def\processfollowingtoken#1% strut toegevoegd +% {\appendtoks#1\to\MPtoks +% \setbox\MPbox=\hbox{\RotFont\setstrut\strut\the\MPtoks}% +% \startMPdrawing +% n := n + 1 ; len[n] := \the\wd\MPbox ; +% \stopMPdrawing +% \startMPdrawing[-] +% % pic[n] := textext{\RotFont\setstrut\strut#1} ; % btex \RotFont\setstrut\strut#1 etex ; +% pic[n] := btex \RotFont\setstrut\strut#1 etex ; +% pic[n] := pic[n] shifted - llcorner pic[n] ; +% \stopMPdrawing} +% +% \unexpanded\def\dofollowtokens#1#2% +% {\vbox\bgroup +% \forgetall +% \dontcomplain +% \doifundefined{RotFont}{\definefont[RotFont][RegularBold*default]}% +% \MPtoks\emptytoks +% \resetMPdrawing +% \startMPdrawing +% \includeMPgraphic{followtokens} ; +% picture pic[] ; numeric len[], n ; n := 0 ; +% \stopMPdrawing +% \handletokens#2\with\processfollowingtoken +% \startMPdrawing +% if unknown RotPath : path RotPath ; RotPath := origin ; fi ; +% if unknown RotColor : color RotColor ; RotColor := black ; fi ; +% if unknown TraceRot : boolean TraceRot ; TraceRot := false ; fi ; +% if unknown ExtraRot : numeric ExtraRot ; ExtraRot := 0 ; fi ; +% numeric al, at, pl, pc, wid, pos ; pair ap, ad ; +% al := arclength RotPath ; +% if al=0 : +% al := len[n] + ExtraRot ; +% RotPath := origin -- (al,0) ; +% fi ; +% if al<len[n]: +% RotPath := RotPath scaled ((len[n]+ExtraRot)/al) ; +% al := arclength RotPath ; +% fi ; +% if \number#1 = 1 : +% pl := (al-len[n])/(if n>1 : (n-1) else : 1 fi) ; +% pc := 0 ; +% else : % centered / MP +% pl := 0 ; +% pc := arclength RotPath/2 - len[n]/2 ; +% fi ; +% if TraceRot : +% draw RotPath withpen pencircle scaled 1pt withcolor blue ; +% fi ; +% for i=1 upto n : +% wid := abs(xpart urcorner pic[i] - xpart llcorner pic[i]) ; +% pos := len[i]-wid/2 + (i-1)*pl + pc ; +% at := arctime pos of RotPath ; +% ap := point at of RotPath ; +% ad := direction at of RotPath ; +% draw pic[i] shifted (-wid/2,0) rotated(angle(ad)) shifted ap +% withcolor RotColor ; +% if TraceRot : +% draw boundingbox +% pic[i] shifted (-wid/2,0) rotated(angle(ad)) shifted ap +% withpen pencircle scaled .25pt withcolor red ; +% draw ap +% withpen pencircle scaled .50pt withcolor green ; +% fi ; +% endfor ; +% \stopMPdrawing +% \MPdrawingdonetrue +% \getMPdrawing +% \resetMPdrawing +% \egroup} + +\unexpanded\def\getfollowtoken#1% + {\hbox\bgroup + \strut + \ctxlua{mp.follow_text(#1)}% + \egroup} + +\definefontfeature[mp:tp][liga=no] + +\startMPdefinitions + def mfun_follow_draw (expr alternative) = + if unknown RotPath : path RotPath ; RotPath := origin ; fi ; + % if unknown RotColor : color RotColor ; RotColor := black ; fi ; + if unknown TraceRot : boolean TraceRot ; TraceRot := false ; fi ; + if unknown ExtraRot : numeric ExtraRot ; ExtraRot := 0 ; fi ; + picture pic[] ; + numeric len[] ; len[0] := 0 ; + numeric n ; n := lua.mp.follow_size() ; + for i=1 upto n : + pic[i] := lua.mp.follow_slot(i) ; + pic[i] := pic[i] shifted - llcorner pic[i] ; + len[i] := len[i-1] + lua.mp.follow_width(i) ; + endfor ; + numeric al, at, pl, pc, wid, pos ; pair ap, ad ; + al := arclength RotPath ; + if al = 0 : + al := len[n] + ExtraRot ; + RotPath := origin -- (al,0) ; + fi ; + if al < len[n]: + RotPath := RotPath scaled ((len[n]+ExtraRot)/al) ; + al := arclength RotPath ; + fi ; + if alternative = 1 : + pl := (al-len[n])/(if n>1 : (n-1) else : 1 fi) ; + pc := 0 ; + else : % centered / MP + pl := 0 ; + pc := arclength RotPath/2 - len[n]/2 ; + fi ; + if TraceRot : + draw RotPath withpen pencircle scaled 1pt withcolor blue ; + fi ; + for i=1 upto n : + % wid := abs(xpart urcorner pic[i] - xpart llcorner pic[i]) ; + wid := lua.mp.follow_width(i) ; + pos := len[i]-wid/2 + (i-1)*pl + pc ; + at := arctime pos of RotPath ; + ap := point at of RotPath ; + ad := direction at of RotPath ; + if mfun_trial_run : + % skip (ok, somewhat inefficient as we can consider a + % dedicated store and textext variant (todo) + else : + pic[i] := pic[i] shifted (-wid/2,0) rotated(angle(ad)) shifted ap ; + draw pic[i] ; % withcolor RotColor ; + if TraceRot : + draw boundingbox pic[i] withpen pencircle scaled .25pt withcolor red ; + draw ap withpen pencircle scaled .50pt withcolor green ; + fi ; + fi ; + endfor ; + if TraceRot : + draw boundingbox currentpicture withpen pencircle scaled .25pt withcolor blue ; + fi ; + enddef ; +\stopMPdefinitions + +\startluacode + local nodecodes = nodes.nodecodes + + local visible_code = { + [nodecodes.glyph] = true, + [nodecodes.glue] = true, + [nodecodes.hlist] = true, + [nodecodes.vlist] = true, + [nodecodes.rule] = true, + } + + local disc_code = nodecodes.disc + local kern_code = nodecodes.kern + + local c_userkern = nodes.kerncodes.userkern + local a_fontkern = attributes.private("fontkern") + + local n = nil + local s = 0 + + function mp.follow_reset() + r = nil + s = 0 + end + + function mp.follow_initialize(b) + if not r then + local l = tex.takebox(b).list + n = { } + s = 0 + while l do + local c = l + l = l.next + local id = c.id + if visible_code[id] then + s = s + 1 + n[s] = c + c.prev = nil + c.next = nil + elseif id == kern_code then + if c.subtype == c_userkern and not c[a_fontkern] then + s = s + 1 + n[s] = c + c.prev = nil + else + n[s].next = c + c.prev = n[s] + end + c.next = nil + elseif id == disc_code then + local r = c.replace + while r do + s = s + 1 + n[s] = r + r = r.next + r.prev = nil + r.next = nil + end + end + end + end + end + + function mp.follow_size() + mp.print(s) + end + + function mp.follow_slot(i) + mp.print('textext("\\getfollowtoken{' .. i .. '}")') + end + + function mp.follow_text(s) + context(n[s]) + end + + function mp.follow_width(i) + mp.print(number.topoints(n[i].width)) + end +\stopluacode \unexpanded\def\dofollowtokens#1#2% {\vbox\bgroup \forgetall \dontcomplain - \doifundefined{RotFont}{\definefont[RotFont][RegularBold*default]}% - \MPtoks\emptytoks - \resetMPdrawing - \startMPdrawing + \setbox\scratchbox\hbox{\addff{mp:tp}#2}% + \ctxlua{mp.follow_initialize(\number\scratchbox)}% + \stopluacode + \startMPcode \includeMPgraphic{followtokens} ; - picture pic[] ; numeric len[], n ; n := 0 ; - \stopMPdrawing - \handletokens#2\with\processfollowingtoken - \startMPdrawing - if unknown RotPath : path RotPath ; RotPath := origin ; fi ; - if unknown RotColor : color RotColor ; RotColor := black ; fi ; - if unknown TraceRot : boolean TraceRot ; TraceRot := false ; fi ; - if unknown ExtraRot : numeric ExtraRot ; ExtraRot := 0 ; fi ; - numeric al, at, pl, pc, wid, pos ; pair ap, ad ; - al := arclength RotPath ; - if al=0 : - al := len[n] + ExtraRot ; - RotPath := origin -- (al,0) ; - fi ; - if al<len[n]: - RotPath := RotPath scaled ((len[n]+ExtraRot)/al) ; - al := arclength RotPath ; - fi ; - if \number#1 = 1 : - pl := (al-len[n])/(if n>1 : (n-1) else : 1 fi) ; - pc := 0 ; - else : % centered / MP - pl := 0 ; - pc := arclength RotPath/2 - len[n]/2 ; - fi ; - if TraceRot : - draw RotPath withpen pencircle scaled 1pt withcolor blue ; - fi ; - for i=1 upto n : - wid := abs(xpart urcorner pic[i] - xpart llcorner pic[i]) ; - pos := len[i]-wid/2 + (i-1)*pl + pc ; - at := arctime pos of RotPath ; - ap := point at of RotPath ; - ad := direction at of RotPath ; - draw pic[i] shifted (-wid/2,0) rotated(angle(ad)) shifted ap - withcolor RotColor ; - if TraceRot : - draw boundingbox - pic[i] shifted (-wid/2,0) rotated(angle(ad)) shifted ap - withpen pencircle scaled .25pt withcolor red ; - draw ap - withpen pencircle scaled .50pt withcolor green ; - fi ; - endfor ; -% fill boundingbox currentpicture ; - \stopMPdrawing - \MPdrawingdonetrue - \getMPdrawing - \resetMPdrawing + mfun_follow_draw(\number#1) ; + \stopMPcode + \ctxlua{mp.follow_reset()}% \egroup} \unexpanded\def\followtokens {\dofollowtokens1} @@ -262,6 +421,8 @@ % \followtokenscentered{So now we have two commands.}} % \stopoverlay +% \followtokengraphicscale{6cm} +% \followtokens{Hans Hagen uses {\darkred\TeX}, {\darkgreen\Lua}, {\darkblue \MetaPost} and friends.} \startuseMPgraphic{fuzzycount} begingroup @@ -289,7 +450,7 @@ [fuzzycount] [n=10] -\def\fuzzycount#1% +\unexpanded\def\fuzzycount#1% {{\tx\useMPgraphic{fuzzycount}{n=#1}}} \defineconversion[fuzzy][\fuzzycount] diff --git a/tex/context/base/mkiv/meta-ini.lua b/tex/context/base/mkiv/meta-ini.lua index 8f7131263..d3865c433 100644 --- a/tex/context/base/mkiv/meta-ini.lua +++ b/tex/context/base/mkiv/meta-ini.lua @@ -75,45 +75,53 @@ local dimenorname = + (C(lpegpatterns.float) + Cc(1)) * lpegpatterns.space^0 * P("\\") * C(lpegpatterns.letter^1) / function(f,s) local t = textype(s) if t == "dimen" then - context("\\the\\dimexpr %s\\%s",f,s) + context("\\the\\dimexpr %s\\%s\\relax",f,s) elseif t == "count" then context("\\the\\numexpr \\%s * %s\\relax",s,f) -- <n>\scratchcounter is not permitted end end -local splitter = lpeg.splitat(":",true) - -function commands.prepareMPvariable(v) -- slow but ok - if v == "" then - MPcolor("black") - else - local typ, var = lpegmatch(splitter,v) - if not var then - -- parse - if colorhash[v] then - MPcolor(v) - elseif tonumber(v) then - context(v) - elseif not lpegmatch(dimenorname,v) then - context("\\number %s",v) -- 0.4 ... - end - elseif typ == "d" then -- to be documented - -- dimension - context("\\the\\dimexpr %s",var) - elseif typ == "n" then -- to be documented - -- number - context("\\the\\numexpr %s",var) - elseif typ == "s" then -- to be documented - -- string - context(var) - elseif typ == "c" then -- to be documented - -- color - MPcolor(var) +local splitter = lpeg.splitat("::",true) + +interfaces.implement { + name = "prepareMPvariable", + arguments = "string", + actions = function(v) + if v == "" then + -- MPcolor("black") + context("black") else - context(var) + local typ, var = lpegmatch(splitter,v) + if not var then + -- parse + if colorhash[v] then + -- MPcolor(v) + context("%q",var) + elseif tonumber(v) then + context(v) + elseif not lpegmatch(dimenorname,v) then + context("\\number %s",v) -- 0.4 ... + end + elseif typ == "d" then -- to be documented + -- dimension + context("\\the\\dimexpr %s\\relax",var) + elseif typ == "n" then -- to be documented + -- number + context("\\the\\numexpr %s\\relax",var) + elseif typ == "s" then -- to be documented + -- string + -- context(var) + context("%q",var) + elseif typ == "c" then -- to be documented + -- color + -- MPcolor(var) + context("%q",var) + else + context(var) + end end end -end +} -- function metapost.formatnumber(f,n) -- just lua format -- f = gsub(f,"@(%d)","%%.%1") diff --git a/tex/context/base/mkiv/meta-ini.mkiv b/tex/context/base/mkiv/meta-ini.mkiv index d0fff83df..1d0fa11e0 100644 --- a/tex/context/base/mkiv/meta-ini.mkiv +++ b/tex/context/base/mkiv/meta-ini.mkiv @@ -248,8 +248,8 @@ \def\meta_flush_current_initializations {\ifconditional\c_meta_include_initializations \the\t_meta_initializations - \fi - \theMPrandomseed;} + \fi} + % \theMPrandomseed;} \def\meta_flush_current_inclusions {\the\t_meta_inclusions} @@ -262,7 +262,7 @@ \meta_enable_include \the\everyMPgraphic \meta_preset_definitions - \setMPrandomseed % this has to change + %\setMPrandomseed % this has to change \edef\p_initializations{\MPinstanceparameter\s!initializations}% \ifx\p_initializations\v!yes \settrue \c_meta_include_initializations @@ -315,6 +315,7 @@ definitions {\meta_flush_current_definitions}% figure {\MPaskedfigure}% method {\MPinstanceparameter\c!method}% + namespace {\??graphicvariable\currentmpvariableclass:}% \relax}% \meta_process_graphic_stop \meta_stop_current_graphic} @@ -334,16 +335,16 @@ \meta_process_graphic{input "#1" ;}% \endgroup} -\newif\ifsetMPrandomseed \setMPrandomseedtrue % false by default - -\let\theMPrandomseed\empty - -\def\setMPrandomseed - {\ifsetMPrandomseed - \def\theMPrandomseed{randomseed:=\mprandomnumber;}% - \else - \let\theMPrandomseed\empty - \fi} +% \newif\ifsetMPrandomseed \setMPrandomseedtrue % false by default +% +% \let\theMPrandomseed\empty +% +% \def\setMPrandomseed +% {\ifsetMPrandomseed +% \def\theMPrandomseed{randomseed:=\mprandomnumber;}% +% \else +% \let\theMPrandomseed\empty +% \fi} %D Calling up previously defined graphics. @@ -521,10 +522,7 @@ \installcorenamespace{graphicvariable} -\def \meta_prepare_variable_default {\MPcolor{black}} % just to be sure we use a color but ... -\edef\meta_unknown_variable_template {\??graphicvariable:\s!unknown} - -\letvalue{\??graphicvariable:\s!unknown}\empty +\def\meta_prepare_variable_default{\MPcolor{black}} % just to be sure we use a color but ... \unexpanded\def\setupMPvariables {\dodoubleempty\meta_setup_variables} @@ -545,11 +543,9 @@ \fi} \def\MPrawvar#1#2% no checking - %{\csname\??graphicvariable#1:#2\endcsname} {\begincsname\??graphicvariable#1:#2\endcsname} \def\MPvariable#1% todo: could be a framed chain - %{\csname\??graphicvariable\currentmpvariableclass:#1\endcsname} {\begincsname\??graphicvariable\currentmpvariableclass:#1\endcsname} \unexpanded\def\useMPvariables @@ -566,9 +562,9 @@ {\edef\m_meta_current_variable_template {\??graphicvariable\currentmpvariableclass:#1}% \edef\m_meta_current_variable - {\csname\ifcsname\m_meta_current_variable_template\endcsname - \m_meta_current_variable_template\else\meta_unknown_variable_template - \fi\endcsname}% + {\ifcsname\m_meta_current_variable_template\endcsname + \lastnamedcs + \fi}% \ifx\m_meta_current_variable\empty \expandafter\meta_prepare_variable_nop \else @@ -582,15 +578,11 @@ {\edef\m_meta_current_variable_template {\??graphicvariable\currentmpvariableclass:#1}% \edef\m_meta_current_variable - {\csname - \ifcsname\m_meta_current_variable_template\endcsname - \m_meta_current_variable_template - \else\ifcsname\??graphicvariable\currentMPgraphicname:#1\endcsname - \??graphicvariable\currentMPgraphicname:#1% - \else - \meta_unknown_variable_template - \fi\fi - \endcsname}% + {\ifcsname\m_meta_current_variable_template\endcsname + \lastnamedcs + \else\ifcsname\??graphicvariable\currentMPgraphicname:#1\endcsname + \lastnamedcs + \fi\fi}% \ifx\m_meta_current_variable\empty \expandafter\meta_prepare_variable_nop \else @@ -621,6 +613,10 @@ \endgroup\meta_prepare_variable_dimension \fi}} +% \def\meta_prepare_variable_yes +% {\expandafter\edef\csname\m_meta_current_variable_template\endcsname +% {\clf_prepareMPvariable {\m_meta_current_variable}}} + \let\MPvar \MPvariable \let\setMPvariables\setupMPvariables @@ -710,16 +706,18 @@ {\setunreferencedobject{MP}} \def\meta_handle_unique_graphic#1#2#3% when there are too many, we can store data at the lua end, although, - {\begingroup % when there are that many they're probably not that unique anyway + {\begingroup % when there are that many they're probably not that unique anyway \edef\currentmpvariableclass{#1}% \extendMPoverlaystamp{#2}% incl prepare - \ifcsname\??mpgraphic\overlaystamp:#1\endcsname\else + \ifcsname\??mpgraphic\overlaystamp:#1\endcsname + \lastnamedcs + \else \meta_enable_include % redundant \global\advance\c_meta_object_counter\plusone \meta_use_box{\number\c_meta_object_counter}\hpack{\meta_process_graphic{#3}}% was vbox, graphic must end up as hbox \setxvalue{\??mpgraphic\overlaystamp:#1}{\meta_reuse_box{\number\c_meta_object_counter}{\the\MPllx}{\the\MPlly}{\the\MPurx}{\the\MPury}}% + \csname\??mpgraphic\overlaystamp:#1\endcsname\empty \fi - \csname\??mpgraphic\overlaystamp:#1\endcsname\empty \endgroup} \unexpanded\def\startuniqueMPgraphic @@ -1495,6 +1493,12 @@ \def\MPruntab#1#2{\clf_mpruntab{#1}#2\relax} \let\mpruntab\MPruntab % #2 is number \def\MPrunset#1#2{\clf_mprunset{#1}{#2}} \let\mprunset\MPrunset +\prependtoks \clf_mppushvariables \to \everybeforepagebody +\appendtoks \clf_mppopvariables \to \everyafterpagebody + +\let\MPpushvariables\clf_mppushvariables +\let\MPpopvariables \clf_mppopvariables + %D We also provide an outputless run: \unexpanded\def\startMPcalculation diff --git a/tex/context/base/mkiv/meta-pdf.lua b/tex/context/base/mkiv/meta-pdf.lua index 3cbff63b1..c17a2a4c7 100644 --- a/tex/context/base/mkiv/meta-pdf.lua +++ b/tex/context/base/mkiv/meta-pdf.lua @@ -541,13 +541,13 @@ end -- main converter -local a_colorspace = attributes.private('colormodel') +local a_colormodel = attributes.private('colormodel') function mptopdf.convertmpstopdf(name) resetall() local ok, m_data, n = resolvers.loadbinfile(name, 'tex') -- we need a binary load ! if ok then - mps.colormodel = texgetattribute(a_colorspace) + mps.colormodel = texgetattribute(a_colormodel) statistics.starttiming(mptopdf) mptopdf.nofconverted = mptopdf.nofconverted + 1 pdfcode(formatters["\\letterpercent\\space mptopdf begin: n=%s, file=%s"](mptopdf.nofconverted,file.basename(name))) diff --git a/tex/context/base/mkiv/meta-tex.lua b/tex/context/base/mkiv/meta-tex.lua index 1008e45c0..71207975d 100644 --- a/tex/context/base/mkiv/meta-tex.lua +++ b/tex/context/base/mkiv/meta-tex.lua @@ -124,6 +124,10 @@ function metapost.format_string(fmt,...) end function metapost.format_number(fmt,num) + if not num then + num = fmt + fmt = "%e" + end local number = tonumber(num) if number then local base, exponent = lpegmatch(enumber,formatters[lpegmatch(cleaner,fmt)](number)) @@ -150,6 +154,59 @@ end implement { name = "metapostformatted", actions = metapost.svformat, arguments = { "string", "string" } } implement { name = "metapostgraphformat", actions = metapost.nvformat, arguments = { "string", "string" } } +-- kind of new + +local f_exponent = formatters["\\MPexponent{%s}{%s}"] + +local mpformatters = table.setmetatableindex(function(t,k) + local v = formatters[lpegmatch(cleaner,k)] + t[k] = v + return v +end) + +function metapost.texexp(num,bfmt,efmt) + local number = tonumber(num) + if number then + local base, exponent = lpegmatch(enumber,format("%e",number)) + if base and exponent then + if bfmt then + -- base = formatters[lpegmatch(cleaner,bfmt)](base) + base = mpformatters[bfmt](base) + else + base = format("%f",base) + end + if efmt then + -- exponent = formatters[lpegmatch(cleaner,efmt)](exponent) + exponent = mpformatters[efmt](exponent) + else + exponent = format("%i",exponent) + end + return f_exponent(base,exponent) + elseif bfmt then + -- return formatters[lpegmatch(cleaner,bfmt)](number) + return mpformatters[bfmt](number) + else + return number + end + else + return num + end +end + +-- not in context a namespace + +if _LUAVERSION < 5.2 then + utilities.strings.formatters.add(formatters,"texexp", [[texexp(...)]], "local texexp = metapost.texexp") +else + utilities.strings.formatters.add(formatters,"texexp", [[texexp(...)]], { texexp = metapost.texexp }) +end + +-- print(string.formatters["%!3.3!texexp!"](10.4345E30)) +-- print(string.formatters["%3!texexp!"](10.4345E30,"%2.3f","%2i")) +-- print(string.formatters["%2!texexp!"](10.4345E30,"%2.3f")) +-- print(string.formatters["%1!texexp!"](10.4345E30)) +-- print(string.formatters["%!texexp!"](10.4345E30)) + -- local function test(fmt,n) -- logs.report("mp format test","fmt: %s, n: %s, result: %s, \\exponent{%s}{%s}",fmt,n, -- formatters[lpegmatch(cleaner,fmt)](n), @@ -180,16 +237,18 @@ local f_textext = formatters[ [[textext("%s")]] ] local f_mthtext = formatters[ [[textext("\mathematics{%s}")]] ] local f_exptext = formatters[ [[textext("\mathematics{%s\times10^{%s}}")]] ] +-- local cleaner = Cs((P("\\")/"\\\\" + P("@@")/"@" + P("@")/"%%" + P(1))^0) + local mpprint = mp.print -function mp.format(fmt,str) +function mp.format(fmt,str) -- bah, this overloads mp.format in mlib-lua.lua fmt = lpegmatch(cleaner,fmt) mpprint(f_textext(formatters[fmt](metapost.untagvariable(str,false)))) end -function mp.formatted(fmt,num) -- svformat +function mp.formatted(fmt,...) -- svformat fmt = lpegmatch(cleaner,fmt) - mpprint(f_textext(formatters[fmt](tonumber(num) or num))) + mpprint(f_textext(formatters[fmt](...))) end function mp.graphformat(fmt,num) -- nvformat diff --git a/tex/context/base/mkiv/mlib-ctx.lua b/tex/context/base/mkiv/mlib-ctx.lua index 3fe7118b7..96eb27cbd 100644 --- a/tex/context/base/mkiv/mlib-ctx.lua +++ b/tex/context/base/mkiv/mlib-ctx.lua @@ -23,6 +23,8 @@ local mplib = mplib metapost = metapost or {} local metapost = metapost +local context = context + local setters = tokens.setters local setmacro = setters.macro local implement = interfaces.implement @@ -177,6 +179,7 @@ implement { implement { name = "mprunset", + arguments = { "string", "string" }, actions = function(name,connector) local value = metapost.variables[name] if value ~= nil then @@ -213,6 +216,7 @@ implement { { "definitions" }, { "figure" }, { "method" }, + { "namespace" }, } } } @@ -282,7 +286,6 @@ end function metapost.theclippath(...) local result = metapost.getclippath(...) if result then -- we could just print the table --- return concat(metapost.flushnormalpath(result),"\n") return concat(metapost.flushnormalpath(result)," ") else return "" @@ -303,6 +306,7 @@ implement { { "useextensions" }, { "inclusions" }, { "method" }, + { "namespace" }, }, } } @@ -353,6 +357,16 @@ function mptex.reset() end implement { + name = "mppushvariables", + actions = metapost.pushvariables, +} + +implement { + name = "mppopvariables", + actions = metapost.popvariables, +} + +implement { name = "mptexset", arguments = "string", actions = mptex.set diff --git a/tex/context/base/mkiv/mlib-int.lua b/tex/context/base/mkiv/mlib-int.lua index 6d219fe04..108002929 100644 --- a/tex/context/base/mkiv/mlib-int.lua +++ b/tex/context/base/mkiv/mlib-int.lua @@ -8,8 +8,8 @@ if not modules then modules = { } end modules ['mlib-int'] = { local factor = number.dimenfactors.bp local mpprint = mp.print -local mpboolean = mp.boolean -local mpquoted = mp.quoted +----- mpboolean = mp.boolean +----- mpquoted = mp.quoted local getdimen = tex.getdimen local getcount = tex.getcount local get = tex.get @@ -68,11 +68,11 @@ function mp.NOfPages () mpprint(getcount("lastpageno")) function mp.CurrentColumn () mpprint(getcount("mofcolumns")) end function mp.NOfColumns () mpprint(getcount("nofcolumns")) end -function mp.BaseLineSkip () mpprint(getdimen("baselineskip") *factor) end +function mp.BaseLineSkip () mpprint(get ("baselineskip",true) *factor) end function mp.LineHeight () mpprint(getdimen("lineheight") *factor) end function mp.BodyFontSize () mpprint(getdimen("bodyfontsize") *factor) end -function mp.TopSkip () mpprint(getdimen("topskip") *factor) end +function mp.TopSkip () mpprint(get ("topskip",true) *factor) end function mp.StrutHeight () mpprint(getdimen("strutht") *factor) end function mp.StrutDepth () mpprint(getdimen("strutdp") *factor) end @@ -80,8 +80,8 @@ function mp.PageNumber () mpprint(getcount("pageno")) function mp.RealPageNumber () mpprint(getcount("realpageno")) end function mp.NOfPages () mpprint(getcount("lastpageno")) end -function mp.CurrentWidth () mpprint(get("hsize") *factor) end -function mp.CurrentHeight () mpprint(get("vsize") *factor) end +function mp.CurrentWidth () mpprint(get ("hsize") *factor) end +function mp.CurrentHeight () mpprint(get ("vsize") *factor) end function mp.EmWidth () mpprint(emwidths [false]*factor) end function mp.ExHeight () mpprint(exheights[false]*factor) end diff --git a/tex/context/base/mkiv/mlib-lua.lua b/tex/context/base/mkiv/mlib-lua.lua index baf9346c4..9831efc20 100644 --- a/tex/context/base/mkiv/mlib-lua.lua +++ b/tex/context/base/mkiv/mlib-lua.lua @@ -11,7 +11,7 @@ if not modules then modules = { } end modules ['mlib-lua'] = { -- maybe we need mplib.model, but how with instances local type, tostring, select, loadstring = type, tostring, select, loadstring -local find, gsub = string.find, string.gsub +local find, match, gsub, gmatch = string.find, string.match, string.gsub, string.gmatch local formatters = string.formatters local concat = table.concat @@ -62,11 +62,12 @@ end local f_code = formatters["%s return mp._f_()"] local f_numeric = formatters["%.16f"] +local f_integer = formatters["%i"] local f_pair = formatters["(%.16f,%.16f)"] local f_triplet = formatters["(%.16f,%.16f,%.16f)"] local f_quadruple = formatters["(%.16f,%.16f,%.16f,%.16f)"] -function mp.print(...) +local function mpprint(...) for i=1,select("#",...) do local value = select(i,...) if value ~= nil then @@ -85,14 +86,36 @@ function mp.print(...) end end -function mp.boolean(n) +mp.print = mpprint + +-- We had this: +-- +-- table.setmetatablecall(mp,function(t,k) mpprint(k) end) +-- +-- but the next one is more interesting because we cannot use calls like: +-- +-- lua.mp.somedefdname("foo") +-- +-- which is due to expansion of somedefdname during suffix creation. So: +-- +-- lua.mp("somedefdname","foo") + +table.setmetatablecall(mp,function(t,k,...) return t[k](...) end) + +function mp.boolean(b) + n = n + 1 + buffer[n] = b and "true" or "false" +end + +function mp.numeric(f) n = n + 1 - buffer[n] = n and "true" or "false" + buffer[n] = f and f_numeric(f) or "0" end -function mp.numeric(n) +function mp.integer(i) n = n + 1 - buffer[n] = n and f_numeric(n) or "0" + -- buffer[n] = i and f_integer(i) or "0" + buffer[n] = i or "0" end function mp.pair(x,y) @@ -152,6 +175,12 @@ function mp.size(t) buffer[n] = type(t) == "table" and f_numeric(#t) or "0" end +local mpnamedcolor = attributes.colors.mpnamedcolor + +mp.NamedColor = function(str) + mpprint(mpnamedcolor(str)) +end + -- experiment: names can change local datasets = { } @@ -173,7 +202,7 @@ end local replacer = lpeg.replacer("@","%%") -function mp.format(fmt,...) +function mp.fprint(fmt,...) n = n + 1 if not find(fmt,"%%") then fmt = lpegmatch(replacer,fmt) @@ -181,7 +210,7 @@ function mp.format(fmt,...) buffer[n] = formatters[fmt](...) end -function mp.quoted(fmt,s,...) +local function mpquoted(fmt,s,...) n = n + 1 if s then if not find(fmt,"%%") then @@ -195,6 +224,8 @@ function mp.quoted(fmt,s,...) end end +mp.quoted = mpquoted + function mp.n(t) return type(t) == "table" and #t or 0 end @@ -352,9 +383,10 @@ end -- texts: -local factor = 65536*(7227/7200) -local textexts = nil -local mptriplet = mp.triplet +local factor = 65536*(7227/7200) +local textexts = nil +local mptriplet = mp.triplet +local nbdimensions = nodes.boxes.dimensions function mp.tt_initialize(tt) textexts = tt @@ -374,7 +406,7 @@ end -- end function mp.tt_dimensions(n) - local box = textexts[n] + local box = textexts and textexts[n] if box then -- could be made faster with nuts but not critical mptriplet(box.width/factor,box.height/factor,box.depth/factor) @@ -383,6 +415,11 @@ function mp.tt_dimensions(n) end end +function mp.tb_dimensions(category,name) + local w, h, d = nbdimensions(category,name) + mptriplet(w/factor,h/factor,d/factor) +end + function mp.report(a,b) if b then report_message("%s : %s",a,b) @@ -390,3 +427,223 @@ function mp.report(a,b) report_message("%s : %s","message",a) end end + +-- + +local hashes = { } + +function mp.newhash() + for i=1,#hashes+1 do + if not hashes[i] then + hashes[i] = { } + mpprint(i) + return + end + end +end + +function mp.disposehash(n) + hashes[n] = nil +end + +function mp.inhash(n,key) + local h = hashes[n] + mpprint(h and h[key] and true or false) +end + +function mp.tohash(n,key) + local h = hashes[n] + if h then + h[key] = true + end +end + +local modes = tex.modes +local systemmodes = tex.systemmodes + +function mp.mode(s) + mpprint(modes[s] and true or false) +end + +function mp.systemmode(s) + mpprint(systemmodes[s] and true or false) +end + +-- for alan's nodes: + +function mp.isarray(str) + mpprint(find(str,"%d") and true or false) +end + +function mp.prefix(str) + mpquoted(match(str,"^(.-)[%d%[]") or str) +end + +function mp.dimensions(str) + local n = 0 + for s in gmatch(str,"%[?%-?%d+%]?") do --todo: lpeg + n = n + 1 + end + mpprint(n) +end + +-- faster and okay as we don't have many variables but probably only +-- basename makes sense and even then it's not called that often + +-- local hash = table.setmetatableindex(function(t,k) +-- local v = find(k,"%d") and true or false +-- t[k] = v +-- return v +-- end) +-- +-- function mp.isarray(str) +-- mpprint(hash[str]) +-- end +-- +-- local hash = table.setmetatableindex(function(t,k) +-- local v = '"' .. (match(k,"^(.-)%d") or k) .. '"' +-- t[k] = v +-- return v +-- end) +-- +-- function mp.prefix(str) +-- mpprint(hash[str]) +-- end + +local getdimen = tex.getdimen +local getcount = tex.getcount +local gettoks = tex.gettoks +local setdimen = tex.setdimen +local setcount = tex.setcount +local settoks = tex.settoks + +local mpprint = mp.print +local mpquoted = mp.quoted + +local factor = number.dimenfactors.bp + +-- more helpers + +function mp.getdimen(k) mpprint (getdimen(k)*factor) end +function mp.getcount(k) mpprint (getcount(k)) end +function mp.gettoks (k) mpquoted(gettoks (k)) end +function mp.setdimen(k,v) setdimen(k,v/factor) end +function mp.setcount(k,v) setcount(k,v) end +function mp.settoks (k,v) settoks (k,v) end + +-- def foo = lua.mp.foo ... enddef ; % loops due to foo in suffix + +mp._get_dimen_ = mp.getdimen +mp._get_count_ = mp.getcount +mp._get_toks_ = mp.gettoks +mp._set_dimen_ = mp.setdimen +mp._set_count_ = mp.setcount +mp._set_toks_ = mp.settoks + +-- position fun + +do + + local mprint = mp.print + local fprint = mp.fprint + local qprint = mp.quoted + local getwhd = job.positions.whd + local getxy = job.positions.xy + local getposition = job.positions.position + local getpage = job.positions.page + local getregion = job.positions.region + local getmacro = tokens.getters.macro + + function mp.positionpath(name) + local w, h, d = getwhd(name) + if w then + fprint("((%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle)",0,-d,w,-d,w,h,0,h) + else + mprint("(origin--cycle)") + end + end + + function mp.positioncurve(name) + local w, h, d = getwhd(name) + if w then + fprint("((%p,%p)..(%p,%p)..(%p,%p)..(%p,%p)..cycle)",0,-d,w,-d,w,h,0,h) + else + mprint("(origin--cycle)") + end + end + + function mp.positionbox(name) + local p, x, y, w, h, d = getposition(name) + if p then + fprint("((%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle)",x,y-d,x+w,y-d,x+w,y+h,x,y+h) + else + mprint("(%p,%p)",x,y) + end + end + + function mp.positionxy(name) + local x, y = getxy(name) + if x then + fprint("(%p,%p)",x,y) + else + mprint("origin") + end + end + + function mp.positionpage(name) + local p = getpage(name) + if p then + fprint("%p",p) + else + mprint("0") + end + end + + function mp.positionregion(name) + local r = getregion(name) + if r then + qprint(r) + else + qprint("unknown") + end + end + + function mp.positionwhd(name) + local w, h, d = getwhd(name) + if w then + fprint("(%p,%p,%p)",w,h,d) + else + mprint("(0,0,0)") + end + end + + function mp.positionpxy(name) + local p, x, y = getposition(name) + if p then + fprint("(%p,%p,%p)",p,x,y) + else + mprint("(0,0,0)") + end + end + + function mp.positionanchor() + qprint(getmacro("MPanchorid")) + end + +end + +do + + local mprint = mp.print + local qprint = mp.quoted + local getmacro = tokens.getters.macro + + function mp.texvar(name) + mprint(getmacro(metapost.namespace .. name)) + end + + function mp.texstr(name) + qprint(getmacro(metapost.namespace .. name)) + end + +end diff --git a/tex/context/base/mkiv/mlib-pdf.lua b/tex/context/base/mkiv/mlib-pdf.lua index a2d4638a9..0c2945316 100644 --- a/tex/context/base/mkiv/mlib-pdf.lua +++ b/tex/context/base/mkiv/mlib-pdf.lua @@ -31,6 +31,7 @@ local pen_info = mplib.pen_info local object_fields = mplib.fields local save_table = false +local force_stroke = false metapost = metapost or { } local metapost = metapost @@ -68,6 +69,10 @@ directives.register("metapost.savetable",function(v) end end) +trackers.register("metapost.forcestroke",function(v) + force_stroke = v +end) + local pdfliteral = function(pdfcode) local literal = copy_node(mpsliteral) literal.data = pdfcode @@ -136,15 +141,13 @@ function pdfflusher.comment(message) message = formatters["%% mps graphic %s: %s"](metapost.n,message) if experiment then context(pdfliteral(message)) + elseif savedliterals then + local last = #savedliterals + 1 + savedliterals[last] = message + context.MPLIBtoPDF(last) else - if savedliterals then - local last = #savedliterals + 1 - savedliterals[last] = message - context.MPLIBtoPDF(last) - else - savedliterals = { message } - context.MPLIBtoPDF(1) - end + savedliterals = { message } + context.MPLIBtoPDF(1) end end end @@ -342,7 +345,7 @@ local variable = local pattern_lst = (variable * newline^0)^0 -metapost.variables = { } -- to be stacked +metapost.variables = { } -- currently across instances metapost.properties = { } -- to be stacked function metapost.untagvariable(str,variables) -- will be redone @@ -387,11 +390,9 @@ local function setproperties(figure) return properties end -local function setvariables(figure) - local variables = { } - metapost.variables = variables - return variables -end +local function nocomment() end + +metapost.comment = nocomment function metapost.flush(result,flusher,askedfig) if result then @@ -407,7 +408,7 @@ function metapost.flush(result,flusher,askedfig) local flushfigure = flusher.flushfigure local textfigure = flusher.textfigure local processspecial = flusher.processspecial or metapost.processspecial - local variables = setvariables(figure) -- also resets then in case of not found + metapost.comment = flusher.comment or nocomment for index=1,#figures do local figure = figures[index] local properties = setproperties(figure) @@ -564,11 +565,13 @@ function metapost.flush(result,flusher,askedfig) else flushnormalpath(path,result,open) end - if objecttype == "fill" then + if force_stroke then + result[#result+1] = open and "S" or "h S" + elseif objecttype == "fill" then result[#result+1] = evenodd and "h f*" or "h f" -- f* = eo elseif objecttype == "outline" then if both then - result[#result+1] = evenodd and "h B*" or "h B" -- f* = eo + result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo else result[#result+1] = open and "S" or "h S" end @@ -601,7 +604,9 @@ function metapost.flush(result,flusher,askedfig) else flushnormalpath(path,result,open) end - if objecttype == "fill" then + if force_stroke then + result[#result+1] = open and "S" or "h S" + elseif objecttype == "fill" then result[#result+1] = evenodd and "h f*" or "h f" -- f* = eo elseif objecttype == "outline" then result[#result+1] = open and "S" or "h S" @@ -632,6 +637,7 @@ function metapost.flush(result,flusher,askedfig) end end end + metapost.comment = nocomment end end end diff --git a/tex/context/base/mkiv/mlib-pdf.mkiv b/tex/context/base/mkiv/mlib-pdf.mkiv index 78dab716d..5875c7635 100644 --- a/tex/context/base/mkiv/mlib-pdf.mkiv +++ b/tex/context/base/mkiv/mlib-pdf.mkiv @@ -93,7 +93,7 @@ \def\startMPLIBtoPDF#1#2#3#4% {\meta_process_graphic_figure_start \dostarttagged\t!mpgraphic\empty - \naturalhbox attr \imageattribute 1 \bgroup + \naturalhpack attr \imageattribute \plusone \bgroup \dousecolorparameter\s!black\forcecolorhack \setMPboundingbox{#1}{#2}{#3}{#4}% \setbox\MPbox\vpack\bgroup diff --git a/tex/context/base/mkiv/mlib-pps.lua b/tex/context/base/mkiv/mlib-pps.lua index c016e0f36..9fc8fec35 100644 --- a/tex/context/base/mkiv/mlib-pps.lua +++ b/tex/context/base/mkiv/mlib-pps.lua @@ -8,25 +8,26 @@ if not modules then modules = { } end modules ['mlib-pps'] = { local format, gmatch, match, split = string.format, string.gmatch, string.match, string.split local tonumber, type, unpack = tonumber, type, unpack -local round = math.round +local round, sqrt, min, max = math.round, math.sqrt, math.min, math.max local insert, remove, concat = table.insert, table.remove, table.concat local Cs, Cf, C, Cg, Ct, P, S, V, Carg = lpeg.Cs, lpeg.Cf, lpeg.C, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.S, lpeg.V, lpeg.Carg local lpegmatch, tsplitat, tsplitter = lpeg.match, lpeg.tsplitat, lpeg.tsplitter local formatters = string.formatters +local exists, savedata = io.exists, io.savedata -local mplib, metapost, lpdf, context = mplib, metapost, lpdf, context - +local mplib = mplib +local metapost = metapost +local lpdf = lpdf local context = context -local context_setvalue = context.setvalue local implement = interfaces.implement local setmacro = interfaces.setmacro -local texgetbox = tex.getbox +----- texgetbox = tex.getbox local texsetbox = tex.setbox -local textakebox = tex.takebox +local textakebox = tex.takebox -- or: nodes.takebox local copy_list = node.copy_list -local free_list = node.flush_list +local flush_list = node.flush_list local setmetatableindex = table.setmetatableindex local sortedhash = table.sortedhash @@ -62,6 +63,7 @@ local makempy = metapost.makempy local nooutercolor = "0 g 0 G" local nooutertransparency = "/Tr0 gs" -- only when set local outercolormode = 0 +local outercolormodel = 1 local outercolor = nooutercolor local outertransparency = nooutertransparency local innercolor = nooutercolor @@ -73,7 +75,8 @@ local pdftransparency = lpdf.transparency function metapost.setoutercolor(mode,colormodel,colorattribute,transparencyattribute) -- has always to be called before conversion -- todo: transparency (not in the mood now) - outercolormode = mode + outercolormode = mode + outercolormodel = colormodel if mode == 1 or mode == 3 then -- inherit from outer (registered color) outercolor = pdfcolor(colormodel,colorattribute) or nooutercolor @@ -181,7 +184,7 @@ local function checkandconvert(ca,cb,model) normalize(cb,ca) end if not model then - model = colors.model + model = colors.currentnamedmodel() end if model == "all" then model= (#ca == 4 and "cmyk") or (#ca == 3 and "rgb") or "gray" @@ -257,10 +260,10 @@ end local function stopjob() if top then - for n, tn in next, top.textexts do - free_list(tn) + for slot, content in next, top.textexts do + flush_list(content) if trace_textexts then - report_textexts("freeing text %s",n) + report_textexts("freeing text %s",slot) end end if trace_runs then @@ -283,24 +286,17 @@ local function settext(box,slot) -- if trace_textexts then -- report_textexts("getting text %s from box %s",slot,box) -- end - top.textexts[slot] = copy_list(texgetbox(box)) - texsetbox(box,nil) - -- this can become - -- top.textexts[slot] = textakebox(box) - else - -- weird error + top.textexts[slot] = textakebox(box) end end local function gettext(box,slot) if top then + -- maybe check how often referenced texsetbox(box,copy_list(top.textexts[slot])) -- if trace_textexts then -- report_textexts("putting text %s in box %s",slot,box) -- end - -- top.textexts[slot] = nil -- no, pictures can be placed several times - else - -- weird error end end @@ -446,6 +442,11 @@ function models.gray(cr) return checked_color_pair(f_gray,s,s) end +models[1] = models.all +models[2] = models.gray +models[3] = models.rgb +models[4] = models.cmyk + setmetatableindex(models, function(t,k) local v = models.gray t[k] = v @@ -453,7 +454,8 @@ setmetatableindex(models, function(t,k) end) local function colorconverter(cs) - return models[colors.model](cs) + -- return models[colors.currentmodel()](cs) + return models[outercolormodel](cs) end local btex = P("btex") @@ -509,7 +511,7 @@ local parser = Cs(( + 1 )^0) -local checking_enabled = true directives.register("metapost.checktexts",function(v) checking_enabled = v end) +local checking_enabled = false directives.register("metapost.checktexts",function(v) checking_enabled = v end) local function checktexts(str) if checking_enabled then @@ -524,12 +526,6 @@ metapost.checktexts = checktexts local factor = 65536*(7227/7200) --- function metapost.edefsxsy(wd,ht,dp) -- helper for figure --- local hd = ht + dp --- context_setvalue("sx",wd ~= 0 and factor/wd or 0) --- context_setvalue("sy",hd ~= 0 and factor/hd or 0) --- end - implement { name = "mpsetsxsy", arguments = { "dimen", "dimen", "dimen" }, @@ -651,6 +647,7 @@ function metapost.graphic_base_pass(specification) -- name will change (see mlib local inclusions = specification.inclusions or "" local initializations = specification.initializations or "" local askedfig = specification.figure -- no default else no wrapper + metapost.namespace = specification.namespace or "" -- local askedfig, wrappit = checkaskedfig(askedfig) -- @@ -728,7 +725,9 @@ function metapost.graphic_base_pass(specification) -- name will change (see mlib report_metapost("running job %s, asked figure %a",nofruns,askedfig) end processmetapost(mpx, { - preamble, + definitions, + extensions, + inclusions, wrappit and do_begin_fig or "", do_first_run, no_trial_run, @@ -741,6 +740,8 @@ function metapost.graphic_base_pass(specification) -- name will change (see mlib context(stopjob) end +-- we overload metapost.process here + function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig, plugmode) -- overloads startjob(plugmode) processmetapost(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig) @@ -763,11 +764,33 @@ implement { arguments = "string" } +local pdftompy = sandbox.registerrunner { + name = "mpy:pstoedit", + program = "pstoedit", + template = "-ssp -dt -f mpost %pdffile% %mpyfile%", + checkers = { + pdffile = "writable", + mpyfile = "readable", + }, + reporter = report_metapost, +} + +local textopdf = sandbox.registerrunner { + name = "mpy:context", + program = "context", + template = "--once %runmode% %texfile%", + checkers = { + runmode = "string", + texfile = "readable", + }, + reporter = report_metapost, +} + function makempy.processgraphics(graphics) if #graphics == 0 then return end - if mpyfilename and io.exists(mpyfilename) then + if mpyfilename and exists(mpyfilename) then report_metapost("using file: %s",mpyfilename) return end @@ -777,16 +800,17 @@ function makempy.processgraphics(graphics) local mpyfile = file.replacesuffix(mpofile,"mpy") local pdffile = file.replacesuffix(mpofile,"pdf") local texfile = file.replacesuffix(mpofile,"tex") - io.savedata(texfile, { start, preamble, metapost.tex.get(), concat(graphics,"\n"), stop }, "\n") - local command = format("context --once %s %s", (tex.interactionmode == 0 and "--batchmode") or "", texfile) - os.execute(command) - if io.exists(pdffile) then - command = format("pstoedit -ssp -dt -f mpost %s %s", pdffile, mpyfile) - logs.newline() - report_metapost("running: %s",command) - logs.newline() - os.execute(command) - if io.exists(mpyfile) then + savedata(texfile, { start, preamble, metapost.tex.get(), concat(graphics,"\n"), stop }, "\n") + textopdf { + runmode = tex.interactionmode == 0 and "--batchmode" or "", + texfile = texfile, + } + if exists(pdffile) then + pdftompy { + pdffile = pdffile, + mpyfile = mpyfile, + } + if exists(mpyfile) then local result, r = { }, 0 local data = io.loaddata(mpyfile) if data and #data > 0 then @@ -794,7 +818,7 @@ function makempy.processgraphics(graphics) r = r + 1 result[r] = formatters["begingraphictextfig%sendgraphictextfig ;\n"](figure) end - io.savedata(mpyfile,concat(result,"")) + savedata(mpyfile,concat(result,"")) end end end @@ -833,7 +857,15 @@ local function splitprescript(script) local hash = lpegmatch(scriptsplitter,script) for i=#hash,1,-1 do local h = hash[i] +if h == "reset" then + for k, v in next, hash do + if type(k) ~= "number" then + hash[k] = nil + end + end +else hash[h[1]] = h[2] +end end if trace_scripts then report_scripts(table.serialize(hash,"prescript")) @@ -874,6 +906,9 @@ end function metapost.resetplugins(t) -- intialize plugins, before figure if top.plugmode then + + outercolormodel = colors.currentmodel() -- currently overloads the one set at the tex end + -- plugins can have been added resetter = resetteractions.runner analyzer = analyzeractions.runner @@ -920,15 +955,16 @@ local function cm(object) local op = object.path if op then local first, second, fourth = op[1], op[2], op[4] - local tx, ty = first.x_coord , first.y_coord - local sx, sy = second.x_coord - tx, fourth.y_coord - ty - local rx, ry = second.y_coord - ty, fourth.x_coord - tx - if sx == 0 then sx = 0.00001 end - if sy == 0 then sy = 0.00001 end - return sx, rx, ry, sy, tx, ty - else - return 1, 0, 0, 1, 0, 0 -- weird case + if fourth then + local tx, ty = first.x_coord , first.y_coord + local sx, sy = second.x_coord - tx, fourth.y_coord - ty + local rx, ry = second.y_coord - ty, fourth.x_coord - tx + if sx == 0 then sx = 0.00001 end + if sy == 0 then sy = 0.00001 end + return sx, rx, ry, sy, tx, ty + end end + return 1, 0, 0, 1, 0, 0 -- weird case end -- color @@ -937,6 +973,8 @@ local function cl_reset(t) t[#t+1] = metapost.colorinitializer() -- only color end +-- text + local function tx_reset() if top then -- why ? @@ -964,6 +1002,25 @@ local ctx_MPLIBsettext = context.MPLIBsettext -- we always create at least one instance (for dimensions) -- we make sure we don't do that when we use one (else counter issues with e.g. \definelabel) +local eol = S("\n\r")^1 +local cleaner = Cs((P("@@")/"@" + P("@")/"%%" + P(1))^0) +local splitter = Ct( + ( ( + P("s:") * C((1-eol)^1) + + P("n:") * ((1-eol)^1/tonumber) + + P("b:") * ((1-eol)^1/toboolean) + ) * eol^0 )^0) + +local function applyformat(s) + local t = lpegmatch(splitter,s) + if #t == 1 then + return s + else + local f = lpegmatch(cleaner,t[1]) + return formatters[f](unpack(t,2)) + end +end + local function tx_analyze(object,prescript) local data = top.texdata[metapost.properties.number] local tx_stage = prescript.tx_stage @@ -979,6 +1036,9 @@ local function tx_analyze(object,prescript) c = lpegmatch(pat,txc) end end + if prescript.tx_type == "format" then + s = applyformat(s) + end local a = tonumber(prescript.tr_alternative) local t = tonumber(prescript.tr_transparency) local h = fmt(tx_number,a or "-",t or "-",c or "-") @@ -1089,6 +1149,37 @@ local function tx_process(object,prescript,before,after) end end +-- we could probably redo normal textexts in the next way but as it's rather optimized +-- we keep away from that (at least for now) + +local function bx_process(object,prescript,before,after) + local bx_category = prescript.bx_category + local bx_name = prescript.bx_name + if bx_category and bx_name then + if trace_textexts then + report_textexts("category %a, name %a",bx_category,bx_name) + end + local sx, rx, ry, sy, tx, ty = cm(object) -- needs to be frozen outside the function + local wd, ht, dp = nodes.boxes.dimensions(bx_category,bx_name) + before[#before+1] = function() + context.MPLIBgetboxscaledcm(bx_category,bx_name, + f_f(sx), -- bah ... %s no longer checks + f_f(rx), -- bah ... %s no longer checks + f_f(ry), -- bah ... %s no longer checks + f_f(sy), -- bah ... %s no longer checks + f_f(tx), -- bah ... %s no longer checks + f_f(ty), -- bah ... %s no longer checks + sxsy(wd,ht,dp)) + end + if not trace_textexts then + object.path = false -- else: keep it + end + object.color = false + object.grouped = true + object.istext = true + end +end + -- graphics (we use the given index because pictures can be reused) local graphics = { } @@ -1122,10 +1213,53 @@ local function sh_process(object,prescript,before,after) local sh_type = prescript.sh_type if sh_type then nofshades = nofshades + 1 - local domain = lpegmatch(domainsplitter,prescript.sh_domain or "0 1") - local centera = lpegmatch(centersplitter,prescript.sh_center_a or "0 0") - local centerb = lpegmatch(centersplitter,prescript.sh_center_b or "0 0") - local steps = tonumber(prescript.sh_step) or 1 + local domain = lpegmatch(domainsplitter,prescript.sh_domain or "0 1") + local centera = lpegmatch(centersplitter,prescript.sh_center_a or "0 0") + local centerb = lpegmatch(centersplitter,prescript.sh_center_b or "0 0") + local transform = toboolean(prescript.sh_transform or "yes",true) + -- compensation for scaling + local sx = 1 + local sy = 1 + local sr = 1 + local dx = 0 + local dy = 0 + if transform then + local first = lpegmatch(coordinatesplitter,prescript.sh_first or "0 0") + local setx = lpegmatch(coordinatesplitter,prescript.sh_set_x or "0 0") + local sety = lpegmatch(coordinatesplitter,prescript.sh_set_y or "0 0") + + local x = setx[1] -- point that has different x + local y = sety[1] -- point that has different y + + if x == 0 or y == 0 then + -- forget about it + else + local path = object.path + local path1x = path[1].x_coord + local path1y = path[1].y_coord + local path2x = path[x].x_coord + local path2y = path[y].y_coord + + local dxa = path2x - path1x + local dya = path2y - path1y + local dxb = setx[2] - first[1] + local dyb = sety[2] - first[2] + + if dxa == 0 or dya == 0 or dxb == 0 or dyb == 0 then + -- forget about it + else + sx = dxa / dxb ; if sx < 0 then sx = - sx end -- yes or no + sy = dya / dyb ; if sy < 0 then sy = - sy end -- yes or no + + sr = sqrt(sx^2 + sy^2) + + dx = path1x - sx*first[1] + dy = path1y - sy*first[2] + end + end + end + + local steps = tonumber(prescript.sh_step) or 1 local sh_color_a = prescript.sh_color_a_1 or prescript.sh_color_a or "1" local sh_color_b = prescript.sh_color_b_1 or prescript.sh_color_b or "1" -- sh_color_b_<sh_steps> local ca, cb, colorspace, name, model, separation, fractions @@ -1183,13 +1317,13 @@ local function sh_process(object,prescript,before,after) steps = 1 end if sh_type == "linear" then - local coordinates = { centera[1], centera[2], centerb[1], centerb[2] } + local coordinates = { dx + sx*centera[1], dy + sy*centera[2], dx + sx*centerb[1], dy + sy*centerb[2] } lpdf.linearshade(name,domain,ca,cb,1,colorspace,coordinates,separation,steps>1 and steps,fractions) -- backend specific (will be renamed) elseif sh_type == "circular" then local factor = tonumber(prescript.sh_factor) or 1 local radiusa = factor * tonumber(prescript.sh_radius_a) local radiusb = factor * tonumber(prescript.sh_radius_b) - local coordinates = { centera[1], centera[2], radiusa, centerb[1], centerb[2], radiusb } + local coordinates = { dx + sx*centera[1], dy + sy*centera[2], sr*radiusa, dx + sx*centerb[1], dy + sy*centerb[2], sr*radiusb } lpdf.circularshade(name,domain,ca,cb,1,colorspace,coordinates,separation,steps>1 and steps,fractions) -- backend specific (will be renamed) else -- fatal error @@ -1302,7 +1436,7 @@ local function tr_process(object,prescript,before,after) defineprocesscolor(sp_temp,r and r(unpack(s)) or "s=0",true,true) definespotcolor(sp_name,sp_temp,"p=1",true) sp_type = "named" - elseif sp_type == "multitone" then + elseif sp_type == "multitone" then -- (fractions of a multitone) don't work well in mupdf local sp_value = prescript.sp_value or "s:1" local sp_spec = { } local sp_list = split(sp_value," ") @@ -1391,28 +1525,31 @@ local types = { local function gr_process(object,prescript,before,after) local gr_state = prescript.gr_state - if gr_state then - if gr_state == "start" then - local gr_type = utilities.parsers.settings_to_hash(prescript.gr_type) - before[#before+1] = function() - context.MPLIBstartgroup( - gr_type.isolated and 1 or 0, - gr_type.knockout and 1 or 0, - prescript.gr_llx, - prescript.gr_lly, - prescript.gr_urx, - prescript.gr_ury - ) - end - elseif gr_state == "stop" then - after[#after+1] = function() - context.MPLIBstopgroup() - end + if not gr_state then + return + elseif gr_state == "start" then + local gr_type = utilities.parsers.settings_to_set(prescript.gr_type) + local path = object.path + local p1, p2, p3, p4 = path[1], path[2], path[3], path[4] + local llx = min(p1.x_coord,p2.x_coord,p3.x_coord,p4.x_coord) + local lly = min(p1.y_coord,p2.y_coord,p3.y_coord,p4.y_coord) + local urx = max(p1.x_coord,p2.x_coord,p3.x_coord,p4.x_coord) + local ury = max(p1.y_coord,p2.y_coord,p3.y_coord,p4.y_coord) + before[#before+1] = function() + context.MPLIBstartgroup( + gr_type.isolated and 1 or 0, + gr_type.knockout and 1 or 0, + llx, lly, urx, ury + ) + end + elseif gr_state == "stop" then + after[#after+1] = function() + context.MPLIBstopgroup() end - object.path = false - object.color = false - object.grouped = true end + object.path = false + object.color = false + object.grouped = true end -- outlines @@ -1472,6 +1609,7 @@ appendaction(processoractions,"system",sh_process) -- (processoractions,"system",gt_process) appendaction(processoractions,"system",bm_process) appendaction(processoractions,"system",tx_process) +appendaction(processoractions,"system",bx_process) appendaction(processoractions,"system",ps_process) appendaction(processoractions,"system",fg_process) appendaction(processoractions,"system",tr_process) -- last, as color can be reset diff --git a/tex/context/base/mkiv/mlib-pps.mkiv b/tex/context/base/mkiv/mlib-pps.mkiv index cdccfc379..a2eb44826 100644 --- a/tex/context/base/mkiv/mlib-pps.mkiv +++ b/tex/context/base/mkiv/mlib-pps.mkiv @@ -91,6 +91,33 @@ \smashbox\MPbox \box\MPbox} +% \putnextboxincache{hans}{1}\hbox{foo} +% +% \startMPcode +% draw boundingbox rawtexbox("hans",1) ; +% draw rawtexbox("hans",1) ; +% \stopMPcode + +\unexpanded\def\MPLIBgetboxscaledcm#1#2% + {\begingroup + \copyboxfromcache{#1}{#2}\MPtextbox % can be \clf_ + \MPLIBgetboxscaledcm_next} + +\unexpanded\def\MPLIBgetboxscaledcm_next#1#2#3#4#5#6#7#8% 1-6: sx,rx,ry,sy,tx,ty + {\setbox\MPbox\hpack\bgroup + \dotransformnextbox{#1}{#2}{#3}{#4}{#5}{#6}% + \vpack to \zeropoint\bgroup + \vss + \hpack to \zeropoint \bgroup + \fastsxsy{#7}{#8}{\raise\dp\MPtextbox\box\MPtextbox}% + \hss + \egroup + \egroup + \egroup + \smashbox\MPbox + \box\MPbox + \endgroup} + \unexpanded\def\MPLIBgraphictext#1% use at mp end {\startTEXpage[\c!scale=10000]#1\stopTEXpage} @@ -134,12 +161,19 @@ \wd\scratchbox \dimexpr#5\onebasepoint-#3\onebasepoint+2\onebasepoint\relax \ht\scratchbox #6\onebasepoint \dp\scratchbox-#4\onebasepoint + \setbox\scratchbox\hpack\bgroup + \kern-#3\onebasepoint + \box\scratchbox + \egroup \saveboxresource - attr {/Group << /S /Transparency /I \ifnum#1=1 true \else false \fi /K \ifnum#1=1 true \else false \fi >>} + attr {/Group << /S /Transparency /I \ifnum#1=1 true \else false \fi /K \ifnum#2=1 true \else false \fi >>} resources {\pdfbackendcurrentresources} \scratchbox - % \setbox\scratchbox\hbox\bgroup\kern-\onebasepoint\useboxresource\lastsavedboxresourceindex\egroup % why twice? - \setbox\scratchbox\hpack\bgroup\kern-\onebasepoint\useboxresource\lastsavedboxresourceindex\egroup + \setbox\scratchbox\hpack\bgroup + \kern#3\onebasepoint + \kern-\onebasepoint + \useboxresource\lastsavedboxresourceindex + \egroup \wd\scratchbox\zeropoint \ht\scratchbox\zeropoint \dp\scratchbox\zeropoint diff --git a/tex/context/base/mkiv/mlib-run.lua b/tex/context/base/mkiv/mlib-run.lua index 8109cff2d..93ce1fec2 100644 --- a/tex/context/base/mkiv/mlib-run.lua +++ b/tex/context/base/mkiv/mlib-run.lua @@ -6,12 +6,12 @@ if not modules then modules = { } end modules ['mlib-run'] = { license = "see context related readme files", } ---~ cmyk -> done, native ---~ spot -> done, but needs reworking (simpler) ---~ multitone -> ---~ shade -> partly done, todo: cm ---~ figure -> done ---~ hyperlink -> low priority, easy +-- cmyk -> done, native +-- spot -> done, but needs reworking (simpler) +-- multitone -> +-- shade -> partly done, todo: cm +-- figure -> done +-- hyperlink -> low priority, easy -- new * run -- or @@ -30,8 +30,10 @@ nears zero.</p> --ldx]]-- local type, tostring, tonumber = type, tostring, tonumber -local format, gsub, match, find = string.format, string.gsub, string.match, string.find -local concat = table.concat +local gsub, match, find = string.gsub, string.match, string.find +local striplines = utilities.strings.striplines +local concat, insert, remove = table.concat, table.insert, table.remove + local emptystring = string.is_empty local P = lpeg.P @@ -93,8 +95,7 @@ do local finders = { } mplib.finders = finders -- also used in meta-lua.lua - local new_instance = mplib.new - local resolved_file = resolvers.findfile + local new_instance = mplib.new local function preprocessed(name) if not mpbasepath(name) then @@ -160,14 +161,15 @@ function metapost.reporterror(result) report_metapost("error: no result object returned") elseif result.status > 0 then local t, e, l = result.term, result.error, result.log + local report = metapost.texerrors and texerrormessage or report_metapost if t and t ~= "" then - (metapost.texerrors and texerrormessage or report_metapost)("terminal: %s",t) + report("mp error: %s",striplines(t)) end if e == "" or e == "no-error" then e = nil end if e then - (metapost.texerrors and texerrormessage or report_metapost)("error: %s",e) + report("mp error: %s",striplines(e)) end if not t and not e and l then metapost.lastlog = metapost.lastlog .. "\n" .. l @@ -185,6 +187,7 @@ local f_preamble = formatters [ [[ boolean mplib ; mplib := true ; let dump = endinput ; input "%s" ; + randomseed:=%s; ]] ] local methods = { @@ -217,8 +220,18 @@ function metapost.maketext(s,mode) end end +local seed = nil + function metapost.load(name,method) starttiming(mplib) + if not seed then + seed = job.getrandomseed() + if seed <= 1 then + seed = seed % 1000 + elseif seed > 4095 then + seed = seed % 4096 + end + end method = method and methods[method] or "scaled" local mpx = new_instance { ini_version = true, @@ -227,13 +240,14 @@ function metapost.load(name,method) script_error = metapost.scripterror, make_text = metapost.maketext, extensions = 1, + -- random_seed = seed, } report_metapost("initializing number mode %a",method) local result if not mpx then result = { status = 99, error = "out of memory"} else - result = mpx:execute(f_preamble(file.addsuffix(name,"mp"))) -- addsuffix is redundant + result = mpx:execute(f_preamble(file.addsuffix(name,"mp"),seed)) -- addsuffix is redundant end stoptiming(mplib) metapost.reporterror(result) @@ -241,9 +255,8 @@ function metapost.load(name,method) end function metapost.checkformat(mpsinput,method) - local mpsversion = environment.version or "unset version" - local mpsinput = mpsinput or "metafun" - local foundfile = "" + local mpsinput = mpsinput or "metafun" + local foundfile = "" if file.suffix(mpsinput) ~= "" then foundfile = find_file(mpsinput) or "" end @@ -326,6 +339,46 @@ if not metapost.initializescriptrunner then function metapost.initializescriptrunner() end end +do + + local stack, top = { }, nil + + function metapost.setvariable(k,v) + if top then + top[k] = v + else + metapost.variables[k] = v + end + end + + function metapost.pushvariable(k) + local t = { } + if top then + insert(stack,top) + top[k] = t + else + metapost.variables[k] = t + end + top = t + end + + function metapost.popvariable() + top = remove(stack) + end + + local stack = { } + + function metapost.pushvariables() + insert(stack,metapost.variables) + metapost.variables = { } + end + + function metapost.popvariables() + metapost.variables = remove(stack) or metapost.variables + end + +end + function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig) local converted, result = false, { } if type(mpx) == "string" then @@ -334,6 +387,7 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, if mpx and data then local tra = nil starttiming(metapost) + metapost.variables = { } metapost.initializescriptrunner(mpx,trialrun) if trace_graphics then tra = mp_tra[mpx] @@ -376,75 +430,60 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, end -- end of hacks end - if type(data) == "table" then - if trace_tracingall then - mpx:execute("tracingall;") - end - -- table.insert(data,2,"") - for i=1,#data do - local d = data[i] - -- d = string.gsub(d,"\r","") - if d then - if trace_graphics then + + local function process(d,i) + -- d = string.gsub(d,"\r","") + if d then + if trace_graphics then + if i then tra.inp:write(formatters["\n%% begin snippet %s\n"](i)) - tra.inp:write(d) + end + tra.inp:write(d) + if i then tra.inp:write(formatters["\n%% end snippet %s\n"](i)) end - starttiming(metapost.exectime) - result = mpx:execute(d) -- some day we wil use a coroutine with textexts - stoptiming(metapost.exectime) - if trace_graphics and result then - local str = result.log or result.error - if str and str ~= "" then - tra.log:write(str) - end + end + starttiming(metapost.exectime) + result = mpx:execute(d) -- some day we wil use a coroutine with textexts + stoptiming(metapost.exectime) + if trace_graphics and result then + local str = result.log or result.error + if str and str ~= "" then + tra.log:write(str) end - if not metapost.reporterror(result) then - if metapost.showlog then - local str = result.term ~= "" and result.term or "no terminal output" - if not emptystring(str) then - metapost.lastlog = metapost.lastlog .. "\n" .. str - report_metapost("log: %s",str) - end - end - if result.fig then - converted = metapost.convert(result, trialrun, flusher, multipass, askedfig) + end + if not metapost.reporterror(result) then + if metapost.showlog then + local str = result.term ~= "" and result.term or "no terminal output" + if not emptystring(str) then + metapost.lastlog = metapost.lastlog .. "\n" .. str + report_metapost("log: %s",str) end end - else - report_metapost("error: invalid graphic component %s",i) + if result.fig then + converted = metapost.convert(result, trialrun, flusher, multipass, askedfig) + end end + elseif i then + report_metapost("error: invalid graphic component %s",i) + else + report_metapost("error: invalid graphic") end - else + end + + if type(data) == "table" then if trace_tracingall then - data = "tracingall;" .. data - end - if trace_graphics then - tra.inp:write(data) + mpx:execute("tracingall;") end - starttiming(metapost.exectime) - result = mpx:execute(data) - stoptiming(metapost.exectime) - if trace_graphics and result then - local str = result.log or result.error - if str and str ~= "" then - tra.log:write(str) - end + -- table.insert(data,2,"") + for i=1,#data do + process(data[i],i) end - -- todo: error message - if not result then - report_metapost("error: no result object returned") - elseif result.status > 0 then - report_metapost("error: %s",(result.term or "no-term") .. "\n" .. (result.error or "no-error")) - else - if metapost.showlog then - metapost.lastlog = metapost.lastlog .. "\n" .. result.term - report_metapost("info: %s",result.term or "no-term") - end - if result.fig then - converted = metapost.convert(result, trialrun, flusher, multipass, askedfig) - end + else + if trace_tracingall then + data = "tracingall;" .. data end + process(data) end if trace_graphics then local banner = "\n% end graphic\n\n" diff --git a/tex/context/base/mkiv/mtx-context-domotica.tex b/tex/context/base/mkiv/mtx-context-domotica.tex new file mode 100644 index 000000000..62e6e8786 --- /dev/null +++ b/tex/context/base/mkiv/mtx-context-domotica.tex @@ -0,0 +1,167 @@ +%D \module +%D [ file=mtx-context-domotica, +%D version=2016.10.20, +%D title=\CONTEXT\ Extra Trickry, +%D subtitle=Domotica Goodies, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% begin help +% +% usage: context --extra=domotica [options] list-of-files +% +% --topspace=dimension : distance above first line +% --backspace=dimension : distance before left margin +% --bodyfont=list : additional bodyfont settings +% --paperformat=spec : paper*print or paperxprint +% --compact : small margins, 8pt font +% --verycompact : small margins, 7pt font +% +% --openzwave : process openzwave xml files +% --hue : process hue task file +% +% --pattern=spec : files to process +% +% example: context --extra=domotica --openzwave ./config/fibaro/fgms.xml ./open-zwave-master/config/aeotec/zw100.xml +% example: context --extra=domotica --openzwave --pattern="./open-zwave-master/config/**.xml" +% example: context --extra=domotica --hue hue-pragma-tasks.lua +% +% end help + +% --pattern="e:/domotica/open-zwave/open-zwave-master/config/**.xml" + +\input mtx-context-common.tex + +\usemodule[domotica-settings] + +\doifdocumentargument {compact} { + \setdocumentargument{topspace} {5mm} + \setdocumentargument{backspace}{5mm} + \setdocumentargument{bodyfont} {8pt} +} + +\doifdocumentargument {verycompact} { + \setdocumentargument{topspace} {5mm} + \setdocumentargument{backspace}{5mm} + \setdocumentargument{bodyfont} {7pt} +} + +\setupbodyfont + [dejavu,11pt,\getdocumentargument{bodyfont}] % dejavu is more complete + +\setuplayout + [header=0cm, + footer=1.5cm, + topspace=\getdocumentargumentdefault{topspace}{1.5cm}, + backspace=\getdocumentargumentdefault{backspace}{1.5cm}, + width=middle, + height=middle] + +\setuppapersize + [\getdocumentargument{paperformat_paper}] + [\getdocumentargument{paperformat_print}] + +\setuphead + [section] + [style=bold] + +\doifdocumentargument {openzwave} {\enablemode[openzwave]} +\doifdocumentargument {hue} {\enablemode[hue]} + +\startmode[openzwave] + + \starttext + + \setuplist + [chapter] + [style=bold, + width=4em] + + \setuplist + [section] + [width=4em] + + \setupheadertexts + + \setupheadertexts + [chapter][pagenumber] + + \starttitle[title=Zwave devices] + + \placelist[chapter,section] + + \stoptitle + + \startluacode + local arguments = document.arguments + local files = document.files + local pattern = arguments.pattern + local noffiles = #files + + if type(pattern) == "string" then + + local pattern = file.addsuffix(pattern,"xml") + + moduledata.zwave.show_settings(pattern) + + elseif noffiles > 0 then + + -- if arguments.sort then + -- table.sort(files) + -- end + + for i=1,#files do + local filename = file.addsuffix(files[i],"xml") + moduledata.zwave.show_settings(filename) + end + + else + + context("no files given") + + end + \stopluacode + + \stoptext + +\stopmode + +\startmode[hue] + + \starttext + + \setupheadertexts + + \startluacode + + local arguments = document.arguments + local files = document.files + local pattern = arguments.pattern + local filename = files[1] + + if filename then + context.starttitle { title = "Hue: " .. file.nameonly(filename) } + filename = file.addsuffix(filename,"lua") + if lfs.isfile(filename) then + moduledata.hue.show_state(filename) + else + context("unknown file %a",filename) + end + context.stoptitle() + else + context("no files given") + context.stoptitle() + end + + \stopluacode + + \stoptext + +\stopmode + + diff --git a/tex/context/base/mkiv/mtx-context-listing.tex b/tex/context/base/mkiv/mtx-context-listing.tex index 2deffd795..41e468e1f 100644 --- a/tex/context/base/mkiv/mtx-context-listing.tex +++ b/tex/context/base/mkiv/mtx-context-listing.tex @@ -82,6 +82,8 @@ mkii = "tex", cld = "lua", lfg = "lua", + mpiv = "mp", + mpii = "mp", } local pattern = document.arguments.pattern diff --git a/tex/context/base/mkiv/mtx-context-xml.tex b/tex/context/base/mkiv/mtx-context-xml.tex index 9d0680e2a..f8bfeef3a 100644 --- a/tex/context/base/mkiv/mtx-context-xml.tex +++ b/tex/context/base/mkiv/mtx-context-xml.tex @@ -18,11 +18,15 @@ % usage: context --extra=xml [options] list-of-files % % --analyze : show elements and characters +% --template : also export template % --topspace=dimension : distance above first line % --backspace=dimension : distance before left margin % --bodyfont=list : additional bodyfont settings % --paperformat=spec : paper*print or paperxprint % +% context --extra=xml --analyze path::i-context.xml +% context --extra=xml --analyze --template path::i-context.xml +% context --extra=xml --analyze selfautoparent:texmf-context/tex/context/interface/mkiv/i-*.xml % end help \input mtx-context-common.tex @@ -50,8 +54,10 @@ \starttext \startluacode - local pattern = document.arguments.pattern - local files = document.files + local files = document.files + local pattern = document.arguments.pattern or (#files == 1 and files[1]) + local analyze = document.arguments.analyze + local template = document.arguments.template if pattern then files = dir.glob(pattern) @@ -61,12 +67,15 @@ end if #files > 0 then - if document.arguments.analyze then - moduledata.xml.analyzers.structure (files) + if analyze then + moduledata.xml.analyzers.structure(files) context.page() moduledata.xml.analyzers.characters(files) context.page() moduledata.xml.analyzers.entities(files) + if template then + moduledata.xml.analyzers.allsetups(files,type(template) == "string" and template or nil) + end else context("no action given") end diff --git a/tex/context/base/mkiv/mult-aux.mkiv b/tex/context/base/mkiv/mult-aux.mkiv index d44c0242e..a64e09305 100644 --- a/tex/context/base/mkiv/mult-aux.mkiv +++ b/tex/context/base/mkiv/mult-aux.mkiv @@ -584,6 +584,11 @@ {\installbasicparameterhandler{#1}{#2}% \installautosetuphandler {#1}{#2}} +\unexpanded\def\installstylisticautosetuphandler#1#2#3% \??self name \??parent (can be \??self) + {\installbasicparameterhandler{#1}{#2}% + \installautosetuphandler {#1}{#2}% + \installstyleandcolorhandler {#1}{#2}} + \unexpanded\def\installcommandhandler#1#2#3% \??self name \??parent (can be \??self) {\installbasicparameterhandler{#1}{#2}% \installdefinehandler {#1}{#2}{#3}% diff --git a/tex/context/base/mkiv/mult-def.lua b/tex/context/base/mkiv/mult-def.lua index 681144816..7cee595cd 100644 --- a/tex/context/base/mkiv/mult-def.lua +++ b/tex/context/base/mkiv/mult-def.lua @@ -3424,6 +3424,10 @@ return { ["pe"]="دوران", ["ro"]="roteste", }, + ["savebuffer"]={ + ["en"]="savebuffer", + ["nl"]="bewaarbuffer", + }, ["scale"]={ ["cs"]="meritko", ["de"]="format", @@ -3784,6 +3788,10 @@ return { ["pe"]="بارگذاریشرح", ["ro"]="seteazadescriere", }, + ["setupdescription"]={ + ["en"]="setupdescription", + ["nl"]="steldoordefinierenin", + }, ["setupenumerations"]={ ["cs"]="nastavvycty", ["de"]="stellebeschreibungein", @@ -3794,6 +3802,10 @@ return { ["pe"]="بارگذاریشمارهگذاریها", ["ro"]="seteazaenumerare", }, + ["setupenumeration"]={ + ["en"]="setupenumeration", + ["nl"]="steldoornummerenin", + }, ["setupexternalfigures"]={ ["cs"]="nastavexterniobrazy", ["de"]="stelleexterneabbildungenein", @@ -3934,6 +3946,10 @@ return { ["pe"]="بارگذاریفرمولها", ["ro"]="seteazaformule", }, + ["setupformula"]={ + ["en"]="setupformula", + ["nl"]="stelformulein", + }, ["setupframed"]={ ["cs"]="nastavoramovani", ["de"]="stelleumrahmtein", @@ -3954,6 +3970,10 @@ return { ["pe"]="بارگذاریمتنقالبی", ["ro"]="definestetexteinconjurate", }, + ["setupframedtext"]={ + ["en"]="setupframedtext", + ["nl"]="stelkadertekstin", + }, ["setuphead"]={ ["cs"]="nastavnadpis", ["de"]="stelleueberschriftein", @@ -4228,6 +4248,14 @@ return { ["pe"]="بارگذاریبلوکهایحاشیه", ["ro"]="seteazablocurimarginale", }, + ["setupmarginblock"]={ + ["en"]="setupmarginblock", + ["nl"]="stelmargeblokkenin", + }, + ["setupmargindata"]={ + ["en"]="setupmargindata", + ["nl"]="stelinmargein", + }, ["setupmarginrules"]={ ["cs"]="nastavmarginalnilinky", ["de"]="stellemarginallinieein", @@ -5032,6 +5060,10 @@ return { ["pe"]="شروعتنظیم", ["ro"]="startaliniere", }, + ["alignment"]={ + ["en"]="alignment", + ["nl"]="uitlijnen", + }, ["startbackground"]={ ["cs"]="startpozadi", ["de"]="starthintergrund", @@ -5176,6 +5208,10 @@ return { ["pe"]="شروعتصحیحخط", ["ro"]="startcorectielinie", }, + ["linecorrection"]={ + ["en"]="linecorrection", + ["nl"]="regelcorrectie", + }, ["startlinenumbering"]={ ["cs"]="startcislovaniradku", ["de"]="startzeilennumerierung", @@ -5216,6 +5252,10 @@ return { ["pe"]="شروعپانوشتهایموضعی", ["ro"]="startnotesubsollocale", }, + ["localfootnotes"]={ + ["en"]="localfootnotes", + ["nl"]="lokalevoetnoten", + }, ["startmakeup"]={ ["cs"]="startuprava", ["de"]="startumbruch", @@ -5236,6 +5276,10 @@ return { ["pe"]="شروعبلوکحاشیه", ["ro"]="startblocmarginal", }, + ["marginblock"]={ + ["en"]="marginblock", + ["nl"]="margeblok", + }, ["startmarginrule"]={ ["cs"]="startmarginalnilinka", ["de"]="startmarginallinie", @@ -5410,6 +5454,10 @@ return { ["en"]="starttextbackground", ["nl"]="starttekstachtergrond", }, + ["textbackground"]={ + ["en"]="textbackground", + ["nl"]="tekstachtergrond", + }, ["starttextrule"]={ ["cs"]="starttextovalinka", ["de"]="starttextlinie", @@ -6308,7 +6356,7 @@ return { ["en"]="usedirectory", ["fr"]="utilisechemin", ["it"]="usacartella", - ["nl"]="gebruikgebied", + ["nl"]="gebruikpad", ["pe"]="استفادهمسیر", ["ro"]="folosestedirector", }, @@ -6574,6 +6622,10 @@ return { ["pe"]="جایگزین", ["ro"]="alternativ", }, + ["stylealternative"]={ + ["en"]="stylealternative", + ["nl"]="stylevariant", + }, ["anchor"]={ ["en"]="anchor", ["nl"]="anker", @@ -6591,6 +6643,10 @@ return { ["pe"]="apa", ["ro"]="apa", }, + ["arguments"]={ + ["en"]="arguments", + ["nl"]="argumenten", + }, ["arrow"]={ ["cs"]="sipka", ["de"]="pfeil", @@ -7322,6 +7378,10 @@ return { ["pe"]="پروندهتبدیل", ["ro"]="convertestefisier", }, + ["copies"]={ + ["en"]="copies", + ["nl"]="kopieen", + }, ["corner"]={ ["cs"]="roh", ["de"]="winkel", @@ -7685,6 +7745,9 @@ return { ["pe"]="حاشیهزوج", ["ro"]="marginepara", }, + ["exact"]={ + ["en"]="exact", + }, ["exitoffset"]={ ["en"]="exitoffset", }, @@ -8013,6 +8076,10 @@ return { ["pe"]="قالبها", ["ro"]="frames", }, + ["freeregion"]={ + ["en"]="freeregion", + ["nl"]="vrijgebied", + }, ["from"]={ ["cs"]="z", ["de"]="von", @@ -10565,6 +10632,10 @@ return { ["pe"]="توده", ["ro"]="stack", }, + ["stackname"]={ + ["en"]="stackname", + ["nl"]="stapelnaam", + }, ["start"]={ ["cs"]="start", ["de"]="start", @@ -11121,6 +11192,10 @@ return { ["totalnumber"]={ ["en"]="totalnumber", }, + ["transform"]={ + ["en"]="transform", + ["nl"]="transformatie", + }, ["translate"]={ ["en"]="translate", }, @@ -12343,6 +12418,10 @@ return { ["pe"]="قطعی", ["ro"]="absolut", }, + ["anchor"]={ + ["en"]="anchor", + ["nl"]="anker", + }, ["action"]={ ["cs"]="akce", ["de"]="aktion", @@ -12901,6 +12980,7 @@ return { }, ["combination"]={ ["en"]="combination", + ["nl"]="combinatie", }, ["command"]={ ["cs"]="prikaz", @@ -13159,6 +13239,10 @@ return { ["pe"]="لبه", ["ro"]="bordura", }, + ["effective"]={ + ["en"]="effective", + ["nl"]="effectief", + }, ["embed"]={ ["en"]="embed", ["nl"]="sluitin", @@ -13173,6 +13257,9 @@ return { ["pe"]="تهی", ["ro"]="gol", }, + ["enable"]={ + ["en"]="enable", + }, ["end"]={ ["en"]="end", ["nl"]="eind", @@ -13527,10 +13614,10 @@ return { ["pe"]="فرمول", ["ro"]="formula", }, - ["formulae"]={ + ["formulas"]={ ["cs"]="rovnice", ["de"]="formeln", - ["en"]="formulae", + ["en"]="formulas", ["fr"]="formules", ["it"]="formule", ["nl"]="formules", @@ -13797,6 +13884,9 @@ return { ["pe"]="پنهانی", ["ro"]="ascuns", }, + ["hiddenbar"]={ + ["en"]="hiddenbar", + }, ["hiding"]={ ["cs"]="skryt", ["de"]="verbergen", @@ -14168,6 +14258,10 @@ return { ["pe"]="متصلبالا", ["ro"]="unit", }, + ["notjoinedup"]={ + ["en"]="notjoinedup", + ["nl"]="nietaansluitend", + }, ["july"]={ ["cs"]="cervenec", ["de"]="juli", @@ -15144,6 +15238,9 @@ return { ["oldstyle"]={ ["en"]="oldstyle", }, + ["fractions"]={ + ["en"]="fractions", + }, ["on"]={ ["cs"]="zap", ["de"]="an", @@ -17629,16 +17726,15 @@ return { ["cd:csname-l"] = { en = "\\..." }, ["cd:noargument-s"] = { en = "\\..." }, ["cd:noargument-l"] = { en = "\\..." }, - ["cd:oneargument-s"] = { en = "\\...#1" }, - ["cd:oneargument-l"] = { en = "\\...#1" }, - ["cd:twoarguments-s"] = { en = "\\...#1#2" }, - ["cd:twoarguments-l"] = { en = "\\...#1#2" }, - ["cd:threearguments-s"] = { en = "\\...#1#2#3" }, - ["cd:threearguments-l"] = { en = "\\...#1#2#3" }, + ["cd:oneargument"] = { en = "\\...#1" }, + ["cd:twoarguments"] = { en = "\\...#1#2" }, + ["cd:threearguments"] = { en = "\\...#1#2#3" }, ["cd:braces-s"] = { en = "{...}", lua = '"..."' }, ["cd:braces-l"] = { en = "{...,...}", lua = '".. ... .."' }, ["cd:brackets-s"] = { en = "[...]", lua = "{ ... }" }, ["cd:brackets-l"] = { en = "[...,...]", lua = "{..., ...}" }, + ["cd:parenthesis-s"] = { en = "(...)" }, + ["cd:parenthesis-l"] = { en = "(...,...)" }, ["cd:index-s"] = { en = "[...]" }, ["cd:index-l"] = { en = "[..+...+..]" }, ["cd:math-s"] = { en = "$...$" }, diff --git a/tex/context/base/mkiv/mult-fun.lua b/tex/context/base/mkiv/mult-fun.lua index e7ab2c071..df127eb5c 100644 --- a/tex/context/base/mkiv/mult-fun.lua +++ b/tex/context/base/mkiv/mult-fun.lua @@ -15,22 +15,24 @@ return { "metapostversion", "maxdimensions", "drawoptionsfactor", + "dq", "sq", + "crossingscale", "crossingoption", }, commands = { - "transparency", + "loadmodule", "dispose", "nothing", "transparency", "tolist", "topath", "tocycle", -- "sqr", "log", "ln", "exp", "inv", "pow", "pi", "radian", "tand", "cotd", "sin", "cos", "tan", "cot", "atan", "asin", "acos", "invsin", "invcos", "invtan", "acosh", "asinh", "sinh", "cosh", "zmod", "paired", "tripled", - "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", + "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", "unittriangle", "fulltriangle", -- "halfcircle", "quartercircle", "llcircle", "lrcircle", "urcircle", "ulcircle", "tcircle", "bcircle", "lcircle", "rcircle", "lltriangle", "lrtriangle", "urtriangle", "ultriangle", "uptriangle", "downtriangle", "lefttriangle", "righttriangle", "triangle", - "smoothed", "cornered", "superellipsed", "randomized", "squeezed", "enlonged", "shortened", + "smoothed", "cornered", "superellipsed", "randomized", "randomizedcontrols", "squeezed", "enlonged", "shortened", "punked", "curved", "unspiked", "simplified", "blownup", "stretched", "enlarged", "leftenlarged", "topenlarged", "rightenlarged", "bottomenlarged", "crossed", "laddered", "randomshifted", "interpolated", "paralleled", "cutends", "peepholed", @@ -38,6 +40,8 @@ return { "llmoved", "lrmoved", "urmoved", "ulmoved", "rightarrow", "leftarrow", "centerarrow", "boundingbox", "innerboundingbox", "outerboundingbox", "pushboundingbox", "popboundingbox", + "boundingradius", "boundingcircle", "boundingpoint", + "crossingunder", "insideof", "outsideof", "bottomboundary", "leftboundary", "topboundary", "rightboundary", "xsized", "ysized", "xysized", "sized", "xyscaled", "intersection_point", "intersection_found", "penpoint", @@ -45,8 +49,10 @@ return { "withshade", "withcircularshade", "withlinearshade", -- old but kept "defineshade", "shaded", -- "withshading", "withlinearshading", "withcircularshading", "withfromshadecolor", "withtoshadecolor", - "shadedinto", "withshadecolors", "withshadedomain", "withshademethod", "withshadefactor", "withshadevector", - "withshadecenter", "withshadedirection", "withshadestep", "withshadefraction", + "shadedinto", "withshadecolors", + "withshadedomain", "withshademethod", "withshadefactor", "withshadevector", + "withshadecenter", "withshadedirection", "withshaderadius", "withshadetransform", + "withshadestep", "withshadefraction", "cmyk", "spotcolor", "multitonecolor", "namedcolor", "drawfill", "undrawfill", "inverted", "uncolored", "softened", "grayed", "greyed", @@ -55,8 +61,8 @@ return { "graphictext", "loadfigure", "externalfigure", "figure", "register", "outlinetext", -- "lua", "checkedbounds", "checkbounds", "strut", "rule", "withmask", "bitmapimage", - "colordecimals", "ddecimal", "dddecimal", "ddddecimal", - "textext", "thetextext", "rawtextext", "textextoffset", + "colordecimals", "ddecimal", "dddecimal", "ddddecimal", "colordecimalslist", + "textext", "thetextext", "rawtextext", "textextoffset", "texbox", "thetexbox", "rawtexbox", "verbatim", "thelabel", "label", "autoalign", @@ -71,7 +77,7 @@ return { -- "define_sampled_linear_shade", "define_sampled_circular_shade", "space", "crlf", "dquote", "percent", "SPACE", "CRLF", "DQUOTE", "PERCENT", "grayscale", "greyscale", "withgray", "withgrey", - "colorpart", + "colorpart", "colorlike", "readfile", "clearxy", "unitvector", "center", -- redefined "epsed", "anchored", @@ -92,7 +98,7 @@ return { -- "pushcurrentpicture", "popcurrentpicture", -- - "arrowpath", + "arrowpath", "resetarrows", -- "colorlike", "dowithpath", "rangepath", "straightpath", "addbackground", -- "cleanstring", "asciistring", "setunstringed", "getunstringed", "unstringed", -- "showgrid", @@ -107,6 +113,7 @@ return { -- "recolor", "refill", "redraw", "retext", "untext", "restroke", "reprocess", "repathed", "tensecircle", "roundedsquare", "colortype", "whitecolor", "blackcolor", "basiccolors", "complementary", "complemented", + "resolvedcolor", -- -- "swappointlabels", "normalfill", "normaldraw", "visualizepaths", "detailpaths", "naturalizepaths", @@ -119,11 +126,11 @@ return { "drawlineoptions", "drawpointoptions", "drawcontroloptions", "drawlabeloptions", "draworiginoptions", "drawboundoptions", "drawpathoptions", "resetdrawoptions", -- - "undashed", + "undashed", "pencilled", -- "decorated", "redecorated", "undecorated", -- - "passvariable", "passarrayvariable", "tostring", "format", "formatted", + "passvariable", "passarrayvariable", "tostring", "topair", "format", "formatted", "quotation", "quote", "startpassingvariable", "stoppassingvariable", -- "eofill", "eoclip", "nofill", "fillup", "eofillup", @@ -132,5 +139,9 @@ return { "addbackground", -- "shadedup", "shadeddown", "shadedleft", "shadedright", + -- + "sortlist", "copylist", "shapedlist", "listtocurves", "listtolines", "listsize", "listlast", "uniquelist", + -- + "circularpath", "squarepath", "linearpath", }, } diff --git a/tex/context/base/mkiv/mult-ini.lua b/tex/context/base/mkiv/mult-ini.lua index 76517f37e..19585a7fa 100644 --- a/tex/context/base/mkiv/mult-ini.lua +++ b/tex/context/base/mkiv/mult-ini.lua @@ -33,6 +33,7 @@ interfaces.formats = mark(interfaces.formats or { }) interfaces.translations = mark(interfaces.translations or { }) interfaces.setupstrings = mark(interfaces.setupstrings or { }) interfaces.corenamespaces = mark(interfaces.corenamespaces or { }) +interfaces.usednamespaces = mark(interfaces.usednamespaces or { }) local registerstorage = storage.register local sharedstorage = storage.shared @@ -44,6 +45,7 @@ local formats = interfaces.formats local translations = interfaces.translations local setupstrings = interfaces.setupstrings local corenamespaces = interfaces.corenamespaces +local usednamespaces = interfaces.usednamespaces local reporters = { } -- just an optimization registerstorage("interfaces/constants", constants, "interfaces.constants") @@ -53,6 +55,7 @@ registerstorage("interfaces/formats", formats, "interfaces.formats registerstorage("interfaces/translations", translations, "interfaces.translations") registerstorage("interfaces/setupstrings", setupstrings, "interfaces.setupstrings") registerstorage("interfaces/corenamespaces", corenamespaces, "interfaces.corenamespaces") +registerstorage("interfaces/usednamespaces", usednamespaces, "interfaces.usednamespaces") interfaces.interfaces = { "cs", "de", "en", "fr", "it", "nl", "ro", "pe", @@ -95,6 +98,11 @@ setmetatableindex(setupstrings, valueiskey) function interfaces.registernamespace(n,namespace) corenamespaces[n] = namespace + usednamespaces[namespace] = n +end + +function interfaces.getnamespace(n) + return usednamespaces[n] .. ">" end local function resolve(t,k) diff --git a/tex/context/base/mkiv/mult-ini.mkiv b/tex/context/base/mkiv/mult-ini.mkiv index d7dc31ec1..8fd0d9472 100644 --- a/tex/context/base/mkiv/mult-ini.mkiv +++ b/tex/context/base/mkiv/mult-ini.mkiv @@ -122,6 +122,7 @@ \def\s!filll {filll} \def\s!to {to} \let\!!to \s!to % obsolete \def\s!attr {attr} +\def\s!axis {axis} \def\s!bottom{bottom} \def\s!top {top} @@ -223,9 +224,9 @@ \def\selectinterface {\writestatus{interface}{defining \currentinterface\space interface}% - \writeline - \writestatus{interface}{using \currentresponses\space messages}% - \writeline + %writeline + \writestatus{interface}{using \currentresponses\space messages}% + %\writeline \let\selectinterface\relax} \else @@ -242,10 +243,10 @@ \doifundefined{\s!prefix!##1}{\let##1=##2}}% \selectinterface\currentinterface\defaultinterface \writestatus{interface}{defining \currentinterface\space interface}% - \writeline + %\writeline \selectinterface\currentresponses\currentinterface \writestatus{interface}{using \currentresponses\space messages}% - \writeline + %\writeline \let\selectinterface\relax} \fi @@ -836,7 +837,12 @@ int: \currentinterface/\currentresponses} \unexpanded\def\showcontextbanner - {\writeline\writebanner{\contextbanner}\writeline} + %{\writeline + % \writestring\contextbanner + % \writeline} + {\writestatus\m!system\empty + \writestatus\m!system\contextbanner + \writestatus\m!system\empty} \edef\formatversion {\the\normalyear .\the\normalmonth.\the\normalday} @@ -855,6 +861,6 @@ \def\dump{\the\everydump\normaldump} \fi -\appendtoks \showcontextbanner \to \everydump +% \appendtoks \showcontextbanner \to \everydump \protect \endinput diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua index be7b02747..4501afefb 100644 --- a/tex/context/base/mkiv/mult-low.lua +++ b/tex/context/base/mkiv/mult-low.lua @@ -14,7 +14,7 @@ return { "zerocount", "minusone", "minustwo", "plusone", "plustwo", "plusthree", "plusfour", "plusfive", "plussix", "plusseven", "pluseight", "plusnine", "plusten", "plussixteen", "plushundred", "plustwohundred", "plusthousand", "plustenthousand", "plustwentythousand", "medcard", "maxcard", "maxcardminusone", - "zeropoint", "onepoint", "halfapoint", "onebasepoint", "maxdimen", "scaledpoint", "thousandpoint", + "zeropoint", "onepoint", "halfapoint", "onebasepoint", "maxcount", "maxdimen", "scaledpoint", "thousandpoint", "points", "halfpoint", "zeroskip", "zeromuskip", "onemuskip", @@ -100,7 +100,7 @@ return { "startcomponent", "stopcomponent", "component", "startproduct", "stopproduct", "product", "startproject", "stopproject", "project", - "starttext", "stoptext", "startnotext", "stopnotext","startdocument", "stopdocument", "documentvariable", "setupdocument", "presetdocument", + "starttext", "stoptext", "startnotext", "stopnotext","startdocument", "stopdocument", "documentvariable", "unexpandeddocumentvariable", "setupdocument", "presetdocument", "startmodule", "stopmodule", "usemodule", "usetexmodule", "useluamodule","setupmodule","currentmoduleparameter","moduleparameter", "everystarttext", "everystoptext", -- @@ -133,6 +133,8 @@ return { "optionalspace", "asciispacechar", -- "Ux", "eUx", "Umathaccents", + -- + "parfillleftskip", "parfillrightskip", }, ["helpers"] = { -- @@ -203,12 +205,12 @@ return { -- "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", -- - "scratchcounter", "globalscratchcounter", - "scratchdimen", "globalscratchdimen", - "scratchskip", "globalscratchskip", - "scratchmuskip", "globalscratchmuskip", - "scratchtoks", "globalscratchtoks", - "scratchbox", "globalscratchbox", + "scratchcounter", "globalscratchcounter", "privatescratchcounter", + "scratchdimen", "globalscratchdimen", "privatescratchdimen", + "scratchskip", "globalscratchskip", "privatescratchskip", + "scratchmuskip", "globalscratchmuskip", "privatescratchmuskip", + "scratchtoks", "globalscratchtoks", "privatescratchtoks", + "scratchbox", "globalscratchbox", "privatescratchbox", -- "normalbaselineskip", "normallineskip", "normallineskiplimit", -- @@ -399,6 +401,7 @@ return { "cldprocessfile", "cldloadfile", "cldcontext", "cldcommand", -- "carryoverpar", + "lastlinewidth", -- "assumelongusagecs", -- @@ -421,5 +424,7 @@ return { "naturalhbox", "naturalvbox", "naturalhpack", "naturalvpack", -- "frule", + -- + "compoundhyphenpenalty", } } diff --git a/tex/context/base/mkiv/mult-mps.lua b/tex/context/base/mkiv/mult-mps.lua index a6bebc266..1d7252c29 100644 --- a/tex/context/base/mkiv/mult-mps.lua +++ b/tex/context/base/mkiv/mult-mps.lua @@ -12,7 +12,7 @@ return { "tracingmacros", "tracingonline", "tracingoutput", "tracingrestores", "tracingspecs", "tracingstats", "tracingtitles", "truecorners", "warningcheck", "year", - "false", "nullpicture", "pencircle", "true", + "false", "nullpicture", "pencircle", "penspec", "true", "and", "angle", "arclength", "arctime", "ASCII", "boolean", "bot", "char", "color", "cosd", "cycle", "decimal", "directiontime", "floor", "fontsize", "hex", "infont", "intersectiontimes", "known", "length", "llcorner", @@ -33,6 +33,7 @@ return { "randomseed", "also", "contour", "doublepath", "withcolor", "withcmykcolor", "withpen", "dashed", + "envelope", "if", "else", "elseif", "fi", "for", "endfor", "forever", "exitif", "within", "forsuffixes", "step", "until", "charlist", "extensible", "fontdimen", "headerbyte", "kern", "ligtable", @@ -76,7 +77,7 @@ return { "arrowhead", "currentpen", "currentpicture", "cuttings", "defaultfont", "extra_beginfig", "extra_endfig", - "ditto", "EOF", "down", + "down", "evenly", "fullcircle", "halfcircle", "identity", "in", "left", "pensquare", "penrazor", "penspec", "origin", "quartercircle", "right", @@ -129,6 +130,8 @@ return { "join_radius", "charscale", -- actually a mult-fun one -- + "ditto", "EOF", -- maybe also down etc + -- "pen_lft", "pen_rt", "pen_top", "pen_bot", -- "pen_count_", }, metafont = { diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua index d9c432f7c..956f83636 100644 --- a/tex/context/base/mkiv/mult-prm.lua +++ b/tex/context/base/mkiv/mult-prm.lua @@ -210,6 +210,8 @@ return { "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervgap", + "Umathnolimitsupfactor", + "Umathnolimitsubfactor", "Umiddle", "Uoverdelimiter", "Uradical", @@ -231,6 +233,12 @@ return { "aligntab", "attribute", "attributedef", + "hyphenpenaltymode", + "automatichyphenmode", + "automatichyphenpenalty", + "automaticdiscretionary", + "explicithyphenpenalty", + "explicitdiscretionary", "bodydir", "boundary", "boxdir", @@ -252,6 +260,7 @@ return { "formatname", "gleaders", "hyphenationmin", + "hyphenationbounds", "ifabsdim", "ifabsnum", "ifprimitive", @@ -268,6 +277,7 @@ return { "leftmarginkern", "letcharcode", "letterspacefont", + "linedir", "localbrokenpenalty", "localinterlinepenalty", "localleftbox", @@ -281,10 +291,15 @@ return { "mathdir", "mathdisplayskipmode", "matheqnogapstep", + "mathitalicsmode", + "mathnolimitsmode", "mathoption", "mathscriptsmode", "mathstyle", "mathsurroundskip", + "mathsurroundmode", + "mathrulesmode", + "mathrulesfam", "noboundary", "nokerns", "nohrule", @@ -307,6 +322,7 @@ return { "pdfvariable", "postexhyphenchar", "posthyphenchar", + "predisplaygapfactor", "preexhyphenchar", "prehyphenchar", "primitive", @@ -324,6 +340,7 @@ return { "scantextokens", "setfontid", "setrandomseed", + "shapemode", "suppressfontnotfounderror", "suppressifcsnameerror", "suppresslongerror", @@ -638,6 +655,8 @@ return { "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervgap", + "Umathnolimitsupfactor", + "Umathnolimitsubfactor", "Umiddle", "Uoverdelimiter", "Uradical", @@ -669,6 +688,12 @@ return { "atopwithdelims", "attribute", "attributedef", + "hyphenpenaltymode", + "automatichyphenmode", + "automatichyphenpenalty", + "automaticdiscretionary", + "explicithyphenpenalty", + "explicitdiscretionary", "badness", "baselineskip", "batchmode", @@ -821,6 +846,8 @@ return { "hyphenation", "hyphenchar", "hyphenpenalty", + "hyphenationmin", + "hyphenationbounds", "if", "ifabsdim", "ifabsnum", @@ -887,6 +914,7 @@ return { "letcharcode", "letterspacefont", "limits", + "linedir", "linepenalty", "lineskip", "lineskiplimit", @@ -917,15 +945,20 @@ return { "mathdisplayskipmode", "matheqnogapstep", "mathinner", + "mathitalicsmode", + "mathnolimitsmode", "mathop", "mathopen", "mathoption", "mathord", "mathpunct", "mathrel", + "mathrulesmode", + "mathrulesfam", "mathscriptsmode", "mathstyle", "mathsurroundskip", + "mathsurroundmode", "mathsurround", "maxdeadcycles", "maxdepth", @@ -1121,6 +1154,7 @@ return { "postexhyphenchar", "posthyphenchar", "predisplaydirection", + "predisplaygapfactor", "predisplaypenalty", "predisplaysize", "preexhyphenchar", @@ -1166,6 +1200,7 @@ return { "setfontid", "setlanguage", "setrandomseed", + "shapemode", "sfcode", "shipout", "show", @@ -1197,6 +1232,7 @@ return { "suppressifcsnameerror", "suppresslongerror", "suppressoutererror", + "suppressmathparerror", "synctex", "tabskip", "tagcode", diff --git a/tex/context/base/mkiv/mult-sys.mkiv b/tex/context/base/mkiv/mult-sys.mkiv index 88e956d66..bd3ff9b3d 100644 --- a/tex/context/base/mkiv/mult-sys.mkiv +++ b/tex/context/base/mkiv/mult-sys.mkiv @@ -38,52 +38,54 @@ %D First we define some system constants used for both the multi||lingual %D interface and multi||linguag typesetting. +% definesystemconstant {slovene} +% definesystemconstant {cz} +% definesystemconstant {vn} + \definesystemconstant {afrikaans} \definesystemconstant {af} +\definesystemconstant {ancientgreek} \definesystemconstant {agr} +\definesystemconstant {ancientlatin} \definesystemconstant {ala} \definesystemconstant {arabic} \definesystemconstant {ar} +\definesystemconstant {bokmal} \definesystemconstant {nb} \definesystemconstant {catalan} \definesystemconstant {ca} \definesystemconstant {chinese} \definesystemconstant {cn} +\definesystemconstant {chinese} \definesystemconstant {cn} \definesystemconstant {croatian} \definesystemconstant {hr} \definesystemconstant {czech} \definesystemconstant {cs} - \definesystemconstant {cz} \definesystemconstant {danish} \definesystemconstant {da} \definesystemconstant {dutch} \definesystemconstant {nl} \definesystemconstant {english} \definesystemconstant {en} +\definesystemconstant {farsi} \definesystemconstant {fa} % just persian \definesystemconstant {finnish} \definesystemconstant {fi} \definesystemconstant {french} \definesystemconstant {fr} +\definesystemconstant {gbenglish} \definesystemconstant {gb} \definesystemconstant {german} \definesystemconstant {de} +\definesystemconstant {greek} \definesystemconstant {gr} \definesystemconstant {hungarian} \definesystemconstant {hu} \definesystemconstant {italian} \definesystemconstant {it} +\definesystemconstant {japanese} \definesystemconstant {ja} +\definesystemconstant {korean} \definesystemconstant {kr} \definesystemconstant {latin} \definesystemconstant {la} -\definesystemconstant {ancientlatin} \definesystemconstant {ala} \definesystemconstant {lithuanian} \definesystemconstant {lt} -\definesystemconstant {bokmal} \definesystemconstant {nb} \definesystemconstant {malayalam} \definesystemconstant {ml} \definesystemconstant {norwegian} \definesystemconstant {no} \definesystemconstant {nynorsk} \definesystemconstant {nn} -\definesystemconstant {polish} \definesystemconstant {pl} \definesystemconstant {persian} \definesystemconstant {pe} +\definesystemconstant {polish} \definesystemconstant {pl} \definesystemconstant {portuguese} \definesystemconstant {pt} \definesystemconstant {romanian} \definesystemconstant {ro} \definesystemconstant {russian} \definesystemconstant {ru} \definesystemconstant {slovak} \definesystemconstant {sk} \definesystemconstant {slovenian} \definesystemconstant {sl} -\definesystemconstant {slovene} % obsolete \definesystemconstant {spanish} \definesystemconstant {es} \definesystemconstant {swedish} \definesystemconstant {sv} +\definesystemconstant {thai} \definesystemconstant {th} % mojca mentioned it at BT2013 but we need more info \definesystemconstant {turkish} \definesystemconstant {tr} \definesystemconstant {turkmen} \definesystemconstant {tk} -\definesystemconstant {gbenglish} \definesystemconstant {gb} \definesystemconstant {ukenglish} \definesystemconstant {uk} -\definesystemconstant {usenglish} \definesystemconstant {us} \definesystemconstant {ukrainian} \definesystemconstant {ua} -\definesystemconstant {greek} \definesystemconstant {gr} -\definesystemconstant {ancientgreek} \definesystemconstant {agr} +\definesystemconstant {usenglish} \definesystemconstant {us} \definesystemconstant {vietnamese} \definesystemconstant {vi} - \definesystemconstant {vn} -\definesystemconstant {chinese} \definesystemconstant {cn} -\definesystemconstant {japanese} \definesystemconstant {ja} -\definesystemconstant {korean} \definesystemconstant {kr} -\definesystemconstant {thai} \definesystemconstant {th} % mojca mentioned it at BT2013 but we need more info %D For proper \UNICODE\ support we need a few font related constants. @@ -147,6 +149,7 @@ \definesystemconstant {sans} \definesystemconstant {mono} \definesystemconstant {math} +\definesystemconstant {nomath} \definesystemconstant {handwriting} \definesystemconstant {calligraphy} \definesystemconstant {casual} @@ -356,7 +359,7 @@ \definesystemconstant {integral} \definesystemconstant {insert} % maybe insertclass \definesystemconstant {marker} - +\definesystemconstant {kernpairs} \definesystemconstant {mixedcolumn} %definesystemconstant {property} diff --git a/tex/context/base/mkiv/node-acc.lua b/tex/context/base/mkiv/node-acc.lua index ed34dbec9..dccd7b7c0 100644 --- a/tex/context/base/mkiv/node-acc.lua +++ b/tex/context/base/mkiv/node-acc.lua @@ -8,92 +8,72 @@ if not modules then modules = { } end modules ['node-acc'] = { local nodes, node = nodes, node -local nodecodes = nodes.nodecodes -local tasks = nodes.tasks - -local nuts = nodes.nuts -local tonut = nodes.tonut -local tonode = nodes.tonode - -local getid = nuts.getid -local getfield = nuts.getfield -local getattr = nuts.getattr -local getlist = nuts.getlist -local getchar = nuts.getchar -local getnext = nuts.getnext - -local setfield = nuts.setfield -local setattr = nuts.setattr -local setlink = nuts.setlink -local setchar = nuts.setchar -local setsubtype = nuts.setsubtype - -local traverse_nodes = nuts.traverse -local traverse_id = nuts.traverse_id -local copy_node = nuts.copy -local free_nodelist = nuts.flush_list -local insert_after = nuts.insert_after - -local glue_code = nodecodes.glue -local kern_code = nodecodes.kern -local glyph_code = nodecodes.glyph -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist - -local a_characters = attributes.private("characters") - -local threshold = 65536 -- not used -local nofreplaced = 0 +local nodecodes = nodes.nodecodes +local tasks = nodes.tasks + +local nuts = nodes.nuts +local tonut = nodes.tonut +local tonode = nodes.tonode + +local getid = nuts.getid +local getfield = nuts.getfield +local getattr = nuts.getattr +local getlist = nuts.getlist +local getchar = nuts.getchar +local getnext = nuts.getnext + +local setfield = nuts.setfield +local setattr = nuts.setattr +local setlink = nuts.setlink +local setchar = nuts.setchar +local setsubtype = nuts.setsubtype +local getwidth = nuts.getwidth +local setwidth = nuts.setwidth + +----- traverse_nodes = nuts.traverse +local traverse_id = nuts.traverse_id +----- copy_node = nuts.copy +local insert_after = nuts.insert_after +local copy_no_components = nuts.copy_no_components + +local glue_code = nodecodes.glue +----- kern_code = nodecodes.kern +local glyph_code = nodecodes.glyph +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist + +local a_characters = attributes.private("characters") + +local threshold = 65536 -- not used +local nofreplaced = 0 -- todo: nbsp etc --- todo: collapse kerns - --- p_id +-- todo: collapse kerns (not needed, backend does this) +-- todo: maybe cache as we now create many nodes +-- todo: check for subtype related to spacing (13/14 but most seems to be user anyway) local function injectspaces(head) local p, p_id local n = head while n do local id = getid(n) - if id == glue_code then -- todo: check for subtype related to spacing (13/14 but most seems to be 0) - -- if getfield(n,."width") > 0 then -- threshold - -- if p and p_id == glyph_code then + if id == glue_code then if p and getid(p) == glyph_code then - local g = copy_node(p) - local c = getfield(g,"components") - if c then -- it happens that we copied a ligature - free_nodelist(c) - setfield(g,"components",nil) - setsubtype(g,256) - end + -- unless we don't care about the little bit of overhead + -- we can just: local g = copy_node(g) + local g = copy_no_components(p) local a = getattr(n,a_characters) setchar(g,32) - setlink(p,g) - setlink(g,n) --- we could cache as we now create many nodes - setfield(n,"width",getfield(n,"width") - getfield(g,"width")) + setlink(p,g,n) + setwidth(n,getwidth(n) - getwidth(g)) if a then setattr(g,a_characters,a) end setattr(n,a_characters,0) nofreplaced = nofreplaced + 1 end - -- end elseif id == hlist_code or id == vlist_code then injectspaces(getlist(n),attribute) - -- elseif id == kern_code then -- the backend already collapses - -- local first = n - -- while true do - -- local nn = getnext(n) - -- if nn and getid(nn) == kern_code then - -- -- maybe we should delete kerns but who cares at this stage - -- setfield(first,"kern",getfield(first,"kern") + getfield(nn,"kern") - -- setfield(nn,"kern",0) - -- n = nn - -- else - -- break - -- end - -- end end p_id = id p = n diff --git a/tex/context/base/mkiv/node-aux.lua b/tex/context/base/mkiv/node-aux.lua index ebe113fc6..c6b276337 100644 --- a/tex/context/base/mkiv/node-aux.lua +++ b/tex/context/base/mkiv/node-aux.lua @@ -20,7 +20,6 @@ local glyph_code = nodecodes.glyph local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist local attributelist_code = nodecodes.attributelist -- temporary -local math_code = nodecodes.math local nuts = nodes.nuts local tonut = nuts.tonut @@ -36,6 +35,10 @@ local getfont = nuts.getfont local getchar = nuts.getchar local getattr = nuts.getattr local getfield = nuts.getfield +local getboth = nuts.getboth +local getcomponents = nuts.getcomponents +local getwidth = nuts.getwidth +local setwidth = nuts.setwidth local setfield = nuts.setfield local setattr = nuts.setattr @@ -43,22 +46,21 @@ local setlink = nuts.setlink local setlist = nuts.setlist local setnext = nuts.setnext local setprev = nuts.setprev +local setcomponents = nuts.setcomponents +local setattrlist = nuts.setattrlist local traverse_nodes = nuts.traverse local traverse_id = nuts.traverse_id -local free_node = nuts.free +local flush_node = nuts.flush +local flush_list = nuts.flush_list local hpack_nodes = nuts.hpack local unset_attribute = nuts.unset_attribute local first_glyph = nuts.first_glyph local copy_node = nuts.copy -local copy_node_list = nuts.copy_list +----- copy_node_list = nuts.copy_list local find_tail = nuts.tail -local insert_node_after = nuts.insert_after -local isnode = nuts.is_node local getbox = nuts.getbox - -local nodes_traverse_id = nodes.traverse_id -local nodes_first_glyph = nodes.first_glyph +local count = nuts.count local nodepool = nuts.pool local new_glue = nodepool.glue @@ -93,13 +95,13 @@ local report_error = logs.reporter("node-aux:error") local function takebox(id) local box = getbox(id) if box then - local copy = copy_node(box) local list = getlist(box) + setlist(box,nil) + local copy = copy_node(box) if list then setlist(copy,list) - setlist(box,nil) end - texsetbox(id,nil) + texsetbox(id,false) return copy end end @@ -125,7 +127,7 @@ end function nuts.takelist(n) local l = getlist(n) setlist(n) - free_node(n) + flush_node(n) return l end @@ -138,7 +140,7 @@ local function repackhlist(list,...) local temp, b = hpack_nodes(list,...) list = getlist(temp) setlist(temp) - free_node(temp) + flush_node(temp) return list, b end @@ -262,16 +264,6 @@ nuts.unsetattributes = unset_attributes nodes.unsetattribut -- end -- end -- --- if not node.end_of_math then --- function node.end_of_math(n) --- for n in traverse_id(math_code,getnext(next)) do --- return n --- end --- end --- end --- --- nodes.endofmath = node.end_of_math --- -- local function firstline(n) -- while n do -- local id = getid(n) @@ -300,16 +292,6 @@ function nuts.firstcharacter(n,untagged) -- tagged == subtype > 255 end end --- function nodes.firstcharacter(n,untagged) -- tagged == subtype > 255 --- if untagged then --- return nodes_first_glyph(n) --- else --- for g in nodes_traverse_id(glyph_code,n) do --- return g --- end --- end --- end - local function firstcharinbox(n) local l = getlist(getbox(n)) if l then @@ -366,11 +348,10 @@ local function tonodes(str,fnt,attr) -- (str,template_glyph) -- moved from blob- n = new_glyph(fnt,s) end if attr then -- normally false when template - -- setfield(n,"attr",copy_node_list(attr)) - setfield(n,"attr",attr) + setattrlist(n,attr) end if head then - insert_node_after(head,tail,n) + setlink(tail,n) else head = n end @@ -386,79 +367,6 @@ nodes.tonodes = function(str,fnt,attr) return tonode(head), tonode(tail) end --- local function link(list,currentfont,currentattr,head,tail) --- for i=1,#list do --- local n = list[i] --- if n then --- local tn = isnode(n) --- if not tn then --- local tn = type(n) --- if tn == "number" then --- if not currentfont then --- currentfont = current_font() --- end --- local h, t = tonodes(tostring(n),currentfont,currentattr) --- if not h then --- -- skip --- elseif not head then --- head = h --- tail = t --- else --- setfield(tail,"next",h) --- setfield(h,"prev",t) --- tail = t --- end --- elseif tn == "string" then --- if #tn > 0 then --- if not currentfont then --- currentfont = current_font() --- end --- local h, t = tonodes(n,currentfont,currentattr) --- if not h then --- -- skip --- elseif not head then --- head, tail = h, t --- else --- setfield(tail,"next",h) --- setfield(h,"prev",t) --- tail = t --- end --- end --- elseif tn == "table" then --- if #tn > 0 then --- if not currentfont then --- currentfont = current_font() --- end --- head, tail = link(n,currentfont,currentattr,head,tail) --- end --- end --- elseif not head then --- head = n --- tail = find_tail(n) --- elseif getid(n) == attributelist_code then --- -- weird case --- report_error("weird node type in list at index %s:",i) --- for i=1,#list do --- local l = list[i] --- report_error("%3i: %s %S",i,getid(l) == attributelist_code and "!" or ">",l) --- end --- os.exit() --- else --- setfield(tail,"next",n) --- setfield(n,"prev",tail) --- if getnext(n) then --- tail = find_tail(n) --- else --- tail = n --- end --- end --- else --- -- permitting nil is convenient --- end --- end --- return head, tail --- end - local function link(list,currentfont,currentattr,head,tail) -- an oldie, might be replaced for i=1,#list do local n = list[i] @@ -543,6 +451,25 @@ function nodes.locate(start,wantedid,wantedsubtype) return found and tonode(found) end +local function rehpack(n,width) + local head = getlist(n) + local size = width or getwidth(n) + local temp = hpack_nodes(head,size,"exactly") + setwidth(n,size) + setfield(n,"glue_set", getfield(temp,"glue_set")) + setfield(n,"glue_sign", getfield(temp,"glue_sign")) + setfield(n,"glue_order",getfield(temp,"glue_order")) + setlist(temp) + flush_node(temp) + return n +end + +nuts.rehpack = rehpack + +function nodes.rehpack(n,...) + rehpack(tonut(n),...) +end + -- I have no use for this yet: -- -- \skip0=10pt plus 2pt minus 2pt @@ -561,3 +488,177 @@ end -- return 0 -- end -- end + +-- these component helpers might move to another module + +-- nodemode helper: here we also flatten components, no check for disc here + +function nuts.set_components(target,start,stop) + local head = getcomponents(target) + if head then + flush_list(head) + head = nil + end + if start then + setprev(start) + else + return nil + end + if stop then + setnext(stop) + end + local tail = nil + while start do + local c = getcomponents(start) + local n = getnext(start) + if c then + if head then + setlink(tail,c) + else + head = c + end + tail = find_tail(c) + setcomponents(start) + flush_node(start) + else + if head then + setlink(tail,start) + else + head = start + end + tail = start + end + start = n + end + setcomponents(target,head) + -- maybe also upgrade the subtype but we don't use it anyway + return head +end + +function nuts.get_components(target) + return getcomponents(target) +end + +nuts.get_components = getcomponents + +function nuts.take_components(target) + local c = getcomponents(target) + setcomponents(target) + -- maybe also upgrade the subtype but we don't use it anyway + return c +end + +-- nodemode helper: we assume a glyph and a flat components list (basemode can +-- have nested components) + +function nuts.count_components(n,marks) + local components = getcomponents(n) + if components then + if marks then + local i = 0 + for g in traverse_id(glyph_code,components) do + if not marks[getchar(g)] then + i = i + 1 + end + end + return i + else + return count(glyph_code,components) + end + else + return 0 + end +end + +-- nodemode helper: the next and prev pointers are untouched + +function nuts.copy_no_components(g,copyinjection) + local components = getcomponents(g) + if components then + setcomponents(g) + local n = copy_node(g) + if copyinjection then + copyinjection(n,g) + end + setcomponents(g,components) + -- maybe also upgrade the subtype but we don't use it anyway + return n + else + local n = copy_node(g) + if copyinjection then + copyinjection(n,g) + end + return n + end +end + +function nuts.copy_only_glyphs(current) + local head = nil + local previous = nil + for n in traverse_id(glyph_code,current) do + n = copy_node(n) + if head then + setlink(previous,n) + else + head = n + end + previous = n + end + return head +end + +-- node- and basemode helper + +function nuts.use_components(head,current) + local components = getcomponents(current) + if not components then + return head, current, current + end + local prev, next = getboth(current) + local first = current + local last = next + while components do + local gone = current + local tail = find_tail(components) + if prev then + setlink(prev,components) + end + if next then + setlink(tail,next) + end + if first == current then + first = components + end + if head == current then + head = components + end + current = components + setcomponents(gone) + flush_node(gone) + while true do + components = getcomponents(current) + if components then + next = getnext(current) + break -- current is composed + end + if next == last then + last = current + break -- components is false + end + prev = current + current = next + next = getnext(current) + end + end + return head, first, last +end + +-- function nuts.current_tail() +-- local whatever = texnest[texnest.ptr] +-- if whatever then +-- local tail = whatever.tail +-- if tail then +-- return tonut(tail) +-- end +-- end +-- end diff --git a/tex/context/base/mkiv/node-bck.lua b/tex/context/base/mkiv/node-bck.lua index a095ac4c4..abb025b74 100644 --- a/tex/context/base/mkiv/node-bck.lua +++ b/tex/context/base/mkiv/node-bck.lua @@ -11,14 +11,13 @@ if not modules then modules = { } end modules ['node-bck'] = { local attributes, nodes, node = attributes, nodes, node -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction local nodecodes = nodes.nodecodes local listcodes = nodes.listcodes local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist -local glyph_code = nodecodes.glyph local cell_code = listcodes.cell local nuts = nodes.nuts @@ -34,8 +33,8 @@ local getid = nuts.getid local getlist = nuts.getlist local getattr = nuts.getattr local getsubtype = nuts.getsubtype +local getwhd = nuts.getwhd -local setfield = nuts.setfield local setattr = nuts.setattr local setlink = nuts.setlink local setlist = nuts.setlist @@ -48,7 +47,7 @@ local new_glue = nodepool.glue local a_color = attributes.private('color') local a_transparency = attributes.private('transparency') -local a_colorspace = attributes.private('colormodel') +local a_colormodel = attributes.private('colormodel') local a_background = attributes.private('background') local a_alignbackground = attributes.private('alignbackground') @@ -65,33 +64,32 @@ local function add_backgrounds(head) -- rather old code .. to be redone list = head end end - local width = getfield(current,"width") + local width, height, depth = getwhd(current) if width > 0 then local background = getattr(current,a_background) if background then -- direct to hbox -- colorspace is already set so we can omit that and stick to color - local mode = getattr(current,a_colorspace) + local mode = getattr(current,a_colormodel) if mode then - local height = getfield(current,"height") - local depth = getfield(current,"depth") local skip = id == hlist_code and width or (height + depth) local glue = new_glue(-skip) local rule = new_rule(width,height,depth) local color = getattr(current,a_color) local transparency = getattr(current,a_transparency) - setattr(rule,a_colorspace,mode) + setattr(rule,a_colormodel,mode) if color then setattr(rule,a_color,color) end if transparency then setattr(rule,a_transparency,transparency) end - setlink(rule,glue) - if list then - setlink(glue,list) - end - setlist(current,rule) +-- setlink(rule,glue) +-- if list then +-- setlink(glue,list) +-- end +-- setlist(current,rule) + setlist(current,rule,glue,list) end end end @@ -131,15 +129,15 @@ local function add_alignbackgrounds(head) -- if background then -- current has subtype 5 (cell) - local width = getfield(current,"width") + local width, height, depth = getwhd(current) if width > 0 then - local mode = getattr(found,a_colorspace) + local mode = getattr(found,a_colormodel) if mode then local glue = new_glue(-width) - local rule = new_rule(width,getfield(current,"height"),getfield(current,"depth")) + local rule = new_rule(width,height,depth) local color = getattr(found,a_color) local transparency = getattr(found,a_transparency) - setattr(rule,a_colorspace,mode) + setattr(rule,a_colormodel,mode) if color then setattr(rule,a_color,color) end @@ -174,21 +172,16 @@ end nodes.handlers.backgrounds = function(head) local head, done = add_backgrounds (tonut(head)) return tonode(head), done end nodes.handlers.alignbackgrounds = function(head) local head, done = add_alignbackgrounds(tonut(head)) return tonode(head), done end --- elsewhere: needs checking - --- tasks.appendaction("shipouts","normalizers","nodes.handlers.backgrounds") --- tasks.appendaction("shipouts","normalizers","nodes.handlers.alignbackgrounds") - interfaces.implement { name = "enablebackgroundboxes", onlyonce = true, - actions = nodes.tasks.enableaction, + actions = enableaction, arguments = { "'shipouts'", "'nodes.handlers.backgrounds'" } } interfaces.implement { name = "enablebackgroundalign", onlyonce = true, - actions = nodes.tasks.enableaction, + actions = enableaction, arguments = { "'shipouts'", "'nodes.handlers.alignbackgrounds'" } } diff --git a/tex/context/base/mkiv/node-fin.lua b/tex/context/base/mkiv/node-fin.lua index a2d63d38d..ffb2ae49e 100644 --- a/tex/context/base/mkiv/node-fin.lua +++ b/tex/context/base/mkiv/node-fin.lua @@ -26,6 +26,7 @@ local getid = nuts.getid local getlist = nuts.getlist local getleader = nuts.getleader local getattr = nuts.getattr +local getwidth = nuts.getwidth local setlist = nuts.setlist local setleader = nuts.setleader @@ -42,12 +43,9 @@ local glyph_code = nodecodes.glyph local disc_code = nodecodes.disc local glue_code = nodecodes.glue local rule_code = nodecodes.rule -local whatsit_code = nodecodes.whatsit local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist -local normal_rule = rulecodes.normal - local states = attributes.states local numbers = attributes.numbers local a_trigger = attributes.private('trigger') @@ -179,7 +177,6 @@ function states.finalize(namespace,attribute,head) -- is this one ok? end -- we need to deal with literals too (reset as well as oval) --- if id == glyph_code or (id == whatsit_code and getsubtype(stack) == pdfliteral_code) or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then local function process(namespace,attribute,head,inheritance,default) -- one attribute local stack = head @@ -208,27 +205,31 @@ local function process(namespace,attribute,head,inheritance,default) -- one attr if content ~= list then setlist(stack,list) end - done = done or ok + if ok then + done = true + end else local list, ok = process(namespace,attribute,content,inheritance,default) if content ~= list then setlist(stack,list) end - done = done or ok + if ok then + done = true + end end else local list, ok = process(namespace,attribute,content,inheritance,default) if content ~= list then setlist(stack,list) end - done = done or ok + if ok then + done = true + end end -- end nested -- end elseif id == rule_code then --- if subtype(stack) == normal_rule then - check = getfield(stack,"width") ~= 0 --- end + check = getwidth(stack) ~= 0 end -- much faster this way than using a check() and nested() function if check then @@ -236,14 +237,14 @@ local function process(namespace,attribute,head,inheritance,default) -- one attr if c then if default and c == inheritance then if current ~= default then - head = insert_node_before(head,stack,copied(nsdata[default])) + head = insert_node_before(head,stack,copied(nsdata[default])) current = default - done = true + done = true end elseif current ~= c then - head = insert_node_before(head,stack,copied(nsdata[c])) + head = insert_node_before(head,stack,copied(nsdata[c])) current = c - done = true + done = true end if leader then local savedcurrent = current @@ -262,20 +263,26 @@ local function process(namespace,attribute,head,inheritance,default) -- one attr if leader ~= list then setleader(stack,list) end - done = done or ok + if ok then + done = true + end else local list, ok = process(namespace,attribute,leader,inheritance,default) if leader ~= list then setleader(stack,list) end - done = done or ok + if ok then + done = true + end end else local list, ok = process(namespace,attribute,leader,inheritance,default) if leader ~= list then setleader(stack,list) end - done = done or ok + if ok then + done = true + end end -- end nested -- current = savedcurrent @@ -283,14 +290,14 @@ local function process(namespace,attribute,head,inheritance,default) -- one attr end elseif default and inheritance then if current ~= default then - head = insert_node_before(head,stack,copied(nsdata[default])) + head = insert_node_before(head,stack,copied(nsdata[default])) current = default - done = true + done = true end elseif current > 0 then - head = insert_node_before(head,stack,copied(nsnone)) + head = insert_node_before(head,stack,copied(nsnone)) current = 0 - done = true + done = true end check = false end @@ -320,7 +327,7 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at if id == glyph_code then check = true elseif id == disc_code then - check = true -- notneeded when we flatten replace + check = true -- not needed when we flatten replace elseif id == glue_code then leader = getleader(stack) if leader then @@ -337,27 +344,31 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at if content ~= list then setlist(stack,list) end - done = done or ok + if ok then + done = true + end else local list, ok = selective(namespace,attribute,content,inheritance,default) if content ~= list then setlist(stack,list) end - done = done or ok + if ok then + done = true + end end else local list, ok = selective(namespace,attribute,content,inheritance,default) if content ~= list then setlist(stack,list) end - done = done or ok + if ok then + done = true + end end -- end nested end elseif id == rule_code then --- if subtype(stack) == normal_rule then - check = getfield(stack,"width") ~= 0 --- end + check = getwidth(stack) ~= 0 end if check then @@ -368,7 +379,9 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at local data = nsdata[default] head = insert_node_before(head,stack,copied(data[nsforced or getattr(stack,nsselector) or nsselector])) current = default - done = true + if ok then + done = true + end end else local s = getattr(stack,nsselector) @@ -377,7 +390,9 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at head = insert_node_before(head,stack,copied(data[nsforced or getattr(stack,nsselector) or nsselector])) current = c current_selector = s - done = true + if ok then + done = true + end end end if leader then @@ -389,20 +404,26 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at if leader ~= list then setleader(stack,list) end - done = done or ok + if ok then + done = true + end else local list, ok = selective(namespace,attribute,leader,inheritance,default) if leader ~= list then setleader(stack,list) end - done = done or ok + if ok then + done = true + end end else local list, ok = selective(namespace,attribute,leader,inheritance,default) if leader ~= list then setleader(stack,list) end - done = done or ok + if ok then + done = true + end end -- end nested leader = false @@ -410,9 +431,9 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at elseif default and inheritance then if current ~= default then local data = nsdata[default] - head = insert_node_before(head,stack,copied(data[nsforced or getattr(stack,nsselector) or nsselector])) + head = insert_node_before(head,stack,copied(data[nsforced or getattr(stack,nsselector) or nsselector])) current = default - done = true + done = true end elseif current > 0 then head = insert_node_before(head,stack,copied(nsnone)) @@ -464,57 +485,63 @@ local function stacked(namespace,attribute,head,default) -- no triggering, no in if a and current ~= a and nslistwise[a] then -- viewerlayer / needs checking, see below local p = current current = a - head = insert_node_before(head,stack,copied(nsdata[a])) + head = insert_node_before(head,stack,copied(nsdata[a])) local list = stacked(namespace,attribute,content,current) -- two return values if content ~= list then setlist(stack,list) end - done = true head, stack = insert_node_after(head,stack,copied(nsnone)) current = p + done = true else local list, ok = stacked(namespace,attribute,content,current) if content ~= list then setlist(stack,list) -- only if ok end - done = done or ok + if ok then + done = true + end end else local list, ok = stacked(namespace,attribute,content,current) if content ~= list then setlist(stack,list) -- only if ok end - done = done or ok + if ok then + done = true + end end end elseif id == rule_code then --- if subtype(stack) == normal_rule then - check = getfield(stack,"width") ~= 0 --- end + check = getwidth(stack) ~= 0 end if check then local a = getattr(stack,attribute) if a then if current ~= a then - head = insert_node_before(head,stack,copied(nsdata[a])) - depth = depth + 1 - current, done = a, true + head = insert_node_before(head,stack,copied(nsdata[a])) + depth = depth + 1 + current = a + done = true end if leader then local list, ok = stacked(namespace,attribute,content,current) if leader ~= list then setleader(stack,list) -- only if ok end - done = done or ok + if ok then + done = true + end leader = false end elseif default > 0 then -- elseif current > 0 then - head = insert_node_before(head,stack,copied(nsnone)) - depth = depth - 1 - current, done = 0, true + head = insert_node_before(head,stack,copied(nsnone)) + depth = depth - 1 + current = 0 + done = true end check = false end @@ -574,19 +601,21 @@ local function stacker(namespace,attribute,head,default) -- no triggering, no in if content ~= list then setlist(current,list) end - done = done or ok + if ok then + done = true + end end else local list, ok = stacker(namespace,attribute,content,default) if list ~= content then setlist(current,list) end - done = done or ok + if ok then + done = true + end end elseif id == rule_code then --- if subtype(stack) == normal_rule then - check = getfield(current,"width") ~= 0 --- end + check = getwidth(current) ~= 0 end if check then @@ -600,11 +629,14 @@ local function stacker(namespace,attribute,head,default) -- no triggering, no in if n then head = insert_node_before(head,current,tonut(n)) -- a end - attrib, done = a, true + attrib = a + done = true if leader then -- tricky as a leader has to be a list so we cannot inject before local list, ok = stacker(namespace,attribute,leader,attrib) - done = done or ok + if ok then + done = true + end leader = false end end diff --git a/tex/context/base/mkiv/node-fin.mkiv b/tex/context/base/mkiv/node-fin.mkiv index 413a00722..6c5bf17f1 100644 --- a/tex/context/base/mkiv/node-fin.mkiv +++ b/tex/context/base/mkiv/node-fin.mkiv @@ -34,46 +34,47 @@ \definesystemattribute[trigger][public] -\newcount\attributeboxcount +\newcount\c_syst_attr_trigger \edef\startinheritattributes{\attribute\triggerattribute\plusone} \edef\stopinheritattributes {\attribute\triggerattribute\attributeunsetvalue} -\def\doattributedcopy{\afterassignment\dodoattributedcopy\attributeboxcount} -\def\doattributedbox {\afterassignment\dodoattributedbox \attributeboxcount} +\def\syst_attr_trigger_copy_yes{\afterassignment\syst_attr_trigger_copy_indeed\c_syst_attr_trigger} +\def\syst_attr_trigger_dump_yes{\afterassignment\syst_attr_trigger_dump_indeed\c_syst_attr_trigger} -\def\dodoattributedcopy - {\startinheritattributes - \ifvbox\attributeboxcount - \vpack{\unvcopy\attributeboxcount}% +\def\syst_attr_trigger_copy_indeed + {\ifvbox\c_syst_attr_trigger + \vpack attr \triggerattribute \plusone {\unvcopy\c_syst_attr_trigger}% \else - \hpack{\unhcopy\attributeboxcount}% - \fi - \stopinheritattributes} - -\def\dodoattributedbox - {\startinheritattributes - \ifvbox\attributeboxcount - \vpack{\unvbox\attributeboxcount}% + \hpack attr \triggerattribute \plusone {\unhcopy\c_syst_attr_trigger}% + \fi} + +\def\syst_attr_trigger_dump_indeed + {\ifvbox\c_syst_attr_trigger + \vpack attr \triggerattribute \plusone {\unvbox\c_syst_attr_trigger}% \else - \hpack{\unhbox\attributeboxcount}% - \fi - \stopinheritattributes} + \hpack attr \triggerattribute \plusone {\unhbox\c_syst_attr_trigger}% + \fi} -\def\enableattributeinheritance +\unexpanded\def\enableattributeinheritance {\clf_enablestatetriggering - \let\attributedcopy\doattributedcopy - \let\attributedbox \doattributedbox} + \let\attributedcopy\syst_attr_trigger_copy_yes + \let\attributedbox \syst_attr_trigger_dump_yes} -\def\disableattributeinheritance +\unexpanded\def\disableattributeinheritance {\clf_disablestatetriggering \let\attributedcopy\copy \let\attributedbox \box} \disableattributeinheritance +\installtexdirective + {attributes.inheritance} + {\enableattributeinheritance} + {\disableattributeinheritance} + % \appendtoks -% \enableattributeinheritance % will become default +% \enableattributeinheritance % might become default % \to\everyjob \protect \endinput diff --git a/tex/context/base/mkiv/node-fnt.lua b/tex/context/base/mkiv/node-fnt.lua index e77280c37..8aa088f88 100644 --- a/tex/context/base/mkiv/node-fnt.lua +++ b/tex/context/base/mkiv/node-fnt.lua @@ -64,11 +64,9 @@ local ischar = nuts.ischar -- checked local traverse_id = nuts.traverse_id local traverse_char = nuts.traverse_char -local remove_node = nuts.remove local protect_glyph = nuts.protect_glyph -local free_node = nuts.free +local flush_node = nuts.flush -local glyph_code = nodecodes.glyph local disc_code = nodecodes.disc local boundary_code = nodecodes.boundary local word_boundary = nodes.boundarycodes.word @@ -80,11 +78,6 @@ local setmetatableindex = table.setmetatableindex -- -- maybe getting rid of the intermediate shared can save some time --- potential speedup: check for subtype < 256 so that we can remove that test --- elsewhere, danger: injected nodes will not be dealt with but that does not --- happen often; we could consider processing sublists but that might need more --- checking later on; the current approach also permits variants - local run = 0 local setfontdynamics = { } @@ -146,7 +139,12 @@ fonts.hashes.processes = fontprocesses local ligaturing = nuts.ligaturing local kerning = nuts.kerning -local expanders +-- -- -- this will go away + +local disccodes = nodes.disccodes +local explicit_code = disccodes.explicit +local automatic_code = disccodes.automatic +local expanders = nil function fonts.setdiscexpansion(v) if v == nil or v == true then @@ -164,57 +162,79 @@ end fonts.setdiscexpansion(true) -function handlers.characters(head) +-- -- -- till here + +local function start_trace(head) + run = run + 1 + report_fonts() + report_fonts("checking node list, run %s",run) + report_fonts() + local n = tonut(head) + while n do + local char, id = isglyph(n) + if char then + local font = getfont(n) + local attr = getattr(n,0) or 0 + report_fonts("font %03i, dynamic %03i, glyph %C",font,attr,char) + elseif id == disc_code then + report_fonts("[disc] %s",nodes.listtoutf(n,true,false,n)) + elseif id == boundary_code then + report_fonts("[boundary] %i:%i",getsubtype(n),getfield(n,"value")) + else + report_fonts("[%s]",nodecodes[id]) + end + n = getnext(n) + end +end + +local function stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant,e,expanders) + report_fonts() + report_fonts("statics : %s",u > 0 and concat(keys(usedfonts)," ") or "none") + report_fonts("dynamics: %s",a > 0 and concat(keys(attrfonts)," ") or "none") + report_fonts("built-in: %s",b > 0 and b or "none") + report_fonts("removed : %s",r > 0 and r or "none") +if expanders then + report_fonts("expanded: %s",e > 0 and e or "none") +end + report_fonts() +end + +function handlers.characters(head,groupcode,size,packtype,direction) -- either next or not, but definitely no already processed list starttiming(nodes) local usedfonts = { } local attrfonts = { } local basefonts = { } - local a, u, b = 0, 0, 0 local basefont = nil local prevfont = nil local prevattr = 0 - local mode = nil local done = false local variants = nil local redundant = nil + local none = false + local nuthead = tonut(head) + + local a, u, b, r, e = 0, 0, 0, 0, 0 if trace_fontrun then - run = run + 1 - report_fonts() - report_fonts("checking node list, run %s",run) - report_fonts() - local n = tonut(head) - while n do - local char, id = isglyph(n) - if char then - local font = getfont(n) - local attr = getattr(n,0) or 0 - report_fonts("font %03i, dynamic %03i, glyph %C",font,attr,char) - elseif id == disc_code then - report_fonts("[disc] %s",nodes.listtoutf(n,true,false,n)) - elseif id == boundary_code then - report_fonts("[boundary] %i:%i",getsubtype(n),getfield(n,"value")) - else - report_fonts("[%s]",nodecodes[id]) - end - n = getnext(n) - end + start_trace(head) end - local nuthead = tonut(head) + -- There is no gain in checking for a single glyph and then having a fast path. On the + -- metafun manual (with some 2500 single char lists) the difference is just noise. for n in traverse_char(nuthead) do local font = getfont(n) - local attr = getattr(n,0) or 0 -- zero attribute is reserved for fonts in context + local attr = (none and prevattr) or getattr(n,0) or 0 -- zero attribute is reserved for fonts in context if font ~= prevfont or attr ~= prevattr then prevfont = font prevattr = attr - mode = fontmodes[font] -- we can also avoid the attr check variants = fontvariants[font] - if mode == "none" then + none = fontmodes[font] == "none" + if none then -- skip + -- variants = false protect_glyph(n) else if basefont then @@ -233,7 +253,7 @@ function handlers.characters(head) a = a + 1 elseif force_basepass then b = b + 1 - basefont = { n, nil } + basefont = { n, false } basefonts[b] = basefont end end @@ -246,7 +266,7 @@ function handlers.characters(head) u = u + 1 elseif force_basepass then b = b + 1 - basefont = { n, nil } + basefont = { n, false } basefonts[b] = basefont end end @@ -267,19 +287,23 @@ function handlers.characters(head) report_fonts("replacing %C by %C",char,variant) end setchar(p,variant) - if not redundant then - redundant = { n } + if redundant then + r = r + 1 + redundant[r] = n else - redundant[#redundant+1] = n + r = 1 + redundant = { n } end end end elseif keep_redundant then -- go on, can be used for tracing - elseif not redundant then - redundant = { n } + elseif redundant then + r = r + 1 + redundant[r] = n else - redundant[#redundant+1] = n + r = 1 + redundant = { n } end end end @@ -294,8 +318,10 @@ function handlers.characters(head) for b in traverse_id(boundary_code,nuthead) do if getsubtype(b) == word_boundary then if redundant then - redundant[#redundant+1] = b + r = r + 1 + redundant[r] = b else + r = 1 redundant = { b } end end @@ -304,7 +330,7 @@ function handlers.characters(head) end if redundant then - for i=1,#redundant do + for i=1,r do local r = redundant[i] local p, n = getboth(r) if r == nuthead then @@ -316,38 +342,50 @@ function handlers.characters(head) if b > 0 then for i=1,b do local bi = basefonts[i] - if r == bi[1] then + local b1 = bi[1] + local b2 = bi[2] + if b1 == b2 then + if b1 == r then + bi[1] = false + bi[2] = false + end + elseif b1 == r then bi[1] = n - end - if r == bi[2] then - bi[2] = n + elseif b2 == r then + bi[2] = p end end end - free_node(r) + flush_node(r) end end - local e = 0 - if force_discrun then -- basefont is not supported in disc only runs ... it would mean a lot of -- ranges .. we could try to run basemode as a separate processor run but -- not for now (we can consider it when the new node code is tested - - -- local prevfont = nil - -- local prevattr = 0 - for d in traverse_id(disc_code,nuthead) do - -- we could use first_glyph, only doing replace is good enough + -- we could use first_glyph, only doing replace is good enough because + -- pre and post are normally used for hyphens and these come from fonts + -- that part of the hyphenated word local _, _, r = getdisc(d) if r then + local prevfont = nil + local prevattr = nil + local none = false for n in traverse_char(r) do local font = getfont(n) - local attr = getattr(n,0) or 0 -- zero attribute is reserved for fonts in context + local attr = (none and prevattr) or getattr(n,0) or 0 -- zero attribute is reserved for fonts in context if font ~= prevfont or attr ~= prevattr then - if attr > 0 then + prevfont = font + prevattr = attr + none = fontmodes[font] == "none" -- very unlikely that we run into disc nodes in none mode + if none then + -- skip + -- variants = false + protect_glyph(n) + elseif attr > 0 then local used = attrfonts[font] if not used then used = { } @@ -370,16 +408,14 @@ function handlers.characters(head) end end end - prevfont = font - prevattr = attr end + -- we assume one font for now (and if there are more and we get into issues then + -- we can always remove the break) + break end - break elseif expanders then local subtype = getsubtype(d) - if subtype == discretionary_code then - -- already done when replace - else + if subtype == automatic_code or subtype == explicit_code then expanders[subtype](d) e = e + 1 end @@ -389,34 +425,35 @@ function handlers.characters(head) end if trace_fontrun then - report_fonts() - report_fonts("statics : %s",u > 0 and concat(keys(usedfonts)," ") or "none") - report_fonts("dynamics: %s",a > 0 and concat(keys(attrfonts)," ") or "none") - report_fonts("built-in: %s",b > 0 and b or "none") - report_fonts("removed : %s",redundant and #redundant > 0 and #redundant or "none") - if expanders then - report_fonts("expanded: %s",e > 0 and e or "none") - end - report_fonts() + stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant,e,expanders) end + -- in context we always have at least 2 processors if u == 0 then -- skip elseif u == 1 then local font, processors = next(usedfonts) + -- local attr = a == 0 and false or 0 -- 0 is the savest way + local attr = a > 0 and 0 or false -- 0 is the savest way for i=1,#processors do - local h, d = processors[i](head,font,0) + local h, d = processors[i](head,font,attr,direction) if d then - head = h or head + if h then + head = h + end done = true end end else - for font, processors in next, usedfonts do + -- local attr = a == 0 and false or 0 -- 0 is the savest way + local attr = a > 0 and 0 or false -- 0 is the savest way + for font, processors in next, usedfonts do -- unordered for i=1,#processors do - local h, d = processors[i](head,font,0) + local h, d = processors[i](head,font,attr,direction) if d then - head = h or head + if h then + head = h + end done = true end end @@ -426,22 +463,26 @@ function handlers.characters(head) -- skip elseif a == 1 then local font, dynamics = next(attrfonts) - for attribute, processors in next, dynamics do -- attr can switch in between + for attribute, processors in next, dynamics do -- unordered, attr can switch in between for i=1,#processors do - local h, d = processors[i](head,font,attribute) + local h, d = processors[i](head,font,attribute,direction) if d then - head = h or head + if h then + head = h + end done = true end end end else for font, dynamics in next, attrfonts do - for attribute, processors in next, dynamics do -- attr can switch in between + for attribute, processors in next, dynamics do -- unordered, attr can switch in between for i=1,#processors do - local h, d = processors[i](head,font,attribute) + local h, d = processors[i](head,font,attribute,direction) if d then - head = h or head + if h then + head = h + end done = true end end @@ -458,14 +499,15 @@ function handlers.characters(head) if (start or stop) and (start ~= stop) then local front = nuthead == start if stop then - start, stop = ligaturing(start,stop) - start, stop = kerning(start,stop) + start = ligaturing(start,stop) + start = kerning(start,stop) elseif start then -- safeguard start = ligaturing(start) start = kerning(start) end - if front then - head = tonode(start) + if front and nuthead ~= start then + -- nuthead = start + head = tonode(start) end end else @@ -474,26 +516,28 @@ function handlers.characters(head) local range = basefonts[i] local start = range[1] local stop = range[2] - if start then + if start then -- and start ~= stop but that seldom happens local front = nuthead == start - local prev, next + local prev = getprev(start) + local next = getnext(stop) if stop then - next = getnext(stop) start, stop = ligaturing(start,stop) start, stop = kerning(start,stop) else - prev = getprev(start) start = ligaturing(start) start = kerning(start) end + -- is done automatically if prev then setlink(prev,start) end if next then setlink(stop,next) end + -- till here if front and nuthead ~= start then - head = tonode(nuthead) + nuthead = start + head = tonode(start) end end end diff --git a/tex/context/base/mkiv/node-ini.lua b/tex/context/base/mkiv/node-ini.lua index f8720f717..bdccf8cba 100644 --- a/tex/context/base/mkiv/node-ini.lua +++ b/tex/context/base/mkiv/node-ini.lua @@ -12,6 +12,8 @@ modules.</p> --ldx]]-- -- this module is being reconstructed +-- +-- todo: datatype table per node type -- todo: query names with new node.subtypes @@ -90,6 +92,13 @@ local listcodes = mark(getsubtypes("list")) local rulecodes = mark(getsubtypes("rule")) +if not rulecodes[5] then + rulecodes[5] = "over" + rulecodes[6] = "under" + rulecodes[7] = "fraction" + rulecodes[8] = "radical" +end + -- local glyphcodes = allocate { -- [0] = "character", -- [1] = "glyph", @@ -248,6 +257,7 @@ local accentcodes = mark(getsubtypes("accent")) -- [1] = "left", -- [2] = "middle", -- [3] = "right", +-- [4] = "no", -- } local fencecodes = mark(getsubtypes("fence")) @@ -274,6 +284,18 @@ local usercodes = allocate { [116] = "tokens" -- t } +local noadoptions = allocate { + set = 0x08, + unused_1 = 0x00 + 0x08, + unused_2 = 0x01 + 0x08, + axis = 0x02 + 0x08, + no_axis = 0x04 + 0x08, + exact = 0x10 + 0x08, + left = 0x11 + 0x08, + middle = 0x12 + 0x08, + right = 0x14 + 0x08, +} + skipcodes = allocate(swapped(skipcodes,skipcodes)) boundarycodes = allocate(swapped(boundarycodes,boundarycodes)) noadcodes = allocate(swapped(noadcodes,noadcodes)) @@ -293,6 +315,7 @@ fencecodes = allocate(swapped(fencecodes,fencecodes)) rulecodes = allocate(swapped(rulecodes,rulecodes)) leadercodes = allocate(swapped(leadercodes,leadercodes)) usercodes = allocate(swapped(usercodes,usercodes)) +noadoptions = allocate(swapped(noadoptions,noadoptions)) nodes.skipcodes = skipcodes nodes.boundarycodes = boundarycodes @@ -313,6 +336,7 @@ nodes.fencecodes = fencecodes nodes.rulecodes = rulecodes nodes.leadercodes = leadercodes nodes.usercodes = usercodes +nodes.noadoptions = noadoptions nodes.gluecodes = skipcodes -- more official nodes.whatsitcodes = whatcodes -- more official @@ -327,25 +351,38 @@ kerncodes.kerning = kerncodes.fontkern kerncodes.italiccorrection = kerncodes.italiccorrection or 1 -- new nodes.codes = allocate { -- mostly for listing - glue = skipcodes, - boundary = boundarycodes, - noad = noadcodes, - node = nodecodes, - hlist = listcodes, - vlist = listcodes, - glyph = glyphcodes, - kern = kerncodes, - penalty = penaltycodes, - math = mathnodes, - fill = fillcodes, - margin = margincodes, - disc = disccodes, - whatsit = whatcodes, - accent = accentcodes, - fence = fencecodes, - rule = rulecodes, - leader = leadercodes, - user = usercodes, + glue = skipcodes, + boundary = boundarycodes, + noad = noadcodes, + node = nodecodes, + hlist = listcodes, + vlist = listcodes, + glyph = glyphcodes, + kern = kerncodes, + penalty = penaltycodes, + math = mathnodes, + fill = fillcodes, + margin = margincodes, + disc = disccodes, + whatsit = whatcodes, + accent = accentcodes, + fence = fencecodes, + rule = rulecodes, + leader = leadercodes, + user = usercodes, + noadoptions = noadoptions, +} + +nodes.noadoptions = { + set = 0x08, + unused_1 = 0x00 + 0x08, + unused_2 = 0x01 + 0x08, + axis = 0x02 + 0x08, + no_axis = 0x04 + 0x08, + exact = 0x10 + 0x08, + left = 0x11 + 0x08, + middle = 0x12 + 0x08, + right = 0x14 + 0x08, } local report_codes = logs.reporter("nodes","codes") @@ -373,3 +410,11 @@ if not nodecodes.dir then report_codes("use a newer version of luatex") os.exit() end + +-- We don't need this sanitize-after-callback in ConTeXt and by disabling it we +-- also have a way to check if LuaTeX itself does the right thing. + +if node.fix_node_lists then + node.fix_node_lists(false) +end + diff --git a/tex/context/base/mkiv/node-ini.mkiv b/tex/context/base/mkiv/node-ini.mkiv index d04e647de..369b06ab2 100644 --- a/tex/context/base/mkiv/node-ini.mkiv +++ b/tex/context/base/mkiv/node-ini.mkiv @@ -34,8 +34,8 @@ \registerctxluafile{node-ext}{1.001} \registerctxluafile{node-acc}{1.001} % experimental %registerctxluafile{node-prp}{1.001} % makes no sense (yet) - -\doifelsefile{node-ppt.lua}{\registerctxluafile{node-ppt}{1.001}}{} +\registerctxluafile{node-ppt}{1.001} +\registerctxluafile{node-scn}{1.001} \newcount\c_node_tracers_show_box % box number diff --git a/tex/context/base/mkiv/node-ltp.lua b/tex/context/base/mkiv/node-ltp.lua index ae17ab9ef..22a4799ad 100644 --- a/tex/context/base/mkiv/node-ltp.lua +++ b/tex/context/base/mkiv/node-ltp.lua @@ -21,6 +21,7 @@ if not modules then modules = { } end modules ['node-par'] = { -- todo: check and improve protrusion -- todo: arabic etc (we could use pretty large scales there) .. marks and cursive -- todo: see: we need to check this with the latest patches to the tex kernel +-- todo: adapt math glue spacing to new model (left/right) -- todo: optimize a bit more (less par.*) @@ -135,21 +136,20 @@ if not modules then modules = { } end modules ['node-par'] = { local utfchar = utf.char local write, write_nl = texio.write, texio.write_nl -local sub, format = string.sub, string.format +local sub, formatters = string.sub, string.formatters local round, floor = math.round, math.floor local insert, remove = table.insert, table.remove -local fonts, nodes, node = fonts, nodes, node +-- local fonts, nodes, node = fonts, nodes, node -- too many locals local trace_basic = false trackers.register("builders.paragraphs.basic", function(v) trace_basic = v end) local trace_lastlinefit = false trackers.register("builders.paragraphs.lastlinefit", function(v) trace_lastlinefit = v end) local trace_adjusting = false trackers.register("builders.paragraphs.adjusting", function(v) trace_adjusting = v end) local trace_protruding = false trackers.register("builders.paragraphs.protruding", function(v) trace_protruding = v end) local trace_expansion = false trackers.register("builders.paragraphs.expansion", function(v) trace_expansion = v end) -local trace_quality = false trackers.register("builders.paragraphs.quality", function(v) trace_quality = v end) local report_parbuilders = logs.reporter("nodes","parbuilders") -local report_hpackers = logs.reporter("nodes","hpackers") +----- report_hpackers = logs.reporter("nodes","hpackers") local calculate_badness = tex.badness local texnest = tex.nest @@ -185,7 +185,6 @@ local constructors = parbuilders.constructors local setmetatableindex = table.setmetatableindex local fonthashes = fonts.hashes -local fontdata = fonthashes.identifiers local chardata = fonthashes.characters local quaddata = fonthashes.quads local parameters = fonthashes.parameters @@ -206,6 +205,16 @@ local getchar = nuts.getchar local getdisc = nuts.getdisc local getattr = nuts.getattr local getdisc = nuts.getdisc +local getglue = nuts.getglue +local getwhd = nuts.getwhd +local getcomponents = nuts.getcomponents +local getkern = nuts.getkern +local getpenalty = nuts.getpenalty +local getdir = nuts.getdir +local getshift = nuts.getshift +local getwidth = nuts.getwidth +local getheight = nuts.getheight +local getdepth = nuts.getdepth local isglyph = nuts.isglyph @@ -217,22 +226,26 @@ local setnext = nuts.setnext local setprev = nuts.setprev local setdisc = nuts.setdisc local setsubtype = nuts.setsubtype - -local slide_nodelist = nuts.slide -- get rid of this, probably ok > 78.2 +local setglue = nuts.setglue +local setwhd = nuts.setwhd +local setkern = nuts.setkern +local setdir = nuts.setdir +local setshift = nuts.setshift +local setwidth = nuts.setwidth +----- getheight = nuts.getheight +----- getdepth = nuts.getdepth + +local slide_node_list = nuts.slide -- get rid of this, probably ok > 78.2 local find_tail = nuts.tail -local new_node = nuts.new local copy_node = nuts.copy -local copy_nodelist = nuts.copy_list -local flush_node = nuts.free -local flush_nodelist = nuts.flush_list -local hpack_nodes = nuts.hpack +local flush_node = nuts.flush +local flush_node_list = nuts.flush_list +----- hpack_nodes = nuts.hpack local xpack_nodes = nuts.hpack local replace_node = nuts.replace local insert_node_after = nuts.insert_after local insert_node_before = nuts.insert_before -local traverse_by_id = nuts.traverse_id - -local setnodecolor = nodes.tracers.colors.set +local is_zero_glue = nuts.is_zero_glue local nodepool = nuts.pool @@ -278,7 +291,7 @@ local ligature_code = glyphcodes.ligature local stretch_orders = nodes.fillcodes local leftmargin_code = margincodes.left -local rightmargin_code = margincodes.right +----- rightmargin_code = margincodes.right local automatic_disc_code = disccodes.automatic local regular_disc_code = disccodes.regular @@ -318,6 +331,7 @@ local new_lineskip = nodepool.lineskip local new_baselineskip = nodepool.baselineskip local new_temp = nodepool.temp local new_rule = nodepool.rule +local new_hlist = nodepool.hlist local is_rotated = nodes.is_rotated local is_parallel = nodes.textdir_is_parallel @@ -342,7 +356,7 @@ local function new_dir_stack(dir) -- also use elsewhere end -- The next function checks a dir node and returns the new dir state. By --- using s static table we are quite efficient. This function is used +-- using a static table we are quite efficient. This function is used -- in the parbuilder. local function checked_line_dir(stack,current) @@ -350,12 +364,12 @@ local function checked_line_dir(stack,current) local n = stack.n + 1 stack.n = n stack[n] = current - return getfield(current,"dir") + return getdir(current) elseif n > 0 then local n = stack.n local dirnode = stack[n] dirstack.n = n - 1 - return getfield(dirnode,"dir") + return getdir(dirnode) else report_parbuilders("warning: missing pop node (%a)",1) -- in line ... end @@ -372,7 +386,7 @@ local function inject_dirs_at_end_of_line(stack,current,start,stop) while start and start ~= stop do local id = getid(start) if id == dir_code then - if not dir_pops[getfield(start,"dir")] then -- weird, what is this # + if not dir_pops[getdir(start)] then -- weird, what is this # n = n + 1 stack[n] = start elseif n > 0 then @@ -384,7 +398,7 @@ local function inject_dirs_at_end_of_line(stack,current,start,stop) start = getnext(start) end for i=n,1,-1 do - h, current = insert_node_after(current,current,new_dir(dir_negations[getfield(stack[i],"dir")])) + h, current = insert_node_after(current,current,new_dir(dir_negations[getdir(stack[i])])) end stack.n = n return current @@ -616,12 +630,16 @@ local function find(head) -- do we really want to recurse into an hlist? else head = getnext(head) end - elseif id == protrusion_code then - local v = getfield(head,"value") - if v == 1 or v == 3 then - head = getnext(head) - if head then + elseif id == boundary_code then + if getsubtype(head) == protrusion_code then + local v = getfield(head,"value") + if v == 1 or v == 3 then head = getnext(head) + if head then + head = getnext(head) + end + else + return head end else return head @@ -666,12 +684,16 @@ local function find(head,tail) else tail = getprev(tail) end - elseif id == protrusion_code then - local v = getfield(tail,"value") - if v == 2 or v == 3 then - tail = getprev(tail) - if tail then + elseif id == boundary_code then + if getsubtype(head) == protrusion_code then + local v = getfield(tail,"value") + if v == 2 or v == 3 then tail = getprev(tail) + if tail then + tail = getprev(tail) + end + else + return tail end else return tail @@ -726,10 +748,11 @@ local function add_to_width(line_break_dir,checked_expansion,s) -- split into tw while s do local char, id = isglyph(s) if char then + local wd, ht, dp = getwhd(s) if is_rotated[line_break_dir] then -- can be shared - size = size + getfield(s,"height") + getfield(s,"depth") + size = size + ht + dp else - size = size + getfield(s,"width") + size = size + wd end if checked_expansion then local data = checked_expansion[getfont(s)] @@ -742,13 +765,14 @@ local function add_to_width(line_break_dir,checked_expansion,s) -- split into tw end end elseif id == hlist_code or id == vlist_code then - if is_parallel[getfield(s,"dir")][line_break_dir] then - size = size + getfield(s,"width") + local wd, ht, dp = getwhd(s) + if is_parallel[getdir(s)][line_break_dir] then + size = size + wd else - size = size + getfield(s,"height") + getfield(s,"depth") + size = size + ht + dp end elseif id == kern_code then - local kern = getfield(s,"kern") + local kern = getkern(s) if kern ~= 0 then if checked_expansion and expand_kerns and (getsubtype(s) == kerning_code or getattr(a_fontkern)) then local stretch, shrink = kern_stretch_shrink(s,kern) @@ -764,7 +788,7 @@ local function add_to_width(line_break_dir,checked_expansion,s) -- split into tw size = size + kern end elseif id == rule_code then - size = size + getfield(s,"width") + size = size + getwidth(s) elseif trace_unsupported then report_parbuilders("unsupported node at location %a",6) end @@ -809,21 +833,28 @@ local function compute_break_width(par,break_type,p) -- split in two if id == glyph_code then return -- happens often elseif id == glue_code then - local order = stretch_orders[getfield(p,"stretch_order")] - break_width.size = break_width.size - getfield(p,"width") - break_width[order] = break_width[order] - getfield(p,"stretch") - break_width.shrink = break_width.shrink - getfield(p,"shrink") + local wd, stretch, shrink, stretch_order = getglue(p) + local order = stretch_orders[stretch_order] + break_width.size = break_width.size - wd + break_width[order] = break_width[order] - stretch + break_width.shrink = break_width.shrink - shrink elseif id == penalty_code then -- do nothing elseif id == kern_code then local s = getsubtype(p) if s == userkern_code or s == italickern_code then - break_width.size = break_width.size - getfield(p,"kern") + break_width.size = break_width.size - getkern(p) else return end elseif id == math_code then - break_width.size = break_width.size - getfield(p,"surround") + break_width.size = break_width.size - getkern(p) -- surround + -- new in luatex + local wd, stretch, shrink, stretch_order = getglue(p) + local order = stretch_orders[stretch_order] + break_width.size = break_width.size - wd + break_width[order] = break_width[order] - stretch + break_width.shrink = break_width.shrink - shrink else return end @@ -833,29 +864,37 @@ end local function append_to_vlist(par, b) local prev_depth = par.prev_depth + local head_field = par.head_field + local tail_field = head_field and slide_node_list(head_field) -- todo: find_tail + local is_hlist = getid(b) == hlist_code -- if prev_depth > par.ignored_dimen then if prev_depth > ignore_depth then - if getid(b) == hlist_code then - local d = getfield(par.baseline_skip,"width") - prev_depth - getfield(b,"height") -- deficiency of space between baselines - local s = d < par.line_skip_limit and new_lineskip(par.lineskip) or new_baselineskip(d) - local head_field = par.head_field + if is_hlist then + local width, stretch, shrink, stretch_order, shrink_order = getglue(par.baseline_skip) + local delta = width - prev_depth - getheight(b) -- deficiency of space between baselines + local skip = nil + if delta < par.line_skip_limit then + width, stretch, shrink, stretch_order, shrink_order = getglue(par.lineskip) + skip = new_lineskip(width, stretch, shrink, stretch_order, shrink_order) + else + skip = new_baselineskip(delta, stretch, shrink, stretch_order, shrink_order) + end if head_field then - local n = slide_nodelist(head_field) -- todo: find_tail - setlink(n,s) + setlink(tail_field,skip) else - par.head_field = s + par.head_field = skip + head_field = skip end + tail_field = skip end end - local head_field = par.head_field if head_field then - local n = slide_nodelist(head_field) -- todo: find_tail - setlink(n,b) + setlink(tail_field,b) else par.head_field = b end - if getid(b) == hlist_code then - local pd = getfield(b,"depth") + if is_hlist then + local pd = getdepth(b) par.prev_depth = pd texnest[texnest.ptr].prevdepth = pd end @@ -864,7 +903,7 @@ end local function append_list(par, b) local head_field = par.head_field if head_field then - local n = slide_nodelist(head_field) -- todo: find_tail + local n = slide_node_list(head_field) -- todo: find_tail setlink(n,b) else par.head_field = b @@ -878,7 +917,7 @@ local hztolerance = 2500 local hzwarned = false local function used_skip(s) - return s and (getfield(s,"width") ~= 0 or getfield(s,"stretch") ~= 0 or getfield(s,"shrink") ~= 0) and s or nil + return s and not is_zero_glue(s) and s end local function initialize_line_break(head,display) @@ -970,7 +1009,7 @@ local function initialize_line_break(head,display) prev_depth = texnest[texnest.ptr].prevdepth, - final_par_glue = slide_nodelist(head), -- todo: we know tail already, slow + final_par_glue = slide_node_list(head), -- todo: we know tail already, slow par_break_dir = tex.pardir, line_break_dir = tex.pardir, @@ -1069,13 +1108,17 @@ local function initialize_line_break(head,display) local l = check_shrinkage(par,left_skip) local r = check_shrinkage(par,right_skip) - local l_order = stretch_orders[getfield(l,"stretch_order")] - local r_order = stretch_orders[getfield(r,"stretch_order")] - background.size = getfield(l,"width") + getfield(r,"width") - background.shrink = getfield(l,"shrink") + getfield(r,"shrink") - background[l_order] = getfield(l,"stretch") - background[r_order] = getfield(r,"stretch") + background[r_order] + local lwidth, lstretch, lshrink, lstretch_order, lshrink_order = getglue(l) + local rwidth, rstretch, rshrink, rstretch_order, rshrink_order = getglue(r) + + local l_order = stretch_orders[lstretch_order] + local r_order = stretch_orders[rstretch_order] + + background.size = lwidth + rwidth + background.shrink = lshrink + rshrink + background[l_order] = lstretch + background[r_order] = rstretch + background[r_order] -- this will move up so that we can assign the whole par table @@ -1139,9 +1182,9 @@ local function initialize_line_break(head,display) end if last_line_fit > 0 then - local spec = par.final_par_glue.spec - local stretch = spec.stretch - local stretch_order = spec.stretch_order + local final_par_glue = par.final_par_glue + local stretch = getfield(final_par_glue,"stretch") + local stretch_order = getfield(final_par_glue,"stretch_order") if stretch > 0 and stretch_order > 0 and background.fi == 0 and background.fil == 0 and background.fill == 0 and background.filll == 0 then par.do_last_line_fit = true local si = stretch_orders[stretch_order] @@ -1205,7 +1248,7 @@ local function post_line_break(par) if not lastnode then -- only at the end - lastnode = slide_nodelist(head) -- todo: find_tail + lastnode = slide_node_list(head) -- todo: find_tail if lastnode == par.final_par_glue then lineend = lastnode lastnode = getprev(lastnode) @@ -1217,7 +1260,7 @@ local function post_line_break(par) lastnode = replace_node(lastnode,new_rightskip(rightskip)) glue_break = true lineend = lastnode - lastnode = getprev(r) + lastnode = getprev(lastnode) elseif id == disc_code then local prevlast = getprev(lastnode) local nextlast = getnext(lastnode) @@ -1228,7 +1271,7 @@ local function post_line_break(par) report_parbuilders('unsupported disc at location %a',3) end if pre then - flush_nodelist(pre) + flush_node_list(pre) pre = nil -- signal end if replace then @@ -1239,13 +1282,13 @@ local function post_line_break(par) setdisc(lastnode,pre,post,replace) local pre, post, replace = getdisc(prevlast) if pre then - flush_nodelist(pre) + flush_node_list(pre) end if replace then - flush_nodelist(replace) + flush_node_list(replace) end if post then - flush_nodelist(post) + flush_node_list(post) end setdisc(prevlast) -- nil,nil,nil elseif subtype == first_disc_code then @@ -1258,7 +1301,7 @@ local function post_line_break(par) setfield(lastnode,"post") -- nil end if replace then - flush_nodelist(replace) + flush_node_list(replace) end if pre then setlink(prevlast,pre) @@ -1272,9 +1315,11 @@ local function post_line_break(par) setdisc(lastnode) -- nil, nil, nil disc_break = true elseif id == kern_code then - setfield(lastnode,"kern",0) + setkern(lastnode,0) elseif getid(lastnode) == math_code then - setfield(lastnode,"surround",0) + setkern(lastnode,0) -- surround + -- new in luatex + setglue(lastnode) -- zeros end end lastnode = inject_dirs_at_end_of_line(stack,lastnode,getnext(head),current_break.cur_break) @@ -1365,21 +1410,21 @@ local function post_line_break(par) local adjust_head = texlists.adjust_head local pre_adjust_head = texlists.pre_adjust_head -- - setfield(finished_line,"shift",cur_indent) + setshift(finished_line,cur_indent) -- -- -- this is gone: -- -- if par.each_line_height ~= ignored_dimen then - -- setfield(finished_line,"height",par.each_line_height) + -- setheight(finished_line,par.each_line_height) -- end -- if par.each_line_depth ~= ignored_dimen then - -- setfield(finished_line,"depth",par.each_line_depth) + -- setdepth(finished_line,par.each_line_depth) -- end -- if par.first_line_height ~= ignored_dimen and (current_line == par.first_line + 1) then - -- setfield(finished_line,"height",par.first_line_height) + -- setheight(finished_line,par.first_line_height) -- end -- if par.last_line_depth ~= ignored_dimen and current_line + 1 == par.best_line then - -- setfield(finished_line,"depth",par.last_line_depth) + -- setdepth(finished_line,par.last_line_depth) -- end -- if texlists.pre_adjust_head ~= pre_adjust_head then @@ -1427,29 +1472,35 @@ local function post_line_break(par) local next = nil while true do next = getnext(current) - if next == current_break.cur_break or getid(next) == glyph_code then + if next == current_break.cur_break then break end - local id = getid(next) - local subtype = getsubtype(next) - if id == localpar_code then + local id = getid(next) + if id == glyph_code then + break + elseif id == localpar_code then -- nothing elseif id < math_code then -- messy criterium break elseif id == math_code then -- keep the math node - setfield(next,"surround",0) - break - elseif id == kern_code and (subtype ~= userkern_code and subtype ~= italickern_code and not getattr(next,a_fontkern)) then - -- fontkerns and accent kerns as well as otf injections + setkern(next,0) -- surround + -- new in luatex + setglue(lastnode) -- zeros break + elseif id == kern_code then + local subtype = getsubtype(next) + if subtype ~= userkern_code and subtype ~= italickern_code and not getattr(next,a_fontkern) then + -- fontkerns and accent kerns as well as otf injections + break + end end current = next end if current ~= head then setnext(current) - flush_nodelist(getnext(head)) + flush_node_list(getnext(head)) setlink(head,next) end end @@ -1480,7 +1531,7 @@ local function wrap_up(par) par.do_last_line_fit = false else local glue = par.final_par_glue - setfield(glue,"width",getfield(glue,"width") + active_short - active_glue) + setwidth(glue,getwidth(glue) + active_short - active_glue) setfield(glue,"stretch",0) if trace_lastlinefit then report_parbuilders("applying last line fit, short %a, glue %p",active_short,active_glue) @@ -1915,8 +1966,8 @@ local function try_break(pi, break_type, par, first_p, current, checked_expansio local id = getid(l) if id == glyph_code then -- ok ? - elseif id == disc_code and l.post then - l = l.post -- TODO: first char could be a disc + elseif id == disc_code and getfield(l,"post") then + l = getfield(l,"post") -- TODO: first char could be a disc else l = find_protchar_left(l) end @@ -2199,10 +2250,11 @@ function constructors.methods.basic(head,d) while current and p_active ~= n_active do local char, id = isglyph(current) if char then + local wd, ht, dp = getwhd(current) if is_rotated[par.line_break_dir] then - active_width.size = active_width.size + getfield(current,"height") + getfield(current,"depth") + active_width.size = active_width.size + ht + dp else - active_width.size = active_width.size + getfield(current,"width") + active_width.size = active_width.size + wd end if checked_expansion then local currentfont = getfont(current) @@ -2222,10 +2274,11 @@ function constructors.methods.basic(head,d) end end elseif id == hlist_code or id == vlist_code then - if is_parallel[getfield(current,"dir")][par.line_break_dir] then - active_width.size = active_width.size + getfield(current,"width") + local wd, ht, dp = getwhd(current) + if is_parallel[getdir(current)][par.line_break_dir] then + active_width.size = active_width.size + wd else - active_width.size = active_width.size + getfield(current,"depth") + getfield(current,"height") + active_width.size = active_width.size + ht + dp end elseif id == glue_code then -- if par.auto_breaking then @@ -2245,10 +2298,11 @@ function constructors.methods.basic(head,d) end end check_shrinkage(par,current) - local order = stretch_orders[getfield(current,"stretch_order")] - active_width.size = active_width.size + getfield(current,"width") - active_width[order] = active_width[order] + getfield(current,"stretch") - active_width.shrink = active_width.shrink + getfield(current,"shrink") + local width, stretch, shrink, stretch_order = getglue(current) + local order = stretch_orders[stretch_order] + active_width.size = active_width.size + width + active_width[order] = active_width[order] + stretch + active_width.shrink = active_width.shrink + shrink elseif id == disc_code then local subtype = getsubtype(current) if subtype ~= second_disc_code then @@ -2256,7 +2310,7 @@ function constructors.methods.basic(head,d) if second_pass or subtype <= automatic_disc_code then local actual_pen = subtype == automatic_disc_code and par.ex_hyphen_penalty or par.hyphen_penalty -- 0.81 : - -- local actual_pen = getfield(current,"penalty") + -- local actual_pen = getpenalty(current) -- local pre, post, replace = getdisc(current) if not pre then -- trivial pre-break @@ -2335,9 +2389,9 @@ function constructors.methods.basic(head,d) p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion) end local active_width = par.active_width - active_width.size = active_width.size + getfield(current,"kern") + active_width.size = active_width.size + getkern(current) else - local kern = getfield(current,"kern") + local kern = getkern(current) if kern ~= 0 then active_width.size = active_width.size + kern if checked_expansion and expand_kerns and (getsubtype(current) == kerning_code or getattr(current,a_fontkern)) then @@ -2362,11 +2416,13 @@ function constructors.methods.basic(head,d) p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion) end local active_width = par.active_width - active_width.size = active_width.size + getfield(current,"surround") + active_width.size = active_width.size + getkern(current) -- surround + -- new in luatex + + getwidth(current) elseif id == rule_code then - active_width.size = active_width.size + getfield(current,"width") + active_width.size = active_width.size + getwidth(current) elseif id == penalty_code then - p_active, n_active = try_break(getfield(current,"penalty"), unhyphenated_code, par, first_p, current, checked_expansion) + p_active, n_active = try_break(getpenalty(current), unhyphenated_code, par, first_p, current, checked_expansion) elseif id == dir_code then par.line_break_dir = checked_line_dir(dirstack) or par.line_break_dir elseif id == localpar_code then @@ -2448,727 +2504,730 @@ end -- standard tex logging .. will be adapted .. -local function write_esc(cs) - local esc = tex.escapechar - if esc then - write("log",utfchar(esc),cs) - else - write("log",cs) +do + + local function write_esc(cs) + local esc = tex.escapechar + if esc then + write("log",utfchar(esc),cs) + else + write("log",cs) + end end -end -function diagnostics.start() -end + function diagnostics.start() + end -function diagnostics.stop() - write_nl("log",'') -end + function diagnostics.stop() + write_nl("log",'') + end -function diagnostics.current_pass(par,what) - write_nl("log",format("@%s",what)) -end + function diagnostics.current_pass(par,what) + write_nl("log",formatters["@%s"](what)) + end -local verbose = false -- true + local verbose = false -- true -local function short_display(target,a,font_in_short_display) - while a do - local char, id = isglyph(a) - if char then - local font = getfont(a) - if font ~= font_in_short_display then - write(target,tex.fontidentifier(font) .. ' ') - font_in_short_display = font - end - if getsubtype(a) == ligature_code then - font_in_short_display = short_display(target,getfield(a,"components"),font_in_short_display) - else - write(target,utfchar(char)) - end - elseif id == disc_code then - local pre, post, replace = getdisc(a) - font_in_short_display = short_display(target,pre,font_in_short_display) - font_in_short_display = short_display(target,post,font_in_short_display) - elseif verbose then - write(target,format("[%s]",nodecodes[id])) - elseif id == rule_code then - write(target,"|") - elseif id == glue_code then - write(target," ") - elseif id == kern_code then - local s = getsubtype(a) - if s == userkern_code or s == italickern_code or getattr(a,a_fontkern) then - if verbose then - write(target,"[|]") - -- else - -- write(target,"") + local function short_display(target,a,font_in_short_display) + while a do + local char, id = isglyph(a) + if char then + local font = getfont(a) + if font ~= font_in_short_display then + write(target,tex.fontidentifier(font) .. ' ') + font_in_short_display = font + end + -- todo: instead of components the split tounicode string + if getsubtype(a) == ligature_code then + font_in_short_display = short_display(target,getcomponents(a),font_in_short_display) + else + write(target,utfchar(char)) end + elseif id == disc_code then + local pre, post, replace = getdisc(a) + font_in_short_display = short_display(target,pre,font_in_short_display) + font_in_short_display = short_display(target,post,font_in_short_display) + elseif verbose then + write(target,formatters["[%s]"](nodecodes[id])) + elseif id == rule_code then + write(target,"|") + elseif id == glue_code then + write(target," ") + elseif id == kern_code then + local s = getsubtype(a) + if s == userkern_code or s == italickern_code or getattr(a,a_fontkern) then + if verbose then + write(target,"[|]") + -- else + -- write(target,"") + end + else + write(target,"[]") + end + elseif id == math_code then + write(target,"$") else write(target,"[]") end - elseif id == math_code then - write(target,"$") - else - write(target,"[]") + a = getnext(a) end - a = getnext(a) + return font_in_short_display end - return font_in_short_display -end -diagnostics.short_display = short_display + diagnostics.short_display = short_display -function diagnostics.break_node(par, q, fit_class, break_type, current) -- %d ? - local passive = par.passive - local typ_ind = break_type == hyphenated_code and '-' or "" - if par.do_last_line_fit then - local s = number.toscaled(q.active_short) - local g = number.toscaled(q.active_glue) - if current then - write_nl("log",format("@@%d: line %d.%d%s t=%s s=%s g=%s", - passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits,s,g)) + function diagnostics.break_node(par, q, fit_class, break_type, current) -- %d ? + local passive = par.passive + local typ_ind = break_type == hyphenated_code and '-' or "" + if par.do_last_line_fit then + local s = number.toscaled(q.active_short) + local g = number.toscaled(q.active_glue) + if current then + write_nl("log",formatters["@@%d: line %d.%d%s t=%s s=%s g=%s"]( + passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits,s,g)) + else + write_nl("log",formatters["@@%d: line %d.%d%s t=%s s=%s a=%s"]( + passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits,s,g)) + end else - write_nl("log",format("@@%d: line %d.%d%s t=%s s=%s a=%s", - passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits,s,g)) + write_nl("log",formatters["@@%d: line %d.%d%s t=%s"]( + passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits)) + end + if not passive.prev_break then + write("log"," -> @0") + else + write("log",formatters[" -> @%d"](passive.prev_break.serial or 0)) end - else - write_nl("log",format("@@%d: line %d.%d%s t=%s", - passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits)) - end - if not passive.prev_break then - write("log"," -> @0") - else - write("log",format(" -> @%d", passive.prev_break.serial or 0)) end -end -function diagnostics.feasible_break(par, current, r, b, pi, d, artificial_demerits) - local printed_node = par.printed_node - if printed_node ~= current then - write_nl("log","") + function diagnostics.feasible_break(par, current, r, b, pi, d, artificial_demerits) + local printed_node = par.printed_node + if printed_node ~= current then + write_nl("log","") + if not current then + par.font_in_short_display = short_display("log",getnext(printed_node),par.font_in_short_display) + else + local save_link = getnext(current) + setnext(current) + write_nl("log","") + par.font_in_short_display = short_display("log",getnext(printed_node),par.font_in_short_display) + setnext(current,save_link) + end + par.printed_node = current + end + write_nl("log","@") if not current then - par.font_in_short_display = short_display("log",getnext(printed_node),par.font_in_short_display) + write_esc("par") else - local save_link = getnext(current) - setnext(current) - write_nl("log","") - par.font_in_short_display = short_display("log",getnext(printed_node),par.font_in_short_display) - setnext(current,save_link) + local id = getid(current) + if id == glue_code then + -- print nothing + elseif id == penalty_code then + write_esc("penalty") + elseif id == disc_code then + write_esc("discretionary") + elseif id == kern_code then + write_esc("kern") + elseif id == math_code then + write_esc("math") + else + write_esc("unknown") + end + end + local via, badness, demerits = 0, '*', '*' + if r.break_node then + via = r.break_node.serial or 0 + end + if b <= infinite_badness then + badness = tonumber(d) end - par.printed_node = current + if not artificial_demerits then + demerits = tonumber(d) + end + write("log",formatters[" via @%d b=%s p=%s d=%s"](via,badness,pi,demerits)) end - write_nl("log","@") - if not current then - write_esc("par") - else - local id = getid(current) - if id == glue_code then - -- print nothing - elseif id == penalty_code then - write_esc("penalty") - elseif id == disc_code then - write_esc("discretionary") - elseif id == kern_code then - write_esc("kern") - elseif id == math_code then - write_esc("math") + + -- + + local function common_message(hlist,line,str) + write_nl("") + if status.output_active then -- unset + write(str," has occurred while \\output is active") else - write_esc("unknown") + write(str) end + local fileline = status.linenumber + if line > 0 then + write(formatters[" in paragraph at lines %s--%s"](fileline,"--",fileline+line-1)) + elseif line < 0 then + write(formatters[" in alignment at lines "](fileline,"--",fileline-line-1)) + else + write(formatters[" detected at line %s"](fileline)) + end + write_nl("") + diagnostics.short_display(getlist(hlist),false) + write_nl("") + -- diagnostics.start() + -- show_box(getlist(hlist)) + -- diagnostics.stop() + end + + function diagnostics.overfull_hbox(hlist,line,d) + common_message(hlist,line,formatters["Overfull \\hbox (%spt too wide)"](number.toscaled(d))) end - local via, badness, demerits = 0, '*', '*' - if r.break_node then - via = r.break_node.serial or 0 + + function diagnostics.bad_hbox(hlist,line,b) + common_message(hlist,line,formatters["Tight \\hbox (badness %i)"](b)) end - if b <= infinite_badness then - badness = tonumber(d) -- format("%d", b) + + function diagnostics.underfull_hbox(hlist,line,b) + common_message(hlist,line,formatters["Underfull \\hbox (badness %i)"](b)) end - if not artificial_demerits then - demerits = tonumber(d) -- format("%d", d) + + function diagnostics.loose_hbox(hlist,line,b) + common_message(hlist,line,formatters["Loose \\hbox (badness %i)"](b)) end - write("log",format(" via @%d b=%s p=%s d=%s", via, badness, pi, demerits)) + end -- reporting -- statistics.register("alternative parbuilders", function() if nofpars > 0 then - return format("%s paragraphs, %s lines (%s protruded, %s adjusted)", nofpars, noflines, nofprotrudedlines, nofadjustedlines) + return formatters["%s paragraphs, %s lines (%s protruded, %s adjusted)"](nofpars,noflines,nofprotrudedlines,nofadjustedlines) end end) --- actually scaling kerns is not such a good idea and it will become --- configureable - --- This is no way a replacement for the built in (fast) packer --- it's just an alternative for special (testing) purposes. --- --- We could use two hpacks: one to be used in the par builder --- and one to be used for other purposes. The one in the par --- builder is much more simple as it does not need the expansion --- code but only need to register the effective expansion factor --- with the glyph. - -local function glyph_width_height_depth(curdir,pdir,p) - local wd = getfield(p,"width") - local ht = getfield(p,"height") - local dp = getfield(p,"depth") - if is_rotated[curdir] then - if is_parallel[curdir][pdir] then - local half = (ht + dp) / 2 - return wd, half, half - else - local half = wd / 2 - return ht + dp, half, half - end - elseif is_rotated[pdir] then - if is_parallel[curdir][pdir] then - local half = (ht + dp) / 2 - return wd, half, half +do + + -- actually scaling kerns is not such a good idea and it will become + -- configureable + + -- This is no way a replacement for the built in (fast) packer + -- it's just an alternative for special (testing) purposes. + -- + -- We could use two hpacks: one to be used in the par builder + -- and one to be used for other purposes. The one in the par + -- builder is much more simple as it does not need the expansion + -- code but only need to register the effective expansion factor + -- with the glyph. + + local setnodecolor = nodes.tracers.colors.set + + local function glyph_width_height_depth(curdir,pdir,p) + local wd, ht, dp = getwhd(p) + if is_rotated[curdir] then + if is_parallel[curdir][pdir] then + local half = (ht + dp) / 2 + return wd, half, half + else + local half = wd / 2 + return ht + dp, half, half + end + elseif is_rotated[pdir] then + if is_parallel[curdir][pdir] then + local half = (ht + dp) / 2 + return wd, half, half + else + return ht + dp, wd, 0 -- weird + end else - return ht + dp, wd, 0 -- weird - end - else - if glyphdir_is_equal[curdir][pdir] then - return wd, ht, dp - elseif is_opposite[curdir][pdir] then - return wd, dp, ht - else -- can this happen? - return ht + dp, wd, 0 + if glyphdir_is_equal[curdir][pdir] then + return wd, ht, dp + elseif is_opposite[curdir][pdir] then + return wd, dp, ht + else -- can this happen? + return ht + dp, wd, 0 + end end end -end -local function pack_width_height_depth(curdir,pdir,p) - local wd = getfield(p,"width") - local ht = getfield(p,"height") - local dp = getfield(p,"depth") - if is_rotated[curdir] then - if is_parallel[curdir][pdir] then - local half = (ht + dp) / 2 - return wd, half, half - else -- can this happen? - local half = wd / 2 - return ht + dp, half, half - end - else - if pardir_is_equal[curdir][pdir] then - return wd, ht, dp - elseif is_opposite[curdir][pdir] then - return wd, dp, ht - else -- weird dimensions, can this happen? - return ht + dp, wd, 0 + local function pack_width_height_depth(curdir,pdir,p) + local wd, ht, dp = getwhd(p) + if is_rotated[curdir] then + if is_parallel[curdir][pdir] then + local half = (ht + dp) / 2 + return wd, half, half + else -- can this happen? + local half = wd / 2 + return ht + dp, half, half + end + else + if pardir_is_equal[curdir][pdir] then + return wd, ht, dp + elseif is_opposite[curdir][pdir] then + return wd, dp, ht + else -- weird dimensions, can this happen? + return ht + dp, wd, 0 + end end end -end - --- local function xpack(head,width,method,direction,analysis) --- --- -- inspect(analysis) --- --- local expansion = method == "cal_expand_ratio" --- local natural = analysis.size --- local font_stretch = analysis.adjust_stretch --- local font_shrink = analysis.adjust_shrink --- local font_expand_ratio = 0 --- local delta = width - natural --- --- local hlist = new_node("hlist") --- --- setlist(hlist,head) --- setfield(hlist,"dir",direction or tex.textdir) --- setfield(hlist,"width",width) --- setfield(hlist,"height",height) --- setfield(hlist,"depth",depth) --- --- if delta == 0 then --- --- setfield(hlist,"glue_sign",0) --- setfield(hlist,"glue_order",0) --- setfield(hlist,"glue_set",0) --- --- else --- --- local order = analysis.filll ~= 0 and fillcodes.filll or --- analysis.fill ~= 0 and fillcodes.fill or --- analysis.fil ~= 0 and fillcodes.fil or --- analysis.fi ~= 0 and fillcodes.fi or 0 --- --- if delta > 0 then --- --- if expansion and order == 0 and font_stretch > 0 then --- font_expand_ratio = (delta/font_stretch) * 1000 --- else --- local stretch = analysis.stretch --- if stretch ~= 0 then --- setfield(hlist,"glue_sign",1) -- stretch --- setfield(hlist,"glue_order",order) --- setfield(hlist,"glue_set",delta/stretch) --- else --- setfield(hlist,"glue_sign",0) -- nothing --- setfield(hlist,"glue_order",order) --- setfield(hlist,"glue_set",0) --- end --- end --- --- else --- --- if expansion and order == 0 and font_shrink > 0 then --- font_expand_ratio = (delta/font_shrink) * 1000 --- else --- local shrink = analysis.shrink --- if shrink ~= 0 then --- setfield(hlist,"glue_sign",2) -- shrink --- setfield(hlist,"glue_order",order) --- setfield(hlist,"glue_set",-delta/stretch) --- else --- setfield(hlist,"glue_sign",0) -- nothing --- setfield(hlist,"glue_order",order) --- setfield(hlist,"glue_set",0) --- end --- end --- --- end --- --- end --- --- if not expansion or font_expand_ratio == 0 then --- -- nothing --- elseif font_expand_ratio > 0 then --- if font_expand_ratio > 1000 then --- font_expand_ratio = 1000 --- end --- local current = head --- while current do --- local id = getid(current) --- if id == glyph_code then --- local stretch, shrink = char_stretch_shrink(current) -- get only one --- if stretch then --- if trace_expansion then --- setnodecolor(g,"hz:positive") --- end --- current.expansion_factor = font_expand_ratio * stretch --- end --- elseif id == kern_code then --- local kern = getfield(current,"kern") --- if kern ~= 0 and getsubtype(current) == kerning_code then --- setfield(current,"kern",font_expand_ratio * kern) --- end --- end --- current = getnext(current) --- end --- elseif font_expand_ratio < 0 then --- if font_expand_ratio < -1000 then --- font_expand_ratio = -1000 --- end --- local current = head --- while current do --- local id = getid(current) --- if id == glyph_code then --- local stretch, shrink = char_stretch_shrink(current) -- get only one --- if shrink then --- if trace_expansion then --- setnodecolor(g,"hz:negative") --- end --- current.expansion_factor = font_expand_ratio * shrink --- end --- elseif id == kern_code then --- local kern = getfield(current,"kern") --- if kern ~= 0 and getsubtype(current) == kerning_code then --- setfield(current,"kern",font_expand_ratio * kern) --- end --- end --- current = getnext(current) --- end --- end --- return hlist, 0 --- end - -local function hpack(head,width,method,direction,firstline,line) -- fast version when head = nil - - -- we can pass the adjust_width and adjust_height so that we don't need to recalculate them but - -- with the glue mess it's less trivial as we lack detail .. challenge - local hlist = new_node("hlist") - - setfield(hlist,"dir",direction) - - if head == nil then - setfield(hlist,"width",width) - return hlist, 0 - else - setlist(hlist,head) - end + -- local function xpack(head,width,method,direction,analysis) + -- + -- -- inspect(analysis) + -- + -- local expansion = method == "cal_expand_ratio" + -- local natural = analysis.size + -- local font_stretch = analysis.adjust_stretch + -- local font_shrink = analysis.adjust_shrink + -- local font_expand_ratio = 0 + -- local delta = width - natural + -- + -- local hlist = new_hlist() + -- + -- setlist(hlist,head) + -- setdir(hlist,direction or tex.textdir) + -- setwhd(hlist,width,height,depth) + -- + -- if delta == 0 then + -- + -- setfield(hlist,"glue_sign",0) + -- setfield(hlist,"glue_order",0) + -- setfield(hlist,"glue_set",0) + -- + -- else + -- + -- local order = analysis.filll ~= 0 and fillcodes.filll or + -- analysis.fill ~= 0 and fillcodes.fill or + -- analysis.fil ~= 0 and fillcodes.fil or + -- analysis.fi ~= 0 and fillcodes.fi or 0 + -- + -- if delta > 0 then + -- + -- if expansion and order == 0 and font_stretch > 0 then + -- font_expand_ratio = (delta/font_stretch) * 1000 + -- else + -- local stretch = analysis.stretch + -- if stretch ~= 0 then + -- setfield(hlist,"glue_sign",1) -- stretch + -- setfield(hlist,"glue_order",order) + -- setfield(hlist,"glue_set",delta/stretch) + -- else + -- setfield(hlist,"glue_sign",0) -- nothing + -- setfield(hlist,"glue_order",order) + -- setfield(hlist,"glue_set",0) + -- end + -- end + -- + -- else + -- + -- if expansion and order == 0 and font_shrink > 0 then + -- font_expand_ratio = (delta/font_shrink) * 1000 + -- else + -- local shrink = analysis.shrink + -- if shrink ~= 0 then + -- setfield(hlist,"glue_sign",2) -- shrink + -- setfield(hlist,"glue_order",order) + -- setfield(hlist,"glue_set",-delta/stretch) + -- else + -- setfield(hlist,"glue_sign",0) -- nothing + -- setfield(hlist,"glue_order",order) + -- setfield(hlist,"glue_set",0) + -- end + -- end + -- + -- end + -- + -- end + -- + -- if not expansion or font_expand_ratio == 0 then + -- -- nothing + -- elseif font_expand_ratio > 0 then + -- if font_expand_ratio > 1000 then + -- font_expand_ratio = 1000 + -- end + -- local current = head + -- while current do + -- local id = getid(current) + -- if id == glyph_code then + -- local stretch, shrink = char_stretch_shrink(current) -- get only one + -- if stretch then + -- if trace_expansion then + -- setnodecolor(g,"hz:positive") + -- end + -- current.expansion_factor = font_expand_ratio * stretch + -- end + -- elseif id == kern_code then + -- local kern = getkern(current) + -- if kern ~= 0 and getsubtype(current) == kerning_code then + -- setkern(current,font_expand_ratio * kern) + -- end + -- end + -- current = getnext(current) + -- end + -- elseif font_expand_ratio < 0 then + -- if font_expand_ratio < -1000 then + -- font_expand_ratio = -1000 + -- end + -- local current = head + -- while current do + -- local id = getid(current) + -- if id == glyph_code then + -- local stretch, shrink = char_stretch_shrink(current) -- get only one + -- if shrink then + -- if trace_expansion then + -- setnodecolor(g,"hz:negative") + -- end + -- current.expansion_factor = font_expand_ratio * shrink + -- end + -- elseif id == kern_code then + -- local kern = getkern(current) + -- if kern ~= 0 and getsubtype(current) == kerning_code then + -- setkern(current,font_expand_ratio * kern) + -- end + -- end + -- current = getnext(current) + -- end + -- end + -- return hlist, 0 + -- end + + local function hpack(head,width,method,direction,firstline,line) -- fast version when head = nil + + -- we can pass the adjust_width and adjust_height so that we don't need to recalculate them but + -- with the glue mess it's less trivial as we lack detail .. challenge + + local hlist = new_hlist() + + setdir(hlist,direction) + + if head == nil then + setwidth(hlist,width) + return hlist, 0 + else + setlist(hlist,head) + end - local cal_expand_ratio = method == "cal_expand_ratio" or method == "subst_ex_font" + local cal_expand_ratio = method == "cal_expand_ratio" or method == "subst_ex_font" - direction = direction or tex.textdir + direction = direction or tex.textdir - local line = 0 + local line = 0 - local height = 0 - local depth = 0 - local natural = 0 - local font_stretch = 0 - local font_shrink = 0 - local font_expand_ratio = 0 - local last_badness = 0 - local expansion_stack = cal_expand_ratio and { } -- todo: optionally pass this - local expansion_index = 0 - local total_stretch = { [0] = 0, 0, 0, 0, 0 } - local total_shrink = { [0] = 0, 0, 0, 0, 0 } + local height = 0 + local depth = 0 + local natural = 0 + local font_stretch = 0 + local font_shrink = 0 + local font_expand_ratio = 0 + local last_badness = 0 + local expansion_stack = cal_expand_ratio and { } -- todo: optionally pass this + local expansion_index = 0 + local total_stretch = { [0] = 0, 0, 0, 0, 0 } + local total_shrink = { [0] = 0, 0, 0, 0, 0 } - local hpack_dir = direction + local hpack_dir = direction - local adjust_head = texlists.adjust_head - local pre_adjust_head = texlists.pre_adjust_head - local adjust_tail = adjust_head and slide_nodelist(adjust_head) -- todo: find_tail - local pre_adjust_tail = pre_adjust_head and slide_nodelist(pre_adjust_head) -- todo: find_tail + local adjust_head = texlists.adjust_head + local pre_adjust_head = texlists.pre_adjust_head + local adjust_tail = adjust_head and slide_node_list(adjust_head) -- todo: find_tail + local pre_adjust_tail = pre_adjust_head and slide_node_list(pre_adjust_head) -- todo: find_tail - new_dir_stack(hpack_dir) + new_dir_stack(hpack_dir) - local checked_expansion = false + local checked_expansion = false - if cal_expand_ratio then - checked_expansion = { } - setmetatableindex(checked_expansion,check_expand_lines) - end + if cal_expand_ratio then + checked_expansion = { } + setmetatableindex(checked_expansion,check_expand_lines) + end - -- this one also needs to check the font, so in the end indeed we might end up with two variants + -- this one also needs to check the font, so in the end indeed we might end up with two variants - local fontexps, lastfont + local fontexps, lastfont - local function process(current) -- called nested in disc replace + local function process(current) -- called nested in disc replace - while current do - local char, id = isglyph(current) - if char then - if cal_expand_ratio then - local currentfont = getfont(current) - if currentfont ~= lastfont then - fontexps = checked_expansion[currentfont] -- a bit redundant for the par line packer - lastfont = currentfont + while current do + local char, id = isglyph(current) + if char then + if cal_expand_ratio then + local currentfont = getfont(current) + if currentfont ~= lastfont then + fontexps = checked_expansion[currentfont] -- a bit redundant for the par line packer + lastfont = currentfont + end + if fontexps then + local expansion = fontexps[char] + if expansion then + font_stretch = font_stretch + expansion.glyphstretch + font_shrink = font_shrink + expansion.glyphshrink + expansion_index = expansion_index + 1 + expansion_stack[expansion_index] = current + end + end + end + -- use inline + local wd, ht, dp = glyph_width_height_depth(hpack_dir,"TLT",current) -- was TRT ? + natural = natural + wd + if ht > height then + height = ht end - if fontexps then - local expansion = fontexps[char] - if expansion then - font_stretch = font_stretch + expansion.glyphstretch - font_shrink = font_shrink + expansion.glyphshrink + if dp > depth then + depth = dp + end + elseif id == kern_code then + local kern = getkern(current) + if kern == 0 then + -- no kern + elseif getsubtype(current) == kerning_code then -- check getkern(p) + if cal_expand_ratio then + local stretch, shrink = kern_stretch_shrink(current,kern) + font_stretch = font_stretch + stretch + font_shrink = font_shrink + shrink expansion_index = expansion_index + 1 expansion_stack[expansion_index] = current end + natural = natural + kern + else + natural = natural + kern end - end - -- use inline - local wd, ht, dp = glyph_width_height_depth(hpack_dir,"TLT",current) -- was TRT ? - natural = natural + wd - if ht > height then - height = ht - end - if dp > depth then - depth = dp - end - elseif id == kern_code then - local kern = getfield(current,"kern") - if kern == 0 then - -- no kern - elseif getsubtype(current) == kerning_code then -- check getfield(p,"kern") - if cal_expand_ratio then - local stretch, shrink = kern_stretch_shrink(current,kern) - font_stretch = font_stretch + stretch - font_shrink = font_shrink + shrink - expansion_index = expansion_index + 1 - expansion_stack[expansion_index] = current + elseif id == disc_code then + local subtype = getsubtype(current) + if subtype ~= second_disc_code then + -- todo : local stretch, shrink = char_stretch_shrink(s) + local replace = getfield(current,"replace") + if replace then + process(replace) + end end - natural = natural + kern - else - natural = natural + kern - end - elseif id == disc_code then - local subtype = getsubtype(current) - if subtype ~= second_disc_code then - -- todo : local stretch, shrink = char_stretch_shrink(s) - local replace = getfield(current,"replace") - if replace then - process(replace) + elseif id == glue_code then + local wd, stretch, shrink, stretch_order, shrink_order = getglue(current) + natural = natural + wd + total_stretch[stretch_order] = total_stretch[stretch_order] + stretch + total_shrink [shrink_order] = total_shrink[shrink_order] + shrink + if getsubtype(current) >= leaders_code then + local leader = getleader(current) + local wd, ht, dp = getwhd(leader) -- can become getwhd(current) after 1.003 + if ht > height then + height = ht + end + if dp > depth then + depth = dp + end end - end - elseif id == glue_code then - natural = natural + getfield(current,"width") - local op = getfield(current,"stretch_order") - local om = getfield(current,"shrink_order") - total_stretch[op] = total_stretch[op] + getfield(current,"stretch") - total_shrink [om] = total_shrink [om] + getfield(current,"shrink") - if getsubtype(current) >= leaders_code then - local leader = getleader(current) - local ht = getfield(leader,"height") - local dp = getfield(leader,"depth") + elseif id == hlist_code or id == vlist_code then + local sh = getshift(current) + local wd, ht, dp = pack_width_height_depth(hpack_dir,getdir(current) or hpack_dir,current) -- added: or pack_dir + local hs, ds = ht - sh, dp + sh + natural = natural + wd + if hs > height then + height = hs + end + if ds > depth then + depth = ds + end + elseif id == rule_code then + local wd, ht, dp = getwhd(current) + natural = natural + wd if ht > height then height = ht end if dp > depth then depth = dp end + elseif id == math_code then + natural = natural + getkern(current) -- surround + -- new in luatex + + getwidth(current) + elseif id == unset_code then + local wd, ht, dp = getwhd(current) + local sh = getshift(current) + local hs = ht - sh + local ds = dp + sh + natural = natural + wd + if hs > height then + height = hs + end + if ds > depth then + depth = ds + end + elseif id == ins_code or id == mark_code then + local prev, next = getboth(current) + if adjust_tail then -- todo + setlink(prev,next) + setlink(adjust_tail,current) + setnext(current) + adjust_tail = current + else + adjust_head = current + adjust_tail = current + setboth(current) + end + elseif id == adjust_code then + local list = getlist(current) + if adjust_tail then + setnext(adjust_tail,list) + else + adjust_head = list + end + adjust_tail = slide_node_list(list) -- find_tail(list) + elseif id == dir_code then + hpack_dir = checked_line_dir(stack,current) or hpack_dir + elseif id == marginkern_code then + local width = getwidth(current) + if cal_expand_ratio then + -- is this ok? + local glyph = getfield(current,"glyph") + local char_pw = getsubtype(current) == leftmargin_code and left_pw or right_pw + font_stretch = font_stretch - width - char_pw(glyph) + font_shrink = font_shrink - width - char_pw(glyph) + expansion_index = expansion_index + 1 + expansion_stack[expansion_index] = glyph + end + natural = natural + width end - elseif id == hlist_code or id == vlist_code then - local sh = getfield(current,"shift") - local wd, ht, dp = pack_width_height_depth(hpack_dir,getfield(current,"dir") or hpack_dir,current) -- added: or pack_dir - local hs, ds = ht - sh, dp + sh - natural = natural + wd - if hs > height then - height = hs - end - if ds > depth then - depth = ds - end - elseif id == rule_code then - local wd = getfield(current,"width") - local ht = getfield(current,"height") - local dp = getfield(current,"depth") - natural = natural + wd - if ht > height then - height = ht - end - if dp > depth then - depth = dp - end - elseif id == math_code then - natural = natural + getfield(current,"surround") - elseif id == unset_code then - local wd = getfield(current,"width") - local ht = getfield(current,"height") - local dp = getfield(current,"depth") - local sh = getfield(current,"shift") - local hs = ht - sh - local ds = dp + sh - natural = natural + wd - if hs > height then - height = hs - end - if ds > depth then - depth = ds - end - elseif id == ins_code or id == mark_code then - local prev, next = getboth(current) - if adjust_tail then -- todo - setlink(prev,next) - setlink(adjust_tail,current) - setnext(current) - adjust_tail = current - else - adjust_head = current - adjust_tail = current - setboth(current) - end - elseif id == adjust_code then - local list = getlist(current) - if adjust_tail then - setnext(adjust_tail,list) - else - adjust_head = list - end - adjust_tail = slide_nodelist(list) -- find_tail(list) - elseif id == dir_code then - hpack_dir = checked_line_dir(stack,current) or hpack_dir - elseif id == marginkern_code then - local width = getfield(current,"width") - if cal_expand_ratio then - -- is this ok? - local glyph = getfield(current,"glyph") - local char_pw = getsubtype(current) == leftmargin_code and left_pw or right_pw - font_stretch = font_stretch - width - char_pw(glyph) - font_shrink = font_shrink - width - char_pw(glyph) - expansion_index = expansion_index + 1 - expansion_stack[expansion_index] = glyph - end - natural = natural + width + current = getnext(current) end - current = getnext(current) - end - - end - process(head) - - if adjust_tail then - adjust_tail.next = nil -- todo - end - if pre_adjust_tail then - pre_adjust_tail.next = nil -- todo - end - if method == "additional" then - width = width + natural - end + end - setfield(hlist,"width",width) - setfield(hlist,"height",height) - setfield(hlist,"depth",depth) + process(head) - local delta = width - natural - if delta == 0 then - setfield(hlist,"glue_sign",0) - setfield(hlist,"glue_order",0) - setfield(hlist,"glue_set",0) - elseif delta > 0 then - -- natural width smaller than requested width - local order = (total_stretch[4] ~= 0 and 4 or total_stretch[3] ~= 0 and 3) or - (total_stretch[2] ~= 0 and 2 or total_stretch[1] ~= 0 and 1) or 0 - if cal_expand_ratio and order == 0 and font_stretch > 0 then -- check sign of font_stretch - font_expand_ratio = delta/font_stretch + if adjust_tail then + adjust_tail.next = nil -- todo + end + if pre_adjust_tail then + pre_adjust_tail.next = nil -- todo + end + if method == "additional" then + width = width + natural + end - if font_expand_ratio > 1 then - font_expand_ratio = 1 - end + setwhd(hlist,width,height,depth) - local fontexps, lastfont - for i=1,expansion_index do - local g = expansion_stack[i] - local e = 0 - local char = isglyph(g) - if char then - local currentfont = getfont(g) - if currentfont ~= lastfont then - fontexps = expansions[currentfont] - lastfont = currentfont - end - local data = fontexps[char] - if trace_expansion then - setnodecolor(g,"hz:positive") - end - e = font_expand_ratio * data.glyphstretch / 1000 - else - local kern = getfield(g,"kern") - local stretch, shrink = kern_stretch_shrink(g,kern) - e = font_expand_ratio * stretch / 1000 - end - setfield(g,"expansion_factor",e) - end - end - local tso = total_stretch[order] - if tso ~= 0 then - setfield(hlist,"glue_sign",1) - setfield(hlist,"glue_order",order) - setfield(hlist,"glue_set",delta/tso) - else + local delta = width - natural + if delta == 0 then setfield(hlist,"glue_sign",0) - setfield(hlist,"glue_order",order) + setfield(hlist,"glue_order",0) setfield(hlist,"glue_set",0) - end - if font_expand_ratio ~= 0 then - -- todo - elseif order == 0 then -- and getlist(hlist) then - last_badness = calculate_badness(delta,total_stretch[0]) - if last_badness > tex.hbadness then - if last_badness > 100 then - diagnostics.underfull_hbox(hlist,line,last_badness) - else - diagnostics.loose_hbox(hlist,line,last_badness) + elseif delta > 0 then + -- natural width smaller than requested width + local order = (total_stretch[4] ~= 0 and 4 or total_stretch[3] ~= 0 and 3) or + (total_stretch[2] ~= 0 and 2 or total_stretch[1] ~= 0 and 1) or 0 + if cal_expand_ratio and order == 0 and font_stretch > 0 then -- check sign of font_stretch + font_expand_ratio = delta/font_stretch + + if font_expand_ratio > 1 then + font_expand_ratio = 1 + end + + local fontexps, lastfont + for i=1,expansion_index do + local g = expansion_stack[i] + local e = 0 + local char = isglyph(g) + if char then + local currentfont = getfont(g) + if currentfont ~= lastfont then + fontexps = expansions[currentfont] + lastfont = currentfont + end + local data = fontexps[char] + if trace_expansion then + setnodecolor(g,"hz:positive") + end + e = font_expand_ratio * data.glyphstretch / 1000 + else + local kern = getkern(g) + local stretch, shrink = kern_stretch_shrink(g,kern) + e = font_expand_ratio * stretch / 1000 + end + setfield(g,"expansion_factor",e) end end - end - else - -- natural width larger than requested width - local order = total_shrink[4] ~= 0 and 4 or total_shrink[3] ~= 0 and 3 - or total_shrink[2] ~= 0 and 2 or total_shrink[1] ~= 0 and 1 or 0 - if cal_expand_ratio and order == 0 and font_shrink > 0 then -- check sign of font_shrink - font_expand_ratio = delta/font_shrink - - if font_expand_ratio < 1 then - font_expand_ratio = -1 + local tso = total_stretch[order] + if tso ~= 0 then + setfield(hlist,"glue_sign",1) + setfield(hlist,"glue_order",order) + setfield(hlist,"glue_set",delta/tso) + else + setfield(hlist,"glue_sign",0) + setfield(hlist,"glue_order",order) + setfield(hlist,"glue_set",0) end - - local fontexps, lastfont - for i=1,expansion_index do - local g = expansion_stack[i] - local e = 0 - local char = isglyph(g) - if char then - local currentfont = getfont(g) - if currentfont ~= lastfont then - fontexps = expansions[currentfont] - lastfont = currentfont - end - local data = fontexps[char] - if trace_expansion then - setnodecolor(g,"hz:negative") + if font_expand_ratio ~= 0 then + -- todo + elseif order == 0 then -- and getlist(hlist) then + last_badness = calculate_badness(delta,total_stretch[0]) + if last_badness > tex.hbadness then + if last_badness > 100 then + diagnostics.underfull_hbox(hlist,line,last_badness) + else + diagnostics.loose_hbox(hlist,line,last_badness) end - e = font_expand_ratio * data.glyphshrink / 1000 - else - local kern = getfield(g,"kern") - local stretch, shrink = kern_stretch_shrink(g,kern) - e = font_expand_ratio * shrink / 1000 end - setfield(g,"expansion_factor",e) end - end - local tso = total_shrink[order] - if tso ~= 0 then - setfield(hlist,"glue_sign",2) - setfield(hlist,"glue_order",order) - setfield(hlist,"glue_set",-delta/tso) else - setfield(hlist,"glue_sign",0) - setfield(hlist,"glue_order",order) - setfield(hlist,"glue_set",0) - end - if font_expand_ratio ~= 0 then - -- todo - elseif tso < -delta and order == 0 then -- and getlist(hlist) then - last_badness = 1000000 - setfield(hlist,"glue_set",1) - local fuzz = - delta - total_shrink[0] - local hfuzz = tex.hfuzz - if fuzz > hfuzz or tex.hbadness < 100 then - local overfullrule = tex.overfullrule - if fuzz > hfuzz and overfullrule > 0 then - -- weird, is always called and no rules shows up - setfield(slide_nodelist(list),"next",new_rule(overfullrule,nil,nil,hlist.dir)) -- todo: find_tail + -- natural width larger than requested width + local order = total_shrink[4] ~= 0 and 4 or total_shrink[3] ~= 0 and 3 + or total_shrink[2] ~= 0 and 2 or total_shrink[1] ~= 0 and 1 or 0 + if cal_expand_ratio and order == 0 and font_shrink > 0 then -- check sign of font_shrink + font_expand_ratio = delta/font_shrink + + if font_expand_ratio < 1 then + font_expand_ratio = -1 + end + + local fontexps, lastfont + for i=1,expansion_index do + local g = expansion_stack[i] + local e = 0 + local char = isglyph(g) + if char then + local currentfont = getfont(g) + if currentfont ~= lastfont then + fontexps = expansions[currentfont] + lastfont = currentfont + end + local data = fontexps[char] + if trace_expansion then + setnodecolor(g,"hz:negative") + end + e = font_expand_ratio * data.glyphshrink / 1000 + else + local kern = getkern(g) + local stretch, shrink = kern_stretch_shrink(g,kern) + e = font_expand_ratio * shrink / 1000 + end + setfield(g,"expansion_factor",e) end - diagnostics.overfull_hbox(hlist,line,-delta) end - elseif order == 0 and getlist(hlist) and last_badness > tex.hbadness then - diagnostics.bad_hbox(hlist,line,last_badness) + local tso = total_shrink[order] + if tso ~= 0 then + setfield(hlist,"glue_sign",2) + setfield(hlist,"glue_order",order) + setfield(hlist,"glue_set",-delta/tso) + else + setfield(hlist,"glue_sign",0) + setfield(hlist,"glue_order",order) + setfield(hlist,"glue_set",0) + end + if font_expand_ratio ~= 0 then + -- todo + elseif tso < -delta and order == 0 then -- and getlist(hlist) then + last_badness = 1000000 + setfield(hlist,"glue_set",1) + local fuzz = - delta - total_shrink[0] + local hfuzz = tex.hfuzz + if fuzz > hfuzz or tex.hbadness < 100 then + local overfullrule = tex.overfullrule + if fuzz > hfuzz and overfullrule > 0 then + -- weird, is always called and no rules shows up + setnext(slide_node_list(list),new_rule(overfullrule,nil,nil,getdir(hlist))) -- todo: find_tail + end + diagnostics.overfull_hbox(hlist,line,-delta) + end + elseif order == 0 and getlist(hlist) and last_badness > tex.hbadness then + diagnostics.bad_hbox(hlist,line,last_badness) + end end + return hlist, last_badness end - return hlist, last_badness -end - -xpack_nodes = hpack -- comment this for old fashioned expansion (we need to fix float mess) - -constructors.methods.hpack = hpack - -local function common_message(hlist,line,str) - write_nl("") - if status.output_active then -- unset - write(str," has occurred while \\output is active") - end - local fileline = status.linenumber - if line > 0 then - write(str," in paragraph at lines ",fileline,"--",fileline+line-1) - elseif line < 0 then - write(str," in alignment at lines ",fileline,"--",fileline-line-1) - else - write(str," detected at line ",fileline) - end - write_nl("") - diagnostics.short_display(hlist.list,false) - write_nl("") - -- diagnostics.start() - -- show_box(hlist.list) - -- diagnostics.stop() -end -function diagnostics.overfull_hbox(hlist,line,d) - common_message(hlist,line,format("Overfull \\hbox (%spt too wide)",number.toscaled(d))) -end - -function diagnostics.bad_hbox(hlist,line,b) - common_message(hlist,line,format("Tight \\hbox (badness %i)",b)) -end + xpack_nodes = hpack -- comment this for old fashioned expansion (we need to fix float mess) -function diagnostics.underfull_hbox(hlist,line,b) - common_message(hlist,line,format("Underfull \\hbox (badness %i)",b)) -end + constructors.methods.hpack = hpack -function diagnostics.loose_hbox(hlist,line,b) - common_message(hlist,line,format("Loose \\hbox (badness %i)",b)) end diff --git a/tex/context/base/mkiv/node-met.lua b/tex/context/base/mkiv/node-met.lua index 432ecd1ec..9ebc8e411 100644 --- a/tex/context/base/mkiv/node-met.lua +++ b/tex/context/base/mkiv/node-met.lua @@ -60,66 +60,86 @@ end -- We start with some helpers and provide all relevant basic functions in the -- node namespace as well. -nodes = nodes or { } -local nodes = nodes - ------ gonuts = type(node.direct) == "table" ------.gonuts = gonuts - -local nodecodes = nodes.nodecodes -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist - -nodes.tostring = node.tostring or tostring -nodes.copy = node.copy -nodes.copy_list = node.copy_list -nodes.delete = node.delete -nodes.dimensions = node.dimensions -nodes.end_of_math = node.end_of_math -nodes.flush_list = node.flush_list -nodes.flush_node = node.flush_node -nodes.free = node.free -nodes.insert_after = node.insert_after -nodes.insert_before = node.insert_before -nodes.hpack = node.hpack -nodes.new = node.new -nodes.tail = node.tail -nodes.traverse = node.traverse -nodes.traverse_id = node.traverse_id -nodes.traverse_char = node.traverse_char -nodes.slide = node.slide -nodes.vpack = node.vpack -nodes.fields = node.fields -nodes.is_node = node.is_node -nodes.setglue = node.setglue - -nodes.first_glyph = node.first_glyph -nodes.has_glyph = node.has_glyph or node.first_glyph - -nodes.current_attr = node.current_attr -nodes.do_ligature_n = node.do_ligature_n -nodes.has_field = node.has_field -nodes.last_node = node.last_node -nodes.usedlist = node.usedlist -nodes.protrusion_skippable = node.protrusion_skippable -nodes.write = node.write +nodes = nodes or { } +local nodes = nodes + +local nodecodes = nodes.nodecodes + +nodes.tostring = node.tostring or tostring +nodes.copy = node.copy +nodes.copy_node = node.copy +nodes.copy_list = node.copy_list +nodes.delete = node.delete +nodes.dimensions = node.dimensions +nodes.rangedimensions = node.rangedimensions +nodes.end_of_math = node.end_of_math +nodes.flush = node.flush_node +nodes.flush_node = node.flush_node +nodes.flush_list = node.flush_list +nodes.free = node.free +nodes.insert_after = node.insert_after +nodes.insert_before = node.insert_before +nodes.hpack = node.hpack +nodes.new = node.new +nodes.tail = node.tail +nodes.traverse = node.traverse +nodes.traverse_id = node.traverse_id +nodes.traverse_char = node.traverse_char +nodes.slide = node.slide +nodes.vpack = node.vpack +nodes.fields = node.fields +nodes.is_node = node.is_node +nodes.setglue = node.setglue + +nodes.first_glyph = node.first_glyph +nodes.has_glyph = node.has_glyph or node.first_glyph + +nodes.current_attr = node.current_attr +nodes.has_field = node.has_field +nodes.last_node = node.last_node +nodes.usedlist = node.usedlist +nodes.protrusion_skippable = node.protrusion_skippable +nodes.check_discretionaries = node.check_discretionaries +nodes.write = node.write + +nodes.count = node.count +nodes.length = node.length + +nodes.has_attribute = node.has_attribute +nodes.set_attribute = node.set_attribute +nodes.find_attribute = node.find_attribute +nodes.unset_attribute = node.unset_attribute + +nodes.protect_glyphs = node.protect_glyphs +nodes.protect_glyph = node.protect_glyph +nodes.unprotect_glyphs = node.unprotect_glyphs +nodes.kerning = node.kerning +nodes.ligaturing = node.ligaturing +nodes.mlist_to_hlist = node.mlist_to_hlist + +if not node.getwhd then + local getfield = node.getfield + function node.getwhd(n) + return getfield(n,"width"), getfield(n,"height"), getfield(n,"depth") + end +end -nodes.has_attribute = node.has_attribute -nodes.set_attribute = node.set_attribute -nodes.unset_attribute = node.unset_attribute +if not node.setwhd then + local setfield = node.setfield + function node.setwhd(n,w,h,d) + setfield(n,"width",w or 0) + setfield(n,"height",h or 0) + setfield(n,"depth",d or 0) + end +end -nodes.protect_glyphs = node.protect_glyphs -nodes.protect_glyph = node.protect_glyph -nodes.unprotect_glyphs = node.unprotect_glyphs -nodes.kerning = node.kerning -nodes.ligaturing = node.ligaturing -nodes.mlist_to_hlist = node.mlist_to_hlist +nodes.getwhd = node.getwhd +nodes.setwhd = node.setwhd nodes.effective_glue = node.effective_glue - -nodes.is_zero_glue = node.is_zero_glue -nodes.getglue = node.getglue nodes.getglue = node.getglue +nodes.setglue = node.setglue +nodes.is_zero_glue = node.is_zero_glue -- if not gonuts or not node.getfield then -- node.getfield = metatable.__index @@ -149,68 +169,85 @@ local n_getattr = node.getattr local n_getdisc = node.getdisc local n_getleader = node.getleader -local n_setnext = node.setnext or - function(c,next) +local n_setnext = node.setnext or -- always + function(c,n) setfield(c,"next",n) end -local n_setprev = node.setprev or - function(c,prev) +local n_setprev = node.setprev or -- always + function(c,p) setfield(c,"prev",p) end -local n_setlink = node.setlink or - function(c1,c2) - if c1 then setfield(c1,"next",c2) end - if c2 then setfield(c2,"prev",c1) end +local n_setlist = node.setlist or -- always + function(c,l) + setfield(c,"list",l) end -local n_setboth = node.setboth or +local n_setlink = node.setlink or -- always +-- function(c1,c2) +-- if c1 then setfield(c1,"next",c2) end +-- if c2 then setfield(c2,"prev",c1) end +-- end + function(...) + -- not that fast but not used often anyway + local h = nil + for i=1,select("#",...) do + local n = (select(i,...)) + if not n then + -- go on + elseif h then + setfield(h,"next",n) + setfield(n,"prev",h) + else + h = n + end + end + return h + end +local n_setboth = node.setboth or -- always function(c,p,n) setfield(c,"prev",p) setfield(c,"next",n) end -node.setnext = n_setnext -node.setprev = n_setprev -node.setlink = n_setlink -node.setboth = n_setboth - -nodes.getfield = n_getfield -nodes.setfield = n_setfield -nodes.getattr = n_getattr -nodes.setattr = n_setattr - -nodes.getnext = n_getnext -nodes.getprev = n_getprev -nodes.getid = n_getid -nodes.getchar = n_getchar -nodes.getfont = n_getfont -nodes.getsubtype = n_getsubtype -nodes.getlist = n_getlist -nodes.getleader = n_getleader -nodes.getdisc = n_getdisc ------.getpre = node.getpre or function(n) local h, _, _, t = n_getdisc(n,true) return h, t end ------.getpost = node.getpost or function(n) local _, h, _, _, t = n_getdisc(n,true) return h, t end ------.getreplace = node.getreplace or function(n) local _, _, h, _, _, t = n_getdisc(n,true) return h, t end - -nodes.is_char = node.is_char -nodes.ischar = node.is_char - -nodes.is_glyph = node.is_glyph -nodes.isglyph = node.is_glyph - -nodes.getbox = node.getbox or tex.getbox -nodes.setbox = node.setbox or tex.setbox -nodes.getskip = node.getskip or tex.get - -local n_new_node = nodes.new -local n_free_node = nodes.free -local n_copy_node = nodes.copy -local n_copy_list = nodes.copy_list -local n_find_tail = nodes.tail -local n_insert_after = nodes.insert_after -local n_insert_before = nodes.insert_before -local n_slide = nodes.slide - -local n_remove_node = node.remove -- not yet nodes.remove +nodes.setnext = n_setnext +nodes.setprev = n_setprev +nodes.setlink = n_setlink +nodes.setboth = n_setboth +nodes.setlist = n_setlist + +nodes.getfield = n_getfield +nodes.setfield = n_setfield +nodes.getattr = n_getattr +nodes.setattr = n_setattr +nodes.takeattr = nodes.unset_attribute + +nodes.getnext = n_getnext +nodes.getprev = n_getprev +nodes.getid = n_getid +nodes.getchar = n_getchar +nodes.getfont = n_getfont +nodes.getsubtype = n_getsubtype +nodes.getlist = n_getlist +nodes.getleader = n_getleader +nodes.getdisc = n_getdisc + +nodes.is_char = node.is_char +nodes.ischar = node.is_char + +nodes.is_glyph = node.is_glyph +nodes.isglyph = node.is_glyph + +nodes.getbox = node.getbox or tex.getbox +nodes.setbox = node.setbox or tex.setbox + +local n_flush_node = nodes.flush +local n_copy_node = nodes.copy +local n_copy_list = nodes.copy_list +local n_find_tail = nodes.tail +local n_insert_after = nodes.insert_after +local n_insert_before = nodes.insert_before +local n_slide = nodes.slide + +local n_remove_node = node.remove -- not yet nodes.remove local function remove(head,current,free_too) local t = current @@ -218,7 +255,7 @@ local function remove(head,current,free_too) if not t then -- forget about it elseif free_too then - n_free_node(t) + n_flush_node(t) t = nil else n_setboth(t) @@ -255,34 +292,15 @@ function nodes.replace(head,current,new) -- no head returned if false if head == current then head = new end - n_free_node(current) + n_flush_node(current) return head, new else - n_free_node(current) + n_flush_node(current) return new end end -local function count(stack,flat) - local n = 0 - while stack do - local id = n_getid(stack) - if not flat and id == hlist_code or id == vlist_code then - local list = n_getlist(stack) - if list then - n = n + 1 + count(list) -- self counts too - else - n = n + 1 - end - else - n = n + 1 - end - stack = n_getnext(stack) - end - return n -end - -nodes.count = count +-- nodes.countall : see node-nut.lua function nodes.append(head,current,...) for i=1,select("#",...) do @@ -455,7 +473,7 @@ metatable.__sub = function(first,second) local tail = n_find_tail(first) for i=1,second do local prev = n_getprev(tail) - n_free_node(tail) -- can become flushlist/flushnode + n_flush_node(tail) -- can become flushlist/flushnode if prev then tail = prev else @@ -490,7 +508,7 @@ metatable.__add = function(first,second) local head = second for i=1,first do local second = n_getnext(head) - n_free_node(head) -- can become flushlist/flushnode + n_flush_node(head) -- can become flushlist/flushnode if second then head = second else @@ -614,7 +632,7 @@ local messyhack = table.tohash { -- temporary solution } table.setmetatableindex(keys,function(t,k) - local v = getfields(k) + local v = (k == "attributelist" or k == nodecodes.attributelist) and { } or getfields(k) if messyhack[k] then for i=1,#v do if v[i] == "subtype" then @@ -651,3 +669,39 @@ end nodes.keys = keys -- [id][subtype] nodes.fields = nodefields -- (n) + +-- temporary hack + +if LUATEXVERSION <= 1.002 then + + local get = tex.get + local flush = node.free + + function tex.get(name,split) + local s = get(name) + if split == true then + if s then + local width = s.width + local stretch = s.stretch + local shrink = s.shrink + local stretch_order = s.stretch_order + local shrink_order = s.shrink_order + flush(s) + return width, stretch, shrink, stretch_order, shrink_order + else + return 0, 0, 0, 0, 0 + end + elseif split == false then + if s then + local width = s.width + flush(s) + return width + else + return 0 + end + else + return s + end + end + +end diff --git a/tex/context/base/mkiv/node-mig.lua b/tex/context/base/mkiv/node-mig.lua index 24bebb0cc..b3820a7d8 100644 --- a/tex/context/base/mkiv/node-mig.lua +++ b/tex/context/base/mkiv/node-mig.lua @@ -16,7 +16,7 @@ local report_nodes = logs.reporter("nodes","migrations") local attributes = attributes local nodes = nodes -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction local nuts = nodes.nuts local tonut = nuts.tonut @@ -26,7 +26,6 @@ local getid = nuts.getid local getlist = nuts.getlist local getattr = nuts.getattr -local setfield = nuts.setfield local setattr = nuts.setattr local setlink = nuts.setlink local setlist = nuts.setlist @@ -139,21 +138,21 @@ end experiments.register("marks.migrate", function(v) if v then - tasks.enableaction("mvlbuilders", "nodes.handlers.migrate") + enableaction("mvlbuilders", "nodes.handlers.migrate") end migrate_marks = v end) experiments.register("inserts.migrate", function(v) if v then - tasks.enableaction("mvlbuilders", "nodes.handlers.migrate") + enableaction("mvlbuilders", "nodes.handlers.migrate") end migrate_inserts = v end) experiments.register("inserts.migrate.nested", function(v) if v then - tasks.enableaction("mvlbuilders", "nodes.handlers.migrate") + enableaction("mvlbuilders", "nodes.handlers.migrate") end inserts_too = v end) diff --git a/tex/context/base/mkiv/node-nut.lua b/tex/context/base/mkiv/node-nut.lua index 1465a6680..7e5c3438b 100644 --- a/tex/context/base/mkiv/node-nut.lua +++ b/tex/context/base/mkiv/node-nut.lua @@ -93,8 +93,6 @@ local direct = node.direct local fastcopy = table.fastcopy -local texget = tex.get - local nodecodes = nodes.nodecodes local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist @@ -119,16 +117,113 @@ nodes.tonut = tonut -- getters -nuts.getfield = direct.getfield -nuts.getnext = direct.getnext -nuts.getprev = direct.getprev -nuts.getid = direct.getid -nuts.getattr = direct.get_attribute or direct.has_attribute or direct.getfield -nuts.getchar = direct.getchar -nuts.getfont = direct.getfont -nuts.getsubtype = direct.getsubtype -nuts.getlist = direct.getlist -- only hlist and vlist ! -nuts.getleader = direct.getleader +if not direct.getwhd then + local getfield = direct.getfield + function direct.getwhd(n) + return getfield(n,"width"), getfield(n,"height"), getfield(n,"depth") + end +end + +if not direct.setwhd then + local setfield = direct.setfield + function direct.setwhd(n,w,h,d) + setfield(n,"width",w or 0) + setfield(n,"height",h or 0) + setfield(n,"depth",d or 0) + end +end + +if not direct.getcomponents then + + local getfield = direct.getfield + local setfield = direct.setfield + local setsubtype = direct.setsubtype + + local attributelist_code = nodecodes.attributelist + + function direct.getcomponents(n) return getfield(n,"components") end + function direct.setcomponents(n,c) setfield(n,"components",c) end + function direct.getkern(n) return getfield(n,"kern") end + function direct.getwidth(n) return getfield(n,"width") end + function direct.setwidth(n,w) return setfield(n,"width",w) end + function direct.getheight(n) return getfield(n,"height") end + function direct.setheight(n,h) return setfield(n,"height",h) end + function direct.getdepth(n) return getfield(n,"depth") end + function direct.setdepth(n,d) return setfield(n,"depth",d) end + function direct.getshift(n) return getfield(n,"shift") end + function direct.setshift(n,s) return setfield(n,"shift",s) end + function direct.getpenalty(n) return getfield(n,"penalty") end + function direct.setpenalty(n,p) setfield(n,"penalty",p) end + function direct.getdir(n) return getfield(n,"dir") end + function direct.setdir(n,p) setfield(n,"dir",p) end + function direct.getlanguage(n) return getfield(n,"lang") end + function direct.setlanguage(n,l) return setfield(n,"lang",l) end + function direct.getattributelist(n) getfield(n,"attr") end + + function direct.getnucleus(n) return getfield(n,"nucleus") end + function direct.setnucleus(n,p) return setfield(n,"nucleus",p) end + function direct.getsup(n) return getfield(n,"sup") end + function direct.setsup(n,p) return setfield(n,"sup",p) end + function direct.getsub(n) return getfield(n,"sub") end + function direct.setsub(n,p) return setfield(n,"sub",p) end + + function direct.setattributelist(n,a) + if a and type(a) ~= attributelist_code then + a = getfield(a,"attr") + end + setfield(n,"attr",a) + end + + function direct.setkern(n,k,s) + setfield(n,"kern",k) + if s then + setsubtype(n,s) + end + end + + function direct.setfont(n,f,c) + setfield(n,"font",f) + if c then + setfield(n,"char",f) + end + end + + function direct.getoffsets(n) + return getfield(n,"xoffset"), getfield(n,"yoffset") + end + + function direct.setoffsets(n,x,y) + if x then + setfield(n,"xoffset",x) + end + if y then + setfield(n,"yoffset",y) + end + end + +end + +if LUATEXVERSION < 1.005 then + local getfield = direct.getfield + function direct.getnucleus(n) return getfield(n,"nucleus") end + function direct.getsub (n) return getfield(n,"sub") end + function direct.getsup (n) return getfield(n,"sup") end +end + +-- if LUATEXVERSION < 1.004 then +-- local gc = direct.getcomponents +-- getcomponents = function(n) local c = gc(n) return c ~= 0 and c or nil end +-- end + +-- local hash = table.setmetatableindex("number") +-- local ga = direct.get_attribute +-- function direct.get_attribute(n,a) +-- hash[a] = hash[a] + 1 +-- return ga(n,a) +-- end +-- function nuts.reportattr() +-- inspect(hash) +-- end -- local function track(name) -- local n = 0 @@ -146,59 +241,58 @@ nuts.getleader = direct.getleader -- setters -nuts.setfield = direct.setfield -nuts.setattr = direct.set_attribute or setfield - -nuts.getbox = direct.getbox -nuts.setbox = direct.setbox -nuts.getskip = direct.getskip or function(s) return tonut(texget(s)) end - -- helpers -nuts.tostring = direct.tostring -nuts.copy = direct.copy -nuts.copy_list = direct.copy_list -nuts.delete = direct.delete -nuts.dimensions = direct.dimensions -nuts.end_of_math = direct.end_of_math -nuts.flush_list = direct.flush_list -nuts.flush_node = direct.flush_node -nuts.free = direct.free -nuts.insert_after = direct.insert_after -nuts.insert_before = direct.insert_before -nuts.hpack = direct.hpack -nuts.new = direct.new -nuts.tail = direct.tail -nuts.traverse = direct.traverse -nuts.traverse_id = direct.traverse_id -nuts.traverse_char = direct.traverse_char -nuts.slide = direct.slide -nuts.writable_spec = direct.writable_spec -nuts.vpack = direct.vpack -nuts.is_node = direct.is_node -nuts.is_direct = direct.is_direct -nuts.is_nut = direct.is_direct -nuts.first_glyph = direct.first_glyph -nuts.has_glyph = direct.has_glyph or direct.first_glyph - -nuts.current_attr = direct.current_attr -nuts.do_ligature_n = direct.do_ligature_n -nuts.has_field = direct.has_field -nuts.last_node = direct.last_node -nuts.usedlist = direct.usedlist -nuts.protrusion_skippable = direct.protrusion_skippable -nuts.write = direct.write - -nuts.has_attribute = direct.has_attribute -nuts.set_attribute = direct.set_attribute -nuts.unset_attribute = direct.unset_attribute - -nuts.protect_glyphs = direct.protect_glyphs -nuts.protect_glyph = direct.protect_glyph -nuts.unprotect_glyphs = direct.unprotect_glyphs -nuts.ligaturing = direct.ligaturing -nuts.kerning = direct.kerning -nuts.effective_glue = direct.effective_glue +nuts.tostring = direct.tostring +nuts.copy = direct.copy +nuts.copy_node = direct.copy +nuts.copy_list = direct.copy_list +nuts.delete = direct.delete +nuts.dimensions = direct.dimensions +nuts.rangedimensions = direct.rangedimensions +nuts.end_of_math = direct.end_of_math +nuts.flush = direct.flush_node +nuts.flush_node = direct.flush_node +nuts.flush_list = direct.flush_list +nuts.free = direct.free +nuts.insert_after = direct.insert_after +nuts.insert_before = direct.insert_before +nuts.hpack = direct.hpack +nuts.new = direct.new +nuts.tail = direct.tail +nuts.traverse = direct.traverse +nuts.traverse_id = direct.traverse_id +nuts.traverse_char = direct.traverse_char +nuts.slide = direct.slide +nuts.writable_spec = direct.writable_spec +nuts.vpack = direct.vpack +nuts.is_node = direct.is_node +nuts.is_direct = direct.is_direct +nuts.is_nut = direct.is_direct +nuts.first_glyph = direct.first_glyph +nuts.has_glyph = direct.has_glyph or direct.first_glyph +nuts.count = direct.count +nuts.length = direct.length +nuts.find_attribute = direct.find_attribute +nuts.unset_attribute = direct.unset_attribute + +nuts.current_attr = direct.current_attr +nuts.has_field = direct.has_field +nuts.last_node = direct.last_node +nuts.usedlist = direct.usedlist +nuts.protrusion_skippable = direct.protrusion_skippable +nuts.check_discretionaries = direct.check_discretionaries +nuts.write = direct.write + +nuts.has_attribute = direct.has_attribute +nuts.set_attribute = direct.set_attribute +nuts.unset_attribute = direct.unset_attribute + +nuts.protect_glyphs = direct.protect_glyphs +nuts.protect_glyph = direct.protect_glyph +nuts.unprotect_glyphs = direct.unprotect_glyphs +nuts.ligaturing = direct.ligaturing +nuts.kerning = direct.kerning if not direct.mlist_to_hlist then -- needed @@ -210,84 +304,115 @@ if not direct.mlist_to_hlist then -- needed end -local is_zero_glue = direct.is_zero_glue -local setglue = direct.setglue -local getglue = direct.getglue - -if not is_zero_glue then - is_zero_glue = function(n) - return not n or ( - getfield(n,"width") == 0 and - getfield(n,"stretch") == 0 and - getfield(n,"shrink") == 0 - ) - end - setglue = function(n,width,stretch,shrink,stretch_order,shrink_order) - setfield(n,"width", width or 0) - setfield(n,"stretch", stretch or 0) - setfield(n,"shrink", shrink or 0) - setfield(n,"stretch_order",stretch_order or 0) - setfield(n,"shrink_order", shrink_order or 0) - end - getglue = function(n) - return - getfield(n,"width"), getfield(n,"stretch"), getfield(n,"shrink"), - getfield(n,"stretch_order"), getfield(n,"shrink_order") - end -end - -nuts.is_zero_glue = is_zero_glue -nuts.setglue = setglue -nuts.getglue = getglue - - --- if not direct.getpre then --- --- local getfield = nuts.getfield --- --- function direct.getpre (n) local h, _, _, t = getdisc(n,true) return h, t end --- function direct.getpost (n) local _, h, _, _, t = getdisc(n,true) return h, t end --- function direct.getreplace(n) local _, _, h, _, _, t = getdisc(n,true) return h, t end --- --- end - -----.getpre = direct.getpre -----.getpost = direct.getpost -----.getreplace = direct.getreplace - -nuts.getdisc = direct.getdisc -nuts.setdisc = direct.setdisc -nuts.setchar = direct.setchar -nuts.setnext = direct.setnext -nuts.setprev = direct.setprev -nuts.setboth = direct.setboth -nuts.getboth = direct.getboth -nuts.setlink = direct.setlink -nuts.setlist = direct.setlist -nuts.setleader = direct.setleader -nuts.setsubtype = direct.setsubtype - -nuts.is_char = direct.is_char -nuts.ischar = direct.is_char -nuts.is_glyph = direct.is_glyph -nuts.isglyph = direct.is_glyph - -local d_remove_node = direct.remove -local d_free_node = direct.free -local d_getfield = direct.getfield -local d_setfield = direct.setfield -local d_getnext = direct.getnext -local d_getprev = direct.getprev -local d_getid = direct.getid -local d_getlist = direct.getlist -local d_find_tail = direct.tail -local d_insert_after = direct.insert_after -local d_insert_before = direct.insert_before -local d_slide = direct.slide ------ d_copy_node = direct.copy -local d_traverse = direct.traverse -local d_setlink = direct.setlink -local d_setboth = direct.setboth +nuts.getfield = direct.getfield +nuts.setfield = direct.setfield + +nuts.getnext = direct.getnext +nuts.setnext = direct.setnext + +nuts.getid = direct.getid + +nuts.getprev = direct.getprev +nuts.setprev = direct.setprev + +nuts.getattr = direct.get_attribute +nuts.setattr = direct.set_attribute +nuts.takeattr = direct.unset_attribute -- ? + +nuts.is_zero_glue = direct.is_zero_glue +nuts.effective_glue = direct.effective_glue + +nuts.getglue = direct.getglue +nuts.setglue = direct.setglue + +nuts.getdisc = direct.getdisc +nuts.setdisc = direct.setdisc +nuts.getdiscretionary = direct.getdisc +nuts.setdiscretionary = direct.setdisc + +nuts.getwhd = direct.getwhd +nuts.setwhd = direct.setwhd +nuts.getwidth = direct.getwidth +nuts.setwidth = direct.setwidth +nuts.getheight = direct.getheight +nuts.setheight = direct.setheight +nuts.getdepth = direct.getdepth +nuts.setdepth = direct.setdepth +nuts.getshift = direct.getshift +nuts.setshift = direct.setshift + +nuts.getnucleus = direct.getnucleus +nuts.setnucleus = direct.setnucleus +nuts.getsup = direct.getsup +nuts.setsup = direct.setsup +nuts.getsub = direct.getsub +nuts.setsub = direct.setsub + +nuts.getchar = direct.getchar +nuts.setchar = direct.setchar +nuts.getfont = direct.getfont +nuts.setfont = direct.setfont + +nuts.getboth = direct.getboth +nuts.setboth = direct.setboth +nuts.setlink = direct.setlink +nuts.setsplit = direct.setsplit + +nuts.getlist = direct.getlist -- only hlist and vlist ! +nuts.setlist = direct.setlist +nuts.getleader = direct.getleader +nuts.setleader = direct.setleader +nuts.getcomponents = direct.getcomponents +nuts.setcomponents = direct.setcomponents + +nuts.getsubtype = direct.getsubtype +nuts.setsubtype = direct.setsubtype + +nuts.getlang = direct.getlang +nuts.setlang = direct.setlang +nuts.getlanguage = direct.getlang +nuts.setlanguage = direct.setlang + +nuts.getattrlist = direct.getattributelist +nuts.setattrlist = direct.setattributelist +nuts.getattributelist = direct.getattributelist +nuts.setattributelist = direct.setattributelist + +nuts.getoffsets = direct.getoffsets +nuts.setoffsets = direct.setoffsets + +nuts.getkern = direct.getkern +nuts.setkern = direct.setkern + +nuts.getdir = direct.getdir +nuts.setdir = direct.setdir + +nuts.getpenalty = direct.getpenalty +nuts.setpenalty = direct.setpenalty + +nuts.getbox = direct.getbox +nuts.setbox = direct.setbox + +nuts.is_char = direct.is_char +nuts.ischar = direct.is_char +nuts.is_glyph = direct.is_glyph +nuts.isglyph = direct.is_glyph + +local d_remove_node = direct.remove +local d_flush_node = direct.flush_node +local d_getnext = direct.getnext +local d_getprev = direct.getprev +local d_getid = direct.getid +local d_getlist = direct.getlist +local d_find_tail = direct.tail +local d_insert_after = direct.insert_after +local d_insert_before = direct.insert_before +local d_slide = direct.slide +----- d_copy_node = direct.copy +local d_traverse = direct.traverse +local d_setlink = direct.setlink +local d_setboth = direct.setboth +local d_getboth = direct.getboth local function remove(head,current,free_too) local t = current @@ -295,7 +420,7 @@ local function remove(head,current,free_too) if not t then -- forget about it elseif free_too then - d_free_node(t) + d_flush_node(t) t = nil else d_setboth(t) -- (t,nil,nil) @@ -303,6 +428,11 @@ local function remove(head,current,free_too) return head, current, t end +-- alias + +nuts.getsurround = nuts.getkern +nuts.setsurround = nuts.setkern + -- bad: we can have prev's being glue_spec nuts.remove = remove @@ -316,32 +446,35 @@ function nuts.replace(head,current,new) -- no head returned if false head, current, new = false, head, current end local prev, next = d_getboth(current) - if next then - d_setlink(new,next) - end - if prev then - d_setlink(new,prev) +-- if next then +-- d_setlink(new,next) +-- end +-- if prev then +-- d_setlink(prev,new) +-- end + if prev or next then + d_setlink(prev,new,next) end if head then if head == current then head = new end - d_free_node(current) + d_flush_node(current) return head, new else - d_free_node(current) + d_flush_node(current) return new end end -local function count(stack,flat) +local function countall(stack,flat) local n = 0 while stack do local id = d_getid(stack) if not flat and id == hlist_code or id == vlist_code then local list = d_getlist(stack) if list then - n = n + 1 + count(list) -- self counts too + n = n + 1 + countall(list) -- self counts too else n = n + 1 end @@ -353,7 +486,11 @@ local function count(stack,flat) return n end -nuts.count = count +nuts.countall = countall + +function nodes.countall(stack,flat) + return countall(tonut(stack),flat) +end function nuts.append(head,current,...) for i=1,select("#",...) do @@ -369,7 +506,7 @@ function nuts.prepend(head,current,...) return head, current end -function nuts.linked(...) +function nuts.linked(...) -- slides ! local head, last for i=1,select("#",...) do local next = select(i,...) @@ -719,41 +856,10 @@ function nuts.copy_properties(source,target,what) return newprops -- for checking end --- a bit special - -local getwidth = { } -local setwidth = { } -local getdimensions = { } -local setdimensions = { } - -nodes.whatsitters = { - getters = { width = getwidth, dimensions = getdimensions }, - setters = { width = setwidth, dimensions = setdimensions }, -} - --- obsolete +-- here: --- local function get_width(n,dir) --- n = tonut(n) --- return getfield(n,"width") --- end --- --- local function get_dimensions(n,dir) --- n = tonut(n) --- return getfield(n,"width"), getfield(n,"height"), getfield(n,"depth") --- end --- --- local whatcodes = nodes.whatcodes --- local pdfrefximage_code = whatcodes.pdfrefximage --- local pdfrefxform_code = whatcodes.pdfrefxform --- --- if pdfrefxform_code then --- getwidth [pdfrefxform_code ] = get_width --- getdimensions[pdfrefxform_code ] = get_dimensions --- end --- --- if pdfrefximage_code then --- getwidth [pdfrefximage_code] = get_width --- getdimensions[pdfrefximage_code] = get_dimensions --- end +nodes.set_synctex_line = node.set_synctex_line +nodes.set_synctex_tag = node.set_synctex_tag +nuts.get_synctex_fields = direct.get_synctex_fields +nuts.set_synctex_fields = direct.set_synctex_fields diff --git a/tex/context/base/mkiv/node-ppt.lua b/tex/context/base/mkiv/node-ppt.lua index 2573e5f5c..5ebfca87d 100644 --- a/tex/context/base/mkiv/node-ppt.lua +++ b/tex/context/base/mkiv/node-ppt.lua @@ -27,10 +27,8 @@ local getnext = nuts.getnext local getprev = nuts.getprev local getsubtype = nuts.getsubtype local getfield = nuts.getfield -local setfield = nuts.setfield local getlist = nuts.getlist local setlist = nuts.setlist -local flushnode = nuts.flush local removenode = nuts.remove local traverse = nuts.traverse local traverse_id = nuts.traverse_id @@ -46,9 +44,6 @@ local userdefined_code = whatsitcodes.userdefined local nodepool = nodes.pool local new_usernumber = nodepool.usernumber -local nutpool = nuts.pool -local nut_usernumber = nutpool.usernumber - local variables = interfaces.variables local v_before = variables.before local v_after = variables.after @@ -89,14 +84,13 @@ local function register(where,data,...) end local writenode = node.write -local flushnode = context.flushnode +local flushnode = context.nodes.flush function commands.deferredproperty(...) -- context(register(...)) flushnode(register(...)) end - function commands.immediateproperty(...) writenode(register(...)) end @@ -107,8 +101,7 @@ local actions = { } properties.actions = actions table.setmetatableindex(actions,function(t,k) report("unknown property action %a",k) - local v = function() end - return v + return function() end end) local f_delayed = formatters["return function(target,head,where,propdata,parent) %s end"] @@ -180,6 +173,9 @@ end -- another experiment (a table or function closure are equally efficient); a function -- is easier when we want to experiment with different (compatible) implementations +-- local nutpool = nuts.pool +-- local nut_usernumber = nutpool.usernumber + -- function nodes.nuts.pool.deferredfunction(...) -- nofdelayed = nofdelayed + 1 -- local n = nut_usernumber(property_id,0) @@ -316,7 +312,7 @@ local anchored = { } table.setmetatableindex(anchored,function(t,k) - v = anchored[v_after] + local v = anchored[v_after] t[k] = v return v end) diff --git a/tex/context/base/mkiv/node-pro.lua b/tex/context/base/mkiv/node-pro.lua index 36670eed2..3251b0133 100644 --- a/tex/context/base/mkiv/node-pro.lua +++ b/tex/context/base/mkiv/node-pro.lua @@ -6,26 +6,17 @@ if not modules then modules = { } end modules ['node-pro'] = { license = "see context related readme files" } -local utfchar = utf.char -local format, concat = string.format, table.concat - local trace_callbacks = false trackers .register("nodes.callbacks", function(v) trace_callbacks = v end) local force_processors = false directives.register("nodes.processors.force", function(v) force_processors = v end) local report_nodes = logs.reporter("nodes","processors") -local nodes = nodes - -local nodecodes = nodes.nodecodes -local glyph_code = nodecodes.glyph -local tasks = nodes.tasks -local nuts = nodes.nuts +local nodes = nodes +local tasks = nodes.tasks +local nuts = nodes.nuts -local first_glyph = nodes.first_glyph -local has_glyph = nodes.has_glyph - -nodes.processors = nodes.processors or { } -local processors = nodes.processors +nodes.processors = nodes.processors or { } +local processors = nodes.processors -- vbox: grouptype: vbox vtop output split_off split_keep | box_type: exactly|aditional -- hbox: grouptype: hbox adjusted_hbox(=hbox_in_vmode) | box_type: exactly|aditional @@ -38,6 +29,9 @@ do local isglyph = nuts.isglyph local getnext = nuts.getnext + local utfchar = utf.char + local concat = table.concat + local n = 0 local function reconstruct(head) -- we probably have a better one @@ -75,125 +69,167 @@ local tracer = processors.tracer processors.enabled = true -- this will become a proper state (like trackers) -function processors.pre_linebreak_filter(head,groupcode) -- ,size,packtype,direction - -- local first, found = first_glyph(head) -- they really need to be glyphs - local found = force_processors or has_glyph(head) - if found then - if trace_callbacks then - local before = nodes.count(head,true) - local head, done = actions(head,groupcode) -- ,size,packtype,direction - local after = nodes.count(head,true) - if done then - tracer("pre_linebreak","changed",head,groupcode,before,after,true) +do + + local has_glyph = nodes.has_glyph + + function processors.pre_linebreak_filter(head,groupcode) -- ,size,packtype,direction + local found = force_processors or has_glyph(head) + if found then + if trace_callbacks then + local before = nodes.count(head,true) + local head, done = actions(head,groupcode) -- ,size,packtype,direction + local after = nodes.count(head,true) + if done then + tracer("pre_linebreak","changed",head,groupcode,before,after,true) + else + tracer("pre_linebreak","unchanged",head,groupcode,before,after,true) + end + return done and head or true else - tracer("pre_linebreak","unchanged",head,groupcode,before,after,true) + local head, done = actions(head,groupcode) -- ,size,packtype,direction + return done and head or true end - return done and head or true - else - local head, done = actions(head,groupcode) -- ,size,packtype,direction - return done and head or true + elseif trace_callbacks then + local n = nodes.count(head,false) + tracer("pre_linebreak","no chars",head,groupcode,n,n) end - elseif trace_callbacks then - local n = nodes.count(head,false) - tracer("pre_linebreak","no chars",head,groupcode,n,n) + return true end - return true -end -local function hpack_filter(head,groupcode,size,packtype,direction,attributes) - -- local first, found = first_glyph(head) -- they really need to be glyphs - local found = force_processors or has_glyph(head) - if found then - if trace_callbacks then - local before = nodes.count(head,true) - local head, done = actions(head,groupcode,size,packtype,direction,attributes) - local after = nodes.count(head,true) - if done then - tracer("hpack","changed",head,groupcode,before,after,true) + local function hpack_filter(head,groupcode,size,packtype,direction,attributes) + local found = force_processors or has_glyph(head) + if found then + if trace_callbacks then + local before = nodes.count(head,true) + local head, done = actions(head,groupcode,size,packtype,direction,attributes) + local after = nodes.count(head,true) + if done then + tracer("hpack","changed",head,groupcode,before,after,true) + else + tracer("hpack","unchanged",head,groupcode,before,after,true) + end + return done and head or true else - tracer("hpack","unchanged",head,groupcode,before,after,true) + local head, done = actions(head,groupcode,size,packtype,direction,attributes) + return done and head or true end - return done and head or true - else - local head, done = actions(head,groupcode,size,packtype,direction,attributes) - return done and head or true + elseif trace_callbacks then + local n = nodes.count(head,false) + tracer("hpack","no chars",head,groupcode,n,n) end - elseif trace_callbacks then - local n = nodes.count(head,false) - tracer("hpack","no chars",head,groupcode,n,n) + return true end - return true -end -processors.hpack_filter = hpack_filter + processors.hpack_filter = hpack_filter -do + do - local setfield = nodes.setfield - local hpack = nodes.hpack + local setfield = nodes.setfield + local hpack = nodes.hpack - function nodes.fullhpack(head,...) - local ok = hpack_filter(head) - if not done or done == true then - ok = head + function nodes.fullhpack(head,...) + local ok = hpack_filter(head) + if not done or done == true then + ok = head + end + local hp, b = hpack(ok,...) + setfield(hp,"prev",nil) + setfield(hp,"next",nil) + return hp, b end - local hp, b = hpack(ok,...) - setfield(hp,"prev",nil) - setfield(hp,"next",nil) - return hp, b + end + do + + local setboth = nuts.setboth + local hpack = nuts.hpack + + function nuts.fullhpack(head,...) + local ok = hpack_filter(tonode(head)) + if not done or done == true then + ok = head + else + ok = tonut(ok) + end + local hp, b = hpack(...) + setboth(hp) + return hp, b + end + + end + + callbacks.register('pre_linebreak_filter', processors.pre_linebreak_filter, "all kind of horizontal manipulations (before par break)") + callbacks.register('hpack_filter' , processors.hpack_filter, "all kind of horizontal manipulations (before hbox creation)") + end do - local setboth = nuts.setboth - local hpack = nuts.hpack + local actions = tasks.actions("finalizers") -- head, where + + -- beware, these are packaged boxes so no first_glyph test + -- maybe some day a hash with valid groupcodes + -- + -- beware, much can pass twice, for instance vadjust passes two times + -- + -- something weird here .. group mvl when making a vbox - function nuts.fullhpack(head,...) - local ok = hpack_filter(tonode(head)) - if not done or done == true then - ok = head + function processors.post_linebreak_filter(head,groupcode) + if trace_callbacks then + local before = nodes.count(head,true) + local head, done = actions(head,groupcode) + local after = nodes.count(head,true) + if done then + tracer("post_linebreak","changed",head,groupcode,before,after,true) + else + tracer("post_linebreak","unchanged",head,groupcode,before,after,true) + end + return done and head or true else - ok = tonut(ok) + local head, done = actions(head,groupcode) + return done and head or true end - local hp, b = hpack(...) - setboth(hp) - return hp, b end + callbacks.register('post_linebreak_filter', processors.post_linebreak_filter,"all kind of horizontal manipulations (after par break)") + end -callbacks.register('pre_linebreak_filter', processors.pre_linebreak_filter, "all kind of horizontal manipulations (before par break)") -callbacks.register('hpack_filter' , processors.hpack_filter, "all kind of horizontal manipulations (before hbox creation)") - -local actions = tasks.actions("finalizers") -- head, where - --- beware, these are packaged boxes so no first_glyph test --- maybe some day a hash with valid groupcodes --- --- beware, much can pass twice, for instance vadjust passes two times --- --- something weird here .. group mvl when making a vbox - -function processors.post_linebreak_filter(head,groupcode) - if trace_callbacks then - local before = nodes.count(head,true) - local head, done = actions(head,groupcode) - local after = nodes.count(head,true) - if done then - tracer("post_linebreak","changed",head,groupcode,before,after,true) - else - tracer("post_linebreak","unchanged",head,groupcode,before,after,true) +do + + local texnest = tex.nest + + local getlist = nodes.getlist + local setlist = nodes.setlist + local getsubtype = nodes.getsubtype + + local line_code = nodes.listcodes.line + + local actions = tasks.actions("contributers") + + function processors.contribute_filter(groupcode) + if groupcode == "box" then -- "pre_box" + local whatever = texnest[texnest.ptr] + if whatever then + local line = whatever.tail + if line and getsubtype(line) == line_code then + local head = getlist(line) + if head then + local okay, done = actions(head,groupcode,line) + if okay and okay ~= head then + setlist(line,okay) + end + end + end + end end - return done and head or true - else - local head, done = actions(head,groupcode) - return done and head or true end -end -callbacks.register('post_linebreak_filter', processors.post_linebreak_filter,"all kind of horizontal manipulations (after par break)") + callbacks.register('contribute_filter', processors.contribute_filter,"things done with lines") + +end statistics.register("h-node processing time", function() return statistics.elapsedseconds(nodes,"including kernel") -- hm, ok here? diff --git a/tex/context/base/mkiv/node-ref.lua b/tex/context/base/mkiv/node-ref.lua index 9f2d0918c..b313a00b6 100644 --- a/tex/context/base/mkiv/node-ref.lua +++ b/tex/context/base/mkiv/node-ref.lua @@ -20,82 +20,90 @@ local concat = table.concat local attributes, nodes, node = attributes, nodes, node -local allocate = utilities.storage.allocate, utilities.storage.mark -local mark = utilities.storage.allocate, utilities.storage.mark - -local nodeinjections = backends.nodeinjections -local codeinjections = backends.codeinjections - -local cleanupreferences = false -local cleanupdestinations = true - -local transparencies = attributes.transparencies -local colors = attributes.colors -local references = structures.references -local tasks = nodes.tasks - -local trace_references = false trackers.register("nodes.references", function(v) trace_references = v end) -local trace_destinations = false trackers.register("nodes.destinations", function(v) trace_destinations = v end) -local trace_areas = false trackers.register("nodes.areas", function(v) trace_areas = v end) -local show_references = false trackers.register("nodes.references.show", function(v) show_references = tonumber(v) or (v and 2.25 or false) end) -local show_destinations = false trackers.register("nodes.destinations.show", function(v) show_destinations = tonumber(v) or (v and 2.00 or false) end) - -local report_reference = logs.reporter("backend","references") -local report_destination = logs.reporter("backend","destinations") -local report_area = logs.reporter("backend","areas") - -local nuts = nodes.nuts -local nodepool = nuts.pool - -local tonode = nuts.tonode -local tonut = nuts.tonut - -local getfield = nuts.getfield -local setfield = nuts.setfield -local setlink = nuts.setlink -local setnext = nuts.setnext -local setprev = nuts.setprev -local getnext = nuts.getnext -local getprev = nuts.getprev -local getid = nuts.getid -local getlist = nuts.getlist -local setlist = nuts.setlist -local getattr = nuts.getattr -local setattr = nuts.setattr -local getsubtype = nuts.getsubtype - -local hpack_list = nuts.hpack -local vpack_list = nuts.vpack -local list_dimensions = nuts.dimensions -local traverse = nuts.traverse -local find_node_tail = nuts.tail - -local nodecodes = nodes.nodecodes -local skipcodes = nodes.skipcodes -local listcodes = nodes.listcodes - -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local glue_code = nodecodes.glue -local glyph_code = nodecodes.glyph -local rule_code = nodecodes.rule -local dir_code = nodecodes.dir -local localpar_code = nodecodes.localpar - -local leftskip_code = skipcodes.leftskip -local rightskip_code = skipcodes.rightskip -local parfillskip_code = skipcodes.parfillskip - -local line_code = listcodes.line - -local new_rule = nodepool.rule -local new_kern = nodepool.kern - -local free_node = nuts.free - -local tosequence = nodes.tosequence - -local implement = interfaces.implement +local allocate = utilities.storage.allocate, utilities.storage.mark +local mark = utilities.storage.allocate, utilities.storage.mark + +local nodeinjections = backends.nodeinjections +local codeinjections = backends.codeinjections + +local cleanupreferences = false +local cleanupdestinations = true + +local transparencies = attributes.transparencies +local colors = attributes.colors +local references = structures.references +local enableaction = nodes.tasks.enableaction + +local trace_references = false trackers.register("nodes.references", function(v) trace_references = v end) +local trace_destinations = false trackers.register("nodes.destinations", function(v) trace_destinations = v end) +local trace_areas = false trackers.register("nodes.areas", function(v) trace_areas = v end) +local show_references = false trackers.register("nodes.references.show", function(v) show_references = tonumber(v) or (v and 2.25 or false) end) +local show_destinations = false trackers.register("nodes.destinations.show", function(v) show_destinations = tonumber(v) or (v and 2.00 or false) end) + +local report_reference = logs.reporter("backend","references") +local report_destination = logs.reporter("backend","destinations") +local report_area = logs.reporter("backend","areas") + +local nuts = nodes.nuts +local nodepool = nuts.pool + +local tonode = nuts.tonode +local tonut = nuts.tonut + +local getfield = nuts.getfield +local setfield = nuts.setfield +local setlink = nuts.setlink +local setnext = nuts.setnext +local setprev = nuts.setprev +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getlist = nuts.getlist +local setlist = nuts.setlist +local getwidth = nuts.getwidth +local setwidth = nuts.setwidth +local getheight = nuts.getheight +local getattr = nuts.getattr +local setattr = nuts.setattr +local getsubtype = nuts.getsubtype +local getwhd = nuts.getwhd +local getdir = nuts.getdir +local setshift = nuts.setshift + +local hpack_list = nuts.hpack +local vpack_list = nuts.vpack +local list_dimensions = nuts.dimensions +local list_rangedimensions = nuts.rangedimensions +local traverse = nuts.traverse +local find_node_tail = nuts.tail + +local nodecodes = nodes.nodecodes +local skipcodes = nodes.skipcodes +local listcodes = nodes.listcodes + +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local glue_code = nodecodes.glue +local glyph_code = nodecodes.glyph +local rule_code = nodecodes.rule +local dir_code = nodecodes.dir +local localpar_code = nodecodes.localpar + +local leftskip_code = skipcodes.leftskip +local rightskip_code = skipcodes.rightskip +local parfillskip_code = skipcodes.parfillskip + +local line_code = listcodes.line + +local new_rule = nodepool.rule +local new_kern = nodepool.kern +local new_hlist = nodepool.hlist + +local flush_node = nuts.flush + +local tosequence = nodes.tosequence + +local implement = interfaces.implement -- Normally a (destination) area is a box or a simple stretch if nodes but when it is -- a paragraph we have a problem: we cannot calculate the height well. This happens @@ -104,7 +112,7 @@ local implement = interfaces.implement local function hlist_dimensions(start,stop,parent) local last = stop and getnext(stop) if parent then - return list_dimensions(getfield(parent,"glue_set"),getfield(parent,"glue_sign"),getfield(parent,"glue_order"),start,last) + return list_rangedimensions(parent,start,last) else return list_dimensions(start,last) end @@ -117,33 +125,30 @@ local function vlist_dimensions(start,stop) -- also needs the stretch and so setnext(stop,nil) end local v = vpack_list(start) - local w = getfield(v,"width") - local h = getfield(v,"height") - local d = getfield(v,"depth") + local w, h, d = getwhd(v) setlist(v) -- not needed - free_node(v) + flush_node(v) if temp then setnext(stop,temp) end return w, h, d end +-- not ok when vlist at mvl level + local function dimensions(parent,start,stop) -- in principle we could move some to the caller local id = getid(start) if start == stop then - if id == hlist_code or id == vlist_code or id == glyph_code or id == rule_code then + if id == hlist_code or id == vlist_code or id == rule_code or id == glyph_code then + local sw, sh, sd = getwhd(start) + local pw, ph, pd = getwhd(parent) + local ht = sh == 0 and ph or sh -- changed + local dp = sd == 0 and pd or sd -- changed if trace_areas then - report_area("dimensions taken of %a",nodecodes[id]) - end - -- hm, parent can be zero - local width = getfield(start,"width") - local height = getfield(parent,"height") - local depth = getfield(parent,"depth") - if height == 0 and depth == 0 then - height = getfield(start,"height") - depth = getfield(start,"depth") + report_area("dimensions taken of %a (%p,%p,%p) with parent (%p,%p,%p) -> (%p,%p,%p)", + nodecodes[id],sw,sh,sd,pw,ph,pd,sw,ht,dp) end - return width, height, depth + return sw, ht, dp else if trace_areas then report_area("dimensions calculated of %a",nodecodes[id]) @@ -174,7 +179,8 @@ local function dimensions(parent,start,stop) -- in principle we could move some if trace_areas then report_area("dimensions taken of first line in vlist") end - return getfield(c,"width"), getfield(c,"height"), getfield(c,"depth"), c + local w, h, d = getwhd(c) + return w, h, d, c else if trace_areas then report_area("dimensions taken of vlist (probably wrong)") @@ -211,7 +217,7 @@ local function dimensions(parent,start,stop) -- in principle we could move some report_area("dimensions taken of vlist") end local w, h, d = vlist_dimensions(first,last,parent) - local ht = getfield(first,"height") + local ht = getheight(first) return w, ht, d + h - ht, first else -- return hlist_dimensions(start,stop,parent) @@ -219,7 +225,8 @@ local function dimensions(parent,start,stop) -- in principle we could move some if trace_areas then report_area("dimensions taken of first line in vlist") end - return getfield(first,"width"), getfield(first,"height"), getfield(first,"depth"), first + local w, h, d = getwhd(first) + return w, h, d, first else if trace_areas then report_area("dimensions taken of vlist (probably wrong)") @@ -255,35 +262,40 @@ local function inject_range(head,first,last,reference,make,stack,parent,pardir,t -- special case, we only treat the first line in a vlist local l = getlist(line) if trace_areas then - report_area("%s: %i : %s %s %s => w=%p, h=%p, d=%p, c=%S","line", + report_area("%s: %i : %s %s %s => w=%p, h=%p, d=%p","line", reference,pardir or "---",txtdir or "---", - tosequence(l,nil,true),width,height,depth,resolved) + tosequence(l,nil,true),width,height,depth) end setlist(line,result) setlink(result,l) return head, last + elseif head == first then + if trace_areas then + report_area("%s: %i : %s %s %s => w=%p, h=%p, d=%p","head", + reference,pardir or "---",txtdir or "---", + tosequence(first,last,true),width,height,depth) + end + setlink(result,first) + return result, last else - if head == first then - if trace_areas then - report_area("%s: %i : %s %s %s => w=%p, h=%p, d=%p, c=%S","head", - reference,pardir or "---",txtdir or "---", - tosequence(first,last,true),width,height,depth,resolved) - end - setlink(result,first) - return result, last - else - if trace_areas then - report_area("%s: %i : %s %s %s => w=%p, h=%p, d=%p, c=%S","middle", - reference,pardir or "---",txtdir or "---", - tosequence(first,last,true),width,height,depth,resolved) - end - local prev = getprev(first) - if prev then - setlink(prev,result) - end - setlink(result,first) - return head, last + if trace_areas then + report_area("%s: %i : %s %s %s => w=%p, h=%p, d=%p","middle", + reference,pardir or "---",txtdir or "---", + tosequence(first,last,true),width,height,depth) end +if first == last and getid(parent) == vlist_code and getid(first) == hlist_code then + if trace_areas then + -- think of a button without \dontleavehmode in the mvl + report_area("compensating for link in vlist") + end + setlink(result,getlist(first)) + setlist(first,result) +else + -- setlink(getprev(first),result) + -- setlink(result,first) + setlink(getprev(first),result,first) +end + return head, last end else return head, last @@ -291,9 +303,7 @@ local function inject_range(head,first,last,reference,make,stack,parent,pardir,t end local function inject_list(id,current,reference,make,stack,pardir,txtdir) - local width = getfield(current,"width") - local height = getfield(current,"height") - local depth = getfield(current,"depth") + local width, height, depth = getwhd(current) local correction = 0 local moveright = false local first = getlist(current) @@ -341,12 +351,9 @@ local function inject_list(id,current,reference,make,stack,pardir,txtdir) setlist(current,result) elseif moveright then -- brr no prevs done -- result after first - local n = getnext(first) - setnext(result,n) - setlink(first,first) - if n then - setprev(n,result) - end + -- setlink(result,getnext(first)) + -- setlink(first,result) + setlink(first,result,getnext(first)) else -- first after result setlink(result,first) @@ -405,9 +412,9 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx done[r] = done[r] - 1 end elseif id == dir_code then - txtdir = getfield(current,"dir") + txtdir = getdir(current) elseif id == localpar_code then - pardir = getfield(current,"dir") + pardir = getdir(current) elseif id == glue_code and getsubtype(current) == leftskip_code then -- any glue at the left? -- else @@ -457,9 +464,9 @@ local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir) end end elseif id == dir_code then - txtdir = getfield(current,"dir") + txtdir = getdir(current) elseif id == localpar_code then - pardir = getfield(current,"dir") + pardir = getdir(current) else local r = getattr(current,attribute) if r and not done[r] then @@ -501,8 +508,8 @@ local function addstring(what,str,shift) --todo make a pluggable helper (in font end local text = typesetters.tohpack(str,infofont) local rule = new_rule(emwidth/5,4*exheight,3*exheight) - setfield(text,"shift",shift) - return hpack_list(nuts.linked(text,rule)) + setshift(text,shift) + return hpack_list(setlink(text,rule)) end end end @@ -540,42 +547,38 @@ local function colorize(width,height,depth,n,reference,what,sr,offset) setattr(rule,a_transparency,u_transparency) if width < 0 then local kern = new_kern(width) - setfield(rule,"width",-width) + setwidth(rule,-width) setnext(kern,rule) setprev(rule,kern) return kern - else - -if sr and sr ~= "" then - local text = addstring(what,sr,shift) - if text then - local kern = new_kern(-getfield(text,"width")) - setlink(kern,text) - setlink(text,rule) - return kern - end -end - - return rule + elseif sr and sr ~= "" then + local text = addstring(what,sr,shift) + if text then + local kern = new_kern(-getwidth(text)) + -- setlink(kern,text) + -- setlink(text,rule) + setlink(kern,text,rule) + return kern + end end + return rule end -local function justadd(what,sr,shift) +local function justadd(what,sr,shift,current) -- needs testing if sr and sr ~= "" then local text = addstring(what,sr,shift) if text then - local kern = new_kern(-getfield(text,"width")) - setlink(kern,text) - setlink(text,rule) - return kern + local kern = new_kern(-getwidth(text)) + setlink(kern,text,current) + return new_hlist(kern) end end end -- references: -local texsetattribute = tex.setattribute local texsetcount = tex.setcount +----- texsetattribute = tex.setattribute local stack = { } local done = { } @@ -624,7 +627,7 @@ local function makereference(width,height,depth,reference) -- height and depth a nofreferences = nofreferences + 1 local result, current, texts if show_references then - local d = sr[1] + local d = resolved if d then local r = d.reference local p = d.prefix @@ -641,15 +644,12 @@ local function makereference(width,height,depth,reference) -- height and depth a end if trace_references then local step = 65536 - result = hpack_list(colorize(width,height-step,depth-step,2,reference,"reference",texts,show_references)) -- step subtracted so that we can see seperate links - setfield(result,"width",0) + result = new_hlist(colorize(width,height-step,depth-step,2,reference,"reference",texts,show_references)) -- step subtracted so that we can see seperate links current = result elseif texts then - texts = justadd("reference",texts,show_references) + texts = justadd("reference",texts,show_references,current) if texts then - result = hpack_list(texts) - setfield(result,"width",0) - current = result + current = texts end end if current then @@ -658,10 +658,7 @@ local function makereference(width,height,depth,reference) -- height and depth a result = annot end references.registerpage(n) - result = hpack_list(result,0) - setfield(result,"width",0) - setfield(result,"height",0) - setfield(result,"depth",0) + result = new_hlist(result) if cleanupreferences then stack[reference] = nil end return result, resolved elseif trace_references then @@ -758,8 +755,7 @@ local function makedestination(width,height,depth,reference) step = 4*65536 width, height, depth = 5*step, 5*step, 0 end - local rule = hpack_list(colorize(width,height,depth,3,reference,"destination",texts,show_destinations)) - setfield(rule,"width",0) + local rule = new_hlist(colorize(width,height,depth,3,reference,"destination",texts,show_destinations)) if not result then result, current = rule, rule else @@ -768,13 +764,9 @@ local function makedestination(width,height,depth,reference) end width, height = width - step, height - step elseif texts then - texts = justadd("destination",texts,show_destinations) + texts = justadd("destination",texts,show_destinations,current) if texts then - result = hpack_list(texts) - if result then - setfield(result,"width",0) - current = result - end + current = texts end end nofdestinations = nofdestinations + 1 @@ -789,11 +781,7 @@ local function makedestination(width,height,depth,reference) current = find_node_tail(annot) end if result then - -- some internal error - result = hpack_list(result,0) - setfield(result,"width",0) - setfield(result,"height",0) - setfield(result,"depth",0) + result = new_hlist(result) end if cleanupdestinations then stack[reference] = nil end return result, resolved @@ -929,8 +917,8 @@ statistics.register("interactive elements", function() end) function references.enableinteraction() - tasks.enableaction("shipouts","nodes.references.handler") - tasks.enableaction("shipouts","nodes.destinations.handler") + enableaction("shipouts","nodes.references.handler") + enableaction("shipouts","nodes.destinations.handler") function references.enableinteraction() end end diff --git a/tex/context/base/mkiv/node-res.lua b/tex/context/base/mkiv/node-res.lua index bb09656fb..8b7ec1a62 100644 --- a/tex/context/base/mkiv/node-res.lua +++ b/tex/context/base/mkiv/node-res.lua @@ -72,17 +72,24 @@ local getbox = nuts.getbox local getfield = nuts.getfield local getid = nuts.getid local getlist = nuts.getlist +local getglue = nuts.getglue local setfield = nuts.setfield local setchar = nuts.setchar local setlist = nuts.setlist +local setwhd = nuts.setwhd +local setglue = nuts.setglue +local setdisc = nuts.setdisc +local setfont = nuts.setfont +local setkern = nuts.setkern +local setpenalty = nuts.setpenalty +local setdir = nuts.setdir +local setshift = nuts.setshift +local setwidth = nuts.setwidth local copy_nut = nuts.copy local new_nut = nuts.new -local free_nut = nuts.free - -local copy_node = nodes.copy -local new_node = nodes.new +local flush_nut = nuts.flush -- at some point we could have a dual set (the overhead of tonut is not much larger than -- metatable associations at the lua/c end esp if we also take assignments into account @@ -178,36 +185,26 @@ local wordboundary = register_nut(new_nut("boundary",boundarycodes.word)) -- the dir field needs to be set otherwise crash: -local rule = register_nut(new_nut("rule")) setfield(rule, "dir","TLT") -local emptyrule = register_nut(new_nut("rule",rulecodes.empty)) setfield(rule, "dir","TLT") -local userrule = register_nut(new_nut("rule",rulecodes.user)) setfield(rule, "dir","TLT") -local hlist = register_nut(new_nut("hlist")) setfield(hlist,"dir","TLT") -local vlist = register_nut(new_nut("vlist")) setfield(vlist,"dir","TLT") - -function nutpool.zeroglue(n) - if n then - return - getfield(n,"width") == 0 and - getfield(n,"stretch") == 0 and - getfield(n,"shrink") == 0 and - getfield(n,"stretch_order") == 0 and - getfield(n,"shrink_order") == 0 - else - return false - end -end +local rule = register_nut(new_nut("rule")) setdir(rule, "TLT") +local emptyrule = register_nut(new_nut("rule",rulecodes.empty)) setdir(rule, "TLT") +local userrule = register_nut(new_nut("rule",rulecodes.user)) setdir(rule, "TLT") +local hlist = register_nut(new_nut("hlist")) setdir(hlist,"TLT") +local vlist = register_nut(new_nut("vlist")) setdir(vlist,"TLT") function nutpool.glyph(fnt,chr) local n = copy_nut(glyph) - if fnt then setfield(n,"font",fnt) end - if chr then setchar(n,chr) end + if fnt then + setfont(n,fnt,chr) + elseif chr then + setchar(n,chr) + end return n end function nutpool.penalty(p) local n = copy_nut(penalty) if p and p ~= 0 then - setfield(n,"penalty",p) + setpenalty(n,p) end return n end @@ -215,7 +212,7 @@ end function nutpool.kern(k) local n = copy_nut(kern) if k and k ~= 0 then - setfield(n,"kern",k) + setkern(n,k) end return n end @@ -238,79 +235,54 @@ end function nutpool.fontkern(k) local n = copy_nut(fontkern) - setfield(n,"kern",k) + if k and k ~= 0 then + setkern(n,k) + end return n end function nutpool.italickern(k) local n = copy_nut(italickern) if k and k ~= 0 then - setfield(n,"kern",k) + setkern(n,k) end return n end function nutpool.gluespec(width,stretch,shrink,stretch_order,shrink_order) + -- maybe setglue local s = copy_nut(glue_spec) - if width and width ~= 0 then - setfield(s,"width",width) - end - if stretch and stretch ~= 0 then - setfield(s,"stretch",stretch) - end - if shrink and shrink ~= 0 then - setfield(s,"shrink",shrink) - end - if stretch_order and stretch_order ~= 0 then - setfield(s,"stretch_order",stretch_order) - end - if shrink_order and shrink_order ~= 0 then - setfield(s,"shrink_order",shrink_order) + if width or stretch or shrink or stretch_order or shrink_order then + setglue(s,width,stretch,shrink,stretch_order,shrink_order) end return s end local function someskip(skip,width,stretch,shrink,stretch_order,shrink_order) + -- maybe setglue local n = copy_nut(skip) - if width and width ~= 0 then - setfield(n,"width",width) - end - if stretch and stretch ~= 0 then - setfield(n,"stretch",stretch) - end - if shrink and shrink ~= 0 then - setfield(n,"shrink",shrink) - end - if stretch_order and stretch_order ~= 0 then - setfield(n,"stretch_order",stretch_order) - end - if shrink_order and shrink_order ~= 0 then - setfield(n,"shrink_order",shrink_order) + if width or stretch or shrink or stretch_order or shrink_order then + setglue(n,width,stretch,shrink,stretch_order,shrink_order) end return n end function nutpool.stretch(a,b) + -- width stretch shrink stretch_order shrink_order local n = copy_nut(glue) - if b then - setfield(n,"stretch",a) - setfield(n,"stretch_order",b) - else - setfield(n,"stretch",1) - setfield(n,"stretch_order",a or 1) + if not b then + a, b = 1, a or 1 end + setglue(n,0,a,0,b,0) return n end function nutpool.shrink(a,b) local n = copy_nut(glue) - if b then - setfield(n,"shrink",a) - setfield(n,"shrink_order",b) - else - setfield(n,"shrink",1) - setfield(n,"shrink_order",a or 1) + if not b then + a, b = 1, a or 1 end + setglue(n,0,0,a,0,0,b) return n end @@ -320,18 +292,8 @@ end function nutpool.negatedglue(glue) local n = copy_nut(glue) - local width = getfield(n,"width") - local stretch = getfield(n,"stretch") - local shrink = getfield(n,"shrink") - if width and width ~= 0 then - setfield(n,"width", -width) - end - if stretch and stretch ~= 0 then - setfield(n,"stretch",-stretch) - end - if shrink and shrink ~= 0 then - setfield(n,"shrink", -shrink) - end + local width, stretch, shrink = getglue(n) + setglue(n,-width,-stretch,-shrink) return n end @@ -351,63 +313,51 @@ function nutpool.baselineskip(width,stretch,shrink) return someskip(baselineskip,width,stretch,shrink) end -function nutpool.disc() - return copy_nut(disc) +function nutpool.disc(pre,post,replace) + local d = copy_nut(disc) + if pre or post or replace then + setdisc(d,pre,post,replace) + end + return d end function nutpool.textdir(dir) local t = copy_nut(textdir) - setfield(t,"dir",dir) + if dir then + setdir(t,dir) + end return t end function nutpool.rule(width,height,depth,dir) -- w/h/d == nil will let them adapt local n = copy_nut(rule) - if width then -- also 0 else adapt - setfield(n,"width",width) - end - if height then -- also 0 else adapt - setfield(n,"height",height) - end - if depth then -- also 0 else adapt - setfield(n,"depth",depth) + if width or height or depth then + setwhd(n,width,height,depth) end if dir then - setfield(n,"dir",dir) + setdir(n,dir) end return n end function nutpool.emptyrule(width,height,depth,dir) -- w/h/d == nil will let them adapt local n = copy_nut(emptyrule) - if width then -- also 0 else adapt - setfield(n,"width",width) - end - if height then -- also 0 else adapt - setfield(n,"height",height) - end - if depth then -- also 0 else adapt - setfield(n,"depth",depth) + if width or height or depth then + setwhd(n,width,height,depth) end if dir then - setfield(n,"dir",dir) + setdir(n,dir) end return n end function nutpool.userrule(width,height,depth,dir) -- w/h/d == nil will let them adapt local n = copy_nut(userrule) - if width then -- also 0 else adapt - setfield(n,"width",width) - end - if height then -- also 0 else adapt - setfield(n,"height",height) - end - if depth then -- also 0 else adapt - setfield(n,"depth",depth) + if width or height or depth then + setwhd(n,width,height,depth) end if dir then - setfield(n,"dir",dir) + setdir(n,dir) end return n end @@ -418,81 +368,7 @@ function nutpool.latelua(code) return n end -if context and _cldo_ then - - -- a typical case where we have more nodes than nuts - - local context = context - - local f_cldo = string.formatters["_cldo_(%i)"] - local register = context.registerfunction - - local latelua_node = register_node(new_node("whatsit",whatsitcodes.latelua)) - local latelua_nut = register_nut (new_nut ("whatsit",whatsitcodes.latelua)) - - local setfield_node = nodes.setfield - local setfield_nut = nuts .setfield - - -- function nodepool.lateluafunction(f) - -- local n = copy_node(latelua_node) - -- setfield_node(n,"string",f_cldo(register(f))) - -- return n - -- end - - -- function nutpool.lateluafunction(f) - -- local n = copy_nut(latelua_nut) - -- setfield_nut(n,"string",f_cldo(register(f))) - -- return n - -- end - - -- when function in latelua: - - function nodepool.lateluafunction(f) - local n = copy_node(latelua_node) - setfield_node(n,"string",f) - return n - end - - function nutpool.lateluafunction(f) - local n = copy_nut(latelua_nut) - setfield_nut(n,"string",f) - return n - end - - local latefunction = nodepool.lateluafunction - local flushnode = context.flushnode - - -- function context.lateluafunction(f) - -- flushnode(latefunction(f)) -- hm, quite some indirect calls - -- end - - -- when function in latelua: - - -- function context.lateluafunction(f) - -- local n = copy_node(latelua_node) - -- setfield_node(n,"string",f) - -- flushnode(n) - -- end - - -- local contextsprint = context.sprint - -- local ctxcatcodes = tex.ctxcatcodes - -- local storenode = context.storenode - - -- when 0.79 is out: - - -- function context.lateluafunction(f) - -- contextsprint(ctxcatcodes,"\\cldl",storenode(latefunction(f))," ") - -- end - - -- when function in latelua: - - function context.lateluafunction(f) - local n = copy_node(latelua_node) - setfield_node(n,"string",f) - contextsprint(ctxcatcodes,"\\cldl",storenode(n)," ") - end - -end +nutpool.lateluafunction = nutpool.latelua function nutpool.leftmarginkern(glyph,width) local n = copy_nut(left_margin_kern) @@ -504,7 +380,7 @@ function nutpool.leftmarginkern(glyph,width) setfield(n,"glyph",glyph) end if width and width ~= 0 then - setfield(n,"width",width) + setwidth(n,width) end return n end @@ -519,7 +395,7 @@ function nutpool.rightmarginkern(glyph,width) setfield(n,"glyph",glyph) end if width and width ~= 0 then - setfield(n,"width",width) + setwidth(n,width) end return n end @@ -532,46 +408,45 @@ function nutpool.noad() return copy_nut(noad) end -function nutpool.hlist(list,width,height,depth,shift) +local function new_hlist(list,width,height,depth,shift) local n = copy_nut(hlist) if list then setlist(n,list) end - if width and width ~= 0 then - setfield(n,"width",width) - end - if height and height ~= 0 then - setfield(n,"height",height) - end - if depth and depth ~= 0 then - setfield(n,"depth",depth) + if width or height or depth then + setwhd(n,width,height,depth) end if shift and shift ~= 0 then - setfield(n,"shift",shift) + setshift(n,shift) end return n end -function nutpool.vlist(list,width,height,depth,shift) +local function new_vlist(list,width,height,depth,shift) local n = copy_nut(vlist) if list then setlist(n,list) end - if width and width ~= 0 then - setfield(n,"width",width) - end - if height and height ~= 0 then - setfield(n,"height",height) - end - if depth and depth ~= 0 then - setfield(n,"depth",depth) + if width or height or depth then + setwhd(n,width,height,depth) end if shift and shift ~= 0 then - setfield(n,"shift",shift) + setshift(n,shift) end return n end +nutpool.hlist = new_hlist +nutpool.vlist = new_vlist + +function nodepool.hlist(list,width,height,depth,shift) + return tonode(new_hlist(list and tonut(list),width,height,depth,shift)) +end + +function nodepool.vlist(list,width,height,depth,shift) + return tonode(new_vlist(list and tonut(list),width,height,depth,shift)) +end + -- local num = userids["my id"] -- local str = userids[num] @@ -657,13 +532,13 @@ local function cleanup(nofboxes) -- todo local nr = nofreserved for i=1,nofreserved do local ri = reserved[i] - free_nut(reserved[i]) + flush_nut(reserved[i]) end if nofboxes then for i=0,nofboxes do local l = getbox(i) if l then - free_nut(l) -- also list ? + flush_nut(l) -- also list ? nl = nl + 1 end end diff --git a/tex/context/base/mkiv/node-rul.lua b/tex/context/base/mkiv/node-rul.lua index 63991813e..4ec651d3b 100644 --- a/tex/context/base/mkiv/node-rul.lua +++ b/tex/context/base/mkiv/node-rul.lua @@ -11,263 +11,113 @@ if not modules then modules = { } end modules ['node-rul'] = { -- -- todo: make robust for layers ... order matters -local attributes, nodes, node = attributes, nodes, node - -local nuts = nodes.nuts -local tonode = nuts.tonode -local tonut = nuts.tonut - -local getfield = nuts.getfield -local setfield = nuts.setfield -local setnext = nuts.setnext -local setprev = nuts.setprev -local setlink = nuts.setlink -local getnext = nuts.getnext -local getprev = nuts.getprev -local getid = nuts.getid -local getattr = nuts.getattr -local setattr = nuts.setattr -local getfont = nuts.getfont -local getsubtype = nuts.getsubtype -local getlist = nuts.getlist -local setlist = nuts.setlist - -local nodecodes = nodes.nodecodes -local tasks = nodes.tasks - -local properties = nodes.properties -local attribs = node.current_attr - -local glyph_code = nodecodes.glyph -local disc_code = nodecodes.disc -local rule_code = nodecodes.rule -local boundary_code = nodecodes.boundary -local dir_code = nodecodes.dir - -function nodes.striprange(first,last) -- todo: dir - if first and last then -- just to be sure - if first == last then - return first, last - end - while first and first ~= last do - local id = getid(first) - if id == glyph_code or id == disc_code or id == dir_code or id == boundary_code then -- or id == rule_code - break - else - first = getnext(first) - end - end - if not first then - return nil, nil - elseif first == last then - return first, last - end - while last and last ~= first do - local id = getid(last) - if id == glyph_code or id == disc_code or id == dir_code or id == boundary_code then -- or id == rule_code - break - else - local prev = getprev(last) -- luatex < 0.70 has italic correction kern not prev'd - if prev then - last = prev - else - break - end - end - end - if not last then - return nil, nil - end - end - return first, last -end - --- todo: order and maybe other dimensions - -local floor = math.floor - -local trace_ruled = false trackers.register("nodes.rules", function(v) trace_ruled = v end) -local report_ruled = logs.reporter("nodes","rules") - -local n_tostring = nodes.idstostring -local n_tosequence = nodes.tosequence - -local a_ruled = attributes.private('ruled') -local a_color = attributes.private('color') -local a_transparency = attributes.private('transparency') -local a_colorspace = attributes.private('colormodel') - -local insert_node_before = nuts.insert_before +-- todo: collect successive bit and pieces and combine them +-- +-- path s ; s := shaped(p) ; % p[] has rectangles +-- fill s withcolor .5white ; +-- draw boundingbox s withcolor yellow; + +local attributes = attributes +local nodes = nodes +local properties = nodes.properties + +local enableaction = nodes.tasks.enableaction + +local nuts = nodes.nuts +local tonode = nuts.tonode +local tonut = nuts.tonut + +local getfield = nuts.getfield +local setfield = nuts.setfield +local setnext = nuts.setnext +local setprev = nuts.setprev +local setlink = nuts.setlink +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getattr = nuts.getattr +local setattr = nuts.setattr +local getfont = nuts.getfont +local getsubtype = nuts.getsubtype +local getlist = nuts.getlist +local setwhd = nuts.setwhd +local setdir = nuts.setdir +local setattrlist = nuts.setattrlist +local setshift = nuts.setshift +local getwidth = nuts.getwidth +local setwidth = nuts.setwidth + +local flushlist = nuts.flush_list +local effective_glue = nuts.effective_glue local insert_node_after = nuts.insert_after -local list_dimensions = nuts.dimensions +local insert_node_before = nuts.insert_before +local find_tail = nuts.tail +local setglue = nuts.setglue +local traverse_id = nuts.traverse_id +local list_dimensions = nuts.rangedimensions local hpack_nodes = nuts.hpack - -local striprange = nodes.striprange - -local fontdata = fonts.hashes.identifiers -local variables = interfaces.variables -local dimenfactor = fonts.helpers.dimenfactor -local splitdimen = number.splitdimen - -local v_yes = variables.yes -local v_all = variables.all -local v_foreground = variables.foreground +local current_attr = nuts.current_attr local nodecodes = nodes.nodecodes -local skipcodes = nodes.skipcodes +local rulecodes = nodes.rulecodes +local gluecodes = nodes.gluecodes +local listcodes = nodes.listcodes local kerncodes = nodes.kerncodes local glyph_code = nodecodes.glyph -local disc_code = nodecodes.disc +local localpar_code = nodecodes.localpar +local dir_code = nodecodes.dir local glue_code = nodecodes.glue -local penalty_code = nodecodes.penalty -local kern_code = nodecodes.kern local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local rule_code = nodecodes.rule -local boundary_code = nodecodes.boundary -local dir_code = nodecodes.dir -local userskip_code = skipcodes.userskip -local spaceskip_code = skipcodes.spaceskip -local xspaceskip_code = skipcodes.xspaceskip -local leader_code = skipcodes.leaders +local indent_code = listcodes.indent +local line_code = listcodes.line -local kerning_code = kerncodes.kern +local leftskip_code = gluecodes.leftskip +local rightskip_code = gluecodes.rightskip +local parfillskip_code = gluecodes.parfillskip local nodepool = nuts.pool local new_rule = nodepool.rule local new_userrule = nodepool.userrule local new_kern = nodepool.kern -local new_glue = nodepool.glue --- we can use this one elsewhere too --- --- todo: functions: word, sentence --- --- glyph rule unset whatsit glue margin_kern kern math disc +local n_tostring = nodes.idstostring +local n_tosequence = nodes.tosequence -local checkdir = true +local variables = interfaces.variables +local implement = interfaces.implement + +local privateattributes = attributes.private + +local a_ruled = privateattributes('ruled') +local a_runningtext = privateattributes('runningtext') +local a_color = privateattributes('color') +local a_transparency = privateattributes('transparency') +local a_colormodel = privateattributes('colormodel') +local a_linefiller = privateattributes("linefiller") +local a_viewerlayer = privateattributes("viewerlayer") + +local v_both = variables.both +local v_left = variables.left +local v_right = variables.right +local v_local = variables["local"] +local v_yes = variables.yes +local v_foreground = variables.foreground --- we assume {glyphruns} and no funny extra kerning, ok, maybe we need --- a dummy character as start and end; anyway we only collect glyphs --- --- 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 analyze - --- todo: switching inside math - --- handlers - -local function processwords(attribute,data,flush,head,parent) -- we have hlistdir and local dir - local n = head - if n then - local f, l, a, d, i, class - local continue, leaders, done, strip, level = false, false, false, true, -1 - while n do - local id = getid(n) - if id == glyph_code or id == rule_code then - local aa = getattr(n,attribute) - if aa then - if aa == a then - if not f then -- ? - f = n - end - 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 - 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, class = newlevel, newclass - d = data[class] - local c = d.continue - leaders = c == v_all - continue = leaders or c == v_yes - end - else - if f then - head, done = flush(head,f,l,d,level,parent,strip), true - end - f, l, a = nil, nil, nil - end - elseif id == disc_code or id == boundary_code then - if f then - l = n - end - elseif id == kern_code and getsubtype(n) == kerning_code then - if f then - l = n - end - elseif id == hlist_code or id == vlist_code then - if f then - head, done = flush(head,f,l,d,level,parent,strip), true - f, l, a = nil, nil, nil - end - local list = getlist(n) - if list then - setlist(n,(processwords(attribute,data,flush,list,n))) -- watch () - end --- elseif checkdir and id == dir_code then -- only changes in dir, we assume proper boundaries --- if f and a then --- l = n --- end - elseif id == dir_code then -- only changes in dir, we assume proper boundaries - if f then - l = n - end - elseif f then - if continue then - if id == penalty_code then - l = n - -- elseif id == kern_code then - -- l = n - elseif id == glue_code then - -- catch \underbar{a} \underbar{a} (subtype test is needed) - local subtype = getsubtype(n) - if getattr(n,attribute) and (subtype == userskip_code or subtype == spaceskip_code or subtype == xspaceskip_code or (leaders and subtype >= leader_code)) 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 - f, l, a = nil, nil, nil - end - end - n = getnext(n) - end - if f then - head, done = flush(head,f,l,d,level,parent,strip), true - end - return head, true -- todo: done - else - return head, false - end -end +local fonthashes = fonts.hashes +local fontdata = fonthashes.identifiers +local fontresources = fonthashes.resources --- nodes.processwords = processwords +local dimenfactor = fonts.helpers.dimenfactor +local splitdimen = number.splitdimen +local setmetatableindex = table.setmetatableindex -nodes.processwords = function(attribute,data,flush,head,parent) -- we have hlistdir and local dir - head = tonut(head) - if parent then - parent = tonut(parent) - end - local head, done = processwords(attribute,data,flush,head,parent) - return tonode(head), done -end +-- + +local striprange = nodes.striprange +local processwords = nodes.processwords -- @@ -286,7 +136,7 @@ local function userrule(t,noattributes) if noattributes == false or noattributes == nil then -- avoid fuzzy ones else - setfield(r,"attr",attribs()) + setattrlist(r,current_attr()) end properties[r] = t return tonode(r) @@ -296,8 +146,31 @@ rules.userrule = userrule local ruleactions = { } rules.ruleactions = ruleactions -callback.register("process_rule",function(n,h,v) - local n = tonut(n) +local function mathradical(n,h,v) + ----- size = getfield(n,"index") + local font = getfield(n,"transform") + local actions = fontresources[font].mathruleactions + if actions then + local action = actions.radicalaction + if action then + action(n,h,v,font) + end + end +end + +local function mathrule(n,h,v) + ----- size = getfield(n,"index") + local font = getfield(n,"transform") + local actions = fontresources[font].mathruleactions + if actions then + local action = actions.hruleaction + if action then + action(n,h,v,font) + end + end +end + +local function useraction(n,h,v) local p = properties[n] if p then local i = p.type or "draw" @@ -306,19 +179,48 @@ callback.register("process_rule",function(n,h,v) a(p,h,v,i,n) end end -end) +end + +local subtypeactions = { + [rulecodes.user] = useraction, + [rulecodes.over] = mathrule, + [rulecodes.under] = mathrule, + [rulecodes.fraction] = mathrule, + [rulecodes.radical] = mathradical, +} + +callbacks.register( + "process_rule", + function(n,h,v) + local n = tonut(n) + local s = getsubtype(n) + local a = subtypeactions[s] + if a then + a(n,h,v) + end + end, + "handle additional user rule features" +) -- +local trace_ruled = false trackers.register("nodes.rules", function(v) trace_ruled = v end) +local report_ruled = logs.reporter("nodes","rules") + function rules.define(settings) data[#data+1] = settings context(#data) end -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 - if getid(f) ~= glyph_code then + local font = nil + local id = getid(f) + if id == glyph_code then + font = getfont(f) + elseif id == hlist_code then + font = getattr(f,a_runningtext) + end + if not font then -- saveguard ... we need to deal with rules and so (math) return head end @@ -336,8 +238,9 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a if not f then return head end - local w, ht, dp = list_dimensions(getfield(parent,"glue_set"),getfield(parent,"glue_sign"),getfield(parent,"glue_order"),f,getnext(l)) + local w, ht, dp = list_dimensions(parent,f,getnext(l)) local method = d.method + local empty = d.empty == v_yes local offset = d.offset local continue = d.continue local dy = d.dy @@ -349,19 +252,19 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a local ma = d.ma local ca = d.ca local ta = d.ta - local colorspace = ma > 0 and ma or getattr(f,a_colorspace) or 1 + local colorspace = ma > 0 and ma or getattr(f,a_colormodel) or 1 local color = ca > 0 and ca or getattr(f,a_color) local transparency = ta > 0 and ta or getattr(f,a_transparency) local foreground = order == v_foreground local layer = getattr(f,a_viewerlayer) - local e = dimenfactor(unit,getfont(f)) -- what if no glyph node + local e = dimenfactor(unit,font) -- what if no glyph node local rt = tonumber(rulethickness) if rt then rulethickness = e * rulethickness / 2 else local n, u = splitdimen(rulethickness) if n and u then -- we need to intercept ex and em and % and ... - rulethickness = n * dimenfactor(u,fontdata[getfont(f)]) / 2 + rulethickness = n * dimenfactor(u,fontdata[font]) / 2 else rulethickness = 1/5 end @@ -381,21 +284,28 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a if layer then setattr(r,a_viewerlayer,layer) end - local k = new_kern(-w) - if foreground then - insert_node_after(head,l,k) - insert_node_after(head,k,r) - l = r - else + if empty then head = insert_node_before(head,f,r) - insert_node_after(head,r,k) + setlink(r,getnext(l)) + setprev(f) + setnext(l) + flushlist(f) + else + local k = new_kern(-w) + if foreground then + insert_node_after(head,l,k) + insert_node_after(head,k,r) + l = r + else + head = insert_node_before(head,f,r) + insert_node_after(head,r,k) + end end if trace_ruled then report_ruled("level %a, width %p, height %p, depth %p, nodes %a, text %a", level,w,ht,dp,n_tostring(f,l),n_tosequence(f,l,true)) end end - if mp and mp ~= "" then local r = userrule { width = w, @@ -417,7 +327,7 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a local dp = -(offset+(i-1)*dy)*e + rulethickness + m local r = new_rule(w,ht,dp) if color then - setattr(r,a_colorspace,colorspace) + setattr(r,a_colormodel,colorspace) setattr(r,a_color,color) end if transparency then @@ -431,17 +341,14 @@ end local process = nodes.processwords -rules.handler = function(head) return process(a_ruled,data,flush_ruled,head) end +rules.handler = function(head) + return process(a_ruled,data,flush_ruled,head) +end function rules.enable() - tasks.enableaction("shipouts","nodes.rules.handler") + enableaction("shipouts","nodes.rules.handler") end --- elsewhere: --- --- tasks.appendaction ("shipouts", "normalizers", "nodes.rules.handler") --- tasks.disableaction("shipouts", "nodes.rules.handler") -- only kick in when used - local trace_shifted = false trackers.register("nodes.shifting", function(v) trace_shifted = v end) local report_shifted = logs.reporter("nodes","shifting") @@ -468,8 +375,8 @@ local function flush_shifted(head,first,last,data,level,parent,strip) -- not tha local next = getnext(last) setprev(first) setnext(last) - local width, height, depth = list_dimensions(getfield(parent,"glue_set"),getfield(parent,"glue_sign"),getfield(parent,"glue_order"),first,next) - local list = hpack_nodes(first,width,"exactly") + local width, height, depth = list_dimensions(parent,first,next) + local list = hpack_nodes(first,width,"exactly") -- we can use a simple pack if first == head then head = list end @@ -480,9 +387,8 @@ local function flush_shifted(head,first,last,data,level,parent,strip) -- not tha setlink(list,next) end local raise = data.dy * dimenfactor(data.unit,fontdata[getfont(first)]) - setfield(list,"shift",raise) - setfield(list,"height",height) - setfield(list,"depth",depth) + setshift(list,raise) + setwhd(list,width,height,depth) if trace_shifted then report_shifted("width %p, nodes %a, text %a",width,n_tostring(first,last),n_tosequence(first,last,true)) end @@ -494,21 +400,204 @@ local process = nodes.processwords nodes.shifts.handler = function(head) return process(a_shifted,data,flush_shifted,head) end function nodes.shifts.enable() - tasks.enableaction("shipouts","nodes.shifts.handler") + enableaction("shipouts","nodes.shifts.handler") end --- linefillers (placeholder) +-- linefillers nodes.linefillers = nodes.linefillers or { } nodes.linefillers.data = nodes.linefillers.data or { } +storage.register("nodes/linefillers/data", nodes.linefillers.data, "nodes.linefillers.data") + +local data = nodes.linefillers.data + +function nodes.linefillers.define(settings) + data[#data+1] = settings + context(#data) +end + +local function linefiller(current,data,width,location) + local height = data.height + local depth = data.depth + local mp = data.mp + local ma = data.ma + local ca = data.ca + local ta = data.ta + if mp and mp ~= "" then + return tonut(userrule { + width = width, + height = height, + depth = depth, + type = "mp", + line = data.rulethickness, + data = mp, + ma = ma, + ca = ca, + ta = ta, + option = location, + direction = getdir(current), + }) + else + local linefiller = new_rule(width,height,depth) + if ca then + setattr(linefiller,a_colorspace,ma) + setattr(linefiller,a_color,ca) + end + if ta then + setattr(linefiller,a_transparency,ta) + end + return linefiller + end +end + +local function find_attr(head,attr) + while head do + local a = head[attr] + if a then + return a, head + end + head = getnext(head) + end +end + function nodes.linefillers.handler(head) - return head, false +-- local current = tonut(head) -- when we hook into the contributers + for current in traverse_id(hlist_code,tonut(head)) do + if getsubtype(current) == line_code then + local list = getlist(current) + if list then + -- why doesn't leftskip take the attributes + -- or list[linefiller] or maybe first match (maybe we need a fast helper for that) + local a = getattr(current,a_linefiller) + if a then + local class = a % 1000 + local data = data[class] + if data then + local location = data.location + local scope = data.scope + local distance = data.distance + local threshold = data.threshold + local leftlocal = false + local rightlocal = false + -- + if scope == v_right then + leftlocal = true + elseif scope == v_left then + rightlocal = true + elseif scope == v_local then + leftlocal = true + rightlocal = true + end + -- + if location == v_left or location == v_both then + local lskip = nil -- leftskip + local iskip = nil -- indentation + local head = list + while head do + local id = getid(head) + if id == glue_code then + if getsubtype(head) == leftskip_code then + lskip = head + else + break + end + elseif id == localpar_code or id == dir_code then + -- go on + elseif id == hlist_code then + if getsubtype(head) == indent_code then + iskip = head + end + break + else + break + end + head = getnext(head) + end + if head then + local indentation = iskip and getwidth(iskip) or 0 + local leftfixed = lskip and getwidth(lskip) or 0 + local lefttotal = lskip and effective_glue(lskip,current) or 0 + local width = lefttotal - (leftlocal and leftfixed or 0) + indentation - distance + if width > threshold then + if iskip then + setwidth(iskip,0) + end + if lskip then + setglue(lskip,leftlocal and getwidth(lskip) or nil) + if distance > 0 then + insert_node_after(list,lskip,new_kern(distance)) + end + insert_node_after(list,lskip,linefiller(current,data,width,"left")) + else + insert_node_before(list,head,linefiller(current,data,width,"left")) + if distance > 0 then + insert_node_before(list,head,new_kern(distance)) + end + end + end + end + end + -- + if location == v_right or location == v_both then + local pskip = nil -- parfillskip + local rskip = nil -- rightskip + local tail = find_tail(list) + while tail and getid(tail) == glue_code do + local subtype = getsubtype(tail) + if subtype == rightskip_code then + rskip = tail + elseif subtype == parfillskip_code then + pskip = tail + else + break + end + tail = getprev(tail) + end + if tail then + local rightfixed = rskip and getwidth(rskip) or 0 + local righttotal = rskip and effective_glue(rskip,current) or 0 + local parfixed = pskip and getwidth(pskip) or 0 + local partotal = pskip and effective_glue(pskip,current) or 0 + local width = righttotal - (rightlocal and rightfixed or 0) + partotal - distance + if width > threshold then + if pskip then + setglue(pskip) + end + if rskip then + setglue(rskip,rightlocal and getwidth(rskip) or nil) + if distance > 0 then + insert_node_before(list,rskip,new_kern(distance)) + end + insert_node_before(list,rskip,linefiller(current,data,width,"right")) + else + insert_node_after(list,tail,linefiller(current,data,width,"right")) + if distance > 0 then + insert_node_after(list,tail,new_kern(distance)) + end + end + end + end + end + end + end + end + end + end + return head end --- interface +local enable = false + +function nodes.linefillers.enable() + if not enable then + -- we could now nil it + enableaction("finalizers","nodes.linefillers.handler") + enable = true + end +end -local implement = interfaces.implement +-- interface implement { name = "definerule", @@ -520,13 +609,14 @@ implement { { "order" }, { "method", "integer" }, { "offset", "number" }, - { "rulethickness", "string" }, + { "rulethickness" }, { "dy", "number" }, { "max", "number" }, { "ma", "integer" }, { "ca", "integer" }, { "ta", "integer" }, - { "mp", "string" }, + { "mp" }, + { "empty" }, } } } @@ -555,3 +645,30 @@ implement { onlyonce = true, actions = nodes.shifts.enable } + +implement { + name = "definelinefiller", + actions = { nodes.linefillers.define, context }, + arguments = { + { + { "method", "integer" }, + { "location", "string" }, + { "scope", "string" }, + { "mp", "string" }, + { "ma", "integer" }, + { "ca", "integer" }, + { "ta", "integer" }, + { "depth", "dimension" }, + { "height", "dimension" }, + { "distance", "dimension" }, + { "threshold", "dimension" }, + { "rulethickness", "dimension" }, + } + } +} + +implement { + name = "enablelinefillers", + onlyonce = true, + actions = nodes.linefillers.enable +} diff --git a/tex/context/base/mkiv/node-rul.mkiv b/tex/context/base/mkiv/node-rul.mkiv index 130ac9671..bfdd17d30 100644 --- a/tex/context/base/mkiv/node-rul.mkiv +++ b/tex/context/base/mkiv/node-rul.mkiv @@ -97,13 +97,13 @@ \appendtoks \ifcsname\??barindex\currentbar\endcsname - \lastnamedcs + \lastnamedcs\zerocount \else \expandafter\newcount\csname\??barindex\currentbar\endcsname \fi -% \normalexpanded{\t_node_rules_checklist{\node_rules_redefine{\currentbar}\the\t_node_rules_checklist}}% - \normalexpanded{\t_node_rules_checklist{\the\t_node_rules_checklist\node_rules_redefine{\currentbar}}}% -% \etoksapp\t_node_rules_checklist{\node_rules_redefine{\currentbar}}% + % \normalexpanded{\t_node_rules_checklist{\node_rules_redefine{\currentbar}\the\t_node_rules_checklist}}% + \normalexpanded{\t_node_rules_checklist{\the\t_node_rules_checklist\relax\node_rules_redefine{\currentbar}}}% + % \etoksapp\t_node_rules_checklist{\node_rules_redefine{\currentbar}}% \node_rules_define \setuevalue\currentbar{\node_rules_direct{\currentbar}}% \to \everydefinebar @@ -124,13 +124,16 @@ ta \thetransparencyattribute\p_node_rules_color offset \barparameter\c!offset\space % number dy \barparameter\c!dy\space % number + empty {\barparameter\c!empty}% \relax}} \unexpanded\def\node_rules_redefine#1% {\def\currentbar{#1}\node_rules_define} \unexpanded\def\node_rules_direct#1% - {\groupedcommand{\node_rules_set{#1}}\relax} + {\groupedcommand + {\node_rules_set{#1}\barparameter\c!left}% + {\relax\barparameter\c!right}} \unexpanded\def\node_rules_set#1% maybe reverse the 1000 (also maybe use more attributes instead of settings) {\edef\currentbar{#1}% @@ -146,13 +149,23 @@ +\csname\??barattribute#1\ifcsname\??bar#1:\number\c_node_rules_index\s!parent\endcsname:\number\c_node_rules_index\fi\endcsname \relax} +\unexpanded\def\resetbar + {\attribute\ruledattribute\attributeunsetvalue} + +\unexpanded\def\nobar + {\groupedcommand + {\resetbar\barparameter\c!left}% + {\relax\barparameter\c!right}} + \unexpanded\def\startbar[#1]% {\begingroup \node_rules_set{#1}% - \ignorespaces} + \ignorespaces + \barparameter\c!left} \unexpanded\def\stopbar {\removeunwantedspaces + \barparameter\c!right \endgroup} \unexpanded\def\setbar[#1]% @@ -176,6 +189,7 @@ \setupbars [\c!method=0, % new: 0=center nested, 1=stack nested \c!continue=\v!no, + \c!empty=, % new: yes = hide text \c!offset=0, % upwards, replaces: topoffset bottomoffset \c!dy=0, \c!max=3, @@ -211,6 +225,14 @@ \definebar[\v!overstrikes] [\v!overstrike] [\c!continue=\v!no] \definebar[\v!understrikes][\v!understrike][\c!continue=\v!no] +\definebar + [\v!hiddenbar] + [\v!underbar] + [\c!continue=\v!yes, + \c!empty=\v!yes, + \c!left=\zwj, + \c!right=\zwj] + % \setupbar[\v!overstrike][continue=all] % we want these always so ... @@ -335,7 +357,7 @@ \else \expandafter\newcount\csname\??shiftindex\currentshift\endcsname \fi - \normalexpanded{\t_node_shifts_checklist{\node_shifts_redefine{\currentshift}\the\t_node_shifts_checklist}}% + \normalexpanded{\t_node_shifts_checklist{\the\t_node_shifts_checklist\node_shifts_redefine{\currentshift}}}% order ? \node_shifts_define \setuevalue\currentshift{\node_shifts_direct{\currentshift}}% \to \everydefineshift @@ -420,4 +442,122 @@ {\begingroup\dostartisolation\begingroup#1} {#2\endgroup\dostopisolation\endgroup}} +%D More rules. + +% The following code rocks and was written with the Toto Live in Poland bluray +% in loop mode on my 5.1 surround development setup (the Toto lineup with Simon +% Phillips on drums). The Amsterdam concert is equally energizing. + +\installcorenamespace{linefiller} +\installcorenamespace{linefillerindex} +\installcorenamespace{linefillerattribute} + +\installcommandhandler \??linefiller {linefiller} \??linefiller + +\definesystemattribute[linefiller][public] + +\newtoks\t_node_linefiller_checklist + +\let\c_node_linefiller_index\relax % temporary synonym + +\let\setuplinefillers\setuplinefiller + +\appendtoks + \ifsecondargument + \node_linefiller_define + \else + \the\t_node_linefiller_checklist + \fi +\to \everysetuplinefiller + +\appendtoks + \ifcsname\??linefillerindex\currentlinefiller\endcsname + \lastnamedcs\zerocount + \else + \expandafter\newcount\csname\??linefillerindex\currentlinefiller\endcsname + \fi + \etoksapp\t_node_linefiller_checklist{\t_node_linefiller_checklist\node_linefiller_redefine{\currentlinefiller}}% + \node_linefiller_define +\to \everydefinelinefiller + +\unexpanded\def\node_linefiller_define + {\edef\p_node_rules_color{\linefillerparameter\c!color}% + \setevalue{\??linefillerattribute\currentlinefiller}{\number + \clf_definelinefiller + %method \linefillerparameter\c!method + location {\linefillerparameter\c!location}% + scope {\linefillerparameter\c!scope}% + mp {\includeMPgraphic{\linefillerparameter\c!mp}}% + ma \thecolormodelattribute + ca \thecolorattribute\p_node_rules_color + ta \thetransparencyattribute\p_node_rules_color + height \dimexpr\linefillerparameter\c!height\relax + depth \dimexpr\linefillerparameter\c!depth\relax + distance \dimexpr\linefillerparameter\c!distance\relax + threshold \dimexpr\linefillerparameter\c!threshold\relax + rulethickness \dimexpr\linefillerparameter\c!rulethickness\relax + \relax}} + +\unexpanded\def\node_linefiller_redefine#1% + {\def\currentlinefiller{#1}\node_linefiller_define} + +\unexpanded\def\node_linefiller_set#1% todo: check parent ! todo: move attr etc to lua + {\def\currentlinefiller{#1}% + \expandafter\let\expandafter\c_node_linefiller_index\csname\??linefillerindex#1\endcsname + \advance\c_node_linefiller_index\plusone + \clf_enablelinefillers + \attribute\linefillerattribute\numexpr + \plusthousand*\c_node_linefiller_index + +\csname\??linefillerattribute#1\ifcsname\??linefiller#1:\number\c_node_linefiller_index\s!parent\endcsname:\number\c_node_linefiller_index\fi\endcsname + \relax} + +\unexpanded\def\startlinefiller + {\dodoubleempty\node_linefiller_start} + +\unexpanded\def\node_linefiller_start[#1][#2]% + {\begingroup + \par + \def\currentlinefiller{#1}% + \ifsecondargument + % we need to update settings + \setuplinefiller[#1][#2]% no \setupcurrentlinefiller as we need to update settings + \fi + \node_linefiller_set{#1}% + \linefillerparameter\c!before + \usealignparameter\linefillerparameter + \uselinefillerstyleandcolor\c!textstyle\c!textcolor} % bars have foregroundcolor + +\unexpanded\def\stoplinefiller + {\par + \linefillerparameter\c!after + \endgroup} + +\unexpanded\def\setlinefiller[#1]% + {\node_linefiller_set{#1}} + +\setuplinefillers + [%c!method=0, + %c!mp=, + \c!location=\v!both, + \c!scope=\v!local, + \c!distance=\zeropoint, + \c!threshold=\zeropoint, + \c!rulethickness=\linewidth, + \c!height=\linewidth, + \c!depth=\zeropoint, + %\c!textcolor=, + %\c!textstyle=, + %\c!align=, + %\c!before=, + %\c!after=, + \c!color=] + +\definelinefiller + [filler] + [\c!height=.75\exheight, + %\c!mp=rules:filler:demo, + %\c!threshold=.25\emwidth, + \c!distance=.25\emwidth, + \c!rulethickness=.25\exheight] + \protect \endinput diff --git a/tex/context/base/mkiv/node-scn.lua b/tex/context/base/mkiv/node-scn.lua new file mode 100644 index 000000000..67a0badec --- /dev/null +++ b/tex/context/base/mkiv/node-scn.lua @@ -0,0 +1,330 @@ +if not modules then modules = { } end modules ['node-scn'] = { + 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 floor = math.floor + +local attributes = attributes +local nodes = nodes + +local nuts = nodes.nuts +local tonode = nuts.tonode +local tonut = nuts.tonut + +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getattr = nuts.getattr +local getsubtype = nuts.getsubtype +local getlist = nuts.getlist +local setlist = nuts.setlist + +local end_of_math = nuts.end_of_math + +local nodecodes = nodes.nodecodes +local rulecodes = nodes.rulecodes +local gluecodes = nodes.gluecodes +local listcodes = nodes.listcodes +local kerncodes = nodes.kerncodes + +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc +local rule_code = nodecodes.rule +local boundary_code = nodecodes.boundary +local dir_code = nodecodes.dir +local math_code = nodecodes.math +local glue_code = nodecodes.glue +local penalty_code = nodecodes.penalty +local kern_code = nodecodes.kern +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist + +local userskip_code = gluecodes.userskip +local spaceskip_code = gluecodes.spaceskip +local xspaceskip_code = gluecodes.xspaceskip +local leader_code = gluecodes.leaders + +local kerning_code = kerncodes.kern + +local variables = interfaces.variables + +local privateattributes = attributes.private + +local a_runningtext = privateattributes('runningtext') +local a_fontkern = privateattributes('fontkern') + +local v_yes = variables.yes +local v_all = variables.all + +local function striprange(first,last) -- todo: dir + if first and last then -- just to be sure + if first == last then + return first, last + end + while first and first ~= last do + local id = getid(first) + if id == glyph_code or id == disc_code or id == dir_code or id == boundary_code then -- or id == rule_code + break + else + first = getnext(first) + end + end + if not first then + return nil, nil + elseif first == last then + return first, last + end + while last and last ~= first do + local id = getid(last) + if id == glyph_code or id == disc_code or id == dir_code or id == boundary_code then -- or id == rule_code + break + else + local prev = getprev(last) -- luatex < 0.70 has italic correction kern not prev'd + if prev then + last = prev + else + break + end + end + end + if not last then + return nil, nil + end + end + return first, last +end + +nodes.striprange = striprange + +-- todo: order and maybe other dimensions + +-- we can use this one elsewhere too +-- +-- todo: functions: word, sentence +-- +-- glyph rule unset whatsit glue margin_kern kern math disc + +-- we assume {glyphruns} and no funny extra kerning, ok, maybe we need +-- a dummy character as start and end; anyway we only collect glyphs +-- +-- 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 analyze + +-- todo: switching inside math + +-- handlers + +local function processwords(attribute,data,flush,head,parent,skip) -- we have hlistdir and local dir + local n = head + if n then + local f, l, a, d, i, class + local continue, leaders, done, strip, level = false, false, false, true, -1 + while n do + local id = getid(n) + if id == glyph_code or id == rule_code or (id == hlist_code and getattr(n,a_runningtext) == 1) then + local aa = getattr(n,attribute) + if aa and aa ~= skip then + if aa == a then + if not f then -- ? + f = n + end + l = n + else + -- possible extensions: when in same class then keep spanning + local newlevel, newclass = floor(aa/1000), aa%1000 -- will be configurable + -- strip = not continue or level == 1 -- 0 + if f then + 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, class = newlevel, newclass + d = data[class] + if d then + local c = d.continue + leaders = c == v_all + continue = leaders or c == v_yes + else + continue = true + end + end + else + if f then + head, done = flush(head,f,l,d,level,parent,strip), true + end + f, l, a = nil, nil, nil + end + if id == hlist_code then + local list = getlist(n) + if list then + setlist(n,(processwords(attribute,data,flush,list,n,aa))) -- watch () + end + end + elseif id == disc_code or id == boundary_code then + if f then + l = n + end + elseif id == kern_code and (getsubtype(n) == kerning_code or getattr(n,a_fontkern)) then + if f then + l = n + end + elseif id == math_code then + -- otherwise not consistent: a $b$ c vs a $b+c$ d etc + -- we need a special (optional) go over math variant + if f then + head, done = flush(head,f,l,d,level,parent,strip), true + f, l, a = nil, nil, nil + end + elseif id == hlist_code or id == vlist_code then + if f then + head, done = flush(head,f,l,d,level,parent,strip), true + f, l, a = nil, nil, nil + end + local list = getlist(n) + if list then + setlist(n,(processwords(attribute,data,flush,list,n,skip))) -- watch () + end + elseif id == dir_code then -- only changes in dir, we assume proper boundaries + if f then + l = n + end + elseif f then + if continue then + if id == penalty_code then + l = n + -- elseif id == kern_code then + -- l = n + elseif id == glue_code then + -- catch \underbar{a} \underbar{a} (subtype test is needed) + local subtype = getsubtype(n) + if getattr(n,attribute) and (subtype == userskip_code or subtype == spaceskip_code or subtype == xspaceskip_code or (leaders and subtype >= leader_code)) 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 + f, l, a = nil, nil, nil + end + end + n = getnext(n) + end + if f then + head, done = flush(head,f,l,d,level,parent,strip), true + end + return head, true -- todo: done + else + return head, false + end +end + +nodes.processwords = function(attribute,data,flush,head,parent) -- we have hlistdir and local dir + head = tonut(head) + if parent then + parent = tonut(parent) + end + local head, done = processwords(attribute,data,flush,head,parent) + return tonode(head), done +end + +-- works on lines ! + +-- todo: stack because skip can change when nested + +local function processranges(attribute,flush,head,parent,depth,skip) + local n = head + if n then + local f, l, a + local done = false + while n do + local id = getid(n) + if id == glyph_code or id == rule_code then + local aa = getattr(n,attribute) +-- if aa and (not skip or aa ~= skip) then + if aa then + if aa == a then + if not f then + f = n + end + l = n + else + if f then + head, done = flush(head,f,l,a,parent,depth), true + end + f, l, a = n, n, aa + end + else + if f then + head, done = flush(head,f,l,a,parent,depth), true + end + f, l, a = nil, nil, nil + end + elseif id == disc_code or id == boundary_code then + if f then + l = n + else + -- weird + end + elseif id == kern_code and (getsubtype(n) == kerning_code or getattr(n,a_fontkern)) then + if f then + l = n + end + -- elseif id == penalty_code then + elseif id == glue_code then + -- todo: leaders + elseif id == hlist_code or id == vlist_code then + local aa = getattr(n,attribute) +-- if aa and (not skip or aa ~= skip) then + if aa then + if aa == a then + if not f then + f = n + end + l = n + else + if f then + head, done = flush(head,f,l,a,parent,depth), true + end + f, l, a = n, n, aa + end + else + if f then + head, done = flush(head,f,l,a,parent,depth), true + end + f, l, a = nil, nil, nil + end + local list = getlist(n) + if list then + setlist(n,(processranges(attribute,flush,list,n,depth+1,aa))) + end + end + n = getnext(n) + end + if f then + head, done = flush(head,f,l,a,parent,depth), true + end + return head, done + else + return head, false + end +end + +nodes.processranges = function(attribute,flush,head,parent) -- we have hlistdir and local dir + head = tonut(head) + if parent then + parent = tonut(parent) + end + local head, done = processranges(attribute,flush,head,parent,0) + return tonode(head), done +end diff --git a/tex/context/base/mkiv/node-ser.lua b/tex/context/base/mkiv/node-ser.lua index 2ad1242c5..f1be21f84 100644 --- a/tex/context/base/mkiv/node-ser.lua +++ b/tex/context/base/mkiv/node-ser.lua @@ -10,7 +10,7 @@ if not modules then modules = { } end modules ['node-ser'] = { -- of luatex; this is pretty old code that needs an overhaul local type = type -local concat, tohash, sortedkeys, printtable = table.concat, table.tohash, table.sortedkeys, table.print +local concat, tohash, sortedkeys, printtable, serialize = table.concat, table.tohash, table.sortedkeys, table.print, table.serialize local formatters, format, rep = string.formatters, string.format, string.rep local allocate = utilities.storage.allocate @@ -38,14 +38,16 @@ local f_char = formatters["%U"] ----- f_char = utilities.strings.chkuni -- formatters["%!chkuni!"] +-- this needs checking with the latest state of affairs: + local expand = allocate ( tohash { -- text: "list", -- list_ptr & ins_ptr & adjust_ptr "pre", -- "post", -- + "replace", -- nobreak "top_skip", -- "attr", -- - "replace", -- nobreak "components", -- lig_ptr "box_left", -- "box_right", -- @@ -85,15 +87,15 @@ local ignore = allocate ( tohash { local dimension = allocate ( tohash { "width", "height", "depth", "shift", "stretch", "shrink", - "xoffset", "yoffset", + "xoffset", "yoffset", "xadvance", "surround", "kern", "box_left_width", "box_right_width" } ) --- flat: don't use next, but indexes --- verbose: also add type --- can be sped up +-- flat : don't use next, but indexes +-- verbose : also add type +-- todo : speed up nodes.dimensionfields = dimension nodes.listablefields = expand @@ -103,7 +105,7 @@ nodes.ignorablefields = ignore local function astable(n,sparse) -- not yet ok, might get obsolete anyway n = tonode(n) - local f, t = getfields(n), { } + local f = getfields(n) for i=1,#f do local v = f[i] local d = n[v] @@ -111,7 +113,7 @@ local function astable(n,sparse) -- not yet ok, might get obsolete anyway if ignore[v] or v == "id" then -- skip elseif expand[v] then -- or: type(n[v]) ~= "string" or type(n[v]) ~= "number" or type(n[v]) ~= "table" - t[v] = "pointer to list" + t[v] = "<list>" elseif sparse then if (type(d) == "number" and d ~= 0) or (type(d) == "string" and d ~= "") then t[v] = d @@ -133,7 +135,7 @@ setinspector("node",function(v) if is_node(v) then printtable(astable(v),tostrin local function totable(n,flat,verbose,noattributes) -- nicest: n,true,true,true local function to_table(n,flat,verbose,noattributes) -- no need to pass - local f = getfields(n) + local f = getfields(n) local tt = { } for k=1,#f do local v = f[k] @@ -143,6 +145,8 @@ local function totable(n,flat,verbose,noattributes) -- nicest: n,true,true,true -- skip elseif noattributes and v == "attr" then -- skip + elseif v == "prev" then + tt[v] = "<node>" elseif expand[v] then if type(nv) == "number" or type(nv) == "string" then tt[v] = nv @@ -213,102 +217,16 @@ local function key(k) return ((type(k) == "number") and "["..k.."]") or k end --- not ok yet; this will become a module - --- todo: adapt to nodecodes etc .. use formatters - -local function serialize(root,name,handle,depth,m,noattributes) - handle = handle or print - if depth then - depth = depth .. " " - handle(format("%s%s={",depth,key(name))) - else - depth = "" - local tname = type(name) - if tname == "string" then - if name == "return" then - handle("return {") - else - handle(name .. "={") - end - elseif tname == "number" then - handle("[" .. name .. "]={") - else - handle("t={") - end - end - if root then - local fld - if root.id then - fld = getfields(root) -- we can cache these (todo) - else - fld = sortedkeys(root) - end - if type(root) == 'table' and root['type'] then -- userdata or table - handle(format("%s type=%q,",depth,root['type'])) - end - for f=1,#fld do - local k = fld[f] - if k == "ref_count" then - -- skip - elseif noattributes and k == "attr" then - -- skip - elseif k == "id" then - local v = root[k] - handle(format("%s id=%s,",depth,nodecodes[v] or noadcodes[v] or v)) - elseif k then - local v = root[k] - local t = type(v) - if t == "number" then - if v == 0 then - -- skip - else - handle(format("%s %s=%s,",depth,key(k),v)) - end - elseif t == "string" then - if v == "" then - -- skip - else - handle(format("%s %s=%q,",depth,key(k),v)) - end - elseif t == "boolean" then - handle(format("%s %s=%q,",depth,key(k),tostring(v))) - elseif v then -- userdata or table - serialize(v,k,handle,depth,m+1,noattributes) - end - end - end - if root['next'] then -- userdata or table - serialize(root['next'],'next',handle,depth,m+1,noattributes) - end - end - if m and m > 0 then - handle(format("%s},",depth)) - else - handle(format("%s}",depth)) - end +function nodes.serialize(root,flat,verbose,noattributes,name) + return serialize(totable(tonode(root),flat,verbose,noattributes),name) end -function nodes.serialize(root,name,noattributes) - local t, n = { }, 0 - local function flush(s) - n = n + 1 - t[n] = s - end - serialize(tonode(root),name,flush,nil,0,noattributes) - return concat(t,"\n") +function nodes.serializebox(n,flat,verbose,noattributes,name) + return serialize(totable(tex.box[n],flat,verbose,noattributes),name) end -function nodes.serializebox(n,flat,verbose,name) - return nodes.serialize(nodes.totable(tex.box[n],flat,verbose),name) -end - -function nodes.visualizebox(...) -- to be checked .. will move to module anyway - context.starttyping() - context.pushcatcodes("verbatim") - context(nodes.serializebox(...)) - context.stoptyping() - context.popcatcodes() +function nodes.visualizebox(n,flat,verbose,noattributes,name) + context.tocontext(totable(tex.box[n],flat,verbose,noattributes),name) end function nodes.list(head,n) -- name might change to nodes.type -- to be checked .. will move to module anyway @@ -340,3 +258,40 @@ function nodes.print(head,n) head = head.next end end + +-- quick hack, nicer is to have a proper expand per node type +-- already prepared + +local function apply(n,action) + while n do + action(n) + local id = n.id + if id == hlist_code or id == vlist_code then + apply(n.list,action) + end + n = n.next + end +end + +nodes.apply = apply + +local nuts = nodes.nuts +local getid = nuts.getid +local getlist = nuts.getlist +local getnext = nuts.getnext + +local function apply(n,action) + while n do + action(n) + local id = getid(n) + if id == hlist_code or id == vlist_code then + local list = getlist(n,action) + if list then + apply(list,action) + end + end + n = getnext(n) + end +end + +nuts.apply = apply diff --git a/tex/context/base/mkiv/node-shp.lua b/tex/context/base/mkiv/node-shp.lua index 2f2af4905..216e6462a 100644 --- a/tex/context/base/mkiv/node-shp.lua +++ b/tex/context/base/mkiv/node-shp.lua @@ -23,9 +23,6 @@ local handlers = nodes.handlers local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist local disc_code = nodecodes.disc -local mark_code = nodecodes.mark -local kern_code = nodecodes.kern -local glue_code = nodecodes.glue local whatsit_code = nodecodes.whatsit local fulldisc_code = disccodes.discretionary @@ -37,15 +34,14 @@ local implement = interfaces.implement local nuts = nodes.nuts local tonut = nuts.tonut local tonode = nuts.tonode -local free_node = nuts.free local remove_node = nuts.remove local traverse_nodes = nuts.traverse local getfield = nuts.getfield local setfield = nuts.setfield -local setsetlink = nuts.setlink -local setsetprev = nuts.setprev -local setsetnext = nuts.setnext +local setlink = nuts.setlink +local setprev = nuts.setprev +local setnext = nuts.setnext local getid = nuts.getid local getdisc = nuts.getdisc local getboth = nuts.getboth diff --git a/tex/context/base/mkiv/node-syn.lua b/tex/context/base/mkiv/node-syn.lua new file mode 100644 index 000000000..1b8e07382 --- /dev/null +++ b/tex/context/base/mkiv/node-syn.lua @@ -0,0 +1,504 @@ +if not modules then modules = { } end modules ['node-syn'] = { + 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" +} + +-- Because we have these fields in some node that are used by sunctex, I decided (because +-- some users seem to like that feature) to implement a variant that might work out better +-- for ConTeXt. This is experimental code. I don't use it myself so it will take a while +-- to mature. There will be some helpers that one can use in more complex situations like +-- included xml files. +-- +-- It is unclear how the output gets interpreted. For instance, we only need to be able to +-- go back to a place where text is entered, but still we need all that redundant box +-- wrapping. +-- +-- Possible optimizations: pack whole lines. + +local type, rawset = type, rawset +local concat = table.concat +local formatters = string.formatters + +local trace = false trackers.register("system.syntex.visualize", function(v) trace = v end) + +local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode + +local getid = nuts.getid +local getlist = nuts.getlist +local setlist = nuts.setlist +local getnext = nuts.getnext +local getwhd = nuts.getwhd +local getwidth = nuts.getwidth +local getsubtype = nuts.getsubtype +local getattr = nuts.getattr + +local nodecodes = nodes.nodecodes +local kerncodes = nodes.kerncodes + +local glue_code = nodecodes.glue +local kern_code = nodecodes.kern +local kern_disc = nodecodes.disc +local rule_code = nodecodes.rule +----- math_code = nodecodes.math +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local glyph_code = nodecodes.glyph +local fontkern_code = kerncodes.fontkern + +local insert_before = nuts.insert_before +local insert_after = nuts.insert_after + +local nodepool = nuts.pool +local new_latelua = nodepool.latelua +local new_rule = nodepool.rule +local new_hlist = nodepool.hlist + +local getdimensions = nuts.dimensions +local getrangedimensions = nuts.rangedimensions + +local a_fontkern = attributes.private("fontkern") + +local get_synctex_fields = nuts.get_synctex_fields +local set_synctex_fields = nuts.set_synctex_fields +local set_syntex_tag = nodes.set_synctex_tag + +local getcount = tex.getcount +local setcount = tex.setcount + +local getpos = function() + getpos = backends.codeinjections.getpos + return getpos() + end + +local f_glue = formatters["g%i,%i:%i,%i"] +local f_glyph = formatters["x%i,%i:%i,%i"] +local f_kern = formatters["k%i,%i:%i,%i:%i"] +local f_rule = formatters["r%i,%i:%i,%i:%i,%i,%i"] +local f_hlist = formatters["[%i,%i:%i,%i:%i,%i,%i"] +local f_vlist = formatters["(%i,%i:%i,%i:%i,%i,%i"] +local s_hlist = "]" +local s_vlist = ")" +local f_hvoid = formatters["h%i,%i:%i,%i:%i,%i,%i"] +local f_vvoid = formatters["v%i,%i:%i,%i:%i,%i,%i"] + +local characters = fonts.hashes.characters + +local synctex = { } +luatex.synctex = synctex + +-- the file name stuff + +local noftags = 0 +local stnums = { } +local sttags = table.setmetatableindex(function(t,name) + noftags = noftags + 1 + t[name] = noftags + stnums[noftags] = name + return noftags +end) + +function synctex.setfilename(name) + if set_syntex_tag and name then + set_syntex_tag(sttags[name]) + end +end + +function synctex.resetfilename() + if set_syntex_tag then + local name = luatex.currentfile() + if name then + set_syntex_tag(name) + end + end +end + +-- the node stuff + +local result = { } +local r = 0 +local f = nil +local nofsheets = 0 +local nofobjects = 0 +local last = 0 +local filesdone = 0 +local enabled = false +local compact = true + +local function writeanchor() + local size = f:seek("end") + f:write("!" .. (size-last) .. "\n") + last = size +end + +local function writefiles() + local total = #stnums + if filesdone < total then + for i=filesdone+1,total do + f:write("Input:"..i..":"..stnums[i].."\n") + end + filesdone = total + end +end + +local function flushpreamble() + local jobname = tex.jobname + stnums[0] = jobname + f = io.open(file.replacesuffix(jobname,"syncctx"),"w") + f:write("SyncTeX Version:1\n") + f:write("Input:0:"..jobname.."\n") + writefiles() + f:write("Output:pdf\n") + f:write("Magnification:1000\n") + f:write("Unit:1\n") + f:write("X Offset:0\n") + f:write("Y Offset:0\n") + f:write("Content:\n") + flushpreamble = writefiles +end + +local function flushpostamble() + writeanchor() + f:write("Postamble:\n") + f:write("Count:"..nofobjects.."\n") + writeanchor() + f:write("Post scriptum:\n") + f:close() + enabled = false +end + +local pageheight = 0 -- todo: set before we do this! + +local function b_hlist(head,current,t,l,w,h,d) + return insert_before(head,current,new_latelua(function() + local x, y = getpos() + r = r + 1 + result[r] = f_hlist(t,l,x,tex.pageheight-y,w,h,d) + nofobjects = nofobjects + 1 + end)) +end + +local function b_vlist(head,current,t,l,w,h,d) + return insert_before(head,current,new_latelua(function() + local x, y = getpos() + r = r + 1 + result[r] = f_vlist(t,l,x,tex.pageheight-y,w,h,d) + nofobjects = nofobjects + 1 + end)) +end + +local function e_hlist(head,current) + return insert_after(head,current,new_latelua(function() + r = r + 1 + result[r] = s_hlist + nofobjects = nofobjects + 1 + end)) +end + +local function e_vlist(head,current) + return insert_after(head,current,new_latelua(function() + r = r + 1 + result[r] = s_vlist + nofobjects = nofobjects + 1 + end)) +end + +local function x_hlist(head,current,t,l,w,h,d) + return insert_before(head,current,new_latelua(function() + local x, y = getpos() + r = r + 1 + result[r] = f_hvoid(t,l,x,tex.pageheight-y,w,h,d) + nofobjects = nofobjects + 1 + end)) +end + +local function x_vlist(head,current,t,l,w,h,d) + return insert_before(head,current,new_latelua(function() + local x, y = getpos() + r = r + 1 + result[r] = f_vvoid(t,l,x,tex.pageheight-y,w,h,d) + nofobjects = nofobjects + 1 + end)) +end + +-- local function x_glyph(head,current,t,l) +-- return insert_before(head,current,new_latelua(function() +-- local x, y = getpos() +-- r = r + 1 +-- result[r] = f_glyph(t,l,x,tex.pageheight-y) +-- nofobjects = nofobjects + 1 +-- end)) +-- end + +-- local function x_glue(head,current,t,l) +-- return insert_before(head,current,new_latelua(function() +-- local x, y = getpos() +-- r = r + 1 +-- result[r] = f_glue(t,l,x,tex.pageheight-y) +-- nofobjects = nofobjects + 1 +-- end)) +-- end + +-- local function x_kern(head,current,t,l,k) +-- return insert_before(head,current,new_latelua(function() +-- local x, y = getpos() +-- r = r + 1 +-- result[r] = f_kern(t,l,x,tex.pageheight-y,k) +-- nofobjects = nofobjects + 1 +-- end)) +-- end + +-- local function x_rule(head,current,t,l,w,h,d) +-- return insert_before(head,current,new_latelua(function() +-- local x, y = getpos() +-- r = r + 1 +-- result[r] = f_rule(t,l,x,tex.pageheight-y,w,h,d) +-- nofobjects = nofobjects + 1 +-- end)) +-- end + +local function collect(head,t,l) + local current = head + while current do + local id = getid(current) + if id == glyph_code then + local first = current + local last = current + while true do + id = getid(current) + if id == glyph_code or id == disc_code then + last = current + elseif id == kern_code and (getsubtype(current) == fontkern_code or getattr(current,a_fontkern)) then + last = current + else + if id == glue_code then + -- we could go on when we're in the same t/l run + local tc, lc = get_synctex_fields(current) + if tc > 0 then + t, l = tc, lc + end + id = nil -- so no test later on + end + local w, h, d = getdimensions(first,getnext(last)) + -- local w, h, d = getrangedimensions(head,first,getnext(last)) + if trace then + -- color is already handled so no colors + head = insert_before(head,first,new_hlist(new_rule(w,32768,32768))) + end +if h < 655360 then + h = 655360 +end +if d < 327680 then + d = 327680 +end + head = x_hlist(head,first,t,l,w,h,d) + break + end + current = getnext(current) + if not current then + local w, h, d = getdimensions(first,getnext(last)) + -- local w, h, d = getrangedimensions(head,first,getnext(last)) + if trace then + -- color is already handled so no colors + head = insert_before(head,first,new_hlist(new_rule(w,32768,32768))) + end +if h < 655360 then + h = 655360 +end +if d < 327680 then + d = 327680 +end + head = x_hlist(head,first,t,l,w,h,d) + return head + end + end + end + if id == hlist_code then + local list = getlist(current) + local tc, lc = get_synctex_fields(current) + if tc > 0 then + t, l = tc, lc + end + if compact then + if list then + local l = collect(list,t,l) + if l ~= list then + setlist(current,l) + end + end + else + local w, h, d = getwhd(current) + if w == 0 or (h == 0 and d == 0) then + if list then + local l = collect(list,t,l) + if l ~= list then + setlist(current,l) + end + end + elseif list then + -- head = b_hlist(head,current,t,l,w,h,d) + head = b_hlist(head,current,0,0,w,h,d) + local l = collect(list,t,l) + if l ~= list then + setlist(current,l) + end + head, current = e_hlist(head,current) + else + -- head = x_hlist(head,current,t,l,w,h,d) + head = x_hlist(head,current,0,0,w,h,d) + end + end + elseif id == vlist_code then + local list = getlist(current) + local tc, lc = get_synctex_fields(current) + if tc > 0 then + t, l = tc, lc + end + if compact then + if list then + local l = collect(list,t,l) + if l ~= list then + setlist(current,l) + end + end + else + local w, h, d = getwhd(current) + if w == 0 or (h == 0 and d == 0) then + if list then + local l = collect(list,t,l) + if l ~= list then + setlist(current,l) + end + end + elseif list then + -- head = b_vlist(head,current,t,l,w,h,d) + head = b_vlist(head,current,0,0,w,h,d) + local l = collect(list,t,l) + if l ~= list then + setlist(current,l) + end + head, current = e_vlist(head,current) + else + -- head = x_vlist(head,current,t,l,w,h,d) + head = x_vlist(head,current,0,0,w,h,d) + end + end + elseif id == glue_code then + local tc, lc = get_synctex_fields(current) + if tc > 0 then + t, l = tc, lc + end + -- head = x_glue(head,current,t,l) + -- elseif id == kern_code then + -- local tc, lc = get_synctex_fields(current) + -- if tc > 0 then + -- t, l = tc, lc + -- end + -- -- local k = getwidth(current) + -- -- if k ~= 0 then + -- -- head = x_kern(head,current,t,l,k) + -- -- end + -- elseif id == rule_code then + -- local tc, lc = get_synctex_fields(current) + -- if tc > 0 then + -- t, l = tc, lc + -- end + -- -- if t > 0 and l > 0 then + -- -- local w, h, d = getwhd(current) + -- -- head = x_rule(head,current,t,l,w,h,d) + -- -- end + end + current = getnext(current) + end + return head +end + +-- range of same numbers + +function synctex.collect(head) + if enabled then + result, r = { }, 0 + head = collect(tonut(head),0,0) + return tonode(head), true + else + return head, false + end +end + +-- also no solution for bad first file resolving in sumatra + +function synctex.flush() + if enabled then + nofsheets = nofsheets + 1 -- could be realpageno + flushpreamble() + writeanchor() + f:write("{"..nofsheets.."\n") + if compact then + f:write(f_vlist(0,0,0,0,tex.pagewidth,tex.pageheight,0)) + f:write("\n") + end + f:write(concat(result,"\n")) + if compact then + f:write("\n") + f:write(s_vlist) + end + f:write("\n") + writeanchor() + f:write("}"..nofsheets.."\n") + nofobjects = nofobjects + 2 + result, r = { }, 0 + end +end + +function synctex.enable() + if not enabled and node.set_synctex_mode then + enabled = true + node.set_synctex_mode(1) + tex.normalsynctex = 0 + nodes.tasks.appendaction("shipouts", "after", "nodes.synctex.collect") + end +end + +function synctex.finish() + if enabled then + flushpostamble() + end +end + +-- not the best place + +luatex.registerstopactions(synctex.finish) + +nodes.tasks.appendaction("shipouts", "after", "luatex.synctex.collect") + +-- moved here + +local report_system = logs.reporter("system") +local synctex = false + +directives.register("system.synctex", function(v) + if v == "context" then + luatex.synctex.enable() + setcount("normalsynctex",0) + synctex = true + else + v = tonumber(v) or (toboolean(v,true) and 1) or (v == "zipped" and 1) or (v == "unzipped" and -1) or 0 + setcount("normalsynctex",v) + synctex = v ~= 0 + end + if synctex then + report_system("synctex functionality is enabled (%s), expect runtime overhead!",tostring(v)) + else + report_system("synctex functionality is disabled!") + end +end) + +statistics.register("synctex tracing",function() + if synctex or getcount("normalsynctex") ~= 0 then + return "synctex has been enabled (extra log file generated)" + end +end) diff --git a/tex/context/base/mkiv/node-tra.lua b/tex/context/base/mkiv/node-tra.lua index d184620ef..8c79e0ab8 100644 --- a/tex/context/base/mkiv/node-tra.lua +++ b/tex/context/base/mkiv/node-tra.lua @@ -47,10 +47,14 @@ local getsubtype = nuts.getsubtype local getlist = nuts.getlist local getdisc = nuts.getdisc local setattr = nuts.setattr +local getglue = nuts.getglue local isglyph = nuts.isglyph +local getcomponents = nuts.getcomponents +local getdir = nuts.getdir +local getwidth = nuts.getwidth local flush_list = nuts.flush_list -local count_nodes = nuts.count +local count_nodes = nuts.countall local used_nodes = nuts.usedlist local traverse_by_id = nuts.traverse_id @@ -75,7 +79,6 @@ local rule_code = nodecodes.rule local dir_code = nodecodes.dir local localpar_code = nodecodes.localpar local whatsit_code = nodecodes.whatsit -local gluespec_code = nodecodes.gluespec local dimenfactors = number.dimenfactors local fillorders = nodes.fillcodes @@ -122,6 +125,7 @@ function nodes.handlers.checkforleaks(sparse) end local f_sequence = formatters["U+%04X:%s"] +local f_subrange = formatters["[[ %s ][ %s ][ %s ]]"] local function tosequence(start,stop,compact) if start then @@ -132,7 +136,7 @@ local function tosequence(start,stop,compact) local c, id = isglyph(start) if c then if compact then - local components = getfield(start,"components") + local components = getcomponents(start) if components then t[#t+1] = tosequence(components,nil,compact) else @@ -141,6 +145,9 @@ local function tosequence(start,stop,compact) else t[#t+1] = f_sequence(c,utfchar(c)) end + elseif id == disc_code then + local pre, post, replace = getdisc(start) + t[#t+1] = f_subrange(pre and tosequence(pre),post and tosequence(post),replace and tosequence(replace)) elseif id == rule_code then if compact then t[#t+1] = "|" @@ -148,7 +155,7 @@ local function tosequence(start,stop,compact) t[#t+1] = nodecodes[id] end elseif id == dir_code or id == localpar_code then - t[#t+1] = "[" .. getfield(start,"dir") .. "]" + t[#t+1] = "[" .. getdir(start) .. "]" elseif compact then t[#t+1] = "[]" else @@ -280,11 +287,11 @@ local function showsimplelist(h,depth,n) end -- \startluacode --- callback.register('buildpage_filter',function() nodes.show_simple_list(tex.lists.contrib_head) end) +-- callbacks.register('buildpage_filter',function() nodes.show_simple_list(tex.lists.contrib_head) end) -- \stopluacode -- \vbox{b\footnote{n}a} -- \startluacode --- callback.register('buildpage_filter',nil) +-- callbacks.register('buildpage_filter',nil) -- \stopluacode nodes.showsimplelist = function(h,depth) showsimplelist(h,depth,0) end @@ -311,7 +318,7 @@ local function listtoutf(h,joiner,textonly,last,nodisc) end elseif textonly then if id == glue_code then - if getfield(h,"width") > 0 then + if getwidth(h) > 0 then w[#w+1] = " " end elseif id == hlist_code or id == vlist_code then @@ -376,7 +383,7 @@ local function nodetodimen(n) n = tonut(n) local id = getid(n) if id == kern_code then - local width = getfield(n,"width") + local width = getwidth(n) if width == 0 then return "0pt" else @@ -385,11 +392,10 @@ local function nodetodimen(n) elseif id ~= glue_code then return "0pt" end - local stretch_order = getfield(n,"stretch_order") - local shrink_order = getfield(n,"shrink_order") - local stretch = getfield(n,"stretch") / 65536 - local shrink = getfield(n,"shrink") / 65536 - local width = getfield(n,"width") / 65536 + local width, stretch, shrink, stretch_order, shrink_order = getglue(n) + stretch = stretch / 65536 + shrink = shrink / 65536 + width = width / 65536 if stretch_order ~= 0 then if shrink_order ~= 0 then return f_f_f(width,stretch,fillorders[stretch_order],shrink,fillorders[shrink_order]) @@ -431,12 +437,12 @@ dimenfactors[""] = dimenfactors.pt local function numbertodimen(d,unit,fmt) if not d or d == 0 then - if not unit or unit == "pt" then - return "0pt" - elseif fmt then - return formatters[fmt](0,unit) - else + if fmt then + return formatters[fmt](0,unit or "pt") + elseif unit then return 0 .. unit + else + return "0pt" end elseif fmt then if not unit then diff --git a/tex/context/base/mkiv/node-tsk.lua b/tex/context/base/mkiv/node-tsk.lua index 56a4b18ef..c33f0e9f4 100644 --- a/tex/context/base/mkiv/node-tsk.lua +++ b/tex/context/base/mkiv/node-tsk.lua @@ -30,6 +30,20 @@ local sequencers = utilities.sequencers local compile = sequencers.compile local nodeprocessor = sequencers.nodeprocessor +local newsequencer = sequencers.new + +local appendgroup = sequencers.appendgroup +----- prependgroup = sequencers.prependgroup +----- replacegroup = sequencers.replacegroup +local enablegroup = sequencers.enablegroup +local disablegroup = sequencers.disablegroup + +local appendaction = sequencers.appendaction +local prependaction = sequencers.prependaction +local replaceaction = sequencers.replaceaction +local enableaction = sequencers.enableaction +local disableaction = sequencers.disableaction + local frozengroups = "no" function tasks.freeze(kind) @@ -41,7 +55,7 @@ function tasks.new(specification) -- was: name,arguments,list local arguments = specification.arguments or 0 local sequence = specification.sequence if name and sequence then - local tasklist = sequencers.new { + local tasklist = newsequencer { -- we can move more to the sequencer now .. todo } tasksdata[name] = { @@ -53,7 +67,7 @@ function tasks.new(specification) -- was: name,arguments,list processor = specification.processor or nodeprocessor } for l=1,#sequence do - sequencers.appendgroup(tasklist,sequence[l]) + appendgroup(tasklist,sequence[l]) end end end @@ -104,7 +118,7 @@ end function tasks.enableaction(name,action) local data = valid(name) if data then - sequencers.enableaction(data.list,action) + enableaction(data.list,action) data.runner = false end end @@ -112,7 +126,7 @@ end function tasks.disableaction(name,action) local data = valid(name) if data then - sequencers.disableaction(data.list,action) + disableaction(data.list,action) data.runner = false end end @@ -120,23 +134,30 @@ end function tasks.replaceaction(name,group,oldaction,newaction) local data = valid(name) if data then - sequencers.replaceaction(data.list,group,oldaction,newaction) + replaceaction(data.list,group,oldaction,newaction) data.runner = false end end -function tasks.setaction(name,action,value) - if value then - tasks.enableaction(name,action) - else - tasks.disableaction(name,action) +do + + local enableaction = tasks.enableaction + local disableaction = tasks.disableaction + + function tasks.setaction(name,action,value) + if value then + enableaction(name,action) + else + disableaction(name,action) + end end + end function tasks.enablegroup(name,group) local data = validgroup(name,"enable group") if data then - sequencers.enablegroup(data.list,group) + enablegroup(data.list,group) data.runner = false end end @@ -144,7 +165,7 @@ end function tasks.disablegroup(name,group) local data = validgroup(name,"disable group") if data then - sequencers.disablegroup(data.list,group) + disablegroup(data.list,group) data.runner = false end end @@ -152,7 +173,7 @@ end function tasks.appendaction(name,group,action,where,kind) local data = validgroup(name,"append action") if data then - sequencers.appendaction(data.list,group,action,where,kind) + appendaction(data.list,group,action,where,kind) data.runner = false end end @@ -160,7 +181,7 @@ end function tasks.prependaction(name,group,action,where,kind) local data = validgroup(name,"prepend action") if data then - sequencers.prependaction(data.list,group,action,where,kind) + prependaction(data.list,group,action,where,kind) data.runner = false end end @@ -168,7 +189,7 @@ end function tasks.removeaction(name,group,action) local data = validgroup(name,"remove action") if data then - sequencers.removeaction(data.list,group,action) + removeaction(data.list,group,action) data.runner = false end end @@ -366,6 +387,7 @@ tasks.new { tasks.new { name = "shipouts", arguments = 0, + -- nostate = true, -- maybe but only for main ones so little gain processor = nodeprocessor, sequence = { "before", -- for users @@ -418,3 +440,15 @@ tasks.new { -- "after", -- for users -- } -- } + +tasks.new { + name = "contributers", + arguments = 2, -- [head] where parent + processor = nodeprocessor, + sequence = { + "before", -- for users + "normalizers", + "after", -- for users + } +} + diff --git a/tex/context/base/mkiv/node-tst.lua b/tex/context/base/mkiv/node-tst.lua index 4832c048c..1109f28a3 100644 --- a/tex/context/base/mkiv/node-tst.lua +++ b/tex/context/base/mkiv/node-tst.lua @@ -32,6 +32,9 @@ local getprev = nuts.getprev local getid = nuts.getid local getchar = nuts.getchar local getsubtype = nuts.getsubtype +local getkern = nuts.getkern +local getpenalty = nuts.getpenalty +local getwidth = nuts.getwidth local find_node_tail = nuts.tail @@ -39,11 +42,11 @@ function nuts.leftmarginwidth(n) -- todo: three values while n do local id = getid(n) if id == glue_code then - return getsubtype(n) == leftskip_code and getfield(n,"width") or 0 + return getsubtype(n) == leftskip_code and getwidth(n) or 0 elseif id == whatsit_code then n = getnext(n) elseif id == hlist_code then - return getfield(n,"width") + return getwidth(n) else break end @@ -57,7 +60,7 @@ function nuts.rightmarginwidth(n) while n do local id = getid(n) if id == glue_code then - return getsubtype(n) == rightskip_code and getfield(n,"width") or 0 + return getsubtype(n) == rightskip_code and getwidth(n) or 0 elseif id == whatsit_code then n = getprev(n) else @@ -72,10 +75,9 @@ function nuts.somespace(n,all) if n then local id = getid(n) if id == glue_code then - return (all or ((getfield(n,"width") or 0) ~= 0)) and glue_code -- temp: or 0 - -- return (all or (getfield(n,"width") ~= 0)) and glue_code + return (all or (getwidth(n) ~= 0)) and glue_code -- temp: or 0 elseif id == kern_code then - return (all or (getfield(n,"kern") ~= 0)) and kern + return (all or (getkern(n) ~= 0)) and kern elseif id == glyph_code then local category = chardata[getchar(n)].category -- maybe more category checks are needed @@ -90,7 +92,7 @@ function nuts.somepenalty(n,value) local id = getid(n) if id == penalty_code then if value then - return getfield(n,"penalty") == value + return getpenalty(n) == value else return true end diff --git a/tex/context/base/mkiv/node-typ.lua b/tex/context/base/mkiv/node-typ.lua index 2d84e07a3..dea48cda8 100644 --- a/tex/context/base/mkiv/node-typ.lua +++ b/tex/context/base/mkiv/node-typ.lua @@ -18,14 +18,15 @@ local tonut = nuts.tonut local setfield = nuts.setfield local setlink = nuts.setlink local setchar = nuts.setchar +local setattrlist = nuts.setattrlist local getfield = nuts.getfield local getfont = nuts.getfont +local getattrlist = nuts.getattrlist local hpack_node_list = nuts.hpack local vpack_node_list = nuts.vpack local full_hpack_list = nuts.fullhpack -local copy_node = nuts.copy local nodepool = nuts.pool local new_glyph = nodepool.glyph @@ -33,20 +34,26 @@ local new_glue = nodepool.glue local utfvalues = utf.values -local currentfont = font.current -local currentattr = node.current_attr +local currentfont = font.current -- mabe nicer is fonts .current +local currentattr = node.current_attr -- mabe nicer is attributes.current local fontparameters = fonts.hashes.parameters -local function tonodes(str,fontid,spacing,templateglyph) -- quick and dirty +-- when attrid == true then take from glyph or current else use the given value + +local function tonodes(str,fontid,spacing,templateglyph,attrid) -- quick and dirty local head, prev = nil, nil --- local attrid = nil if not fontid then if templateglyph then fontid = getfont(templateglyph) --- attrid = getfield(templateglyph,"attr") else fontid = currentfont() --- attrid = currentattr() + end + end + if attrid == true then + if templateglyph then + attrid = false -- we copy with the glyph + else + attrid = currentattr() end end local fp = fontparameters[fontid] @@ -75,10 +82,14 @@ local function tonodes(str,fontid,spacing,templateglyph) -- quick and dirty if not next then -- nothing elseif not head then --- setfield(next,"attr",attrid) + if attrid then + setattrlist(next,attrid) + end head = next else --- setfield(next,"attr",attrid) + if attrid then + setattrlist(next,attrid) + end setlink(prev,next) end prev = next diff --git a/tex/context/base/mkiv/pack-box.mkiv b/tex/context/base/mkiv/pack-box.mkiv index fad7d6e18..8279fcd71 100644 --- a/tex/context/base/mkiv/pack-box.mkiv +++ b/tex/context/base/mkiv/pack-box.mkiv @@ -24,10 +24,15 @@ %D which in itself is ok, but can lead to loops due to rounding errors (happened %D in demo-obv). -\definelayer[\v!text-2][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height] -\definelayer[\v!text-1][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height] -\definelayer[\v!text+1][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height] -\definelayer[\v!text+2][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height] +% \definelayer[\v!text-2][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height] +% \definelayer[\v!text-1][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height] +% \definelayer[\v!text+1][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height] +% \definelayer[\v!text+2][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height] + +\definelayer[\v!text-2][\c!position=\v!yes,\c!region=,\c!width=\textwidth,\c!height=\textheight] +\definelayer[\v!text-1][\c!position=\v!yes,\c!region=,\c!width=\textwidth,\c!height=\textheight] +\definelayer[\v!text+1][\c!position=\v!yes,\c!region=,\c!width=\textwidth,\c!height=\textheight] +\definelayer[\v!text+2][\c!position=\v!yes,\c!region=,\c!width=\textwidth,\c!height=\textheight] \unexpanded\def\internaltextoverlay#1% will become more generic and installable {\startoverlay % i.e. probably an overlay by itself @@ -42,6 +47,10 @@ \installcorenamespace {anchor} +% produces a box too +% +% \anchor[text-1][preset=lefttop][framed settings]{HELLO WORLD} + \unexpanded\def\defineanchor {\doquadrupleempty\pack_anchors_define} @@ -64,14 +73,11 @@ {\begingroup \edef\currentanchor{#1}% \ifcsname\??anchor\currentanchor\endcsname - \expandafter\pack_anchor_predefined + \expandafter\lastnamedcs \else \expandafter\pack_anchor_notdefined \fi} -\def\pack_anchor_predefined - {\csname\??anchor\currentanchor\endcsname} - \def\pack_anchor_notdefined {\dodoubleempty\pack_anchor_notdefined_indeed} @@ -93,33 +99,72 @@ \newdimen\d_pack_anchors_height \newdimen\d_pack_anchors_depth -\definelayer[anchor] % \defineoverlay[anchor][\ruledhbox{\flushlayer[anchor]}] +% \definelayer[anchor] + +\newcount\c_pack_anchors_n +\newtoks \t_pack_anchors_flush + +\unexpanded\def\pack_anchors_register#1#2% + {\global\advance\c_pack_anchors_n\plusone + \pagereference[\v!layer:\v!anchor:\number\c_pack_anchors_n]% + \putboxincache\v!anchor{\number\c_pack_anchors_n}\b_pack_anchors + \doglobal\appendetoks + \pack_anchors_flush{\number\c_pack_anchors_n}{#1}{#2}% + \to \t_pack_anchors_flush + \glet\pack_anchors_flush_all\pack_anchors_flush_all_indeed} + +\unexpanded\def\pack_anchors_flush#1#2#3% + {\doifelseboxincache\v!anchor{#1} + {\doifelsereferencefound{\v!layer:\v!anchor:#1} + {\ifnum\currentreferencerealpage=\realpageno\relax + \setlayer[#2][#3,\c!position=\v!no]{\directboxfromcache\v!anchor{#1}}% + \else + \donetrue + \fi + }\donetrue}% + \donetrue}% + +\unexpanded\def\pack_anchors_flush_all_indeed + {\donefalse + \the\t_pack_anchors_flush + \ifdone\else + \global\t_pack_anchors_flush\emptytoks + \glet\pack_anchors_flush_all\relax + \fi} + +\let\pack_anchors_flush_all\relax + +\appendtoks + \pack_anchors_flush_all +\to \everybeforepagebody \def\pack_anchors_process_finish#1#2#3% brrr: we need to apply offset only once .. a bit messy {\checkpositionoverlays - % for the moment we ignore the depth \setbox\b_pack_anchors\box\nextbox - \d_pack_anchors_width \wd\b_pack_anchors - \d_pack_anchors_height\ht\b_pack_anchors - \d_pack_anchors_depth \dp\b_pack_anchors - \setbox\scratchbox\emptyhbox - \wd\scratchbox\d_pack_anchors_width - \ht\scratchbox\d_pack_anchors_height - \dp\scratchbox\d_pack_anchors_depth - \setlayer - [anchor] - [\c!width=\d_pack_anchors_width, - \c!height=\d_pack_anchors_height, - \c!offset=\zeropoint, - #2,#3] - {\setlayer[#1]{\box\b_pack_anchors}}% % #1 uses ovelaywidth/height - \framed % could be a predefined framed - [\c!background=anchor, - \c!offset=\v!overlay, - \c!frame=\v!off, - #3] - {\box\scratchbox}% - \endgroup} + \framed % could be a predefined framed but used seldom + [\c!offset=\v!overlay,\c!frame=\v!off,#3] + {\pack_anchors_register{#1}{#2}% + \novrule % hm, not needed as we frame the size (but kind of default) + \s!width \wd\b_pack_anchors + \s!height\ht\b_pack_anchors + \s!depth \dp\b_pack_anchors}% + \endgroup} + +% \setlayeranchored[text-1][preset=lefttop]{HELLO WORLD} produces a simple (empty) hbox +% synchronizes per page + +\unexpanded\def\setlayeranchored + {\begingroup + \dodoubleempty\pack_anchors_set_finish} + +\def\pack_anchors_set_finish[#1][#2]% + {\dowithnextbox + {\iffirstargument + \checkpositionoverlays + \setbox\b_pack_anchors\box\nextbox + \dontleavehmode\hpack{\pack_anchors_register{#1}{#2}}% + \fi + \endgroup}\hbox} % collectors @@ -147,7 +192,6 @@ \unexpanded\def\resetcollector[#1]% {\ifcsname\??collectorbox#1\endcsname - %\global\setbox\csname\??collectorbox#1\endcsname\emptybox \global\setbox\lastnamedcs\emptybox \fi} @@ -159,7 +203,6 @@ {\edef\currentcollector{#1}% \ifcsname\??collectorbox\currentcollector\endcsname \settrue\c_pack_boxes_collector_valid_box - %\expandafter\let\expandafter\b_pack_boxes_collector\csname\??collectorbox\currentcollector\endcsname \expandafter\let\expandafter\b_pack_boxes_collector\lastnamedcs \else \setfalse\c_pack_boxes_collector_valid_box @@ -573,7 +616,7 @@ \ifconditional\c_pack_boxes_t \paperheight -\MPy\currentbgposition+\MPy\currentpageposition % not checked \else\ifconditional\c_pack_boxes_b - \scratchheight+\MPy\currentbgposition-\MPy\currentpageposition % not checked + \scratchheight+\MPy\currentbgposition-\MPy\currentpageposition + \MPh\currentbgposition % not checked (\MPh added) \else \scratchheight \fi\fi diff --git a/tex/context/base/mkiv/pack-com.mkiv b/tex/context/base/mkiv/pack-com.mkiv index c9c3bab4b..8abee1daf 100644 --- a/tex/context/base/mkiv/pack-com.mkiv +++ b/tex/context/base/mkiv/pack-com.mkiv @@ -487,7 +487,8 @@ \let\stopfloatcombination\relax \def\pack_combinations_start_float[#1][#2]% - {\vbox\bgroup + {\ifinsidefloat\else\dontleavehmode\fi % tricky, floatcombinations fail to align well otherwise + \vbox\bgroup %\insidecolumnstrue % trick, forces no centering, todo: proper switch/feature \postcenterfloatmethod\zerocount \forcelocalfloats @@ -496,10 +497,10 @@ \def\pack_combinations_stop_float#1% {\scratchtoks\emptytoks \dorecurse\noflocalfloats - {\appendetoks{\noexpand\getlocalfloat{\recurselevel}}{}\to\scratchtoks}% brrr + {\appendetoks{\getlocalfloat{\recurselevel}}{}\to\scratchtoks}% brrr \expanded{\startcombination[#1]\the\scratchtoks}\stopcombination \resetlocalfloats - \egroup} + \egroup} %D \macros %D {definepairedbox, setuppairedbox, placepairedbox} diff --git a/tex/context/base/mkiv/pack-lyr.mkiv b/tex/context/base/mkiv/pack-lyr.mkiv index 61ed1e64b..8661fe57a 100644 --- a/tex/context/base/mkiv/pack-lyr.mkiv +++ b/tex/context/base/mkiv/pack-lyr.mkiv @@ -217,6 +217,7 @@ \def\pack_layers_set[#1][#2][#3]% #4 == box do \fi is ok {\bgroup + \checkpositionoverlays % otherwise funny regions \edef\currentlayer{#1}% \edef\p_pack_layers_state{\layerparameter\c!state}% \ifx\p_pack_layers_state\v!stop @@ -266,26 +267,22 @@ \fi \egroup} -% todo left/right - +% todo: left/right % todo: get position data in one go \def\pack_layers_set_last_position_yes % target: left|right {% this will become one call \edef\m_pack_layers_anchor{\??layerposition\the\c_pack_layers_current_data}% \edef\m_pack_layers_page {\MPp\m_pack_layers_anchor}% - \edef\m_pack_layers_region{\MPr\m_pack_layers_anchor}% + %edef\m_pack_layers_region{\MPr\m_pack_layers_anchor}% wrong one + \edef\m_pack_layers_region{\layerparameter\c!region}% \d_pack_layers_x_position \dimexpr-\MPx\m_pack_layers_region+\MPx\m_pack_layers_anchor\relax \d_pack_layers_y_position \dimexpr \MPy\m_pack_layers_region-\MPy\m_pack_layers_anchor+\MPh\m_pack_layers_region\relax \xdef\lastlayerxpos{\the\d_pack_layers_x_position}% \xdef\lastlayerypos{\the\d_pack_layers_y_position}% - % \writestatus{region}{\m_pack_layers_region -> (\MPx\m_pack_layers_region,\MPy\m_pack_layers_region)}% - % \writestatus{self} {\m_pack_layers_anchor -> (\MPx\m_pack_layers_anchor,\MPy\m_pack_layers_anchor)}% - % \writestatus{delta} {(\lastlayerxpos,\lastlayerypos)}% - % \begingroup - % \edef\currentlayer{\currentlayer\m_pack_layers_page}% - % \global\letlayerparameter\c!position\v!yes - % \endgroup + % \writestatus{layering}{region: \m_pack_layers_region=>\MPxywhd\m_pack_layers_region}% + % \writestatus {}{anchor: \m_pack_layers_anchor=>\MPxywhd\m_pack_layers_anchor}% + % \writestatus {}{offset: \c!dx,\c!dy =>\lastlayerxpos,\lastlayerypos}% \global\letlayerparameter\c!state\v!start % needed ? \setbox\b_layers\vpack to \d_pack_layers_y_size {\hpack to \d_pack_layers_x_size @@ -294,6 +291,8 @@ \def\pack_layers_set_last_position_nop {\setbox\b_layers\emptybox + \d_pack_layers_x_position\p_pack_layers_sx\dimexpr\p_pack_layers_x\relax + \d_pack_layers_y_position\p_pack_layers_sy\dimexpr\p_pack_layers_y\relax \globallet\lastlayerxpos\!!zeropoint \globallet\lastlayerypos\!!zeropoint \doifinset\v!bottom\p_pack_layers_corner\pack_layers_set_bottom_positions @@ -359,8 +358,6 @@ \d_pack_layers_y_offset\p_pack_layers_sy\dimexpr \ifx\p_pack_layers_voffset\v!max\d_pack_layers_y_size\else\p_pack_layers_voffset\fi+\p_pack_layers_offset+\p_pack_layers_dy \relax - \d_pack_layers_x_position\p_pack_layers_sx\dimexpr\p_pack_layers_x\relax - \d_pack_layers_y_position\p_pack_layers_sy\dimexpr\p_pack_layers_y\relax \ifx\p_pack_layers_position\v!yes \pack_layers_set_last_position_yes \else @@ -436,6 +433,8 @@ \smashbox\nextbox \vskip\dimexpr\d_pack_layers_y_position+\d_pack_layers_y_offset\relax \hskip\dimexpr\d_pack_layers_x_position+\d_pack_layers_x_offset\relax + % or maybe instead of the \vskip + % \raise-\dimexpr\d_pack_layers_y_position+\d_pack_layers_y_offset\relax \box\nextbox \ifvoid\layerpagebox % already flushed @@ -603,7 +602,7 @@ {\setlayoutcomponentattribute{\v!layer:#2}}% \resetlayoutcomponentattribute % we have conflicting demands: some mechanisms want ll anchoring .. I need to figure this out - % an dmaybe we will have 'origin=bottom' or so + % and maybe we will have 'origin=bottom' or so \setbox\nextbox \ifx\p_pack_layers_option\v!test \ruledvbox \else \vpack \fi \ifx\p_pack_layers_method\v!overlay to \d_overlay_height \fi \layoutcomponentboxattribute {\pack_layers_top_fill @@ -611,13 +610,13 @@ {\box\nextbox \hss}% \pack_layers_bottom_fill}% - % % \edef\currentlayer{#2}% :\the\realpageno}% local .. check \anchor % \edef\p_pack_layers_position{\layerparameter\c!position}% local \ifx\p_pack_layers_position\v!yes \edef\p_pack_layers_region{\layerparameter\c!region}% - \ifx\p_pack_layers_region\empty \else - \anch_mark_tagged_box\nextbox\layeranchor + \ifx\p_pack_layers_region\empty + \else + \anch_mark_tagged_box\nextbox\p_pack_layers_region % was \layeranchor \fi \fi \box\nextbox diff --git a/tex/context/base/mkiv/pack-obj.lua b/tex/context/base/mkiv/pack-obj.lua index 8a1af2b70..cba0dcf8f 100644 --- a/tex/context/base/mkiv/pack-obj.lua +++ b/tex/context/base/mkiv/pack-obj.lua @@ -25,7 +25,6 @@ local setbox = nuts.setbox local new_latelua = nuts.pool.latelua local settexdimen = tokens.setters.dimen -local settexcount = tokens.setters.count local gettexbox = tokens.getters.box local gettexdimen = tokens.getters.dimen diff --git a/tex/context/base/mkiv/pack-rul.lua b/tex/context/base/mkiv/pack-rul.lua index 427a2d11d..30eda7dd2 100644 --- a/tex/context/base/mkiv/pack-rul.lua +++ b/tex/context/base/mkiv/pack-rul.lua @@ -11,8 +11,6 @@ if not modules then modules = { } end modules ['pack-rul'] = { --ldx]]-- -- we need to be careful with display math as it uses shifts --- challenge: adapt glue_set --- setfield(h,"glue_set", getfield(h,"glue_set") * getfield(h,"width")/maxwidth -- interesting ... doesn't matter much -- \framed[align={lohi,middle}]{$x$} -- \framed[align={lohi,middle}]{$ $} @@ -26,6 +24,7 @@ local hlist_code = nodes.nodecodes.hlist local vlist_code = nodes.nodecodes.vlist local box_code = nodes.listcodes.box local line_code = nodes.listcodes.line +local equation_code = nodes.listcodes.equation local texsetdimen = tex.setdimen local texsetcount = tex.setcount @@ -40,18 +39,30 @@ local getnext = nuts.getnext local getprev = nuts.getprev local getlist = nuts.getlist local setlist = nuts.setlist +local getwhd = nuts.getwhd local getid = nuts.getid local getsubtype = nuts.getsubtype local getbox = nuts.getbox +local getdir = nuts.getdir +local setshift = nuts.setshift +local setwidth = nuts.setwidth +local getwidth = nuts.getwidth local hpack = nuts.hpack local traverse_id = nuts.traverse_id -local node_dimensions = nuts.dimensions -local free_node = nuts.free +local list_dimensions = nuts.dimensions +local flush_node = nuts.flush + +local checkformath = false + +directives.register("framed.checkmath",function(v) checkformath = v end) -- experiment + +-- beware: dir nodes and pseudostruts can end up on lines of their own local function doreshapeframedbox(n) local box = getbox(n) local noflines = 0 + local nofnonzero = 0 local firstheight = nil local lastdepth = nil local lastlinelength = 0 @@ -59,28 +70,28 @@ local function doreshapeframedbox(n) local maxwidth = 0 local totalwidth = 0 local averagewidth = 0 - local boxwidth = getfield(box,"width") + local boxwidth = getwidth(box) if boxwidth ~= 0 then -- and h.subtype == vlist_code local list = getlist(box) if list then local function check(n,repack) + local width, height, depth = getwhd(n) if not firstheight then - firstheight = getfield(n,"height") + firstheight = height end - lastdepth = getfield(n,"depth") - noflines = noflines + 1 - local l = getlist(n) + lastdepth = depth + noflines = noflines + 1 + local l = getlist(n) if l then if repack then local subtype = getsubtype(n) if subtype == box_code or subtype == line_code then - -- used to be: hpack(copy(l)).width - lastlinelength = node_dimensions(l,getfield(n,"dir")) + lastlinelength = list_dimensions(l,getdir(n)) else - lastlinelength = getfield(n,"width") + lastlinelength = width end else - lastlinelength = getfield(n,"width") + lastlinelength = width end if lastlinelength > maxwidth then maxwidth = lastlinelength @@ -88,6 +99,9 @@ local function doreshapeframedbox(n) if lastlinelength < minwidth or minwidth == 0 then minwidth = lastlinelength end + if lastlinelength > 0 then + nofnonzero = nofnonzero + 1 + end totalwidth = totalwidth + lastlinelength end end @@ -110,35 +124,34 @@ local function doreshapeframedbox(n) if l then local subtype = getsubtype(h) if subtype == box_code or subtype == line_code then - local p = hpack(l,maxwidth,'exactly',getfield(h,"dir")) -- multiple return value - if false then - setlist(h,p) - setfield(h,"shift",0) -- needed for display math, so no width check possible - -- setfield(p,"attr",getfield(h,"attr")) - else - setfield(h,"glue_set",getfield(p,"glue_set")) - setfield(h,"glue_order",getfield(p,"glue_order")) - setfield(h,"glue_sign",getfield(p,"glue_sign")) - setlist(p) - free_node(p) + local p = hpack(l,maxwidth,'exactly',getdir(h)) -- multiple return value + setfield(h,"glue_set",getfield(p,"glue_set")) + setfield(h,"glue_order",getfield(p,"glue_order")) + setfield(h,"glue_sign",getfield(p,"glue_sign")) + setlist(p) + flush_node(p) + elseif checkformath and subtype == equation_code then + -- display formulas use a shift + if nofnonzero == 1 then + setshift(h,0) end end - setfield(h,"width",maxwidth) + setwidth(h,maxwidth) end end end -- if vdone then -- for v in traverse_id(vlist_code,list) do - -- local width = getfield(n,"width") + -- local width = getwidth(n) -- if width > maxwidth then - -- setfield(v,"width",maxwidth) + -- setwidth(v,maxwidth) -- end -- end -- end - setfield(box,"width",maxwidth) + setwidth(box,maxwidth) averagewidth = noflines > 0 and totalwidth/noflines or 0 else -- e.g. empty math {$ $} or \hbox{} or ... -setfield(box,"width",0) + setwidth(box,0) end end end @@ -155,15 +168,16 @@ local function doanalyzeframedbox(n) local noflines = 0 local firstheight = nil local lastdepth = nil - if getfield(box,"width") ~= 0 then + if getwidth(box) ~= 0 then local list = getlist(box) if list then local function check(n) + local width, height, depth = getwhd(n) if not firstheight then - firstheight = getfield(n,"height") + firstheight = height end - lastdepth = getfield(n,"depth") - noflines = noflines + 1 + lastdepth = depth + noflines = noflines + 1 end for h in traverse_id(hlist_code,list) do check(h) @@ -182,7 +196,7 @@ implement { name = "doreshapeframedbox", actions = doreshapeframedbox, arguments implement { name = "doanalyzeframedbox", actions = doanalyzeframedbox, arguments = "integer" } local function maxboxwidth(box) - local boxwidth = getfield(box,"width") + local boxwidth = getwidth(box) if boxwidth == 0 then return 0 end @@ -201,12 +215,12 @@ local function maxboxwidth(box) if repack then local subtype = getsubtype(n) if subtype == box_code or subtype == line_code then - lastlinelength = node_dimensions(l,getfield(n,"dir")) + lastlinelength = list_dimensions(l,getdir(n)) else - lastlinelength = getfield(n,"width") + lastlinelength = getwidth(n) end else - lastlinelength = getfield(n,"width") + lastlinelength = getwidth(n) end if lastlinelength > maxwidth then maxwidth = lastlinelength @@ -226,6 +240,6 @@ nodes.maxboxwidth = maxboxwidth implement { name = "themaxboxwidth", - actions = function(n) context("%isp",maxboxwidth(getbox(n))) end, + actions = function(n) context("%rsp",maxboxwidth(getbox(n))) end, -- r = rounded arguments = "integer" } diff --git a/tex/context/base/mkiv/pack-rul.mkiv b/tex/context/base/mkiv/pack-rul.mkiv index 635863302..eec7b8cb3 100644 --- a/tex/context/base/mkiv/pack-rul.mkiv +++ b/tex/context/base/mkiv/pack-rul.mkiv @@ -142,7 +142,7 @@ [\c!width=\v!fit, \c!height=\v!broad, %\c!lines=, - \c!offset=.25ex, % \defaultframeoffset + \c!offset=.25\exheight, % \defaultframeoffset \c!empty=\v!no, \c!frame=\v!on, %\c!topframe=, @@ -176,7 +176,7 @@ \c!location=\v!normal, %\c!orientation=, \c!autowidth=\v!yes, - %\c!setups= + %\c!setups=, \c!loffset=\zeropoint, \c!roffset=\zeropoint, \c!toffset=\zeropoint, @@ -607,7 +607,11 @@ {\vpack to \framedbackgroundheight{\vss\box\b_framed_normal\vss}} % vertical shift \backgroundheight \def\pack_framed_add_region % experiment - {\anch_mark_region_box\b_framed_normal} + {\ifx\p_framed_region\v!yes + \anch_mark_region_box\b_framed_normal + \else + \anch_mark_tagged_box\b_framed_normal\p_framed_region + \fi} \def\pack_framed_add_background {\setbox\b_framed_normal\hbox % was vbox % see also *1* @@ -809,12 +813,13 @@ \newconditional\c_framed_has_width \newconditional\c_framed_has_height \newconditional\c_framed_has_format -\newconditional\c_framed_has_strut \newconditional\c_framed_is_overlaid \newconditional\c_framed_has_frame \newconditional\c_framed_has_extra_offset \newconditional\c_framed_text_location_none +\newconstant \c_framed_has_strut % 0=relaxes 1=pseudostruts 2=realstruts + %D \macros %D {framed, setupframed} %D @@ -936,7 +941,9 @@ \def\pack_framed_start_framed_nop_indeed[#1]% {\pack_framed_initialize \bgroup - \setupcurrentframed[#1]% here ! + \iffirstargument + \setupcurrentframed[#1]% here ! + \fi \pack_framed_process_indeed \bgroup \ignorespaces} @@ -1030,7 +1037,7 @@ \unexpanded\def\pack_framed_process_box_indeed#1#2% component box (assumes parameters set and grouped usage) {\setbox\b_framed_normal\box#2% could actually be \let\b_framed_normal#2 \edef\p_framed_region{\framedparameter\c!region}% - \ifx\p_framed_region\v!yes % maybe later named + \ifx\p_framed_region\empty\else \pack_framed_add_region \fi \edef\p_framed_rulethickness{\framedparameter\c!rulethickness}% also used in backgrounds @@ -1226,18 +1233,18 @@ \framed_offset_alternative_unknown \fi % the next check could move to strutalternative - \ifconditional\c_framed_has_strut + \ifcase\c_framed_has_strut % none (not even noindent) + \let\localbegstrut\relax + \let\localendstrut\relax + \let\localstrut \relax + \or % no / overlay + \let\localbegstrut\pseudobegstrut + \let\localendstrut\pseudoendstrut + \let\localstrut \pseudostrut + \else \let\localbegstrut\begstrut \let\localendstrut\endstrut \let\localstrut \strut - \else - \let\localbegstrut\pseudobegstrut % was: \relax - \let\localendstrut\pseudoendstrut % was: \relax - \let\localstrut \pseudostrut % was: \relax - %\ifconditional\c_framed_has_height\ifdim\d_framed_height<\strutht % saveguard - % \let\localbegstrut\relax % but not that - % \let\localstrut \relax % save after all - %\fi\fi \fi \ifx\p_framed_autostrut\v!yes \let\delayedbegstrut\relax @@ -1390,7 +1397,7 @@ % struts (use let instead?) \setvalue{\??framedstrutalternative\v!no}% - {\setfalse\c_framed_has_strut} + {\c_framed_has_strut\plusone} \setvalue{\??framedstrutalternative\v!global}% {\setstrut} @@ -1407,49 +1414,47 @@ \def\framed_strut_alternative_unknown {\setstrut} +\setvalue{\??framedstrutalternative\v!none}% not even pseudo struts + {\c_framed_has_strut\zerocount} + % offsets \setvalue{\??framedoffsetalternative\v!none}% {\setfalse\c_framed_has_offset - \setfalse\c_framed_has_strut + \c_framed_has_strut\plusone \setfalse\c_framed_is_overlaid \d_framed_local_offset\d_framed_linewidth} \setvalue{\??framedoffsetalternative\v!overlay}% {% \ifx\p_framed_frame\v!no \setfalse\c_framed_has_frame \fi % test first \setfalse\c_framed_has_offset - \setfalse\c_framed_has_strut - \settrue \c_framed_is_overlaid + \c_framed_has_strut\plusone + \settrue\c_framed_is_overlaid \d_framed_local_offset\zeropoint} % \setvalue{\??framedoffsetalternative\v!strut}% % {\setfalse\c_framed_has_offset -% \settrue \c_framed_has_strut -% \settrue \c_framed_is_overlaid +% \c_framed_has_strut\plustwo +% \settrue\c_framed_is_overlaid % \d_framed_local_offset\zeropoint} \setvalue{\??framedoffsetalternative\v!default}% new per 2-6-2000 {\settrue \c_framed_has_offset - \settrue \c_framed_has_strut + \c_framed_has_strut\plustwo \setfalse\c_framed_is_overlaid \let\localoffset\defaultframeoffset \letframedparameter\c!offset\defaultframeoffset % brrr \d_framed_local_offset\dimexpr\localoffset+\d_framed_linewidth\relax} -\setvalue{\??framedoffsetalternative\s!unknown}% - {\settrue \c_framed_has_offset - \settrue \c_framed_has_strut - \setfalse\c_framed_is_overlaid - \let\defaultframeoffset\localoffset - \d_framed_local_offset\dimexpr\localoffset+\d_framed_linewidth\relax} - \def\framed_offset_alternative_unknown {\settrue \c_framed_has_offset - \settrue \c_framed_has_strut + \c_framed_has_strut\plustwo \setfalse\c_framed_is_overlaid \let\defaultframeoffset\localoffset \d_framed_local_offset\dimexpr\localoffset+\d_framed_linewidth\relax} +\letvalue{\??framedoffsetalternative\s!unknown}\framed_offset_alternative_unknown + % so far for alternatives \let\pack_framed_stop_orientation\relax @@ -1599,9 +1604,9 @@ \pack_framed_stop_orientation % moved here at 2014-05-25 \iftrialtypesetting \else \edef\p_framed_region{\framedparameter\c!region}% - \ifx\p_framed_region\v!yes % maybe later named + \ifx\p_framed_region\empty\else \pack_framed_add_region - \fi + \fi \fi \d_framed_applied_offset \ifconditional\c_framed_is_overlaid @@ -1669,16 +1674,37 @@ \newdimen\d_framed_locator_ht \newdimen\d_framed_locator_dp +\newdimen\d_framed_locator_lo +\newdimen\d_framed_locator_ro -\def\pack_framed_locater_set#1% +\def\pack_framed_locator_set#1% {\d_framed_locator_ht\dimexpr #1+\d_framed_linewidth \ifconditional\c_framed_has_offset +\framedparameter\c!offset \fi + +\framedparameter\c!toffset \relax \d_framed_locator_dp\dimexpr\ht\b_framed_normal-\d_framed_locator_ht\relax} +\def\pack_framed_locator_set_lo + {\global\d_framed_locator_lo\dimexpr + \d_framed_linewidth + \ifconditional\c_framed_has_offset + +\framedparameter\c!offset + \fi + +\framedparameter\c!loffset + \relax} + +\def\pack_framed_locator_set_ro + {\global\d_framed_locator_ro\dimexpr + \d_framed_linewidth + \ifconditional\c_framed_has_offset + +\framedparameter\c!offset + \fi + +\framedparameter\c!roffset + \relax} + % \ruledhbox % {A % \framed[width=2cm,align=middle,location=hanging]{location\\equals\\hanging} @@ -1743,11 +1769,11 @@ \installframedlocator \v!high {} - {\pack_framed_locater_set\strutht + {\pack_framed_locator_set\strutht \setbox\b_framed_normal\hpack{\lower\d_framed_locator_dp\box\b_framed_normal}% \ht\b_framed_normal\strutht \dp\b_framed_normal\strutdp - \hpack{\box\b_framed_normal}} + \hpack{\box\b_framed_normal}} % why pack \installframedlocator \v!line {} @@ -1758,7 +1784,7 @@ \installframedlocator \v!low {} - {\pack_framed_locater_set\strutdp + {\pack_framed_locator_set\strutdp \setbox\b_framed_normal\hpack{\lower\d_framed_locator_ht\box\b_framed_normal}% \ht\b_framed_normal\strutht \dp\b_framed_normal\strutdp @@ -1766,7 +1792,7 @@ \installframedlocator \v!top {} - {\pack_framed_locater_set\strutht + {\pack_framed_locator_set\strutht \setbox\b_framed_normal\hpack{\lower\d_framed_locator_dp\box\b_framed_normal}% \ht\b_framed_normal\d_framed_locator_ht \dp\b_framed_normal\d_framed_locator_dp @@ -1786,7 +1812,7 @@ \installframedlocator \v!bottom {} - {\pack_framed_locater_set\strutdp + {\pack_framed_locator_set\strutdp \setbox\b_framed_normal\hpack{\lower\d_framed_locator_ht\box\b_framed_normal}% \ht\b_framed_normal\d_framed_locator_dp \dp\b_framed_normal\d_framed_locator_ht @@ -1796,6 +1822,16 @@ {\pack_framed_remove_depth} {\pack_framed_restore_depth} +\newdimen\d_framed_formula + +\installframedlocator \v!formula % private, will become a more generic name + {} + {\pack_framed_locator_set\d_framed_formula + \setbox\b_framed_normal\hpack{\lower\d_framed_locator_dp\box\b_framed_normal}% + \ht\b_framed_normal\d_framed_locator_ht + \dp\b_framed_normal\d_framed_locator_dp + \hpack{\box\b_framed_normal}} + % also used in fastlocalframed \newdimen\d_framed_original_wd @@ -1952,12 +1988,13 @@ % \inheritedmathframedframed{\Ustartmath\triggermathstyle\c_framed_mstyle#2\Ustopmath}% % \endgroup} -\newcount\c_pack_framed_mc +\newcount\c_pack_framed_mathframed +\newtoks \t_pack_framed_mathframed \def\pack_framed_math_pos - {\global\advance\c_pack_framed_mc\plusone - \xdef\pack_framed_mc_one{mcf:1:\number\c_pack_framed_mc}% - \xdef\pack_framed_mc_two{mcf:2:\number\c_pack_framed_mc}% + {\global\advance\c_pack_framed_mathframed\plusone + \xdef\pack_framed_mc_one{mcf:1:\number\c_pack_framed_mathframed}% + \xdef\pack_framed_mc_two{mcf:2:\number\c_pack_framed_mathframed}% \xypos\pack_framed_mc_two} \def\pack_framed_mathframed_indeed[#1]#2% no fancy nesting supported here @@ -1971,9 +2008,20 @@ \else\ifx\m_framed_location\v!low\else \let\normalstrut\pack_framed_math_strut \fi\fi - \inheritedmathframedframed{\Ustartmath\triggermathstyle\c_framed_mstyle#2\Ustopmath}% + \inheritedmathframedframed\bgroup + \Ustartmath + \triggermathstyle\c_framed_mstyle + \the\t_pack_framed_mathframed + #2% + \Ustopmath + \egroup \endgroup} +\appendtoks + \mathraggedstatus\plustwo % makes \startalign work + \eqalignmode \zerocount % makes \startalign fit +\to \t_pack_framed_mathframed + \installframedlocator \v!mathematics {} {\lower\dimexpr\MPy\pack_framed_mc_two-\MPy\pack_framed_mc_one\relax @@ -2861,7 +2909,7 @@ \iffirstargument \setupcurrentframedtext[#1]% \fi - \edef\p_framed_text_strut{\letframedtextparameter\c!strut}% + \edef\p_framed_text_strut{\framedtextparameter\c!strut}% \letframedtextparameter\c!strut\v!no \inheritedframedtextframed\bgroup \blank[\v!disable]% @@ -3007,6 +3055,7 @@ \ifx\currentframedcontent\v!off \let\stopframedcontent\egroup \else + \checkframedcontentparent \let\stopframedcontent\pack_framed_stop_content_indeed \expandafter\pack_framed_start_content_indeed \fi} diff --git a/tex/context/base/mkiv/page-brk.mkiv b/tex/context/base/mkiv/page-brk.mkiv index eabcb74f8..b651cc8b4 100644 --- a/tex/context/base/mkiv/page-brk.mkiv +++ b/tex/context/base/mkiv/page-brk.mkiv @@ -246,12 +246,25 @@ {\page \doifelseoddpage\donothing\page_reset_marks_and_insert_dummy} +% \installpagebreakmethod \v!quadruple % not yet ok inside columnsets +% {\ifdoublesided +% \ifnum\numexpr\realpageno/\plusfour\relax=\numexpr\realpageno/\plustwo\relax\else +% \page_breaks_handle_direct\v!yes +% \page_breaks_handle_direct\v!empty +% \page_breaks_handle_direct\v!empty +% \fi +% \fi} + \installpagebreakmethod \v!quadruple % not yet ok inside columnsets {\ifdoublesided - \ifnum\numexpr\realpageno/\plusfour\relax=\numexpr\realpageno/\plustwo\relax\else + \ifcase\modulonumber\plusfour\realpageno\else \page_breaks_handle_direct\v!yes - \page_breaks_handle_direct\v!empty - \page_breaks_handle_direct\v!empty + \doloop + {\ifcase\modulonumber\plusfour\realpageno\relax + \exitloop + \else + \page_breaks_handle_direct\v!empty + \fi}% \fi \fi} diff --git a/tex/context/base/mkiv/page-cst.lua b/tex/context/base/mkiv/page-cst.lua index 782bbebfc..03707a312 100644 --- a/tex/context/base/mkiv/page-cst.lua +++ b/tex/context/base/mkiv/page-cst.lua @@ -24,7 +24,6 @@ local setmetatableindex = table.setmetatableindex local properties = nodes.properties local nodecodes = nodes.nodecodes -local gluecodes = nodes.gluecodes local rulecodes = nodes.rulecodes local hlist_code = nodecodes.hlist @@ -32,24 +31,16 @@ local vlist_code = nodecodes.vlist local kern_code = nodecodes.kern local glue_code = nodecodes.glue local penalty_code = nodecodes.penalty -local insert_code = nodecodes.ins -local mark_code = nodecodes.mark local rule_code = nodecodes.rule -local topskip_code = gluecodes.topskip -local lineskip_code = gluecodes.lineskip -local baselineskip_code = gluecodes.baselineskip -local userskip_code = gluecodes.userskip - local nuts = nodes.nuts local tonode = nuts.tonode local tonut = nuts.tonut local hpack = nuts.hpack local vpack = nuts.vpack -local freenode = nuts.free local flushlist = nuts.flush_list -local removenode = nuts.remove +----- removenode = nuts.remove local getfield = nuts.getfield local setfield = nuts.setfield @@ -59,6 +50,12 @@ local setnext = nuts.setnext local setprev = nuts.setprev local setsubtype = nuts.setsubtype local setbox = nuts.setbox +local getwhd = nuts.getwhd +local setwhd = nuts.setwhd +local getkern = nuts.getkern +local getpenalty = nuts.getpenalty +local getwidth = nuts.getwidth +local getheight = nuts.getheight local getnext = nuts.getnext local getprev = nuts.getprev @@ -68,7 +65,6 @@ local getsubtype = nuts.getsubtype local takebox = nuts.takebox local takelist = nuts.takelist local splitbox = nuts.splitbox -local getskip = nuts.getskip local getattribute = nuts.getattribute local copylist = nuts.copy_list @@ -84,9 +80,7 @@ local theprop = nuts.theprop local nodepool = nuts.pool -local new_hlist = nodepool.hlist local new_vlist = nodepool.vlist -local new_kern = nodepool.kern local new_trace_rule = nodepool.rule local new_empty_rule = nodepool.emptyrule @@ -99,13 +93,11 @@ local v_fixed = variables.fixed local v_top = variables.top local v_bottom = variables.bottom local v_repeat = variables["repeat"] -local v_left = variables.left -local v_right = variables.right local v_yes = variables.yes local v_page = variables.page local v_first = variables.first local v_last = variables.last -local v_wide = variables.wide +----- v_wide = variables.wide pagebuilders = pagebuilders or { } -- todo: pages.builders pagebuilders.columnsets = pagebuilders.columnsets or { } @@ -349,11 +341,7 @@ function columnsets.prepareflush(name) for r=1,nofrows-1 do setlink(column[r],column[r+1]) end - local v = new_vlist(column[1]) - setfield(v,"height",height) --- setfield(v,"depth",linedepth) - setfield(v,"width",widths[c]) - columns[c] = v + columns[c] = new_vlist(column[1],widths[c],height,0) -- linedepth end -- texsetcount("c_page_grid_first_column",firstcolumn) @@ -634,8 +622,9 @@ function columnsets.check(t) if boxwidth > 0 and boxheight > 0 then -- we're ok elseif box then - boxwidth = getfield(box,"width") - boxheight = getfield(box,"height") + getfield(box,"depth") + local wd, ht, dp = getwhd(box) + boxwidth = wd + boxheight = ht + dp else report("empty box") return @@ -722,9 +711,7 @@ function columnsets.put(t) end end cells[c][r] = box - setfield(box,"height",lineheight) - setfield(box,"depth",linedepth) - setfield(box,"width",widths[c]) + setwhd(box,widths[c],lineheight,linedepth) dataset.reserved_c = false dataset.reserved_r = false dataset.reserved_nc = false @@ -787,9 +774,9 @@ end -- if line then -- break -- end --- used = used + getfield(head,"width") +-- used = used + getwidth(head) -- elseif id == kern_code then --- used = used + getfield(head,"kern") +-- used = used + getkern(head) -- elseif id == penalty_code then -- end -- if used > available then @@ -816,7 +803,8 @@ local function checkroom(head,available,row) while head do local id = getid(head) if id == hlist_code or id == vlist_code or id == rule_code then -- <= rule_code - used = used + getfield(head,"height") + getfield(head,"depth") + local wd, ht, dp = getwhd(head) + used = used + ht + dp line = true if used > available then break @@ -825,18 +813,18 @@ local function checkroom(head,available,row) if line then break end - used = used + getfield(head,"width") + used = used + getwidth(head) if used > available then break end elseif id == kern_code then - used = used + getfield(head,"kern") + used = used + getkern(head) if used > available then break end elseif id == penalty_code then -- not good enough ... we need to look bakck too - if getfield(head,"penalty") >= 10000 then + if getpenalty(head) >= 10000 then line = false else break @@ -874,9 +862,9 @@ end -- if id == hlist_code or id == vlist_code or id == rule_code then -- <= rule_code -- hd = getfield(head,"height") + getfield(head,"depth") -- elseif id == glue_code then --- hd = getfield(head,"width") +-- hd = getwidth(head) -- elseif id == kern_code then --- hd = getfield(head,"kern") +-- hd = getkern(head) -- elseif id == penalty_code then -- end -- if used + hd > available then @@ -931,7 +919,7 @@ local function findslice(dataset,head,available,column,row) attempts = attempts + 1 texsetbox("scratchbox",tonode(new_vlist(copy))) local done = splitbox("scratchbox",usedsize,"additional") - local used = getfield(done,"height") + local used = getheight(done) local rest = takebox("scratchbox") if used > (usedsize+slack) then if trace_detail then @@ -955,7 +943,7 @@ local function findslice(dataset,head,available,column,row) texsetbox("scratchbox",tonode(new_vlist(head))) done = splitbox("scratchbox",usedsize,"additional") rest = takebox("scratchbox") - used = getfield(done,"height") + used = getheight(done) if attempts > 1 then used = available end @@ -1002,9 +990,7 @@ function columnsets.add(name,box) -- getmetatable(v).columngap = nofcolumngaps properties[v] = { columngap = nofcolumngaps } -- report("setting gap %a at (%i,%i)",nofcolumngaps,foundc,foundr) - setfield(v,"height",lineheight) - setfield(v,"depth",linedepth) - setfield(v,"width",widths[currentcolumn]) + setwhd(v,widths[currentcolumn],lineheight,linedepth) local column = cells[foundc] -- column[foundr] = v @@ -1251,9 +1237,7 @@ function columnsets.setarea(t) local column = t.c local row = t.r if column and row then - setfield(box,"height",dataset.lineheight) - setfield(box,"depth",dataset.linedepth) - setfield(box,"width",dataset.widths[column]) + setwhd(box,dataset.widths[column],dataset.lineheight,dataset.linedepth) cells[column][row] = box end end diff --git a/tex/context/base/mkiv/page-cst.mkiv b/tex/context/base/mkiv/page-cst.mkiv index 4559ec33f..ed4512561 100644 --- a/tex/context/base/mkiv/page-cst.mkiv +++ b/tex/context/base/mkiv/page-cst.mkiv @@ -293,15 +293,15 @@ % todo line numbers and marks \unexpanded\def\page_grid_command_flush_page_column#1% - {\scratchcounter#1\relax - \clf_flushcolumnsetcolumn{\currentpagegrid}\scratchcounter + {\privatescratchcounter#1\relax + \clf_flushcolumnsetcolumn{\currentpagegrid}\privatescratchcounter \anch_mark_column_box\b_page_grid_column - \page_marks_synchronize_column\c_page_grid_first_column\c_page_grid_last_column\scratchcounter\b_page_grid_column - \ifnum\scratchcounter>\c_page_grid_n_of_left - \advance\scratchcounter-\c_page_grid_n_of_left - \page_lines_add_numbers_to_box\b_page_grid_column\scratchcounter\c_page_grid_n_of_right\plustwo + \page_marks_synchronize_column\c_page_grid_first_column\c_page_grid_last_column\privatescratchcounter\b_page_grid_column + \ifnum\privatescratchcounter>\c_page_grid_n_of_left + \advance\privatescratchcounter-\c_page_grid_n_of_left + \page_lines_add_numbers_to_box\b_page_grid_column\privatescratchcounter\c_page_grid_n_of_right\plustwo \else - \page_lines_add_numbers_to_box\b_page_grid_column\scratchcounter\c_page_grid_n_of_left\plustwo + \page_lines_add_numbers_to_box\b_page_grid_column\privatescratchcounter\c_page_grid_n_of_left\plustwo \fi \begingroup \edef\currentpagegrid{\currentpagegrid:#1}% diff --git a/tex/context/base/mkiv/page-flt.lua b/tex/context/base/mkiv/page-flt.lua index caa8d490d..53780e420 100644 --- a/tex/context/base/mkiv/page-flt.lua +++ b/tex/context/base/mkiv/page-flt.lua @@ -21,11 +21,8 @@ local C, S, P, lpegmatch = lpeg.C, lpeg.S, lpeg.P, lpeg.match -- we use floatbox, floatwidth, floatheight -- text page leftpage rightpage (todo: top, bottom, margin, order) -local flush_node_list = node.flush_list - local setdimen = tex.setdimen local setcount = tex.setcount -local texgetbox = tex.getbox local texsetbox = tex.setbox local textakebox = nodes.takebox diff --git a/tex/context/base/mkiv/page-flw.mkiv b/tex/context/base/mkiv/page-flw.mkiv index 56fe32e5b..688791fe5 100644 --- a/tex/context/base/mkiv/page-flw.mkiv +++ b/tex/context/base/mkiv/page-flw.mkiv @@ -75,7 +75,7 @@ \fi \to \everydefinetextflow -\let\b_page_textflow_box\zerocount +\newcount\b_page_textflow_box \def\textflowcollector#1% {\csname\??textflowbox#1\endcsname} @@ -141,3 +141,42 @@ \endgroup} \protect \endinput + +% \setuppapersize [A6] +% \setupbodyfont [pagella, 12pt] +% +% \definetextflow [even] [width=\textwidth] +% \definetextflow [odd] [width=\textwidth] +% +% \starttextflow [even] \dorecurse{15}{\input bryson} \stoptextflow +% \starttextflow [odd] \dorecurse {5}{\input knuth } \stoptextflow +% +% \starttext +% +% \doloop { +% \ifodd\realpageno +% \doiftextflowelse{odd} { +% \bgroup +% \vsize\dimexpr\textheight-\strutdp\relax +% \flushtextflow{odd} +% \egroup +% } { +% \null +% } +% \page +% \else +% \doiftextflowelse{even} { +% \bgroup +% \vsize\dimexpr\textheight-\strutdp\relax +% \flushtextflow{even} +% \egroup +% } { +% \null +% } +% \page +% \fi +% \doiftextflowelse{even}\donothing{\doiftextflowelse{odd}\donothing\exitloop} +% } +% +% \stoptext + diff --git a/tex/context/base/mkiv/page-inj.lua b/tex/context/base/mkiv/page-inj.lua index fd66ead08..d3548b4fb 100644 --- a/tex/context/base/mkiv/page-inj.lua +++ b/tex/context/base/mkiv/page-inj.lua @@ -22,7 +22,6 @@ local variables = interfaces.variables local texsetcount = tex.setcount -local v_yes = variables.yes local v_previous = variables.previous local v_next = variables.next diff --git a/tex/context/base/mkiv/page-ins.lua b/tex/context/base/mkiv/page-ins.lua index 235f586c6..4791bc69b 100644 --- a/tex/context/base/mkiv/page-ins.lua +++ b/tex/context/base/mkiv/page-ins.lua @@ -12,8 +12,6 @@ structures = structures or { } structures.inserts = structures.inserts or { } local inserts = structures.inserts -local report_inserts = logs.reporter("inserts") - local allocate = utilities.storage.allocate inserts.stored = inserts.stored or allocate { } -- combining them in one is inefficient in the @@ -21,10 +19,6 @@ inserts.data = inserts.data or allocate { } -- bytecode storage pool local variables = interfaces.variables local v_page = variables.page -local v_columns = variables.columns -local v_firstcolumn = variables.firstcolumn -local v_lastcolumn = variables.lastcolumn -local v_text = variables.text local context = context local implement = interfaces.implement diff --git a/tex/context/base/mkiv/page-ins.mkiv b/tex/context/base/mkiv/page-ins.mkiv index c91073a14..09ba70b70 100644 --- a/tex/context/base/mkiv/page-ins.mkiv +++ b/tex/context/base/mkiv/page-ins.mkiv @@ -55,17 +55,18 @@ \unexpanded\def\page_inserts_synchronize_registers {\currentinsertionnumber\csname\??insertionnumber\currentinsertion\endcsname} -% for practical reasone we still set these elsewhere but that might chaneg in the future +% for practical reasons we still set these elsewhere but that might change in the future % % \global\count\currentinsertionnumber\numexpr\insertionparameter\c!factor/\insertionparameter\c!n\relax % \global\skip \currentinsertionnumber\insertionparameter\c!distance \relax % \global\dimen\currentinsertionnumber\insertionparameter\c!maxheight\relax} +% \floatingpenalty\zerocount \appendtoks \page_inserts_synchronize_registers \to \everysetupinsertion -\unexpanded\def\page_inserts_process#1% beware, this addapts currentinsertion ! +\unexpanded\def\page_inserts_process#1% beware, this adapts currentinsertion ! {\edef\currentinsertion{#1}% \currentinsertionnumber\csname\??insertionnumber\currentinsertion\endcsname \doprocessinsert\currentinsertionnumber} % old method diff --git a/tex/context/base/mkiv/page-lay.mkiv b/tex/context/base/mkiv/page-lay.mkiv index 1fde9e9c9..f2e39c660 100644 --- a/tex/context/base/mkiv/page-lay.mkiv +++ b/tex/context/base/mkiv/page-lay.mkiv @@ -92,9 +92,12 @@ \newdimen\topdistance \newdimen\headerdistance +\newdimen\textdistance \newdimen\footerdistance \newdimen\bottomdistance +\newdimen\textovershoot % available in pagebuilder + %D We need to calculate the extra distances: \newdimen\naturalmarginwidth @@ -107,6 +110,7 @@ \newdimen\naturalrightmargindistance \newdimen\naturaltopdistance \newdimen\naturalheaderdistance +\newdimen\naturaltextdistance \newdimen\naturalfooterdistance \newdimen\naturalbottomdistance @@ -178,6 +182,7 @@ \global\naturalrightmargindistance\layoutparameter\c!rightmargindistance \global\naturaltopdistance \layoutparameter\c!topdistance \global\naturalheaderdistance \layoutparameter\c!headerdistance + \global\naturaltextdistance \layoutparameter\c!textdistance \global\naturalfooterdistance \layoutparameter\c!footerdistance \global\naturalbottomdistance \layoutparameter\c!bottomdistance % @@ -192,6 +197,7 @@ \global\rightmargindistance \layoutdistance\rightmarginwidth\naturalrightmargindistance \global\topdistance \layoutdistance\topheight \naturaltopdistance \global\headerdistance \layoutdistance\headerheight \naturalheaderdistance + \global\textdistance \naturaltextdistance \global\footerdistance \layoutdistance\footerheight \naturalfooterdistance \global\bottomdistance \layoutdistance\bottomheight \naturalbottomdistance } @@ -372,7 +378,11 @@ \doifelseassignment{#2} {\definelayouttarget[#1][#2]} {\setevalue{\??layoutpaper#1}{#2}% - \setevalue{\??layoutprint#1}{#3}}% + \ifthirdargument + \setevalue{\??layoutprint#1}{#3}% + \else + \setevalue{\??layoutprint#1}{#2}% + \fi}% \fi} \appendtoks @@ -447,15 +457,12 @@ \let\setuppaper\page_paper_setup_size_settings \unexpanded\def\adaptpapersize - {\global\let\page_paper_reinstate\page_paper_reinstate_indeed + {\glet\page_paper_reinstate\page_paper_restore \setuppapersize} -\unexpanded\def\page_paper_reinstate_indeed - {\page_paper_restore - \global\let\page_paper_reinstate\relax} - \appendtoks \page_paper_reinstate + \global\let\page_paper_reinstate\relax \to \everyaftershipout \unexpanded\def\page_paper_set_restore#1#2% diff --git a/tex/context/base/mkiv/page-lin.lua b/tex/context/base/mkiv/page-lin.lua index 5b18d9823..8ec4ba5df 100644 --- a/tex/context/base/mkiv/page-lin.lua +++ b/tex/context/base/mkiv/page-lin.lua @@ -50,15 +50,13 @@ local listcodes = nodes.listcodes local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist local whatsit_code = nodecodes.whatsit -local glue_code = nodecodes.glue local glyph_code = nodecodes.glyph local line_code = listcodes.line -local leftskip_code = skipcodes.leftskip local a_displaymath = attributes.private('displaymath') local a_linenumber = attributes.private('linenumber') local a_linereference = attributes.private('linereference') -local a_verbatimline = attributes.private('verbatimline') +----- a_verbatimline = attributes.private('verbatimline') local current_list = { } local cross_references = { } @@ -74,6 +72,10 @@ local setattr = nuts.setattr local getlist = nuts.getlist local getbox = nuts.getbox local getfield = nuts.getfield +----- getdir = nuts.getdir +----- getwidth = nuts.getwidth +local getheight = nuts.getheight +local getdepth = nuts.getdepth local setprop = nuts.setprop local getprop = nuts.getprop @@ -83,17 +85,12 @@ local setfield = nuts.setfield local traverse_id = nuts.traverse_id local traverse = nuts.traverse local copy_node = nuts.copy -local hpack_nodes = nuts.hpack -local linked_nodes = nuts.linked -local insert_node_after = nuts.insert_after -local insert_node_before = nuts.insert_before +----- hpack_nodes = nuts.hpack local is_display_math = nuts.is_display_math local leftmarginwidth = nuts.leftmarginwidth -local nodepool = nuts.pool -local negated_glue = nodepool.negatedglue -local new_hlist = nodepool.hlist -local new_kern = nodepool.kern +----- nodepool = nuts.pool +----- new_kern = nodepool.kern local ctx_convertnumber = context.convertnumber local ctx_makelinenumber = context.makelinenumber @@ -393,7 +390,7 @@ function boxed.stage_one(n,nested) local subtype = getsubtype(n) if subtype ~= line_code then -- go on - elseif getfield(n,"height") == 0 and getfield(n,"depth") == 0 then + elseif getheight(n) == 0 and getdepth(n) == 0 then -- skip funny hlists -- todo: check line subtype else local a = lineisnumbered(n) @@ -412,17 +409,19 @@ function boxed.stage_one(n,nested) end end if getattr(n,a_displaymath) then + -- this probably needs to be adapted ! if is_display_math(n) then check_number(n,a,skip) end else - local v = getattr(list,a_verbatimline) - if not v or v ~= last_v then - last_v = v + -- -- we now prevent nesting anyway .. maybe later we need to check again + -- local v = getattr(list,a_verbatimline) + -- if not v or v ~= last_v then + -- last_v = v check_number(n,a,skip) - else - check_number(n,a,skip,true) - end + -- else + -- check_number(n,a,skip,true) + -- end end skip = false end @@ -485,10 +484,10 @@ function boxed.stage_two(n,m) local li = current_list[i] local n, m, ti = li[1], li[2], t[i] if ti then - -- local d = getfield(n,"dir") + -- local d = getdir(n) -- local l = getlist(n) -- if d == "TRT" then - -- local w = getfield(n,"width") + -- local w = getwidth(n) -- ti = hpack_nodes(linked_nodes(new_kern(-w),ti,new_kern(w))) -- end -- setnext(ti,l) diff --git a/tex/context/base/mkiv/page-lin.mkvi b/tex/context/base/mkiv/page-lin.mkvi index 5756d870b..2692087cc 100644 --- a/tex/context/base/mkiv/page-lin.mkvi +++ b/tex/context/base/mkiv/page-lin.mkvi @@ -174,11 +174,21 @@ % \startlinenumbering[name][<startvalue>|continue|settings] \unexpanded\def\startlinenumbering - {\dodoubleempty\page_lines_start} + {\begingroup + \dodoubleempty\page_lines_start} + +\newcount\c_pages_lines_nesting \def\page_lines_start % we stay downward compatible - {\begingroup - \ifsecondargument + {\advance\c_pages_lines_nesting\plusone + \ifnum\c_pages_lines_nesting>\plusone + \expandafter\dodoubleempty\expandafter\gobbletwooptionals + \else + \expandafter\page_lines_start_indeed + \fi} + +\def\page_lines_start_indeed + {\ifsecondargument \expandafter\page_lines_start_two \else\iffirstargument \doubleexpandafter\page_lines_start_one @@ -276,9 +286,11 @@ \attribute\linenumberattribute\csname\??linenumberinginstance\currentlinenumbering\endcsname\relax} \unexpanded\def\stoplinenumbering - {\attribute\linenumberattribute\attributeunsetvalue - \the\aftereverylinenumbering - \ifconditional\c_page_lines_auto_narrow\par\fi + {\ifconditional\c_pages_lines_nesting=\plusone + \attribute\linenumberattribute\attributeunsetvalue + \the\aftereverylinenumbering + \ifconditional\c_page_lines_auto_narrow\par\fi + \fi \endgroup} % number placement .. will change into (the new) margin code diff --git a/tex/context/base/mkiv/page-mix.lua b/tex/context/base/mkiv/page-mix.lua index c844bd32d..524181c8e 100644 --- a/tex/context/base/mkiv/page-mix.lua +++ b/tex/context/base/mkiv/page-mix.lua @@ -8,11 +8,15 @@ if not modules then modules = { } end modules ["page-mix"] = { -- inserts.getname(name) +-- getfield(l,"head") -> getlist + -- local node, tex = node, tex -- local nodes, interfaces, utilities = nodes, interfaces, utilities -- local trackers, logs, storage = trackers, logs, storage -- local number, table = number, table +-- todo: explore vsplit (for inserts) + local next, type = next, type local concat = table.concat local ceil, floor = math.ceil, math.floor @@ -23,7 +27,6 @@ local trace_detail = false trackers.register("mixedcolumns.detail", function(v) local report_state = logs.reporter("mixed columns") local nodecodes = nodes.nodecodes -local gluecodes = nodes.gluecodes local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist @@ -34,38 +37,40 @@ local insert_code = nodecodes.ins local mark_code = nodecodes.mark local rule_code = nodecodes.rule -local topskip_code = gluecodes.topskip -local lineskip_code = gluecodes.lineskip -local baselineskip_code = gluecodes.baselineskip -local userskip_code = gluecodes.userskip - local nuts = nodes.nuts local tonode = nuts.tonode -local nodetostring = nuts.tostring local listtoutf = nodes.listtoutf local hpack = nuts.hpack local vpack = nuts.vpack -local freenode = nuts.free +local flushnode = nuts.flush local concatnodes = nuts.concat local slidenodes = nuts.slide -- ok here as we mess with prev links intermediately -local getfield = nuts.getfield local setfield = nuts.setfield local setlink = nuts.setlink local setlist = nuts.setlist local setnext = nuts.setnext local setprev = nuts.setprev local setbox = nuts.setbox +local setwhd = nuts.setwhd +local setheight = nuts.setheight +local setdepth = nuts.setdepth +local getfield = nuts.getfield local getnext = nuts.getnext local getprev = nuts.getprev local getid = nuts.getid local getlist = nuts.getlist local getsubtype = nuts.getsubtype local getbox = nuts.getbox -local getskip = nuts.getskip local getattribute = nuts.getattribute +local getwhd = nuts.getwhd +local getkern = nuts.getkern +local getpenalty = nuts.getpenalty +local getwidth = nuts.getwidth +local getheight = nuts.getheight +local getdepth = nuts.getdepth local theprop = nuts.theprop @@ -83,12 +88,7 @@ local variables = interfaces.variables local v_yes = variables.yes local v_global = variables["global"] local v_local = variables["local"] -local v_columns = variables.columns -local v_fixed = variables.fixed -local v_auto = variables.auto local v_none = variables.none -local v_more = variables.more -local v_less = variables.less local v_halfline = variables.halfline local context = context @@ -114,24 +114,31 @@ local forcedbreak = -123 local function collectinserts(result,nxt,nxtid) local inserts, currentskips, nextskips, inserttotal = { }, 0, 0, 0 + local i = result.i + if not i then + i = 0 + result.i = i + end while nxt do if nxtid == insert_code then - inserttotal = inserttotal + getfield(nxt,"height") + getfield(nxt,"depth") + i = i + 1 + result.i = i + inserttotal = inserttotal + getheight(nxt) -- height includes depth local s = getsubtype(nxt) local c = inserts[s] + if trace_detail then + report_state("insert of class %s found",s) + end if not c then + local width = structures.notes.check_spacing(s,i) -- before c = { } inserts[s] = c - local width = getfield(getskip(s),"width") if not result.inserts[s] then currentskips = currentskips + width end nextskips = nextskips + width end c[#c+1] = nxt - if trace_detail then - report_state("insert of class %s found",s) - end elseif nxtid == mark_code then if trace_detail then report_state("mark found") @@ -169,15 +176,15 @@ local function discardtopglue(current,discarded) while current do local id = getid(current) if id == glue_code then - size = size + getfield(current,"width") + size = size + getwidth(current) discarded[#discarded+1] = current current = getnext(current) elseif id == penalty_code then - if getfield(current,"penalty") == forcedbreak then + if getpenalty(current) == forcedbreak then discarded[#discarded+1] = current current = getnext(current) while current and getid(current) == glue_code do - size = size + getfield(current,"width") + size = size + getwidth(current) discarded[#discarded+1] = current current = getnext(current) end @@ -207,7 +214,7 @@ local function stripbottomglue(results,discarded) end local id = getid(t) if id == penalty_code then - if getfield(t,"penalty") == forcedbreak then + if getpenalty(t) == forcedbreak then break else discarded[#discarded+1] = t @@ -216,7 +223,7 @@ local function stripbottomglue(results,discarded) end elseif id == glue_code then discarded[#discarded+1] = t - local width = getfield(t,"width") + local width = getwidth(t) if trace_state then report_state("columns %s, discarded bottom glue %p",i,width) end @@ -253,8 +260,8 @@ local function preparesplit(specification) -- a rather large function slidenodes(head) -- we can have set prev's to nil to prevent backtracking local discarded = { } local originalhead = head - local originalwidth = specification.originalwidth or getfield(list,"width") - local originalheight = specification.originalheight or getfield(list,"height") + local originalwidth = specification.originalwidth or getwidth(list) + local originalheight = specification.originalheight or getheight(list) local current = head local skipped = 0 local height = 0 @@ -302,15 +309,15 @@ local function preparesplit(specification) -- a rather large function } end - local column = 1 - local line = 0 - local result = results[1] - local lasthead = nil - local rest = nil - local lastlocked = nil - local lastcurrent = nil - local lastcontent = nil - local backtracked = false + local column = 1 + local line = 0 + local result = results[1] + local lasthead = nil + local rest = nil + local lastlocked = nil + local lastcurrent = nil + local lastcontent = nil + local backtracked = false if trace_state then report_state("setting collector to column %s",column) @@ -416,12 +423,12 @@ local function preparesplit(specification) -- a rather large function result.height = height result.depth = depth end - head = current - height = 0 - depth = 0 + head = current + height = 0 + depth = 0 if column == nofcolumns then column = 0 -- nicer in trace - rest = head + rest = head return false, 0 else local skipped @@ -442,7 +449,6 @@ local function preparesplit(specification) -- a rather large function local function checked(advance,where,locked) local total = skip + height + depth + advance local delta = total - target --- - 65536*3 local state = "same" local okay = false local skipped = 0 @@ -457,8 +463,8 @@ local function preparesplit(specification) -- a rather large function end end if trace_detail then - report_state("%-7s > column %s, delta %p, threshold %p, advance %p, total %p, target %p => %a (height %p, depth %p, skip %p)", - where,curcol,delta,threshold,advance,total,target,state,skipped,height,depth,skip) + report_state("%-8s > column %s, delta %p, threshold %p, advance %p, total %p, target %p => %a (height %p, depth %p, skip %p)", + where,curcol,delta,threshold,advance,total,target,state,height,depth,skip) end return state, skipped end @@ -478,13 +484,13 @@ local function preparesplit(specification) -- a rather large function head = current local function process_skip(current,nxt) - local advance = getfield(current,"width") + local advance = getwidth(current) if advance ~= 0 then local state, skipped = checked(advance,"glue") if trace_state then - report_state("%-7s > column %s, state %a, advance %p, height %p","glue",column,state,advance,height) + report_state("%-8s > column %s, state %a, advance %p, height %p","glue",column,state,advance,height) if skipped ~= 0 then - report_state("%-7s > column %s, discarded %p","glue",column,skipped) + report_state("%-8s > column %s, discarded %p","glue",column,skipped) end end if state == "quit" then @@ -492,17 +498,17 @@ local function preparesplit(specification) -- a rather large function end height = height + depth + skip depth = 0 -if advance < 0 then - height = height + advance - skip = 0 - if height < 0 then - height = 0 - end -else - skip = height > 0 and advance or 0 -end + if advance < 0 then + height = height + advance + skip = 0 + if height < 0 then + height = 0 + end + else + skip = height > 0 and advance or 0 + end if trace_state then - report_state("%-7s > column %s, height %p, depth %p, skip %p","glue",column,height,depth,skip) + report_state("%-8s > column %s, height %p, depth %p, skip %p","glue",column,height,depth,skip) end else -- what else? ignore? treat as valid as usual? @@ -513,13 +519,13 @@ end end local function process_kern(current,nxt) - local advance = getfield(current,"kern") + local advance = getkern(current) if advance ~= 0 then local state, skipped = checked(advance,"kern") if trace_state then - report_state("%-7s > column %s, state %a, advance %p, height %p, state %a","kern",column,state,advance,height) + report_state("%-8s > column %s, state %a, advance %p, height %p, state %a","kern",column,state,advance,height) if skipped ~= 0 then - report_state("%-7s > column %s, discarded %p","kern",column,skipped) + report_state("%-8s > column %s, discarded %p","kern",column,skipped) end end if state == "quit" then @@ -529,20 +535,20 @@ end depth = 0 skip = 0 if trace_state then - report_state("%-7s > column %s, height %p, depth %p, skip %p","kern",column,height,depth,skip) + report_state("%-8s > column %s, height %p, depth %p, skip %p","kern",column,height,depth,skip) end end end local function process_rule(current,nxt) -- simple variant of h|vlist - local advance = getfield(current,"height") -- + getfield(current,"depth") + local advance = getheight(current) -- + getdepth(current) if advance ~= 0 then local state, skipped = checked(advance,"rule") if trace_state then - report_state("%-7s > column %s, state %a, rule, advance %p, height %p","rule",column,state,advance,inserttotal,height) + report_state("%-8s > column %s, state %a, rule, advance %p, height %p","rule",column,state,advance,inserttotal,height) if skipped ~= 0 then - report_state("%-7s > column %s, discarded %p","rule",column,skipped) + report_state("%-8s > column %s, discarded %p","rule",column,skipped) end end if state == "quit" then @@ -554,7 +560,7 @@ end -- else -- height = height + currentskips -- end - depth = getfield(current,"depth") + depth = getdepth(current) skip = 0 end lastcontent = current @@ -567,7 +573,7 @@ end -- [chapter] [penalty] [section] [penalty] [first line] local function process_penalty(current,nxt) - local penalty = getfield(current,"penalty") + local penalty = getpenalty(current) if penalty == 0 then unlock(penalty) elseif penalty == forcedbreak then @@ -587,14 +593,14 @@ end if trace_state then report_state("cycle: %s, forced column break, same page",cycle) if skipped ~= 0 then - report_state("%-7s > column %s, discarded %p","penalty",column,skipped) + report_state("%-8s > column %s, discarded %p","penalty",column,skipped) end end else if trace_state then report_state("cycle: %s, forced column break, next page",cycle) if skipped ~= 0 then - report_state("%-7s > column %s, discarded %p","penalty",column,skipped) + report_state("%-8s > column %s, discarded %p","penalty",column,skipped) end end return true @@ -617,48 +623,50 @@ end local function process_list(current,nxt) local nxtid = nxt and getid(nxt) line = line + 1 - local inserts, currentskips, nextskips, inserttotal = nil, 0, 0, 0 - local advance = getfield(current,"height") + local inserts, insertskips, nextskips, inserttotal = nil, 0, 0, 0 + local wd, ht, dp = getwhd(current) + local advance = ht + local more = nxt and (nxtid == insert_code or nxtid == mark_code) if trace_state then - report_state("%-7s > column %s, content: %s","line",column,listtoutf(getlist(current),true,true)) + report_state("%-8s > column %s, content: %s","line (1)",column,listtoutf(getlist(current),true,true)) end - if nxt and (nxtid == insert_code or nxtid == mark_code) then - nxt, inserts, localskips, insertskips, inserttotal = collectinserts(result,nxt,nxtid) + if more then + nxt, inserts, insertskips, nextskips, inserttotal = collectinserts(result,nxt,nxtid) end - local state, skipped = checked(advance+inserttotal+currentskips,"line",lastlocked) + local state, skipped = checked(advance+inserttotal+insertskips,more and "line (2)" or "line only",lastlocked) if trace_state then - report_state("%-7s > column %s, state %a, line %s, advance %p, insert %p, height %p","line",column,state,line,advance,inserttotal,height) + report_state("%-8s > column %s, state %a, line %s, advance %p, insert %p, height %p","line (3)",column,state,line,advance,inserttotal,height) if skipped ~= 0 then - report_state("%-7s > column %s, discarded %p","line",column,skipped) + report_state("%-8s > column %s, discarded %p","line (4)",column,skipped) end end if state == "quit" then return true end --- if state == "next" then -- only when profile --- local unprofiled = theprop(current).unprofiled --- if unprofiled then --- local h = unprofiled.height --- local s = unprofiled.strutht --- local t = s/2 --- print("profiled",h,s) --- local snapped = theprop(current).snapped --- if snapped then --- inspect(snapped) --- end --- if h < s + t then --- result.back = - (h - s) --- advance = s --- end --- end --- end + -- if state == "next" then -- only when profile + -- local unprofiled = theprop(current).unprofiled + -- if unprofiled then + -- local h = unprofiled.height + -- local s = unprofiled.strutht + -- local t = s/2 + -- print("profiled",h,s) + -- local snapped = theprop(current).snapped + -- if snapped then + -- inspect(snapped) + -- end + -- if h < s + t then + -- result.back = - (h - s) + -- advance = s + -- end + -- end + -- end height = height + depth + skip + advance + inserttotal if state == "next" then height = height + nextskips else - height = height + currentskips + height = height + insertskips end - depth = getfield(current,"depth") + depth = dp skip = 0 if inserts then -- so we already collect them ... makes backtracking tricky ... alternatively @@ -666,13 +674,11 @@ end appendinserts(result.inserts,inserts) end if trace_state then - report_state("%-7s > column %s, height %p, depth %p, skip %p","line",column,height,depth,skip) + report_state("%-8s > column %s, height %p, depth %p, skip %p","line (5)",column,height,depth,skip) end lastcontent = current end -local kept = head - while current do local id = getid(current) @@ -680,8 +686,6 @@ local kept = head backtracked = false - -- print("process",nodetostring(current)) - if id == hlist_code or id == vlist_code then if process_list(current,nxt) then break end elseif id == glue_code then @@ -693,13 +697,11 @@ local kept = head elseif id == rule_code then if process_rule(current,nxt) then break end else + -- skip inserts and such end if backtracked then - -- print("pickup",nodetostring(current)) nxt = current - else - -- print("move on",nodetostring(current)) end if nxt then @@ -766,12 +768,12 @@ local function finalize(result) local h = r.head if h then setprev(h) -if r.back then - local k = new_glue(r.back) - setlink(k,h) - h = k - r.head = h -end + if r.back then + local k = new_glue(r.back) + setlink(k,h) + h = k + r.head = h + end local t = r.tail if t then setnext(t,nil) @@ -785,10 +787,11 @@ end local l = list[i] local h = new_hlist() t[i] = h - setlist(h,getfield(l,"head")) - setfield(h,"height",getfield(l,"height")) - setfield(h,"depth",getfield(l,"depth")) - setfield(l,"head",nil) + setlist(h,getlist(l)) + local wd, ht, dp = getwhd(l) + -- here ht is still ht + dp ! + setwhd(h,getwidth(h),ht,dp) + setlist(l) end setprev(t[1]) -- needs checking setnext(t[#t]) -- needs checking @@ -947,9 +950,7 @@ local function getsplit(result,n) dp = result.depth end - setfield(v,"width",wd) - setfield(v,"height",ht) - setfield(v,"depth",dp) + setwhd(v,wd,ht,dp) if trace_state then local id = getid(h) @@ -961,8 +962,13 @@ local function getsplit(result,n) end for c, list in next, r.inserts do + local l = concatnodes(list) + for i=1,#list-1 do + setdepth(list[i],0) + end local b = vpack(l) -- multiple arguments, todo: fastvpack + -- setbox("global",c,b) setbox(c,b) r.inserts[c] = nil @@ -986,7 +992,7 @@ end local function cleanup(result) local discarded = result.discarded for i=1,#discarded do - freenode(discarded[i]) + flushnode(discarded[i]) end result.discarded = { } end diff --git a/tex/context/base/mkiv/page-mix.mkiv b/tex/context/base/mkiv/page-mix.mkiv index a8610deb8..7defece12 100644 --- a/tex/context/base/mkiv/page-mix.mkiv +++ b/tex/context/base/mkiv/page-mix.mkiv @@ -57,7 +57,7 @@ % old multicolumns mechanism % % \c!ntop=1, -% \c!rule=\v!off, +% \c!rule=\v!off, : now separator=rule % \c!height=, % \c!blank={\v!line,\v!fixed}, % \c!rulethickness=\linewidth, @@ -359,6 +359,16 @@ \unexpanded\def\startmixedcolumns {\dodoubleempty\page_mix_start_columns} +\def\page_mix_start_columns_checked#1#2% + {\edef\currentmixedcolumnsmethod{\mixedcolumnsparameter\c!method}% + \ifx\currentmixedcolumnsmethod\v!box + \singleexpandafter#1% + \else\ifinsidecolumns + \doubleexpandafter#2% + \else + \doubleexpandafter#1% + \fi\fi} + \unexpanded\def\page_mix_start_columns {\pushmacro\currentmixedcolumns \pushmacro\currentmixedcolumnsmethod @@ -370,15 +380,24 @@ \doubleexpandafter\page_mix_start_columns_c \fi\fi} -\def\page_mix_start_columns_a[#1][#2]% +\def\page_mix_start_columns_a[#1]% [#2]% {\edef\currentmixedcolumns{#1}% - \edef\currentmixedcolumnsmethod{\mixedcolumnsparameter\c!method}% - \mixedcolumnsparameter\c!before\relax + \page_mix_start_columns_checked + \page_mix_start_columns_a_yes + \page_mix_start_columns_a_nop} + +\def\page_mix_start_columns_a_yes[#1]% + {\mixedcolumnsparameter\c!before\relax \begincsname\??mixedcolumnsbefore\currentmixedcolumnsmethod\endcsname\relax \begingroup - \setupcurrentmixedcolumns[#2]% + \setupcurrentmixedcolumns[#1]% \page_mix_initialize_columns - \begincsname\??mixedcolumnsstart\currentmixedcolumnsmethod\endcsname} + \begincsname\??mixedcolumnsstart\currentmixedcolumnsmethod\endcsname + \let\stopmixedcolumns\page_mix_columns_stop_yes} + +\def\page_mix_start_columns_a_nop[#1]% + {\begingroup + \let\stopmixedcolumns\page_mix_columns_stop_nop} \def\page_mix_start_columns_b[#1][#2]% {\doifelseassignment{#1}% @@ -386,44 +405,66 @@ \page_mix_error_b} {\edef\currentmixedcolumns{#1}% \firstargumentfalse}% - \edef\currentmixedcolumnsmethod{\mixedcolumnsparameter\c!method}% - \mixedcolumnsparameter\c!before\relax % so, it doesn't listen to local settings ! + \page_mix_start_columns_checked + \page_mix_start_columns_b_yes + \page_mix_start_columns_b_nop + [#1]} + +\def\page_mix_start_columns_b_yes[#1]% + {\mixedcolumnsparameter\c!before\relax % so, it doesn't listen to local settings ! \begincsname\??mixedcolumnsbefore\currentmixedcolumnsmethod\endcsname\relax \begingroup \iffirstargument \setupcurrentmixedcolumns[#1]% \fi \page_mix_initialize_columns - \begincsname\??mixedcolumnsstart\currentmixedcolumnsmethod\endcsname} % no \relax + \begincsname\??mixedcolumnsstart\currentmixedcolumnsmethod\endcsname % no \relax + \let\stopmixedcolumns\page_mix_columns_stop_yes} + +\def\page_mix_start_columns_b_nop[#1]% + {\begingroup + \let\stopmixedcolumns\page_mix_columns_stop_nop} \def\page_mix_error_b {\writestatus\m!columns{best use an instance of mixed columns}} \def\page_mix_start_columns_c[#1][#2]% {\let\currentmixedcolumns\empty - \edef\currentmixedcolumnsmethod{\mixedcolumnsparameter\c!method}% - \mixedcolumnsparameter\c!before\relax + \page_mix_start_columns_checked + \page_mix_start_columns_c_yes + \page_mix_start_columns_c_nop} + +\def\page_mix_start_columns_c_yes + {\mixedcolumnsparameter\c!before\relax \begincsname\??mixedcolumnsbefore\currentmixedcolumnsmethod\endcsname\relax \begingroup \page_mix_initialize_columns - \begincsname\??mixedcolumnsstart\currentmixedcolumnsmethod\endcsname} + \begincsname\??mixedcolumnsstart\currentmixedcolumnsmethod\endcsname + \let\stopmixedcolumns\page_mix_columns_stop_yes} + +\def\page_mix_start_columns_c_nop + {\begingroup + \let\stopmixedcolumns\page_mix_columns_stop_nop} \unexpanded\def\page_mix_fast_columns_start#1% {\pushmacro\currentmixedcolumns \pushmacro\currentmixedcolumnsmethod \edef\currentmixedcolumns{#1}% \edef\currentmixedcolumnsmethod{\mixedcolumnsparameter\c!method}% - \mixedcolumnsparameter\c!before\relax % so, it doesn't list to local settings ! + \mixedcolumnsparameter\c!before\relax % so, it doesn't listen to local settings ! \begincsname\??mixedcolumnsbefore\currentmixedcolumnsmethod\endcsname\relax \begingroup \page_mix_initialize_columns - \begincsname\??mixedcolumnsstart\currentmixedcolumnsmethod\endcsname} % no \relax + \begincsname\??mixedcolumnsstart\currentmixedcolumnsmethod\endcsname % no \relax + \let\page_mix_fast_columns_stop\page_mix_columns_stop_yes} %D When we stop, we switch over to the balancing routine. After we're done we %D make sure to set the sizes are set, a somewhat redundant action when we %D already have flushed but better be safe. -\unexpanded\def\stopmixedcolumns +\let\page_mix_fast_columns_stop\relax + +\unexpanded\def\page_mix_columns_stop_yes {\begincsname\??mixedcolumnsstop \currentmixedcolumnsmethod\endcsname % no \relax \endgroup \begincsname\??mixedcolumnsafter\currentmixedcolumnsmethod\endcsname\relax @@ -431,7 +472,12 @@ \popmacro\currentmixedcolumnsmethod \popmacro\currentmixedcolumns} -% \unexpanded\def\stopmixedcolumns +\unexpanded\def\page_mix_columns_stop_nop + {\endgroup + \popmacro\currentmixedcolumnsmethod + \popmacro\currentmixedcolumns} + +% \unexpanded\def\page_mix_columns_stop_yes % {\begincsname\??mixedcolumnsstop \currentmixedcolumnsmethod\endcsname % no \relax % \endgroup % \begincsname\??mixedcolumnsafter\currentmixedcolumnsmethod\endcsname\relax @@ -446,18 +492,22 @@ % \fi % } -\let\page_mix_fast_columns_stop\stopmixedcolumns - %D This is how the fast one is used: \unexpanded\def\strc_itemgroups_start_columns {\page_mix_fast_columns_start\s!itemgroupcolumns} -\let\strc_itemgroups_stop_columns\page_mix_fast_columns_stop +\unexpanded\def\strc_itemgroups_stop_columns + {\page_mix_fast_columns_stop} % set by start -\setupmixedcolumns - [\s!itemgroupcolumns] - [\c!grid=\itemgroupparameter\c!grid] +% not used nor documented so commented: +% +% \setupmixedcolumns +% [\s!itemgroupcolumns] +% [\c!grid=\itemgroupparameter\c!grid] +% +% \setupitemgroup +% [\c!grid=\v!yes] % we need a value % better @@ -667,10 +717,11 @@ % maybe intercept empty \clf_mixgetsplit\recurselevel\relax \hskip-\d_page_mix_column_width - \page_mix_hbox to \d_page_mix_column_width \bgroup + \vbox \bgroup + \hsize\d_page_mix_column_width \placenoteinserts - \hss \egroup + \hss \egroup} \unexpanded\def\page_mix_routine_continue @@ -788,25 +839,6 @@ \letvalue{\??mixedcolumnsbefore\s!box}\donothing \letvalue{\??mixedcolumnsafter \s!box}\donothing -% \setvalue{\??mixedcolumnsstart\s!box}% -% {\edef\p_page_mix_strut{\mixedcolumnsparameter\c!strut}% -% \setbox\b_page_mix_collected\vbox\bgroup -% \let\currentoutputroutine\s!mixedcolumn % makes \column work -% \forgetall -% \page_mix_command_set_hsize -% \ifx\p_page_mix_strut\v!yes -% \begstrut -% \ignorespaces -% \fi} -% -% \setvalue{\??mixedcolumnsstop\s!box}% -% {\ifx\p_page_mix_strut\v!yes -% \removeunwantedspaces -% \endstrut -% \fi -% \egroup -% \page_mix_box_balance} - \setvalue{\??mixedcolumnsstart\s!box}% {\edef\p_page_mix_strut{\mixedcolumnsparameter\c!strut}% \setbox\b_page_mix_collected\vbox \bgroup diff --git a/tex/context/base/mkiv/page-mrk.mkiv b/tex/context/base/mkiv/page-mrk.mkiv index 0cd615f8a..43116e84d 100644 --- a/tex/context/base/mkiv/page-mrk.mkiv +++ b/tex/context/base/mkiv/page-mrk.mkiv @@ -25,32 +25,35 @@ \def\pagecutmarkoffset {3mm} % slightly larger than before, and now a fixed size \def\pagecutmarkmargin{10cm} +% maybe all these should be global + \newconditional\c_page_marks_add_more_color \newconditional\c_page_marks_add_more_marking \newconditional\c_page_marks_add_more_lines \newconditional\c_page_marks_add_page_lines \newconditional\c_page_marks_add_more_number +\newcount\c_page_marks_max \newcount\c_page_marks_nx \newcount\c_page_marks_ny \startuniqueMPgraphic{print:color}{w,h,l,o} - if unknown context_crop : input mp-crop.mpiv ; fi ; + loadmodule "crop" ; page_marks_add_color(\MPvar w,\MPvar h,\MPvar l,\MPvar o) ; \stopuniqueMPgraphic \startuniqueMPgraphic{print:marking}{w,h,l,o} - if unknown context_crop : input mp-crop.mpiv ; fi ; + loadmodule "crop" ; page_marks_add_marking(\MPvar w,\MPvar h,\MPvar l,\MPvar o) ; \stopuniqueMPgraphic \startuniqueMPgraphic{print:lines}{w,h,l,o,x,y} - if unknown context_crop : input mp-crop.mpiv ; fi ; + loadmodule "crop" ; page_marks_add_lines(\MPvar w,\MPvar h,\MPvar l,\MPvar o,\MPvar x,\MPvar y) ; \stopuniqueMPgraphic \startuseMPgraphic{print:number}{w,h,l,o,n} - if unknown context_crop : input mp-crop.mpiv ; fi ; + loadmodule "crop" ; page_marks_add_number(\MPvar w,\MPvar h,\MPvar l,\MPvar o,\MPvar n) ; \stopuseMPgraphic @@ -135,6 +138,11 @@ \ifconditional\c_page_marks_add_more_number \page_marks_add_number \fi + \global\advance\c_page_marks_max\minusone + \ifnum\c_page_marks_max>\zerocount\else + \glet\page_marks_add_more\gobbleoneargument + \glet\page_marks_add_page\gobbleoneargument + \fi \egroup} \let\page_marks_add_page\gobbleoneargument @@ -174,13 +182,31 @@ \settrue\c_page_marks_add_more_marking \settrue\c_page_marks_add_more_number} +\installpagecutmark\v!one {\global\c_page_marks_max\plusone} +\installpagecutmark\v!two {\global\c_page_marks_max\plustwo} +\installpagecutmark\v!four{\global\c_page_marks_max\plusfour} + +\unexpanded\def\page_marks_set#1% + {\begincsname\??layoutmarking#1\endcsname} + \appendtoks \setfalse\c_page_marks_add_page_lines \setfalse\c_page_marks_add_more_color \setfalse\c_page_marks_add_more_marking \setfalse\c_page_marks_add_more_lines \setfalse\c_page_marks_add_more_number - \begincsname\??layoutmarking\layoutparameter\c!marking\endcsname + \global\c_page_marks_max\maxcount + \rawprocesscommacommand[\layoutparameter\c!marking]\page_marks_set + \ifnum\c_page_marks_max<\maxcount + \ifconditional\c_page_marks_add_page_lines \else + \ifconditional\c_page_marks_add_more_color \else + \ifconditional\c_page_marks_add_more_marking\else + \ifconditional\c_page_marks_add_more_lines \else + \ifconditional\c_page_marks_add_more_number \else + \settrue\c_page_marks_add_page_lines + \settrue\c_page_marks_add_more_number + \fi\fi\fi\fi\fi + \fi \ifconditional\c_page_marks_add_page_lines \let\page_marks_add_page\page_marks_add_page_indeed \else diff --git a/tex/context/base/mkiv/page-mul.mkiv b/tex/context/base/mkiv/page-mul.mkiv index 5cc60d9ed..fcad2c4c6 100644 --- a/tex/context/base/mkiv/page-mul.mkiv +++ b/tex/context/base/mkiv/page-mul.mkiv @@ -59,7 +59,7 @@ \installcorenamespace {columns} -\installcommandhandler \??columns {columns} \??columns +\installframedcommandhandler \??columns {columns} \??columns %D Going to a new columns is done by means of a \type {\ejectcolumn}. The %D following definition does not always work. @@ -104,7 +104,7 @@ %D A hook: - \let\finishcolumnbox\relax +\let\finishcolumnbox\relax % todo in mkiv %D This will change to a local one: @@ -1457,21 +1457,12 @@ % 3 \input tufte \par \placefigure{}{\framed[width=\hsize,height=3cm]{3}} % \stopcolumns - % \def\backgroundfinishcolumnbox - % {\doifelseinset\@@kloffset{\v!none,\v!overlay} - % {\let\@@kloffset\!!zeropoint} - % {\scratchdimen\@@kloffset - % \advance\scratchdimen -\@@klrulethickness - % \edef\@@kloffset{\the\scratchdimen}}% - % \localframed - % [\??kl] - % [\c!strut=\v!no, - % \c!width=\v!fit, - % \c!height=\v!fit, - % \c!align=]} - - \def\backgroundfinishcolumnbox - {} +\def\backgroundfinishcolumnbox + {\inheritedcolumnsframed} + % [\c!strut=\v!no, + % \c!width=\v!fit, + % \c!height=\v!fit, + % \c!align=]} % to be reconsidered ... (in any case they need to be unexpandable sinze 2011.12.30) @@ -1607,8 +1598,12 @@ \edef\p_option{\columnsparameter\c!option}% \ifx\p_option\v!background \let\finishcolumnbox\backgroundfinishcolumnbox + \doifelseinset{\columnsparameter\c!offset}{\v!none,\v!overlay} + {\d_page_mul_offset\zeropoint}% + {\d_page_mul_offset\dimexpr\columnsparameter\c!offset-\columnsparameter\c!rulethickness\relax}% + \else + \d_page_mul_offset\zeropoint \fi - \d_page_mul_offset\columnsparameter\c!offset\relax \edef\p_command{\columnsparameter\c!command}% \ifx\p_command\empty \else \let\postprocesscolumnline\p_command diff --git a/tex/context/base/mkiv/page-one.mkiv b/tex/context/base/mkiv/page-one.mkiv index a41787133..9bd6951f3 100644 --- a/tex/context/base/mkiv/page-one.mkiv +++ b/tex/context/base/mkiv/page-one.mkiv @@ -213,7 +213,8 @@ \global\advance\d_page_floats_inserted_top\dimexpr\ht\floatbox+\dp\floatbox+\s_page_one_between_top_insert\relax} \def\page_one_insert_top_float % maybe remember last beforeskip - {\insert\namedinsertionnumber\s!topfloat\bgroup + {\floatingpenalty\zerocount + \insert\namedinsertionnumber\s!topfloat\bgroup \forgetall \ifconditional\c_page_one_top_of_insert \ifconditional\c_page_one_correct_top_insert @@ -284,6 +285,7 @@ \page_floats_get \global\advance\d_page_floats_inserted_bottom\dimexpr\ht\floatbox+\dp\floatbox+\d_strc_floats_top\relax \ifdim\d_page_floats_inserted_bottom<\pagegoal\relax + \floatingpenalty\zerocount \insert\namedinsertionnumber\s!bottomfloat\bgroup \forgetall \blank[\rootfloatparameter\c!spacebefore]% @@ -570,6 +572,7 @@ \def\page_one_place_float_bottom_indeed {\global\advance\d_page_floats_inserted_bottom\dimexpr\ht\floatbox+\dp\floatbox+\d_strc_floats_top\relax + \floatingpenalty\zerocount \insert\namedinsertionnumber\s!bottomfloat\bgroup \forgetall \blank[\rootfloatparameter\c!spacebefore]% diff --git a/tex/context/base/mkiv/page-sel.mkvi b/tex/context/base/mkiv/page-sel.mkvi index eb8389032..335d01187 100644 --- a/tex/context/base/mkiv/page-sel.mkvi +++ b/tex/context/base/mkiv/page-sel.mkvi @@ -45,6 +45,9 @@ %D %D This macros inserts the page, according to the settings provided. +%D Beware: width is not the width of the image, but height can be used to control +%D its dimensions. + \installcorenamespace{withpages} \installsetuponlycommandhandler \??withpages {withpages} @@ -64,7 +67,11 @@ {\bgroup \dontcomplain \getfiguredimensions[#filename]% - \setupcurrentwithpages[\c!width=\zeropoint,\c!n=\noffigurepages,#settings]% + \setupcurrentwithpages + [\c!width=\zeropoint,% + \c!n=\noffigurepages,% + \c!category=,% + #settings]% \global\c_page_selectors_n\directwithpagesparameter\c!n\relax \scratchwidth\directwithpagesparameter\c!width\relax \doifinset0{#emptylist} @@ -82,7 +89,11 @@ {\bgroup \dontcomplain \getfiguredimensions[#filename]% - \setupcurrentwithpages[\c!width=\zeropoint,\c!n=\noffigurepages,#settings]% + \setupcurrentwithpages + [\c!width=\zeropoint,% + \c!n=\noffigurepages,% + \c!category=,% + #settings]% \global\c_page_selectors_n\directwithpagesparameter\c!n\relax \scratchwidth\directwithpagesparameter\c!width\relax \edef\p_selection{#selection}% @@ -108,13 +119,19 @@ \egroup} \def\page_selectors_filter_a_page#filename#page% - {\hbox to \textwidth + {\hpack to \textwidth {\ifdim\scratchwidth>\zeropoint \rightorleftpageaction{\scratchwidth\zeropoint}{\hfill}% \fi - \setbox\scratchbox\hbox + \setbox\scratchbox\hpack {\hskip-\scratchwidth - \externalfigure[#filename][\c!page=#page,\c!height=\textheight]\hss}% + \edef\p_category{\directwithpagesparameter\c!category}% \useexternalfigure[foo][width=\textwidth] + \ifx\p_category\empty + \externalfigure[#filename][\c!page=#page,\c!height=\textheight]% + \else + \externalfigure[#filename][\p_category][\c!page=#page]% + \fi + \hss}% \wd\scratchbox\zeropoint \box\scratchbox} \page} @@ -125,14 +142,19 @@ \def\page_selectors_copy[#filename][#settings][#figuresettings]% {\bgroup \getfiguredimensions[#filename]% - \setupcurrentwithpages[\c!marking=\v!off,\c!offset=\zeropoint,\c!n=\noffigurepages,#settings]% + \setupcurrentwithpages + [\c!marking=\v!off,% + \c!offset=\zeropoint,% + \c!n=\noffigurepages,% + \c!category=,% + #settings]% \global\c_page_selectors_n\directwithpagesparameter\c!n\relax \scratchoffset\directwithpagesparameter\c!offset\relax \dorecurse\c_page_selectors_n {\vbox to \textheight {\hsize\textwidth \centeredbox - {\doifelse{\directwithpagesparameter\c!marking}\v!on\cuthbox\hbox % only place where cuthbox is used + {\doifelse{\directwithpagesparameter\c!marking}\v!on\cuthbox\hpack % only place where cuthbox is used {\ifdim\scratchoffset>\zeropoint\relax \advance\vsize -2\scratchoffset \advance\hsize -2\scratchoffset @@ -187,6 +209,7 @@ \c!before=\page,\c!after=\page,\c!inbetween=\blank, \c!frame=,\c!background=,\c!backgroundcolor=, \c!name={#filename}, + \c!category=, #settings]% \global\c_page_selectors_n\directwithpagesparameter\c!n\relax \directwithpagesparameter\c!before @@ -199,7 +222,7 @@ \directwithpagesparameter\c!after \egroup} -\setvalue{\??combinepagesalternative\v!a}% +\setvalue{\??combinepagesalternative\v!a}% use hpacks {\global\combinedpagescounter\directwithpagesparameter\c!start\relax \doloop {\vbox to \textheight @@ -322,8 +345,14 @@ \global\let\slicedpagenumber\!!zerocount \getfiguredimensions[#filename]% \setupcurrentwithpages - [\c!offset=\zeropoint,\c!hoffset=\zeropoint,\c!voffset=\zeropoint, - \c!width=\figurewidth,\c!height=\figureheight,\c!n=\noffigurepages,#oddsettings]% + [\c!offset=\zeropoint,% + \c!hoffset=\zeropoint,% + \c!voffset=\zeropoint, + \c!width=\figurewidth,% + \c!height=\figureheight,% + \c!n=\noffigurepages,% + \c!category=,% + #oddsettings]% \global\c_page_selectors_n\directwithpagesparameter\c!n\relax \ifnum\c_page_selectors_n>\zerocount \definepapersize diff --git a/tex/context/base/mkiv/page-set.mkiv b/tex/context/base/mkiv/page-set.mkiv index 6e6759208..2cea31e1c 100644 --- a/tex/context/base/mkiv/page-set.mkiv +++ b/tex/context/base/mkiv/page-set.mkiv @@ -1515,7 +1515,7 @@ \def\doOTRSETgotoCOLROW#1% <number>|<number>*<number> {\bgroup % really needed - \splitstring#1\at*\to\column\and\row + \splitatasterisk{#1}\column\row \bgroup \ifx\column\empty\else\expanded{\doOTRSETgotoCOLUMN{\column}}\fi \egroup diff --git a/tex/context/base/mkiv/page-sid.mkiv b/tex/context/base/mkiv/page-sid.mkiv index 2c1c624df..f32a443be 100644 --- a/tex/context/base/mkiv/page-sid.mkiv +++ b/tex/context/base/mkiv/page-sid.mkiv @@ -38,7 +38,6 @@ \newdimen \d_page_sides_progress \newdimen \d_page_sides_page_total \newdimen \d_page_sides_saved_depth -\newdimen \d_page_sides_grid_shift \newbox \b_page_sides_bottom @@ -56,8 +55,8 @@ \newdimen \d_page_sides_shift \newdimen \d_page_sides_extrashift -\newdimen \d_page_sided_leftshift -\newdimen \d_page_sided_rightshift +\newdimen \d_page_sides_leftshift +\newdimen \d_page_sides_rightshift \newdimen \d_page_sides_leftskip \newdimen \d_page_sides_rightskip \newdimen \d_page_sides_maximum @@ -78,7 +77,7 @@ \def\page_sides_process_float_cutspace {\global\c_page_sides_float_type\pluseight\page_sides_handle_float} \def\page_sides_process_float_margin {\global\c_page_sides_float_type\pluseight\page_sides_handle_float} -\let\logsidefloat \relax +\let\logsidefloat\relax \newif\iftracesidefloats % public (might change) @@ -288,13 +287,13 @@ % alternative method (unsnapped) % % \def\page_sides_flush_floats_indeed -% {\scratchdimen\dimexpr\d_page_sides_vsize-\d_page_sides_bottomskip-\pagetotal\relax +% {\privatescratchdimen\dimexpr\d_page_sides_vsize-\d_page_sides_bottomskip-\pagetotal\relax % \ifdim\parskip>\zeropoint % why this test ? -% \ifdim\scratchdimen>\parskip -% \blank[\v!nowhite,\the\scratchdimen] % better in stages +% \ifdim\privatescratchdimen>\parskip +% \blank[\v!nowhite,\the\privatescratchdimen] % better in stages % \fi % \else -% \blank[\the\scratchdimen] +% \blank[\the\privatescratchdimen] % \fi} \def\page_sides_check_floats_after_par @@ -364,6 +363,7 @@ \def\page_sides_output_routine_yes % we need to rework this ... add pagediscards and such {\unvbox\normalpagebox % bah, and the discards? +% \pagediscards \setbox\b_page_sides_bottom\lastbox \ifdim\wd\b_page_sides_bottom>\d_page_sides_hsize \penalty-201 % hm, i really need to write this from scatch @@ -416,7 +416,7 @@ % {\ifcase\c_page_sides_float_type % \vbox{#1}% % \or % 1 -% \kern\d_page_sided_leftshift +% \kern\d_page_sides_leftshift % \kern\d_page_sides_shift % \vbox{#1}% % \kern-\d_page_sides_extrashift @@ -429,7 +429,7 @@ % \vbox{#1}% % \kern-\d_page_sides_extrashift % \or % 4 -% \kern\d_page_sided_leftshift +% \kern\d_page_sides_leftshift % \kern\d_page_sides_shift % \vbox{#1\removedepth}% % \kern-\d_page_sides_extrashift @@ -437,7 +437,7 @@ % \kern-\d_page_sides_extrashift % \vbox{#1}% % \kern\d_page_sides_shift -% \kern\d_page_sided_rightshift +% \kern\d_page_sides_rightshift % \or % 6 % \kern-\d_page_sides_extrashift % \vbox{#1}% @@ -450,7 +450,7 @@ % \kern-\d_page_sides_extrashift % \vbox{#1}% % \kern\d_page_sides_shift -% \kern\d_page_sided_rightshift +% \kern\d_page_sides_rightshift % \fi} % % The compact way: @@ -458,9 +458,9 @@ \def\page_sides_relocate_float#1% {\global\setbox\floatbox\hpack {\ifnum\c_page_sides_float_type=\plusfour - \kern\d_page_sided_leftshift + \kern\d_page_sides_leftshift \else\ifnum\c_page_sides_float_type=\plusone - \kern\d_page_sided_leftshift + \kern\d_page_sides_leftshift \fi\fi \ifnum\c_page_sides_float_type>\plusfour \kern-\d_page_sides_extrashift @@ -474,27 +474,27 @@ \kern-\d_page_sides_extrashift \fi \ifnum\c_page_sides_float_type=\pluseight - \kern\d_page_sided_rightshift + \kern\d_page_sides_rightshift \else\ifnum\c_page_sides_float_type=\plusfive - \kern\d_page_sided_rightshift + \kern\d_page_sides_rightshift \fi\fi}} \def\page_sides_apply_vertical_shift {\ifnum\c_page_sides_align=\plusfour \getnoflines{\ht\floatbox}% - \scratchdimen\dimexpr\noflines\lineheight-\strutdepth\relax + \privatescratchdimen\dimexpr\noflines\lineheight-\strutdepth\relax \getrawnoflines\d_page_sides_topskip - \advance\scratchdimen\noflines\lineheight + \advance\privatescratchdimen\noflines\lineheight % todo: maybe rounding problem here % \global\setbox\floatbox\hbox{\lower\lineheight\box\floatbox}% \global\setbox\floatbox\hpack{\lower\strutdepth\box\floatbox}% - \ht\floatbox\scratchdimen + \ht\floatbox\privatescratchdimen \dp\floatbox\zeropoint \fi \ifcase\c_page_sides_align \else \global\d_page_sides_topskip\zeropoint \fi - \scratchdimen + \privatescratchdimen \ifnum\c_page_sides_float_type<\plusfour \d_page_sides_topskip \else\ifnum\c_page_sides_float_type>\plusfive @@ -505,26 +505,26 @@ % the top of the box is at the previous baseline \ifcase\c_page_sides_align % 0 normal - \advance\scratchdimen\strutdepth % or \openstrutdepth + \advance\privatescratchdimen\strutdepth % or \openstrutdepth \or % 1 height - \advance\scratchdimen\strutdepth % or \openstrutdepth + \advance\privatescratchdimen\strutdepth % or \openstrutdepth \or % 2 line \or % 3 depth - \advance\scratchdimen\lineheight % or \openlineheight - \advance\scratchdimen\strutdepth % or \openstrutdepth + \advance\privatescratchdimen\lineheight % or \openlineheight + \advance\privatescratchdimen\strutdepth % or \openstrutdepth \or % 4 grid - \scratchdimen\zeropoint + \privatescratchdimen\zeropoint \or - \advance\scratchdimen\strutheight % or \openstrutheight + \advance\privatescratchdimen\strutheight % or \openstrutheight \fi % new \global\c_page_sides_lines_done\zerocount \ifnum\c_page_sides_n_of_lines>\zerocount - \advance\scratchdimen\c_page_sides_n_of_lines\lineheight + \advance\privatescratchdimen\c_page_sides_n_of_lines\lineheight \fi \global\setbox\floatbox\hpack % why extra box {\vbox - {\vskip\scratchdimen + {\vskip\privatescratchdimen \nointerlineskip \box\floatbox \ifnum\c_page_sides_align=\plusfive \vskip-\lineheight \fi}}% @@ -552,33 +552,25 @@ \prevdepth\d_page_sides_saved_depth} \def\page_sides_place_float_normal - {\d_page_sides_grid_shift\zeropoint % be nice - \page_sides_push_float_inline\firstofoneargument} + {\page_sides_push_float_inline\firstofoneargument} % The following needs some more work .. consider this a quick hack. We % probably need an mkiv hanging grid option. \def\page_sides_place_snap_to_grid#1% - {\snaptogrid[\v!line,\v!offset:\the\d_page_sides_grid_shift]\hbox{#1}} - -% this will be a grid option in float placement: - -\newconstant\c_page_sides_place_grid_shift \c_page_sides_place_grid_shift\plustwo + {\edef\p_grid{\floatparameter\c!grid}% + \ifx\p_grid\empty\else + \snaptogrid[\p_grid]% + \fi + \hbox{#1}} \def\page_sides_place_float_grid {\getrawnoflines\d_page_sides_height % raw ? \d_page_sides_height\noflines\lineheight - \d_page_sides_grid_shift\the\dimexpr \plustwo\lineheight - \ifcase\c_page_sides_place_grid_shift - -3\lineheight % high - \or - -2.5\lineheight % half (does not work currently) - \else - -2\lineheight % low - \fi - \relax \page_sides_push_float_inline\page_sides_place_snap_to_grid} +\let\strc_floats_mark_par_as_free\relax + \def\page_sides_push_float_inline#1% {\begingroup \reseteverypar % needed ! @@ -587,6 +579,7 @@ \page_sides_insert_info \relax \lefttoright % \textdir TLT\relax % or \ifconditional\displaylefttoright below (more work) + \strc_floats_mark_par_as_free \ifcase\c_page_sides_float_type % invalid \or % backspace @@ -650,7 +643,7 @@ \global\setfalse\c_page_floats_room \else \ifdim\dimexpr\pagegoal-\d_page_sides_vsize\relax<\d_page_sides_bottomskip - \global\advance\d_page_sides_vsize \dimen0 + % just weird: \global\advance\d_page_sides_vsize \dimen0 \global\settrue\c_page_sides_short \page_otr_sides_push_penalties % why was this \global\holdinginserts\plusone @@ -671,30 +664,34 @@ % \vskip-\struttotal % \endgroup} -\installtextracker - {sidefloats.anchor} - {\let\page_sides_anchor\page_sides_anchor_yes} - {\let\page_sides_anchor\page_sides_anchor_nop} - -\def\page_sides_anchor_yes - {\darkred - \hskip-5\emwidth - \vrule\s!height.05\exheight\s!depth.05\exheight\s!width10\emwidth} - -\def\page_sides_anchor_nop - {\strut} - -\let\page_sides_anchor\page_sides_anchor_nop +% \installtextracker +% {sidefloats.anchor} +% {\let\page_sides_anchor\page_sides_anchor_yes} +% {\let\page_sides_anchor\page_sides_anchor_nop} +% +% \def\page_sides_anchor_yes +% {\darkred +% \hskip-5\emwidth +% \vrule\s!height.05\exheight\s!depth.05\exheight\s!width10\emwidth} +% +% \def\page_sides_anchor_nop +% {\strut} +% +% \let\page_sides_anchor\page_sides_anchor_nop +% +% \def\page_sides_prepare_space +% {\par +% \begingroup +% \reseteverypar +% \dontleavehmode\hpack to \zeropoint{\page_sides_anchor\hss\strut}% +% \vskip-\parskip +% \vskip-\struttotal +% \inhibitblank +% \endgroup} \def\page_sides_prepare_space - {\par - \begingroup - \reseteverypar - \dontleavehmode\hpack to \zeropoint{\page_sides_anchor\hss\strut}% - \vskip-\parskip - \vskip-\struttotal - \inhibitblank - \endgroup} + {\fakenextstrutline + \inhibitblank} \def\page_sides_handle_float#1% grid (4) is rather experimental {\page_sides_prepare_space @@ -725,8 +722,8 @@ \let\page_sides_check_floats\page_sides_check_floats_indeed \unexpanded\def\page_sides_check_floats_set - {\scratchdimen\dimexpr\d_page_sides_progress+\strutht-\roundingeps\relax - \c_page_sides_n_of_hang\scratchdimen + {\privatescratchdimen\dimexpr\d_page_sides_progress+\strutht-\roundingeps\relax + \c_page_sides_n_of_hang\privatescratchdimen \divide\c_page_sides_n_of_hang \baselineskip\relax \ifnum\c_page_sides_n_of_hang>\zerocount % new from here (needs test case, old code) @@ -735,31 +732,31 @@ \ifcase\c_page_sides_lines_done \global\c_page_sides_lines_done\c_page_sides_n_of_hang \else - \scratchcounter\c_page_sides_lines_done - \advance\scratchcounter-\c_page_sides_n_of_hang - \global\advance\c_page_sides_n_of_lines-\scratchcounter + \privatescratchcounter\c_page_sides_lines_done + \advance\privatescratchcounter-\c_page_sides_n_of_hang + \global\advance\c_page_sides_n_of_lines-\privatescratchcounter \fi \fi % hm, when do we get the parshape branch? needs testing \ifnum\c_page_sides_n_of_lines>\zerocount - \scratchtoks\emptytoks - \scratchcounter\c_page_sides_n_of_lines - \scratchdimen\dimexpr\hsize-\d_page_sides_width\relax + \privatescratchtoks\emptytoks + \privatescratchcounter\c_page_sides_n_of_lines + \privatescratchdimen\dimexpr\hsize-\d_page_sides_width\relax \dorecurse\c_page_sides_n_of_lines - {\appendtoks \zeropoint \hsize \to \scratchtoks}% + {\appendtoks \zeropoint \hsize \to \privatescratchtoks}% \ifnum\c_page_sides_n_of_hang>\c_page_sides_n_of_lines \advance\c_page_sides_n_of_hang -\c_page_sides_n_of_lines\relax - \advance\scratchcounter\c_page_sides_n_of_hang + \advance\privatescratchcounter\c_page_sides_n_of_hang \dorecurse\c_page_sides_n_of_hang % weird, shouldn't that be scratchcounter {\ifnum\c_page_sides_float_type>\plusfour - \appendtoks \zeropoint \scratchdimen \to \scratchtoks + \appendtoks \zeropoint \privatescratchdimen \to \privatescratchtoks \else - \appendtoks \d_page_sides_width\scratchdimen \to \scratchtoks + \appendtoks \d_page_sides_width\privatescratchdimen \to \privatescratchtoks \fi}% \fi \parshape - \numexpr\scratchcounter+\plusone\relax - \the\scratchtoks % \scratchcounter + \numexpr\privatescratchcounter+\plusone\relax + \the\privatescratchtoks % \privatescratchcounter \zeropoint \hsize % \plusone \relax \else @@ -797,12 +794,12 @@ \def\page_sides_inject_dummy_lines {\begingroup - \scratchcounter\pageshrink - \divide\scratchcounter \baselineskip - \advance\scratchcounter \plusone + \privatescratchcounter\pageshrink + \divide\privatescratchcounter \baselineskip + \advance\privatescratchcounter \plusone \parskip\zeropoint - \dorecurse\scratchcounter{\hpack to \hsize{}}% - \kern-\scratchcounter\baselineskip + \dorecurse\privatescratchcounter{\hpack to \hsize{}}% + \kern-\privatescratchcounter\baselineskip \penalty\zerocount \endgroup} diff --git a/tex/context/base/mkiv/page-str.lua b/tex/context/base/mkiv/page-str.lua index b2f597633..4aeffffd8 100644 --- a/tex/context/base/mkiv/page-str.lua +++ b/tex/context/base/mkiv/page-str.lua @@ -8,35 +8,28 @@ if not modules then modules = { } end modules ['page-str'] = { -- streams -> managers.streams --- work in progresss .. unfinished +-- work in progresss .. unfinished .. non-optimized local concat, insert, remove = table.concat, table.insert, table.remove local nodes, node = nodes, node -local nodepool = nodes.pool local tasks = nodes.tasks local implement = interfaces.implement -local new_kern = nodepool.kern -local new_glyph = nodepool.glyph - local nodecodes = nodes.nodecodes -local gluecodes = nodes.gluecodes -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local glue_code = nodecodes.glue - -local slide_nodelist = node.slide -local write_node = node.write -local free_node = node.free -local copy_nodelist = node.copy_list -local vpack_nodelist = node.vpack -local hpack_nodelist = node.hpack + +local slide_node_list = nodes.slide +local write_node = nodes.write +local flush_node = nodes.flush +local copy_node_list = nodes.copy_list +local vpack_node_list = nodes.vpack local settings_to_array = utilities.parsers.settings_to_array +local enableaction = nodes.tasks.enableaction + local texgetdimen = tex.getdimen local texgetbox = tex.getbox @@ -81,7 +74,7 @@ function streams.collect(head,where) end local last = dana[#dana] if last then - local tail = slide_nodelist(last) + local tail = slide_node_list(last) tail.next, head.prev = head, tail elseif last == false then dana[#dana] = head @@ -125,7 +118,7 @@ function streams.flush(name,copy) -- problem: we need to migrate afterwards for i=1,dn do local di = dana[i] if di then - write_node(copy_nodelist(di.list)) -- list, will be option + write_node(copy_node_list(di.list)) -- list, will be option end end if copy then @@ -140,7 +133,7 @@ function streams.flush(name,copy) -- problem: we need to migrate afterwards if di then write_node(di.list) -- list, will be option di.list = nil - free_node(di) + flush_node(di) end end end @@ -173,17 +166,7 @@ function streams.synchronize(list) -- this is an experiment ! local dana = data[name] local slot = dana[m] if slot then --- for n in nodes.traverse(slot) do --- local id = n.id --- if id == hlist_code or id == vlist_code then --- print(n,n.height,n.depth) --- elseif id == glue_code then --- print(n,n.width,gluecodes[n.subtype]) --- else --- print(n) --- end --- end - local vbox = vpack_nodelist(slot) + local vbox = vpack_node_list(slot) local ht, dp = vbox.height, vbox.depth if ht > height then height = ht @@ -220,11 +203,11 @@ function streams.synchronize(list) -- this is an experiment ! else -- this is not yet ok as we also need to keep an eye on vertical spacing -- so we might need to do some splitting or whatever - local tail = vbox.list and slide_nodelist(vbox.list) + local tail = vbox.list and slide_node_list(vbox.list) local n, delta = 0, delta_height -- for tracing while delta > 0 do -- we need to add some interline penalties - local line = copy_nodelist(texgetbox("strutbox")) + local line = copy_node_list(texgetbox("strutbox")) line.height, line.depth = strutht, strutdp if tail then tail.next, line.prev = line, tail @@ -232,9 +215,9 @@ function streams.synchronize(list) -- this is an experiment ! tail = line n, delta = n +1, delta - struthtdp end - dana[m] = vpack_nodelist(vbox.list) + dana[m] = vpack_node_list(vbox.list) vbox.list = nil - free_node(vbox) + flush_node(vbox) if trace_flushing then report_streams("slot %s:%s with delta (%p,%p) is compensated by %s lines",m,i,delta_height,delta_depth,n) end @@ -252,7 +235,7 @@ tasks.appendaction("mvlbuilders", "normalizers", "streams.collect") tasks.disableaction("mvlbuilders", "streams.collect") function streams.initialize() - tasks.enableaction ("mvlbuilders", "streams.collect") + enableaction("mvlbuilders","streams.collect") function streams.initialize() end end @@ -260,8 +243,8 @@ end -- todo: better names, enable etc implement { - name = "initializestream", - actions = streams.initialize, + name = "initializestream", + actions = streams.initialize, onlyonce = true, } diff --git a/tex/context/base/mkiv/page-txt.mkvi b/tex/context/base/mkiv/page-txt.mkvi index 515d16e13..b67e3aa74 100644 --- a/tex/context/base/mkiv/page-txt.mkvi +++ b/tex/context/base/mkiv/page-txt.mkvi @@ -28,9 +28,9 @@ %D {setuptop, setupheader, setuptext, %D setupfooter, setupbottom} %D -%D The macros in this module sometimes look a bit more complicated -%D than needed, which is a direct result of the fact that their -%D ancestors are quite old and upward compatibility is a must. +%D The macros in this module sometimes look a bit more complicated than +%D needed, which is a direct result of the fact that their ancestors are +%D quite old and upward compatibility is a must. %D %D \showsetup{setuptop} %D \showsetup{setupheader} @@ -154,11 +154,10 @@ %D {setuptoptexts, setupheadertexts, setuptexttexts, %D setupfootertexts, setupbottomtexts} %D -%D The next macros take one or more arguments. The exact setup -%D depends on the number of arguments. Although not that -%D intuitive, the current scheme evolved out of the original. -%D When margin and edge texts as well as middle texts showed -%D up, the current odd|/|even scheme surfaced. +%D The next macros take one or more arguments. The exact setup depends on the number +%D of arguments. Although not that intuitive, the current scheme evolved out of the +%D original. When margin and edge texts as well as middle texts showed up, the +%D current odd|/|even scheme surfaced. %D %D \showsetup{setuptoptexts} %D \showsetup{setupheadertexts} @@ -174,80 +173,8 @@ % todo: \setuplayoutelementtext -% An alternative approach is to have more variables but that does not -% make the code less complex (probably more). - -% \unexpanded\def\page_layouts_setup_texts[#vertical][#horizontal][#a][#b][#c][#d]% -% {\ifsixthargument -% \edef\currentlayoutelement{#vertical:#horizontal}% -% \setlayoutelementparameter\c!lefttext -% {\page_layouts_process_element_double -% \c!leftstyle \c!leftcolor \c!leftwidth {#a}% -% \c!rightstyle\c!rightcolor\c!rightwidth{#d}}% -% \setlayoutelementparameter\c!righttext -% {\page_layouts_process_element_double -% \c!rightstyle\c!rightcolor\c!rightwidth{#b}% -% \c!leftstyle \c!leftcolor \c!leftwidth {#c}}% -% \else\iffifthargument -% \edef\currentlayoutelement{#vertical:\v!text}% -% \setlayoutelementparameter\c!lefttext -% {\page_layouts_process_element_double -% \c!leftstyle \c!leftcolor \c!leftwidth {#horizontal}% -% \c!rightstyle\c!rightcolor\c!rightwidth{#c}}% -% \setlayoutelementparameter\c!righttext -% {\page_layouts_process_element_double -% \c!rightstyle\c!rightcolor\c!rightwidth{#a}% -% \c!leftstyle \c!leftcolor \c!leftwidth {#b}}% -% \else\iffourthargument -% \edef\currentlayoutelement{#vertical:#horizontal}% -% \doifelsenothing{\detokenize{#a}} -% {\resetlayoutelementparameter\c!lefttext} -% {\setlayoutelementparameter\c!lefttext -% {\page_layouts_process_element_double -% \c!leftstyle\c!leftcolor\c!leftwidth{#a}% -% \c!leftstyle\c!leftcolor\c!leftwidth{#a}}}% -% \doifelsenothing{\detokenize{#b}} -% {\resetlayoutelementparameter\c!righttext} -% {\setlayoutelementparameter\c!righttext -% {\page_layouts_process_element_double -% \c!rightstyle\c!rightcolor\c!rightwidth{#b}% -% \c!rightstyle\c!rightcolor\c!rightwidth{#b}}}% -% \else\ifthirdargument -% \edef\currentlayoutelement{#vertical:\v!text}% -% \doifelsenothing{\detokenize{#horizontal}} -% {\resetlayoutelementparameter\c!lefttext} -% {\setlayoutelementparameter\c!lefttext -% {\page_layouts_process_element_double -% \c!leftstyle\c!leftcolor\c!leftwidth{#horizontal}% -% \c!leftstyle\c!leftcolor\c!leftwidth{#horizontal}}}% -% \doifelsenothing{\detokenize{#a}} -% {\resetlayoutelementparameter\c!righttext} -% {\setlayoutelementparameter\c!righttext -% {\page_layouts_process_element_double -% \c!rightstyle\c!rightcolor\c!rightwidth{#a}% -% \c!rightstyle\c!rightcolor\c!rightwidth{#a}}}% -% \else\ifsecondargument -% \edef\currentlayoutelement{#vertical:\v!text}% -% \resetlayoutelementparameter\c!lefttext -% \resetlayoutelementparameter\c!righttext -% \doifelsenothing{\detokenize{#horizontal}} -% {\resetlayoutelementparameter\c!middletext} -% {\setlayoutelementparameter\c!middletext -% {\page_layouts_process_element_single\c!style\c!color\c!width{#horizontal}}}% -% \else -% \edef\currentlayoutelement{#vertical:\v!text}% -% \resetlayoutelementparameter\c!lefttext -% \resetlayoutelementparameter\c!righttext -% \resetlayoutelementparameter\c!middletext -% \edef\currentlayoutelement{#vertical:\v!margin}% -% \resetlayoutelementparameter\c!lefttext -% \resetlayoutelementparameter\c!righttext -% \resetlayoutelementparameter\c!middletext -% \edef\currentlayoutelement{#vertical:\v!edge}% -% \resetlayoutelementparameter\c!lefttext -% \resetlayoutelementparameter\c!righttext -% \resetlayoutelementparameter\c!middletext -% \fi\fi\fi\fi\fi} +%D An alternative approach is to have more variables but that does not make the code +%D less complex (probably more). \unexpanded\def\page_layouts_setup_text_six#vertical#horizontal#a#b#c#d% {\edef\currentlayoutelement{#vertical:#horizontal}% @@ -332,8 +259,8 @@ \ifsecondargument\page_layouts_setup_text_two {#vertical}{#horizontal}\else \page_layouts_setup_text_one {#vertical}\fi\fi\fi\fi\fi} -%D Left and right texts are swapped on odd and even pages, but -%D only when double sided typesetting is enabled. +%D Left and right texts are swapped on odd and even pages, but only when double +%D sided typesetting is enabled. \unexpanded\def\page_layouts_process_element_double {\doifelseoddpage @@ -346,8 +273,7 @@ \def\page_layouts_process_element_double_even#lstyle#color#lwidth#lcontent#rstyle#rcolor#rwidth#rcontent% {\page_layouts_process_element_single#rstyle#rcolor#rwidth{#rcontent}} -%D The next macro will be cleaned up and made less messy and -%D dependent. +%D The next macro will be cleaned up and made less messy and dependent. \let\m_page_layouts_element_content\empty @@ -392,8 +318,7 @@ \setvalue{\??layouttextspecial\v!pagenumber}{\page_layouts_place_page_number} \setvalue{\??layouttextspecial\v!date }{\currentdate} -%D When specified, the texts are automatically limited in -%D length. +%D When specified, the texts are automatically limited in length. % % where used ? % @@ -417,9 +342,8 @@ \appendtoks \page_layouts_place_text_line\v!footer\footerheight \to \footertextcontent \appendtoks \page_layouts_place_text_line\v!bottom\bottomheight \to \bottomtextcontent -%D Texts can be disabled, moved up and ignored, depending in -%D the \type {status} variable. This is handled by the next -%D couple of macros. +%D Texts can be disabled, moved up and ignored, depending in the \type {status} +%D variable. This is handled by the next couple of macros. \newcount\c_page_layouts_element_state_n @@ -494,21 +418,31 @@ \page_layouts_place_text_line_indeed#vertical#height% \egroup} +% \setupheadertexts [11] +% \definetext [title] [header] [aa] +% \setupheadertexts [11] [22] +% \definetext [title] [header] [aa] [bb] +% \setupheadertexts [text] [11] [22] +% \definetext [title] [header] [text] [aa] [bb] +% \setupheadertexts [11] [22] [33] [44] +% \definetext [title] [header] [aa] [bb] [cc] [dd] +% \setupheadertexts [text] [11] [22] [33] [44] +% \definetext [title] [header] [text] [aa] [bb] [cc] [dd] + \def\page_layouts_place_text_line_unknown#vertical#height% {\global\settrue\resyncaftertextline \begingroup % new \page_layouts_reset_element_status#vertical% - \csname\namedlayoutelementhash#vertical\textlinestatus\endcsname - \csname\namedlayoutelementhash#vertical\v!text \textlinestatus\endcsname - \csname\namedlayoutelementhash#vertical\v!margin\textlinestatus\endcsname - \csname\namedlayoutelementhash#vertical\v!edge \textlinestatus\endcsname + \begincsname\namedlayoutelementhash{#vertical}\textlinestatus\endcsname + \begincsname\namedlayoutelementhash{#vertical:\v!text}\textlinestatus\endcsname + \begincsname\namedlayoutelementhash{#vertical:\v!margin}\textlinestatus\endcsname + \begincsname\namedlayoutelementhash{#vertical:\v!edge}\textlinestatus\endcsname \page_layouts_place_text_line_indeed#vertical#height% \endgroup} \letvalue{\??layouttextsline\s!unknown}\page_layouts_place_text_line_unknown -%D The following macro has to be called after a page -%D is flushed. +%D The following macro has to be called after a page is flushed. \unexpanded\def\resetlayouttextlines % public {\csname\??layouttextsreset\v!top \endcsname @@ -523,7 +457,7 @@ \fi} \def\getspecificlayouttext#vertical#horizontal#what% - {\csname\namedlayoutelementhash{#vertical:#horizontal}#what\endcsname} + {\begincsname\namedlayoutelementhash{#vertical:#horizontal}#what\endcsname} % \settext[header][text][middle][xxx][yyy] @@ -565,9 +499,8 @@ \letvalue{\??layouttextcontent\v!text:\c!left }\c!lefttext \letvalue{\??layouttextcontent\v!text:\c!right }\c!righttext -%D The placement of a whole line is handled by the next two -%D macros. These are hooked into the general purpose token -%D list registers mentioned before. +%D The placement of a whole line is handled by the next two macros. These are hooked +%D into the general purpose token list registers mentioned before. \def\page_layouts_place_text_line_indeed#vertical#height% {\let\currentlayouttextline#vertical% @@ -692,10 +625,9 @@ \hbox \layoutcomponentboxattribute to #width{#content}% \layoutelementparameter\c!after}} -%D Although it is far better to use backgrounds for this -%D purpose, one can add a rule in the following way. This -%D method makes the rules disappear in case of an empty text -%D line. Consider this a feature. +%D Although it is far better to use backgrounds for this purpose, one can add a rule +%D in the following way. This method makes the rules disappear in case of an empty +%D text line. Consider this a feature. %D %D \starttyping %D \setupheadertexts[left][right] @@ -717,14 +649,13 @@ %D \macros %D {definetext} %D -%D Some macros ago, we implemented the \type {status} option -%D \type {unknown}. This one is used to take care of -%D symbolic texts handlers. +%D Some macros ago, we implemented the \type {status} option \type {unknown}. This +%D one is used to take care of symbolic texts handlers. %D %D \showsetup{definetext} %D -%D The next example demonstrates how we can use this -%D mechanism to provide page (event) dependent text lines. +%D The next example demonstrates how we can use this mechanism to provide page +%D (event) dependent text lines. %D %D \starttyping %D \definetext[chapter][footer][pagenumber] @@ -738,24 +669,6 @@ \unexpanded\def\definetext {\doseventupleempty\page_layouts_define_text} -% \def\page_layouts_define_text[#tag][#vertical][#horizontal][#a][#b][#c][#d]% -% {\ifseventhargument -% \setvalue{\namedlayoutelementhash{#vertical:#horizontal}#tag}% -% {\dosixtupleempty\page_layouts_setup_texts[#vertical][#horizontal][#a][#b][#c][#d]}% -% \else\ifsixthargument -% \setvalue{\namedlayoutelementhash{#vertical}#tag}% -% {\dosixtupleempty\page_layouts_setup_texts[#vertical][#horizontal][#a][#b][#c]}% -% \else\iffifthargument -% \setvalue{\namedlayoutelementhash{#vertical:#horizontal}#tag}% -% {\dosixtupleempty\page_layouts_setup_texts[#vertical][#horizontal][#a][#b]}% -% \else\iffourthargument -% \setvalue{\namedlayoutelementhash{#vertical}#tag}% -% {\dosixtupleempty\page_layouts_setup_texts[#vertical][#horizontal][#a]}% -% \else -% \setvalue{\namedlayoutelementhash{#vertical}#tag}% -% {\dosixtupleempty\page_layouts_setup_texts[#vertical][#horizontal]}% -% \fi\fi\fi\fi} - \def\page_layouts_define_text[#tag][#vertical][#horizontal][#a][#b][#c][#d]% {\ifseventhargument \setvalue{\namedlayoutelementhash{#vertical:#horizontal}#tag}{\page_layouts_setup_text_six {#vertical}{#horizontal}{#a}{#b}{#c}{#d}}% @@ -784,8 +697,8 @@ \installpagebreakmethod \v!footer {\doifnot{\namedlayoutelementparameter\v!footer\c!state}\v!stop{\setuplayoutelement[\v!footer][\c!state=\v!empty]}} -%D While the header and footer lines are moved away from the -%D main text, the top and bottom lines are centered. +%D While the header and footer lines are moved away from the main text, the top and +%D bottom lines are centered. \setuplayoutelement[\v!top ][\c!state=\v!normal,\c!n=0,\c!before=\vss,\c!after=\vss,\c!strut=] \setuplayoutelement[\v!header][\c!state=\v!normal,\c!n=0,\c!before=, \c!after=\vss,\c!strut=\v!yes] @@ -794,10 +707,10 @@ \setuplayoutelement[\v!bottom][\c!state=\v!normal,\c!n=0,\c!before=\vss,\c!after=\vss,\c!strut=] %D Moved here from strc-pag: - -% We reset a previous location but only when it has a pagenumber -% associated. This is a rather messy test but better than the MkII -% way where we use states and keep settings. +%D +%D We reset a previous location but only when it has a pagenumber associated. This +%D is a rather messy test but better than the MkII way where we use states and keep +%D settings. \let\m_page_layouts_page_number_location \relax \let\m_page_layouts_page_number_location_v\relax @@ -918,9 +831,9 @@ \the\toptextcontent \vskip\dimexpr\topheight+\topdistance\relax \the\headertextcontent - \vskip\dimexpr\headerheight+\headerdistance\relax + \vskip\dimexpr\headerheight+\headerdistance+\textdistance\relax \anch_positions_place_anchors - \vskip-\textheight + \vskip\dimexpr-\textdistance-\textheight\relax \the\texttextcontent \vskip\textheight \the\everyendoftextbody @@ -933,14 +846,19 @@ \smashbox\b_page_layouts_element \box\b_page_layouts_element} +% \ifdefined\page_prepare_backgrounds\else +% \let\page_prepare_backgrounds\gobbleoneargument +% \fi + \def\page_insert_body#1#2% {\setbox\b_page_layouts_element\vpack {\offinterlineskip \calculatereducedvsizes \calculatehsizes \swapmargins - \vskip\dimexpr\headerheight+\headerdistance+\layoutparameter\c!textdistance\relax + \vskip\dimexpr\headerheight+\headerdistance+\textdistance\relax \dontleavehmode + %\page_prepare_backgrounds{#2}% \hbox to \makeupwidth {\begingroup \swapmargins @@ -975,26 +893,24 @@ \smashbox\b_page_layouts_element \box\b_page_layouts_element} -%D The main text area has to be combined with some additional -%D (tracing) information. - -% will be stored as normal and overloaded in page-lyr and later in -% page-spr we overload the the stored version .. evenatually i will -% clear up the experimental mess +%D The main text area has to be combined with some additional (tracing) information. +%D +%D This will be stored as normal and overloaded in page-lyr and later in page-spr we +%D overload the the stored version .. evenatually i will clear up the experimental +%D mess. \def\settextpagecontent#1#2#3% #2 and #3 will disappear / is overloaded - {\setbox#1\hbox to \makeupwidth % maybe \hpack + {\setbox#1\hpack to \makeupwidth {\hss % so don't change this \setlayoutcomponentattribute{\v!page:\v!text}% - \vbox \layoutcomponentboxattribute to \textheight + \vpack \layoutcomponentboxattribute to \textheight {\offinterlineskip \freezetextwidth \hsize\textwidth % local variant of \sethsize <<< in columns? \boxmaxdepth\maxdepth \noindent % content can be < \hsize - \page_otr_command_package_contents#2#3}% + \page_otr_command_package_contents#2#3}% this will vbox \hss}% \dp#1\zeropoint} \protect \endinput - diff --git a/tex/context/base/mkiv/publ-aut.lua b/tex/context/base/mkiv/publ-aut.lua index 5ed25f288..6ad8b1296 100644 --- a/tex/context/base/mkiv/publ-aut.lua +++ b/tex/context/base/mkiv/publ-aut.lua @@ -15,7 +15,6 @@ local lpeg = lpeg local type, next, tostring = type, next, tostring local concat = table.concat -local utfchar = utf.char local utfsub = utf.sub local formatters = string.formatters @@ -27,7 +26,6 @@ local context = context ----- commands = commands local implement = interfaces.implement -local ctx_setmacro = interfaces.setmacro local publications = publications @@ -82,13 +80,13 @@ local andsplitter = Ct { "start", local commasplitter = Ct { "start", start = Cs(V("outer")) + (p_empty + Cs((V("inner") + (1-p_comma))^1) + p_comma)^1, - outer = (P("{")/"") * ((V("inner") + P(1-P("}")))^1) * (P("}")/""), + outer = (P("{")/"") * ((V("inner") + P(1-P("}")))^1) * ((P("}") * P(-1))/""), inner = P("{") * ((V("inner") + P(1-P("}")))^1) * P("}"), } local spacesplitter = Ct { "start", start = Cs(V("outer")) + (Cs((V("inner") + (1-p_space))^1) + p_space)^1, - outer = (P("{")/"") * ((V("inner") + P(1-P("}")))^1) * (P("}")/""), + outer = (P("{")/"") * ((V("inner") + P(1-P("}")))^1) * ((P("}") * P(-1))/""), inner = P("{") * ((V("inner") + P(1-P("}")))^1) * P("}"), } @@ -347,7 +345,6 @@ local currentauthorsymbol = nil local manipulators = typesetters.manipulators local splitmanipulation = manipulators.splitspecification local applymanipulation = manipulators.applyspecification -local manipulatormethods = manipulators.methods local function value(i,field) if currentauthordata then diff --git a/tex/context/base/mkiv/publ-dat.lua b/tex/context/base/mkiv/publ-dat.lua index b9c43ac44..8eb923407 100644 --- a/tex/context/base/mkiv/publ-dat.lua +++ b/tex/context/base/mkiv/publ-dat.lua @@ -22,9 +22,6 @@ if not characters then dofile(resolvers.findfile("char-tex.lua")) end -local chardata = characters.data -local lowercase = characters.lower - local lower, find, sub = string.lower, string.find, string.sub local concat, copy, tohash = table.concat, table.copy, table.tohash local next, type, rawget = next, type, rawget @@ -46,9 +43,11 @@ local p_utf8character = lpegpatterns.utf8character local trace = false trackers.register("publications", function(v) trace = v end) local trace_duplicates = true trackers.register("publications.duplicates", function(v) trace = v end) +local trace_strings = false trackers.register("publications.strings", function(v) trace = v end) local report = logs.reporter("publications") local report_duplicates = logs.reporter("publications","duplicates") +local report_strings = logs.reporter("publications","strings") local allocate = utilities.storage.allocate @@ -191,8 +190,7 @@ local defaultshortcuts = allocate { local space = p_whitespace^0 local separator = space * "+" * space -local l_splitter = lpeg.tsplitat(separator) -local d_splitter = lpeg.splitat (separator) +local p_splitter = lpeg.tsplitat(separator) local unknownfield = function(t,k) local v = "extra" @@ -323,7 +321,7 @@ function publications.parenttag(dataset,tag) if not dataset or not tag then report("error in specification, dataset %a, tag %a",dataset,tag) elseif find(tag,"%+") then - local tags = lpegmatch(l_splitter,tag) + local tags = lpegmatch(p_splitter,tag) local parent = tags[1] local current = datasets[dataset] local luadata = current.luadata @@ -541,8 +539,28 @@ do luadata[hashtag] = entries end + local f_invalid = formatters["<invalid: %s>"] + local function resolve(s,dataset) - return dataset.shortcuts[s] or defaultshortcuts[s] or s -- can be number + local e = dataset.shortcuts[s] + if e then + if trace_strings then + report_strings("%a resolves to %a",s,e) + end + return e + end + e = defaultshortcuts[s] + if e then + if trace_strings then + report_strings("%a resolves to default %a",s,e) + end + return e + end + if tonumber(s) then + return s + end + report("error in database, invalid value %a",s) + return f_invalid(s) end local pattern = p_whitespace^0 @@ -582,8 +600,18 @@ do local p_left = (p_whitespace^0 * left) / "" local p_right = (right * p_whitespace^0) / "" + local keyword = C((R("az","AZ","09") + S("@_:-"))^1) + local key = C((1-space-equal)^1) + local tag = C((1-space-comma)^0) + local category = C((1-space-left)^1) + local s_quoted = ((escape*single) + collapsed + (1-single))^0 + local d_quoted = ((escape*double) + collapsed + (1-double))^0 + + local reference = P("@{") * C((R("az","AZ","09") + S("_:-"))^1) * P("}") + local r_value = reference * Carg(1) / resolve + local balanced = P { - [1] = ((escape * (left+right)) + (collapsed + 1 - (left+right))^1 + V(2))^0, + [1] = ((escape * (left+right)) + (collapsed + r_value + 1 - (left+right))^1 + V(2))^0, [2] = left * V(1) * right, } @@ -594,26 +622,23 @@ do local unbalanced = (left/"") * balanced * (right/"") * P(-1) - local keyword = C((R("az","AZ","09") + S("@_:-"))^1) - local key = C((1-space-equal)^1) - local tag = C((1-space-comma)^0) - local reference = keyword - local category = C((1-space-left)^1) - local s_quoted = ((escape*single) + collapsed + (1-single))^0 - local d_quoted = ((escape*double) + collapsed + (1-double))^0 - + local reference = C((R("az","AZ","09") + S("_:-"))^1) local b_value = p_left * balanced * p_right - -- local u_value = p_left * unbalanced * p_right -- get rid of outer { } - -- local s_value = (single/"") * (u_value + s_quoted) * (single/"") - -- local d_value = (double/"") * (u_value + d_quoted) * (double/"") local s_value = (single/"") * (unbalanced + s_quoted) * (single/"") local d_value = (double/"") * (unbalanced + d_quoted) * (double/"") - local r_value = reference * Carg(1) /resolve + local r_value = P("@") * reference * Carg(1) / resolve + + reference * Carg(1) / resolve + local n_value = C(R("09")^1) - local somevalue = d_value + b_value + s_value + r_value + local e_value = Cs((left * balanced * right + (1 - S(",}")))^0) * Carg(1) / function(s,dataset) + return resolve(s,dataset) + end + + local somevalue = d_value + b_value + s_value + r_value + n_value + e_value local value = Cs((somevalue * ((spacing * hash * spacing)/"" * somevalue)^0)) - value = value / function(s) return lpegmatch(lpegpatterns.stripper,s) end + local stripper = lpegpatterns.stripper + value = value / function(s) return lpegmatch(stripper,s) end local forget = percent^1 * (1-lineending)^0 local spacing = spacing * forget^0 * spacing @@ -636,6 +661,9 @@ do -- converttoxml -> dataset.xmldata from dataset.luadata + -- author = "al-" # @AHSAI # "," # @SHAYKH # " " # @AHMAD # " Ibn " # @ZAYNIDDIN + -- author = {al-@{AHSAI}, @{SHAYKH} @{AHMAD} Ibn @{ZAYNIDDIN}} + function publications.loadbibdata(dataset,content,source,kind) if not source then report("invalid source for dataset %a",dataset) @@ -1189,7 +1217,12 @@ do end end - local pagessplitter = lpeg.splitat(P("-")^1) + local pagessplitter = lpeg.splitat(( + P("-") + -- hyphen + P("—") + -- U+2014 + P("–") + -- U+2013 + P("‒") -- U+2012 + )^1) casters.range = function(str) local first, last = lpegmatch(pagessplitter,str) diff --git a/tex/context/base/mkiv/publ-imp-apa.lua b/tex/context/base/mkiv/publ-imp-apa.lua index f2e7f11e1..a725bf22f 100644 --- a/tex/context/base/mkiv/publ-imp-apa.lua +++ b/tex/context/base/mkiv/publ-imp-apa.lua @@ -162,11 +162,13 @@ categories.standard = { categories.book = { sets = { author = { "author", "editor", "publisher", "title" }, + ineditor = { "editor" }, editionset = generic.editionset, doi = generic.doi, }, required = { "author" }, optional = { + "ineditor", "withauthor", "translator", "year", "month", "day", "subtitle", "type", "file", @@ -181,6 +183,7 @@ categories.book = { categories.inbook = { sets = { author = { "author", "editor", "publisher", "title", }, + ineditor = { "editor" }, editionset = generic.editionset, doi = generic.doi, }, @@ -189,9 +192,10 @@ categories.inbook = { "year" , }, optional = { + "ineditor", "withauthor", "translator", "subtitle", "type", "file", - "booktitle", + "booktitle", "subbooktitle", -- APA ignores this: "chapter", "editionset", "series", "month", @@ -206,6 +210,7 @@ categories.inbook = { categories.incollection = { sets = { author = { "author", "editor", "publisher", "title", }, + ineditor = { "editor" }, editionset = generic.editionset, doi = generic.doi, }, @@ -215,8 +220,10 @@ categories.incollection = { "year", }, optional = { + "ineditor", "withauthor", "translator", "subtitle", "type", "file", + "subbooktitle", "editionset", "series", -- APA ignores this: "chapter", "month", @@ -449,7 +456,7 @@ categories.electronic = { categories.film = { sets = { doi = generic.doi, - author = { "producer", "director", }, + author = { "author", "producer", "director", }, }, required = { "author", diff --git a/tex/context/base/mkiv/publ-imp-apa.mkvi b/tex/context/base/mkiv/publ-imp-apa.mkvi index 5600b5722..182802331 100644 --- a/tex/context/base/mkiv/publ-imp-apa.mkvi +++ b/tex/context/base/mkiv/publ-imp-apa.mkvi @@ -33,9 +33,13 @@ [apa] [\c!default=default, \c!specification=apa, - \c!otherstext={\btxspace\btxlabeltext{apa:others}}, + \c!otherstext={\btxspace\btxlabeltext{others}}, %c!journalconversion=\v!normal, - \c!monthconversion=\v!month] + \c!monthconversion=\v!month, + \c!stopper:initials={. }, % with a (breakable) space + \c!separator:names:2={\btxcomma}, % aka namesep - in this namespace + \c!separator:names:3={\btxcomma\btxnobreakspace\textampersand\space}, % comma separated list + \c!separator:names:4={\btxnobreakspace\textampersand\space}] % last of two, no comma! % First, define list and rendering parameters @@ -50,6 +54,7 @@ \setupbtxlist [apa] [\c!alternative=\v!paragraph, + \c!align={normal,verytolerant,stretch}, %\c!width=\v!fit, %\c!distance=.5\emwidth, \c!margin=3.5\emwidth] @@ -61,10 +66,7 @@ \c!etallimit=7, \c!etaldisplay=6, \c!etaloption=last, - \c!authorconversion=invertedshort, - \c!separator:names:2={\btxcomma}, % aka namesep - in this namespace - \c!separator:names:3={\btxcomma\btxnobreakspace\textampersand\space}, % comma separated list - \c!separator:names:4={\btxnobreakspace\textampersand\space}] % last of two, no comma! + \c!authorconversion=invertedshort] % First, we define a namespace for a few special fields @@ -81,11 +83,24 @@ [apa:\s!list:author] \definebtx + [apa:\s!list:ineditor] + [apa:\s!list:editor] + [\c!authorconversion=normalshort] + +\definebtx [apa:\s!list:translator] [apa:\s!list:author] [\c!authorconversion=normalshort] \definebtx + [apa:\s!list:director] + [apa:\s!list:author] + +\definebtx + [apa:\s!list:producer] + [apa:\s!list:author] + +\definebtx [apa:\s!list:suffix] [apa:\s!list] @@ -101,8 +116,8 @@ [apa:\s!list:\s!page] [apa:\s!list] [\c!separator:2={\btxcomma}, - \c!separator:3={\btxcomma\btxlabeltext{apa:and}\space}, - \c!separator:4={\btxspace\btxlabeltext{apa:and}\space}, + \c!separator:3={\btxcomma\btxlabeltext{and}\space}, + \c!separator:4={\btxspace\btxlabeltext{and}\space}, \c!left={\btxleftparenthesis}, \c!right={\btxrightparenthesis}, \c!command={\wordright}] @@ -186,8 +201,17 @@ [apa:\s!list:title] \definebtx + [apa:\s!list:booktitle:inbook] + [apa:\s!list:title] + +\definebtx [apa:\s!list:title:inbook] [apa:\s!list:title] + [\c!style=] % booktitle is set in italics + +\definebtx + [apa:\s!list:booktitle:incollection] + [apa:\s!list:title] \definebtx [apa:\s!list:title:incollection] @@ -199,11 +223,19 @@ [apa:\s!list:title] \definebtx + [apa:\s!list:booktitle:inproceedings] + [apa:\s!list:title] + +\definebtx [apa:\s!list:title:inproceedings] [apa:\s!list:title] [\c!style=] % booktitle is set in italics \definebtx + [apa:\s!list:booktitle:conference] + [apa:\s!list:title] + +\definebtx [apa:\s!list:title:conference] [apa:\s!list:title] [\c!style=] % booktitle is set in italics @@ -274,15 +306,14 @@ [apa:\s!cite] [apa] [\c!alternative=authoryear, - \c!otherstext={\btxcomma\btxlabeltext{apa:others}}, + \c!otherstext={\btxcomma\btxlabeltext{others}}, \c!etallimit=5, \c!etaldisplay=1, % TODO: when 2-4, show all first time, etaldisplay subsequently... \c!authorconversion=\v!name, \c!sorttype=normal, \c!compress=\v!yes, % note that cite sorts only work with compress=yes. - \c!separator:names:2={\btxcomma}, - \c!separator:names:3={\btxcomma\btxlabeltext{apa:and}\space}, % not \textampersand - \c!separator:names:4={\btxspace\btxlabeltext{apa:and}\space}] % not \textampersand + \c!separator:names:3={\btxcomma\btxlabeltext{and}\space}, % not \textampersand + \c!separator:names:4={\btxspace\btxlabeltext{and}\space}] % not \textampersand \definebtx [apa:\s!cite:name] @@ -318,7 +349,9 @@ [apa:\s!cite:author] [\c!left={(}, \c!right={)}, - \c!inbetween={\btxcomma}] + \c!inbetween={\btxcomma}, + \c!separator:names:3={\btxcomma\textampersand\space}, + \c!separator:names:4={\btxspace\textampersand\space}] \definebtx [apa:\s!cite:default] @@ -326,8 +359,8 @@ \definebtx [apa:\s!cite:authoryears] - [apa:\s!cite:authoryear] - [\c!left=, + [apa:\s!cite:author] + [\c!left=, % these two settings are perhaps redundant? \c!right=, \c!inbetween={\btxspace}] @@ -335,7 +368,9 @@ [apa:\s!cite:authornum] [apa:\s!cite:author] [\c!left={(}, - \c!right={)}] + \c!right={)}, + \c!separator:names:3={\btxcomma\textampersand\space}, + \c!separator:names:4={\btxspace\textampersand\space}] \definebtx [apa:\s!cite:author:num] % todo @@ -355,18 +390,30 @@ \c!right={)}] \definebtx + [apa:\s!cite:lefttext] + [apa:\s!cite] + [\c!left=, + \c!right={\btxspace}] + +\definebtx + [apa:\s!cite:righttext] + [apa:\s!cite] + [\c!left={\btxcomma}, + \c!right=] + +\definebtx [apa:\s!cite:year] [apa:\s!cite] [\c!separator:2={\btxcomma}, % :0 and :1 - between items of a list - \c!separator:3={\btxcomma\btxlabeltext{apa:and}\space}, % not \textampersand - \c!separator:4={\btxspace\btxlabeltext{apa:and}\space}] % not \textampersand + \c!separator:3={\btxcomma\btxlabeltext{and}\space}, % not \textampersand + \c!separator:4={\btxspace\btxlabeltext{and}\space}] % not \textampersand \definebtx [apa:\s!cite:title] [apa:\s!cite] [\c!separator:2={\btxcomma}, % :0 and :1 - between items of a list - \c!separator:3={\btxcomma\btxlabeltext{apa:and}\space}, % not \textampersand - \c!separator:4={\btxspace\btxlabeltext{apa:and}\space}, % not \textampersand + \c!separator:3={\btxcomma\btxlabeltext{and}\space}, % not \textampersand + \c!separator:4={\btxspace\btxlabeltext{and}\space}, % not \textampersand \c!command={\language[\currentbtxlanguage]}, % BAH \c!sorttype=none, \c!style=\v!italic] @@ -394,8 +441,8 @@ [\c!left=, \c!right=, \c!separator:2={\btxcomma}, % :0 and :1 - between items of a list - \c!separator:3={\btxcomma\btxlabeltext{apa:and}\space}, % not \textampersand - \c!separator:4={\btxspace\btxlabeltext{apa:and}\space}] % not \textampersand + \c!separator:3={\btxcomma\btxlabeltext{and}\space}, % not \textampersand + \c!separator:4={\btxspace\btxlabeltext{and}\space}] % not \textampersand \definebtx [apa:\s!cite:pages] @@ -418,8 +465,8 @@ \definebtx [apa:\s!cite:url] [apa:\s!cite] - [\c!left={[}, - \c!right={]}] + [\c!left={(}, + \c!right={)}] \definebtx [apa:\s!cite:doi] @@ -440,8 +487,8 @@ [\c!left={Ref.\nbsp}, \c!right=, \c!separator:2={\btxcomma}, - \c!separator:3={\btxspace\btxlabeltext{apa:and}\space}, - \c!separator:4={\btxspace\btxlabeltext{apa:and}\space}] + \c!separator:3={\btxspace\btxlabeltext{and}\space}, + \c!separator:4={\btxspace\btxlabeltext{and}\space}] \definebtx [apa:\s!cite:entry] @@ -463,24 +510,17 @@ \setupbtxlabeltext [en] - [apa:and=and, - apa:number={no.}, + [apa:number={No.}, apa:edition={ed.}, apa:Editor={Ed.}, apa:Editors={Eds.}, apa:Volume={Vol.}, apa:Volumes={Vols.}, - apa:others={et al.}, - apa:with=with, - apa:page={p.}, - apa:pages={pp.}, apa:nd={n.d.}, % no date - apa:mastersthesis={Master's thesis}, - apa:phdthesis={Doctoral dissertation}, - apa:technicalreport={Tech. Rep.}, % Technical report apa:supplement={Suppl.}, % Supplement (not used?) - apa:patent=Patent, apa:MotionPicture={Motion picture}, + apa:Writer=Writer, + apa:Writers=Writers, apa:Producer=Producer, apa:Producers=Producers, apa:Director=Director, @@ -489,29 +529,21 @@ apa:Author=Author, apa:Translator={Trans.}, % Translator(s) apa:Advanced={Advanced online publication}, - apa:Retrieved={Available from}, % {Retrieved from}, - apa:In=In] + apa:Retrieved={Retrieved from}] % {Available from}] \setupbtxlabeltext [nl] - [apa:and=en, - apa:number={nr.}, + [apa:number={Nr.}, apa:edition={ed.}, % editie apa:Editor=Editor, % Ed./Eds. apa:Editors=Editors, apa:Volume={Vol.}, apa:Volumes={Vols.}, - apa:others={et al.}, - apa:with=met, - apa:page={p.}, - apa:pages={pp.}, apa:nd={g.d.} % geen datum - apa:mastersthesis=Masterproef, - apa:phdthesis=Proefschrift, - apa:technicalreport={Technisch rapport}, % Technical report apa:supplement=Supplement, - apa:patent=Octrooi, apa:MotionPicture=Film, % ? + apa:Writer=Scenarioschrijver, % ? + apa:Writers=Schrijvers, % ? apa:Producer=Producent, % ? apa:Producers=Producents, % ? apa:Director=Directeur, @@ -520,29 +552,21 @@ apa:Author=Auteur, apa:Translator=Vertaler, apa:Advanced={Geavanceerde online publicatie}, - apa:Retrieved={Beschikbaar vanaf}, % {Ontvangen van}, - apa:In=In] + apa:Retrieved={Ontvangen van}] % {Beschikbaar vanaf}] \setupbtxlabeltext [fr] - [apa:and=et, - apa:number={n\high{o}}, + [apa:number={N\high{o}}, apa:edition={édition}, apa:Editor=Éditeur, apa:Editors=Éditeurs, apa:Volume=Volume, apa:Volumes=Volumes, - apa:others={et al.}, - apa:with=avec, - apa:page={p.}, - apa:pages={pp.}, apa:nd={s.d.} % sans date - apa:mastersthesis={Thèse de master (DEA, DESS, master)}, - apa:phdthesis={Thèse de doctorat}, - apa:technicalreport={Rapport technique}, apa:supplement=Supplément, - apa:patent=Brevet, apa:MotionPicture={Film cinématographique}, + apa:Writer=Scénariste, + apa:Writers=Scénaristes, apa:Producer=Producteur, apa:Producers=Producteurs, apa:Director=Réalisateur, @@ -551,29 +575,21 @@ apa:Author=Auteur, apa:Translator=Traducteur, apa:Advanced={Publication en ligne anticipée}, - apa:Retrieved={Disponible à}, % {Téléchargé de}, - apa:In=Dans] + apa:Retrieved={Téléchargé de}] % {Disponible à}] \setupbtxlabeltext [de] - [apa:and=und, - apa:number={nr.}, + [apa:number={Nr.}, apa:edition=Auf\/lage, apa:Editor=Herausgeber, % Hrsg./Hg. apa:Editors=Herausgeber, apa:Volume=Band, % Bd. apa:Volumes={Bände}, - apa:others={et al.}, - apa:with=mit, - apa:page={S.}, - apa:pages={S.}, apa:nd={o.D.}, % ohne Datum (mostly: o.J. / ohne Jahr) - apa:mastersthesis={Masterarbeit}, - apa:phdthesis={Dissertation}, - apa:technicalreport={Technischer Bericht}, apa:supplement={Beilage}, % Supplement - apa:patent=Patent, apa:MotionPicture=Kinofilm, % ? + apa:Writer=Drehbuchautor, % ? + apa:Writers=Schriftsteller, % ? apa:Producer=Producer, % ? apa:Producers=Produzenten, % ? apa:Director=Director, % ? @@ -582,31 +598,23 @@ apa:Author=Autor, apa:Translator={Übersetzer}, % Übers. apa:Advanced={Erweiterte Online-Publikation}, - apa:Retrieved={heruntergeladen von}, - apa:In=In] + apa:Retrieved={heruntergeladen von}] % thanks: Andrea Valle \setupbtxlabeltext [it] - [apa:and=e, - apa:number={nº}, + [apa:number={Nº}, apa:edition={ed.}, % edizione apa:Editor={A cura di}, apa:Editors={A cura di}, apa:Volume={Vol.}, % Volume apa:Volumes={Vol.}, % Volumi - apa:others={et al.}, - apa:with=con, - apa:page={p.}, - apa:pages={pp.}, apa:nd={s.d.}, % senza data - apa:mastersthesis={Tesi di laurea}, - apa:phdthesis={Tesi di dottorato}, - apa:technicalreport={Relazione tecnica}, apa:supplement={Supplemento}, - apa:patent=Brevetto, apa:MotionPicture=Film, % ? + apa:Writer=Sceneggiatore, % ? + apa:Writers=Scrittori, % ? apa:Producer=Produttore, apa:Producers=Produttori, apa:Director=Direttore, @@ -615,29 +623,21 @@ apa:Author=Autore, apa:Translator={Trad.}, % Translator(s) apa:Advanced={Pre-pubblicazione on line}, - apa:Retrieved={Accessible online}, - apa:In=In] + apa:Retrieved={Accessible online}] \setupbtxlabeltext [es] - [apa:and=y, - apa:number={nº}, + [apa:number={Nº}, apa:edition={ed.}, % edición apa:Editor=Editor, % Ed./Eds. apa:Editors=Editores, apa:Volume={Vol.}, % Volumen apa:Volumes={Vols.}, % Volúmenes - apa:others={et al.}, - apa:with=con, - apa:page={p.}, - apa:pages={pp.}, apa:nd={s.f.}, % sin fecha - apa:mastersthesis={Tesis de maestría}, - apa:phdthesis={Tesis doctoral}, - apa:technicalreport={Informe técnico}, apa:supplement=Suplemento, - apa:patent=Patente, apa:MotionPicture=Cinematográfica, + apa:Writer=Guionista, % ? + apa:Writers=Escritores, % ? apa:Producer=Productor, apa:Producers=Productores, apa:Director=Director, @@ -646,49 +646,33 @@ apa:Author=Autor, apa:Translator=Traductor, apa:Advanced={Publicación en línea avanzada}, - apa:Retrieved={Disponible desde}, % {Obtenido de}, - apa:In=En] + apa:Retrieved={Obtenido de}] % {Disponible desde}] % cite setups % The following differs from the default returning n.d. if year is empty -\startsetups btx:apa:nd - \btxlabeltext{apa:nd} -\stopsetups - \startsetups btx:apa:cite:author:year - \texdefinition{\s!btx:\s!cite:concat} - %\btxparameter\c!left \ifx\currentbtxfirst\empty - \fastsetup{btx:apa:nd} - \else - \texdefinition {\s!btx:\s!cite:inject} { - \btxcitereference - \currentbtxfirst - } - \ifx\currentbtxsecond\empty \else - \btxparameter\c!range - \texdefinition {\s!btx:\s!cite:inject} { - \currentbtxsecond - } - \fi - \btxflushsuffix + \def\currentbtxfirst{\fastsetup{\s!btx:apa:nd}} \fi - %\btxparameter\c!right + \fastsetup{\s!btx:\s!cite:author:year} \stopsetups \startsetups btx:apa:cite:author:years - \fastsetup{btx:apa:cite:author:year} + \ifx\currentbtxfirst\empty + \def\currentbtxfirst{\fastsetup{\s!btx:apa:nd}} + \fi + \fastsetup{\s!btx:\s!cite:author:years} \stopsetups % used in publ-imp-page.mkvi \startsetups [btx:apa:list:page-or-pages] \ifx\currentbtxlastpage\empty - \btxlabeltext{apa:page} + \btxlabeltext{p} \else - \btxlabeltext{apa:pages} + \btxlabeltext{pp} \fi \btxnbsp \stopsetups @@ -756,7 +740,7 @@ \begingroup \language[\mainbtxlanguage] \btxleftbracket - \btxusecommand [apa:\s!list:title:\currentbtxcategory] { + \btxusecommand [apa:\s!list:#title:\currentbtxcategory] { \btxflush{#title:\mainbtxlanguage} } \btxrightbracket @@ -766,10 +750,10 @@ \stoptexdefinition \starttexdefinition unexpanded btx:apa:composed-title #title - \btxstartstyleandcolor[apa:\s!list:title:\currentbtxcategory] + \btxstartstyleandcolor[apa:\s!list:#title:\currentbtxcategory] \begingroup \language[\currentbtxlanguage] - \btxusecommand [apa:\s!list:title:\currentbtxcategory] { + \btxusecommand [apa:\s!list:#title:\currentbtxcategory] { \btxflush{#title} \btxdoif {sub#title} { \btxcolon @@ -797,6 +781,22 @@ \texdefinition{btx:apa:composed-title}{title} } \btxdoif {title} { + % A book might have an editor AND an author + \doif {\currentbtxcategory} {book} { + \doifnot {\btxfoundname{author}} {editor} { + \btxdoif {ineditor} { % ineditor authorconversion + \btxleftparenthesis + \btxflush{ineditor} + \btxcomma + \btxsingularorplural {ineditor} { + \btxlabeltext{apa:Editor} + } { + \btxlabeltext{apa:Editors} + } + \btxrightparenthesis + } + } + } \btxdoif {translator} { \btxleftparenthesis \btxflush{translator} @@ -820,6 +820,10 @@ } \stoptexdefinition +\startsetups btx:apa:nd + \btxlabeltext{apa:nd} +\stopsetups + \starttexdefinition unexpanded btx:apa:suffixedyear \btxdoifelse {year} { \btxflush{year} @@ -838,8 +842,9 @@ % #author may be author(set) or editor \starttexdefinition unexpanded btx:apa:author-or-editor #author - \btxdoif {#author} { + \btxdoifelse {#author} { \btxflush{#author} + % use \processaction [] [] here? \doifelse {\btxfoundname{#author}} {editor} { \btxleftparenthesis \btxsingularorplural {editor} { @@ -848,16 +853,40 @@ \btxlabeltext{apa:Editors} } \btxrightparenthesis - } { - \doifelse {\btxfoundname{#author}} {producer} { - \btxleftparenthesis - \btxsingularorplural {producer} { - \btxlabeltext{apa:Producer} + } {\doif {\btxfoundname{#author}} {ineditor} { + \btxleftparenthesis + \btxsingularorplural {ineditor} { + \btxlabeltext{apa:Editor} + } { + \btxlabeltext{apa:Editors} + } + \btxrightparenthesis + } } + \doif {\currentbtxcategory} {film} { + \btxleftparenthesis + \doifelse {\btxfoundname{#author}} {director} { + \btxsingularorplural {director} { + \btxlabeltext{apa:Director} } { - \btxlabeltext{apa:Producers} + \btxlabeltext{apa:Directors} + } + } { + \doif {\btxfoundname{#author}} {author} { + \btxsingularorplural {author} { + \btxlabeltext{apa:Writer} + } { + \btxlabeltext{apa:Writers} + } + } + \doif {\btxfoundname{#author}} {producer} { + \btxsingularorplural {producer} { + \btxlabeltext{apa:Producer} + } { + \btxlabeltext{apa:Producers} + } } - \btxrightparenthesis \btxdoif {director} { + \btxrightparenthesis \removeunwantedspaces \btxparameter{\c!separator:names:3} \btxflush{director} @@ -867,27 +896,19 @@ } { \btxlabeltext{apa:Directors} } - \btxrightparenthesis - } - } { - \doif {\btxfoundname{#author}} {director} { - \btxleftparenthesis - \btxsingularorplural {director} { - \btxlabeltext{apa:Director} - } { - \btxlabeltext{apa:Directors} - } - \btxrightparenthesis } } + \btxrightparenthesis } \btxdoif {withauthor} { \btxleftparenthesis - \btxlabeltext{apa:with} + \btxlabeltext{with} \btxspace \btxflush{withauthor} \btxrightparenthesis } + } { + \texdefinition{btx:apa:title} } \stoptexdefinition @@ -918,10 +939,10 @@ \starttexdefinition unexpanded btx:apa:editor-in \btxdoif {booktitle} { - \btxlabeltext{apa:In} + \btxlabeltext{In} \doifnot {\btxfoundname{author}} {editor} { \btxspace - \texdefinition{btx:apa:author-or-editor} {editor} + \texdefinition{btx:apa:author-or-editor} {ineditor} } \btxspace \texdefinition{btx:apa:composed-title}{booktitle} @@ -950,7 +971,7 @@ \btxflush{type} } } { - \btxlabeltext{apa:technicalreport} + \btxlabeltext{technicalreport} } } \btxdoif {volume} { @@ -978,9 +999,9 @@ \btxdoif {pages} { \texdefinition{btx:apa:leftparenthesis-or-comma} \btxoneorrange {pages} { - \btxlabeltext{apa:page} + \btxlabeltext{p} } { - \btxlabeltext{apa:pages} + \btxlabeltext{pp} } \btxnbsp \btxflush{pages} @@ -1030,9 +1051,9 @@ \btxcomma \doif {\currentbtxcategory} {newspaper} { \btxoneorrange {pages} { - \btxlabeltext{apa:page} + \btxlabeltext{p} } { - \btxlabeltext{apa:pages} + \btxlabeltext{pp} } \btxnbsp } @@ -1090,9 +1111,6 @@ % use \btxentry here? \starttexdefinition unexpanded btx:apa:url - \btxspace - \btxlabeltext{apa:Retrieved} - \btxspace \begingroup \setbreakpoints[doi] \ifconditional\btxinteractive @@ -1110,7 +1128,6 @@ % use \btxentry here? \starttexdefinition unexpanded btx:apa:doi - \btxspace \begingroup \setbreakpoints[doi] \ifconditional\btxinteractive @@ -1135,9 +1152,13 @@ \starttexdefinition unexpanded btx:apa:url-doi-note \doif {\btxfoundname{doi}} {url} { + \btxspace + \btxlabeltext{apa:Retrieved} + \btxspace \texdefinition{btx:apa:url} } \doif {\btxfoundname{doi}} {doi} { + \btxspace \texdefinition{btx:apa:doi} } \texdefinition{btx:apa:note} @@ -1285,7 +1306,7 @@ \btxflush{type} } } { - \btxlabeltext{apa:\currentbtxcategory} + \btxlabeltext{\currentbtxcategory} } \btxrightparenthesis \btxdoif {school} { @@ -1365,7 +1386,7 @@ \btxflush{nationality} } \btxspace - \btxlabeltext{apa:patent} + \btxlabeltext{patent} \btxdoif {number} { \btxspace \btxlabeltext{apa:number} @@ -1439,7 +1460,7 @@ } \doifnot {\btxfoundname{title}} {album} { \btxdoif {album} { - \btxlabeltext{apa:In} + \btxlabeltext{In} \btxspace \btxflush{album} \btxperiod diff --git a/tex/context/base/mkiv/publ-imp-aps.mkvi b/tex/context/base/mkiv/publ-imp-aps.mkvi index 674245714..e9cbd7aaf 100644 --- a/tex/context/base/mkiv/publ-imp-aps.mkvi +++ b/tex/context/base/mkiv/publ-imp-aps.mkvi @@ -33,15 +33,15 @@ [aps] [\c!default=default, \c!specification=aps, - \c!otherstext={\btxspace{\it\btxlabeltext{aps:others}}}, + \c!otherstext={\btxspace{\it\btxlabeltext{others}}}, \c!etallimit=10, \c!etaldisplay=\btxparameter\c!etallimit, %c!journalconversion=\v!normal, \c!monthconversion=\v!month, \c!title=\v!yes, \c!separator:names:2={\btxcomma}, - \c!separator:names:3={\btxcomma\btxlabeltext{aps:and}\space}, - \c!separator:names:4={\btxspace\btxlabeltext{aps:and}\space}] + \c!separator:names:3={\btxcomma\btxlabeltext{and}\space}, + \c!separator:names:4={\btxspace\btxlabeltext{and}\space}] % First, define and set list and rendering parameters @@ -53,7 +53,8 @@ \setupbtxlist [aps] - [\c!alternative=b] % spaces + [\c!alternative=b, % spaces + \c!align={normal,verytolerant,stretch}] \definebtx [aps:\s!list] @@ -84,8 +85,8 @@ [aps:\s!list:\s!page] [aps:\s!list] [\c!separator:2={\btxcomma}, - \c!separator:3={\btxcomma\btxlabeltext{aps:and}\space}, - \c!separator:4={\btxspace\btxlabeltext{aps:and}\space}, + \c!separator:3={\btxcomma\btxlabeltext{and}\space}, + \c!separator:4={\btxspace\btxlabeltext{and}\space}, \c!left={\btxleftparenthesis}, \c!right={\btxrightparenthesis}, \c!command={\wordright}] @@ -353,8 +354,8 @@ [\c!left=, \c!right=, \c!separator:2={\btxcomma}, % :0 and :1 - between items of a list - \c!separator:3={\btxcomma\btxlabeltext{aps:and}\space}, - \c!separator:4={\btxspace\btxlabeltext{aps:and}\space}] + \c!separator:3={\btxcomma\btxlabeltext{and}\space}, + \c!separator:4={\btxspace\btxlabeltext{and}\space}] \definebtx [aps:\s!cite:pages] @@ -379,8 +380,8 @@ \definebtx [aps:\s!cite:url] [aps:\s!cite] - [\c!left={[}, - \c!right={]}] + [\c!left={(}, + \c!right={)}] \definebtx [aps:\s!cite:doi] @@ -408,8 +409,8 @@ [\c!left={Ref.\nbsp}, \c!command=, \c!separator:2={\btxcomma}, - \c!separator:3={\btxspace\btxlabeltext{aps:and}\space}, - \c!separator:4={\btxspace\btxlabeltext{aps:and}\space}] + \c!separator:3={\btxspace\btxlabeltext{and}\space}, + \c!separator:4={\btxspace\btxlabeltext{and}\space}] \definebtx [aps:\s!cite:entry] @@ -429,139 +430,85 @@ \setupbtxlabeltext [en] - [aps:and=and, - aps:number={no.}, + [aps:number={no.}, aps:edition={ed.}, aps:Editor={Ed.}, aps:Editors={Eds.}, aps:Volume={Vol.}, aps:Volumes={Vols.}, - aps:others={et al.}, - aps:page={p.}, - aps:pages={pp.}, - aps:mastersthesis={Master's thesis}, - aps:phdthesis={Doctoral dissertation}, - aps:technicalreport={Tech. Rep.}, % Technical report aps:supplement={Suppl.}, % Supplement (not used?) - aps:patent=Patent, aps:inpress={in press}, aps:tobe={to be published}, - aps:unpublished={unpublished}, - aps:In=In] + aps:unpublished={unpublished}] % Check this (google translate!!): \setupbtxlabeltext [nl] - [aps:and=en, - aps:number={nr.}, + [aps:number={nr.}, aps:edition={ed.}, % editie aps:Editor=Editor, % Ed./Eds. aps:Editors=Editors, aps:Volume={Vol.}, aps:Volumes={Vols.}, - aps:others={et al.}, - aps:page={p.}, - aps:pages={pp.}, - aps:mastersthesis=Masterproef, - aps:phdthesis=Proefschrift, - aps:technicalreport={Technisch rapport}, % Technical report aps:supplement=Supplement, - aps:patent=Octrooi, aps:inpress={in press}, % CHECK THESE! aps:tobe={worden gepubliceerd}, - aps:unpublished={onuitgegeven}, - aps:In=In] + aps:unpublished={onuitgegeven}] \setupbtxlabeltext [fr] - [aps:and=et, - aps:number={n\high{o}}, + [aps:number={n\high{o}}, aps:edition={édition}, aps:Editor=Éditeur, aps:Editors=Éditeurs, aps:Volume=Volume, aps:Volumes=Volumes, - aps:others={et al.}, - aps:page={p.}, - aps:pages={pp.}, - aps:mastersthesis={Thèse de master (DEA, DESS, master)}, - aps:phdthesis={Thèse de doctorat}, - aps:technicalreport={Rapport technique}, aps:supplement=Supplément, - aps:patent=Brevet, aps:inpress={sous impression}, aps:tobe={à paraître}, - aps:unpublished={inédit}, % pour un livre - aps:In=Dans] + aps:unpublished={inédit}] % pour un livre \setupbtxlabeltext [de] - [aps:and=und, - aps:number={nr.}, + [aps:number={nr.}, aps:edition=Auf\/lage, aps:Editor=Herausgeber, % Hrsg./Hg. aps:Editors=Herausgeber, aps:Volume=Band, % Bd. aps:Volumes={Bände}, - aps:others={et al.}, - aps:page={S.}, - aps:pages={S.}, - aps:mastersthesis={Masterarbeit}, - aps:phdthesis={Dissertation}, - aps:technicalreport={Technischer Bericht}, aps:supplement={Beilage}, % Supplement - aps:patent=Patent, aps:inpress={in der Presse}, % CHECK THESE! aps:tobe={veröffentlicht werden}, - aps:unpublished={unveröffentlicht}, - aps:In=In] + aps:unpublished={unveröffentlicht}] % thanks: Andrea Valle \setupbtxlabeltext [it] - [aps:and=e, - aps:number={nº}, + [aps:number={nº}, aps:edition={ed.}, % edizione aps:Editor={A cura di}, aps:Editors={A cura di}, aps:Volume={Vol.}, % Volume aps:Volumes={Vol.}, % Volumi - aps:others={et al.}, - aps:page={p.}, - aps:pages={pp.}, - aps:mastersthesis={Tesi di laurea}, - aps:phdthesis={Tesi di dottorato}, - aps:technicalreport={Relazione tecnica}, aps:supplement={Supplemento}, - aps:patent=Brevetto, aps:inpress={in press}, % CHECK THESE! aps:tobe={da pubblicare}, - aps:unpublished={inedito}, - aps:In=In] + aps:unpublished={inedito}] \setupbtxlabeltext [es] - [aps:and=y, - aps:number={nº}, + [aps:number={nº}, aps:edition={ed.}, % edición aps:Editor=Editor, % Ed./Eds. aps:Editors=Editores, aps:Volume={Vol.}, % Volumen aps:Volumes={Vols.}, % Volúmenes - aps:others={et al.}, - aps:page={p.}, - aps:pages={pp.}, - aps:mastersthesis={Tesis de maestría}, - aps:phdthesis={Tesis doctoral}, - aps:technicalreport={Informe técnico}, aps:supplement=Suplemento, - aps:patent=Patente, aps:inpress={en prensa}, % CHECK THESE! aps:tobe={que se publicará}, - aps:unpublished={inédito}, - aps:In=En] + aps:unpublished={inédito}] % cite setups @@ -604,9 +551,9 @@ \startsetups [btx:aps:list:page-or-pages] \ifx\currentbtxlastpage\empty - \btxlabeltext{aps:page} + \btxlabeltext{p}. \else - \btxlabeltext{aps:pages} + \btxlabeltext{pp}. \fi \btxnbsp \stopsetups @@ -706,7 +653,7 @@ \starttexdefinition unexpanded btx:aps:editor-in \btxdoif {booktitle} { - \btxlabeltext{aps:In} + \btxlabeltext{In} \doifnot {\btxfoundname{author}} {editor} { \btxspace \texdefinition{btx:aps:author-or-editor} {editor} @@ -724,7 +671,7 @@ \btxflush{type} } } { - \btxlabeltext{aps:technicalreport} + \btxlabeltext{technicalreport} } \btxcomma } @@ -752,9 +699,9 @@ } \btxdoif {pages} { \btxoneorrange {pages} { - \btxlabeltext{aps:page} + \btxlabeltext{p}. } { - \btxlabeltext{aps:pages} + \btxlabeltext{pp}. } \btxnbsp \btxflush{pages} @@ -764,6 +711,7 @@ \starttexdefinition unexpanded btx:aps:journal-volume-year \btxdoif {journal} { + \btxspace \btxstartstyleandcolor [aps:\s!list:journal] % expandedjournal abbreviatedjournal \btxflush{expandedjournal -> journal} @@ -981,7 +929,7 @@ \btxflush{type} } } { - \btxlabeltext{aps:\currentbtxcategory} + \btxlabeltext{\currentbtxcategory} } \btxrightparenthesis \btxdoif {school} { @@ -1063,7 +1011,7 @@ \btxflush{nationality} } \btxspace - \btxlabeltext{aps:patent} + \btxlabeltext{patent} \btxdoif {number} { \btxspace \btxlabeltext{aps:number} @@ -1074,7 +1022,6 @@ \italiccorrection \endgroup \texdefinition{btx:aps:doi-url} {\texdefinition{btx:aps:publisher-wherefrom-year}} - \texdefinition{btx:aps:url} \texdefinition{btx:aps:note} \stopsetups @@ -1091,11 +1038,10 @@ \btxdoif {organization} { \btxspace \btxflush{organization} - \btxperiod + \btxcomma } \btxdoif {howpublished} { - \btxspace - \btxflush{howpublished} + \texdefinition{btx:aps:doi-url} {\btxspace\btxflush{howpublished}} } \btxleftparenthesis \texdefinition{btx:aps:year} diff --git a/tex/context/base/mkiv/publ-imp-cite.mkvi b/tex/context/base/mkiv/publ-imp-cite.mkvi index cb1c46fe4..be23326b8 100644 --- a/tex/context/base/mkiv/publ-imp-cite.mkvi +++ b/tex/context/base/mkiv/publ-imp-cite.mkvi @@ -61,6 +61,26 @@ <empty> \stopsetups +\startsetups btx:cite:lefttext + \ifx\currentbtxlefttext\empty + \else + \setbtxparameterset{\s!cite}{lefttext} + \btxparameter\c!left + \currentbtxlefttext + \btxparameter\c!right + \fi +\stopsetups + +\startsetups btx:cite:righttext + \ifx\currentbtxrighttext\empty + \else + \setbtxparameterset{\s!cite}{righttext} + \btxparameter\c!left + \currentbtxrighttext + \btxparameter\c!right + \fi +\stopsetups + \startsetups btx:cite:invalid \btxcitereference {\tt <\currentbtxreference>} @@ -103,7 +123,8 @@ \startsetups btx:cite:normal \texdefinition{\s!btx:\s!cite:concat} - \currentbtxlefttext + %\currentbtxlefttext + \fastsetup{\s!btx:\s!cite:lefttext} \ifx\currentbtxfirst\empty \fastsetup{\s!btx:\s!cite:\s!empty} \else\ifx\currentbtxsecond\empty @@ -140,12 +161,14 @@ } } \fi\fi - \currentbtxrighttext + %\currentbtxrighttext + \fastsetup{\s!btx:\s!cite:righttext} \stopsetups \startsetups btx:cite:range \texdefinition{\s!btx:\s!cite:concat} - \currentbtxlefttext + %\currentbtxlefttext + \fastsetup{\s!btx:\s!cite:lefttext} \ifx\currentbtxfirst\empty \fastsetup{\s!btx:\s!cite:\s!empty} \else @@ -161,14 +184,16 @@ } } \fi - \currentbtxrighttext + %\currentbtxrighttext + \fastsetup{\s!btx:\s!cite:righttext} \stopsetups % somehow related to keywords: \startsetups btx:cite:listelement \texdefinition{\s!btx:\s!cite:concat} - \currentbtxlefttext + %\currentbtxlefttext + \fastsetup{\s!btx:\s!cite:lefttext} \ifx\currentbtxfirst\empty \fastsetup{\s!btx:\s!cite:\s!empty} \else @@ -177,14 +202,17 @@ \currentbtxfirst } \fi - \currentbtxrighttext + %\currentbtxrighttext + \fastsetup{\s!btx:\s!cite:righttext} \stopsetups \startsetups \s!btx:\s!cite:entry \texdefinition{\s!btx:\s!cite:concat} - \currentbtxlefttext + %\currentbtxlefttext + \fastsetup{\s!btx:\s!cite:lefttext} \btxhandleciteentry - \currentbtxrighttext + %\currentbtxrighttext + \fastsetup{\s!btx:\s!cite:righttext} \stopsetups % these three are goodies to get something but are not set up as it makes no @@ -259,7 +287,7 @@ \fastsetup{\s!btx:\s!cite:normal} \stopsetups -% the following is kind of specific, but can be used in many renderings +% the following are kind of specific, but can be used in many renderings \startsetups btx:cite:url \ifx\currentbtxfirst\empty @@ -267,13 +295,29 @@ \else\ifconditional\btxinteractive \goto { \btxcitereference - \hyphenatedurl{\doif{\currentbtxcitealternative}{doi}{doi:}\currentbtxfirst} + \hyphenatedurl{\currentbtxfirst} + } [ + url(\currentbtxfirst) + ] + \else + \btxcitereference + \hyphenatedurl{\currentbtxfirst} + \fi\fi +\stopsetups + +\startsetups btx:cite:doi + \ifx\currentbtxfirst\empty + \fastsetup{\s!btx:\s!cite:\s!empty} + \else\ifconditional\btxinteractive + \goto { + \btxcitereference + \hyphenatedurl{doi:\currentbtxfirst} } [ - url(\doif{\currentbtxcitealternative}{doi}{http://dx.doi.org/}\currentbtxfirst) + url(http://dx.doi.org/\currentbtxfirst) ] \else \btxcitereference - \hyphenatedurl{\doif{\currentbtxcitealternative}{doi}{doi:}\currentbtxfirst} + \hyphenatedurl{doi:\currentbtxfirst} \fi\fi \stopsetups diff --git a/tex/context/base/mkiv/publ-imp-default.mkvi b/tex/context/base/mkiv/publ-imp-default.mkvi index f5c99ac18..564bfcf4e 100644 --- a/tex/context/base/mkiv/publ-imp-default.mkvi +++ b/tex/context/base/mkiv/publ-imp-default.mkvi @@ -23,6 +23,10 @@ \c!sorttype=\v!default, \c!numbering=num] +\setupbtxlist + [default] + [\c!align={normal,verytolerant,stretch}] + \definebtx [\s!default] [\c!default=, % we do not want to fall|-|back on ourself. @@ -275,6 +279,18 @@ [\c!left={(}, \c!right={)}] +\definebtx + [\s!default:\s!cite:lefttext] + [\s!default:\s!cite] + [\c!left=, + \c!right=] + +\definebtx + [\s!default:\s!cite:righttext] + [\s!default:\s!cite] + [\c!left=, + \c!right=] + % Multilingual text strings \setupbtxlabeltext @@ -496,12 +512,14 @@ %D Experiment: -\startsetups btx:default:lefttext - \currentbtxlefttext -\stopsetups +%D See publ-imp-cite.mkvi +% +%\startsetups btx:default:cite:lefttext +% \currentbtxlefttext +%\stopsetups -\startsetups btx:default:righttext - \currentbtxrighttext -\stopsetups +%\startsetups btx:default:cite:righttext +% \currentbtxrighttext +%\stopsetups \stopbtxrenderingdefinitions diff --git a/tex/context/base/mkiv/publ-ini.lua b/tex/context/base/mkiv/publ-ini.lua index c30f780f1..52642c89d 100644 --- a/tex/context/base/mkiv/publ-ini.lua +++ b/tex/context/base/mkiv/publ-ini.lua @@ -24,7 +24,6 @@ if not modules then modules = { } end modules ['publ-ini'] = { local next, rawget, type, tostring, tonumber = next, rawget, type, tostring, tonumber local match, find, gsub = string.match, string.find, string.gsub local concat, sort, tohash = table.concat, table.sort, table.tohash -local utfsub = utf.sub local mod = math.mod local formatters = string.formatters local allocate = utilities.storage.allocate @@ -38,7 +37,6 @@ local upper = utf.upper local report = logs.reporter("publications") local report_cite = logs.reporter("publications","cite") local report_list = logs.reporter("publications","list") -local report_reference = logs.reporter("publications","reference") local report_suffix = logs.reporter("publications","suffix") local trace = false trackers.register("publications", function(v) trace = v end) @@ -72,8 +70,6 @@ local v_yes = variables.yes local v_no = variables.no local v_all = variables.all local v_always = variables.always -local v_hidden = variables.hidden -local v_list = variables.list local v_text = variables.text local v_doublesided = variables.doublesided local v_default = variables.default @@ -81,8 +77,6 @@ local v_dataset = variables.dataset local conditionals = tex.conditionals -local numbertochar = converters.characters - local logsnewline = logs.newline local logspushtarget = logs.pushtarget local logspoptarget = logs.poptarget @@ -108,19 +102,16 @@ manipulatormethods.WORDS = converters.WORDS local context = context local commands = commands local implement = interfaces.implement -local ctx_setmacro = interfaces.setmacro local ctx_doifelse = commands.doifelse local ctx_doif = commands.doif local ctx_doifnot = commands.doifnot local ctx_gobbletwoarguments = context.gobbletwoarguments -local ctx_btxdirectlink = context.btxdirectlink local ctx_btxhandlelistentry = context.btxhandlelistentry local ctx_btxhandlelisttextentry = context.btxhandlelisttextentry local ctx_btxhandlecombientry = context.btxhandlecombientry local ctx_btxchecklistentry = context.btxchecklistentry -local ctx_btxchecklistcombi = context.btxchecklistcombi local ctx_btxsetdataset = context.btxsetdataset local ctx_btxsettag = context.btxsettag @@ -142,10 +133,8 @@ local ctx_btxsetrighttext = context.btxsetrighttext local ctx_btxsetbefore = context.btxsetbefore local ctx_btxsetafter = context.btxsetafter local ctx_btxsetbacklink = context.btxsetbacklink -local ctx_btxsetbacktrace = context.btxsetbacktrace local ctx_btxsetcount = context.btxsetcount local ctx_btxsetconcat = context.btxsetconcat -local ctx_btxsetoveflow = context.btxsetoverflow local ctx_btxsetfirstpage = context.btxsetfirstpage local ctx_btxsetlastpage = context.btxsetlastpage local ctx_btxsetfirstinternal = context.btxsetfirstinternal @@ -1995,6 +1984,33 @@ do arguments = { "string", "string" } } + local function identical(a,b) + local na, nb = #a, #b + if na ~= nb then + return false + end + if na > 0 then + for i=1,na do + if not identical(a[i],b[i]) then + return false + end + end + return true + end + local ha, hb = a.hash, b.hash + if ha then + return ha == hb + end + for k, v in next, a do + if k == "original" or k == "snippets" then + -- skip diagnostic info + elseif v ~= b[k] then + return false + end + end + return true + end + function lists.sameasprevious(dataset,i,name,order,method) local rendering = renderings[dataset] local list = rendering.list @@ -2041,7 +2057,7 @@ do if c_casted and c_casted == p_casted then sameentry = true elseif type(c_casted) == "table" and type(p_casted) == "table" then - sameentry = table.identical(c_casted,p_casted) + sameentry = identical(c_casted,p_casted) end end if trace_detail then diff --git a/tex/context/base/mkiv/publ-ini.mkiv b/tex/context/base/mkiv/publ-ini.mkiv index 29ba543cd..5f9aaa692 100644 --- a/tex/context/base/mkiv/publ-ini.mkiv +++ b/tex/context/base/mkiv/publ-ini.mkiv @@ -14,6 +14,8 @@ % TODO: s! vs v! for default and neutral key/values % todo: too many refs in list +% TODO A.-B. Foo (dash as connector, see JMH) + % todo: no need for all these %'s % todo: tagging @@ -77,6 +79,8 @@ \definelabelclass[btxlabel][2] +\clf_definelabels{btxlabel}{btx}\s!false\relax + % It is not that trivial to come up with a proper organization of setup % and control commands for publications. This is because we have complex % inline as well as extensive list rendering. The rules are partially @@ -1094,7 +1098,10 @@ \unexpanded\def\currentbtxciteauthor % always author {\begingroup - \setbtxparameterset\s!cite\s!author + %\setbtxparameterset\s!cite\s!author + % the alternatives inherit from cite:author + % and APA distinguishes authoryears from authoryear ("and" vs. "&") + \setbtxparameterset\s!cite\currentbtxcitealternative \clf_btxauthor {\currentbtxdataset}% {\currentbtxtag}% diff --git a/tex/context/base/mkiv/publ-reg.lua b/tex/context/base/mkiv/publ-reg.lua index 3f276b49a..b40fbc80a 100644 --- a/tex/context/base/mkiv/publ-reg.lua +++ b/tex/context/base/mkiv/publ-reg.lua @@ -9,7 +9,6 @@ if not modules then modules = { } end modules ['publ-reg'] = { local formatters = string.formatters local concat = table.concat local sortedhash = table.sortedhash -local lpegmatch = lpeg.match local context = context @@ -135,7 +134,6 @@ implement { local ctx_dosetfastregisterentry = context.dosetfastregisterentry -- register entry key ------ p_keywords = lpeg.tsplitat(lpeg.patterns.whitespace^0 * lpeg.P(";") * lpeg.patterns.whitespace^0) local components = publications.components.author local f_author = formatters[ [[\btxindexedauthor{%s}{%s}{%s}{%s}{%s}{%s}]] ] diff --git a/tex/context/base/mkiv/publ-sor.lua b/tex/context/base/mkiv/publ-sor.lua index 218d11093..30a0d9bdd 100644 --- a/tex/context/base/mkiv/publ-sor.lua +++ b/tex/context/base/mkiv/publ-sor.lua @@ -217,6 +217,7 @@ local function sortsequence(dataset,list,sorttype) if type(action) == "function" then local valid = action(dataset,list,method) if valid and #valid > 0 then +-- sorters.setlanguage(options.language,options.method) sorters.sort(valid,compare) return valid else diff --git a/tex/context/base/mkiv/publ-tra.lua b/tex/context/base/mkiv/publ-tra.lua index 4b03307ac..b3d40be61 100644 --- a/tex/context/base/mkiv/publ-tra.lua +++ b/tex/context/base/mkiv/publ-tra.lua @@ -42,7 +42,6 @@ local ctx_monobold = ctx_formatted.monobold local ctx_verbatim = ctx_formatted.verbatim local ctx_rotate = context.rotate -local ctx_llap = context.llap local ctx_rlap = context.rlap local ctx_page = context.page @@ -102,9 +101,6 @@ function tracers.showdatasetcompleteness(settings) local fielddata = specification and specifications[specification] or specifications.apa local categories = fielddata.categories - -- local lpegmatch = lpeg.match - -- local texescape = lpeg.patterns.texescape - local preamble = { "|lTBw(5em)|lBTp(10em)|plT|" } local function identified(tag,category,crossref,index) @@ -145,8 +141,8 @@ function tracers.showdatasetcompleteness(settings) ctx_NC() if indirect then context("\\darkblue") - ctx_verbatim(value) - elseif value then + end + if value then ctx_verbatim(value) end ctx_NC() ctx_NR() @@ -157,7 +153,7 @@ function tracers.showdatasetcompleteness(settings) local function special(done,key,value) ctx_NC() if not done then ctx_monobold("special") end ctx_NC() context(key) - ctx_NC() ctx_verbatim(value) + ctx_NC() if value then ctx_verbatim(value) end ctx_NC() ctx_NR() return done or true end @@ -165,7 +161,7 @@ function tracers.showdatasetcompleteness(settings) local function extra(done,key,value) ctx_NC() if not done then ctx_monobold("extra") end ctx_NC() context(key) - ctx_NC() ctx_verbatim(value) + ctx_NC() if value then ctx_verbatim(value) end ctx_NC() ctx_NR() return done or true end @@ -352,7 +348,9 @@ function tracers.showdatasetauthors(settings) ctx_verbatim(i) end ctx_NC() - ctx_verbatim(k) + if k then + ctx_verbatim(k) + end ctx_EQ() if type(v) == "table" then local t = { } @@ -364,8 +362,9 @@ function tracers.showdatasetauthors(settings) t[i] = vi end end - ctx_verbatim(concat(t, " | ")) - else + v = concat(t, " | ") + end + if v then ctx_verbatim(v) end ctx_NC() @@ -380,9 +379,9 @@ function tracers.showdatasetauthors(settings) end local function commonrow(key,value) - ctx_NC() ctx_rlap(function() ctx_verbatim(key) end) + ctx_NC() if key then ctx_rlap(function() ctx_verbatim(key) end) end ctx_NC() - ctx_EQ() ctx_verbatim(value) + ctx_EQ() if value then ctx_verbatim(value) end ctx_NC() ctx_NR() end diff --git a/tex/context/base/mkiv/regi-ibm.lua b/tex/context/base/mkiv/regi-ibm.lua new file mode 100644 index 000000000..3b95333eb --- /dev/null +++ b/tex/context/base/mkiv/regi-ibm.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['regi-ibm'] = { -- 437 + version = 1.001, + comment = "companion to regi-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +return { [0] = + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0, +} diff --git a/tex/context/base/mkiv/regi-ini.lua b/tex/context/base/mkiv/regi-ini.lua index 37a88fd5f..be8fa1b1c 100644 --- a/tex/context/base/mkiv/regi-ini.lua +++ b/tex/context/base/mkiv/regi-ini.lua @@ -27,9 +27,6 @@ local sequencers = utilities.sequencers local textlineactions = resolvers.openers.helpers.textlineactions local setmetatableindex = table.setmetatableindex -local implement = interfaces.implement -local setmacro = interfaces.setmacro - --[[ldx-- <p>We will hook regime handling code into the input methods.</p> --ldx]]-- @@ -261,56 +258,6 @@ if sequencers then end --- interface: - -implement { - name = "enableregime", - arguments = "string", - actions = function(regime) setmacro("currentregime",enable(regime)) end -} - -implement { - name = "disableregime", - actions = function() setmacro("currentregime",disable()) end -} - -implement { - name = "pushregime", - actions = push -} - -implement { - name = "popregime", - actions = pop -} - -local stack = { } - -implement { - name = "startregime", - arguments = "string", - actions = function(regime) - insert(stack,currentregime) - if trace_translating then - report_translating("start using %a",regime) - end - setmacro("currentregime",enable(regime)) - end -} - -implement { - name = "stopregime", - actions = function() - if #stack > 0 then - local regime = remove(stack) - if trace_translating then - report_translating("stop using %a",regime) - end - setmacro("currentregime",enable(regime)) - end - end -} - -- Next we provide some hacks. Unfortunately we run into crappy encoded -- (read : mixed) encoded xml files that have these ë ä ö ü sequences -- instead of ë ä ö ü @@ -434,3 +381,60 @@ end -- local old = "Pozn" .. char(0xE1) .. "mky" -- local new = fromregime("cp1250",old) -- report_translating("%s -> %s",old,new) + +-- interface (might move to regi-tex.lua) + +if interfaces then + + local implement = interfaces.implement + local setmacro = interfaces.setmacro + + implement { + name = "enableregime", + arguments = "string", + actions = function(regime) setmacro("currentregime",enable(regime)) end + } + + implement { + name = "disableregime", + actions = function() setmacro("currentregime",disable()) end + } + + implement { + name = "pushregime", + actions = push + } + + implement { + name = "popregime", + actions = pop + } + + local stack = { } + + implement { + name = "startregime", + arguments = "string", + actions = function(regime) + insert(stack,currentregime) + if trace_translating then + report_translating("start using %a",regime) + end + setmacro("currentregime",enable(regime)) + end + } + + implement { + name = "stopregime", + actions = function() + if #stack > 0 then + local regime = remove(stack) + if trace_translating then + report_translating("stop using %a",regime) + end + setmacro("currentregime",enable(regime)) + end + end + } + +end diff --git a/tex/context/base/mkiv/scrn-bar.mkvi b/tex/context/base/mkiv/scrn-bar.mkvi index 2f21b0004..efb1a005b 100644 --- a/tex/context/base/mkiv/scrn-bar.mkvi +++ b/tex/context/base/mkiv/scrn-bar.mkvi @@ -125,9 +125,10 @@ \def\scrn_bar_buttons_indeed[#settings][#list]% {\begingroup - %\let\menuparameter\interactionbarparameter + %\let\currentinteractionbar\empty \setupcurrentinteractionbar[#settings]% - \d_scrn_bar_width\interactionbarparameter\c!width + \d_scrn_bar_width \interactionbarparameter\c!width\relax + \d_scrn_bar_distance\interactionbarparameter\c!distance\relax \ifdim\d_scrn_bar_width=\zeropoint \d_scrn_bar_width1.5\emwidth \fi @@ -157,6 +158,10 @@ \hbox to \scratchdimentwo {\setnostrut \startsymbolset[\interactionparameter\c!symbolset]% + \setupbuttons + [#settings,% + \c!height=\the\scratchheight,% + \c!width=\the\scratchdimenone]% \processallactionsinset [#list] [ \v!page=>\scrn_bar_goto\v!firstpage @@ -173,11 +178,7 @@ \endgroup} \def\scrn_bar_goto#action% - {\button - [\c!height=\the\scratchheight,\c!width=\the\scratchdimenone]% - {\symbol[#action]}% we could expand this one once only - [#action]% - \hss} + {\button{\symbol[#action]}[#action]\hss} % todo: this will be \letblackruleparameter\c!width\scratchdimenone (faster) @@ -346,31 +347,34 @@ \advance\scratchcounterfive \plusone \ifnum\recurselevel=\firstsubpage\relax \!!doneatrue \fi \ifnum\recurselevel=\lastsubpage \relax \!!doneatrue \fi + \scratchcountersix\therealsubpageno\recurselevel\relax \c_scrn_bar_mode \if!!donea - \ifnum\recurselevel<\realpageno + \ifnum\scratchcountersix<\realpageno \zerocount - \else\ifnum\recurselevel>\realpageno + \else\ifnum\scratchcountersix>\realpageno \plustwo \else \plusfour \fi\fi \else \ifnum\scratchcounterfive=\scratchcountertwo - \ifnum\recurselevel<\realpageno + \ifnum\scratchcountersix<\realpageno \plusone - \else\ifnum\recurselevel>\realpageno + \else\ifnum\scratchcountersix>\realpageno \plusthree \else \plustwo \fi\fi \else - \plusthree + \minusone \fi \fi - \normalexpanded{\directgotospecbox\noexpand\interactionbarparameter{\scrn_bar_goto_indeed\c_scrn_bar_mode}[page(\therealsubpageno\recurselevel)]}% - \hss - \scratchcounterfive\zerocount}% + \ifnum\c_scrn_bar_mode<\zerocount\else + \normalexpanded{\directgotospecbox\noexpand\interactionbarparameter{\scrn_bar_goto_indeed\c_scrn_bar_mode}[realpage(\the\scratchcountersix)]}% + \hss + \scratchcounterfive\zerocount + \fi}% \unskip \egroup }\fi} diff --git a/tex/context/base/mkiv/scrn-but.mkvi b/tex/context/base/mkiv/scrn-but.mkvi index 98d9f2daa..65b0d2c4e 100644 --- a/tex/context/base/mkiv/scrn-but.mkvi +++ b/tex/context/base/mkiv/scrn-but.mkvi @@ -408,7 +408,8 @@ %D \stoptyping %D %D The no longer hard coded text areas offset compensation makes tuning -%D easier. After all, menus need some setup anyway. +%D easier. After all, menus need some setup anyway. The offsets are +%D added to the width or height (this is different from \MKII). \newbox \b_scrn_menu diff --git a/tex/context/base/mkiv/scrn-fld.mkvi b/tex/context/base/mkiv/scrn-fld.mkvi index a92abebc5..d69e7beb9 100644 --- a/tex/context/base/mkiv/scrn-fld.mkvi +++ b/tex/context/base/mkiv/scrn-fld.mkvi @@ -246,7 +246,6 @@ \fi layer {\fieldbodyparameter\c!fieldlayer}% option {\fieldbodyparameter\c!option}% - align {\fieldbodyparameter\c!align}% clickin {\fieldbodyparameter\c!clickin}% clickout {\fieldbodyparameter\c!clickout}% regionin {\fieldbodyparameter\c!regionin}% diff --git a/tex/context/base/mkiv/scrn-hlp.lua b/tex/context/base/mkiv/scrn-hlp.lua index 99c0565a8..8f6f6f746 100644 --- a/tex/context/base/mkiv/scrn-hlp.lua +++ b/tex/context/base/mkiv/scrn-hlp.lua @@ -8,27 +8,27 @@ if not modules then modules = { } end modules ['scrn-hlp'] = { local tonumber = tonumber -local help = { } -interactions.help = help +local help = { } +interactions.help = help -local context = context -local implement = interfaces.implement +local context = context +local implement = interfaces.implement -local formatters = string.formatters +local formatters = string.formatters -local a_help = attributes.private("help") +local a_help = attributes.private("help") -local copy_nodelist = node.copy_list -local hpack_nodelist = node.hpack +local copy_node_list = node.copy_list +local hpack_node_list = node.hpack -local register_list = nodes.pool.register +local register_list = nodes.pool.register -local texgetbox = tex.getbox +local texgetbox = tex.getbox -local nodecodes = nodes.nodecodes +local nodecodes = nodes.nodecodes -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist local data, references = { }, { } @@ -59,7 +59,7 @@ local function register(specification) interactions.javascripts.setpreamble("HelpTexts",helpscript) helpscript = false end - local b = copy_nodelist(texgetbox(box)) + local b = copy_node_list(texgetbox(box)) register_list(b) data[number] = b if name and name ~= "" then @@ -128,7 +128,7 @@ implement { for i=1,#used do local d = data[used[i]] if d and not done[d] then - local box = hpack_nodelist(copy_nodelist(d)) + local box = hpack_node_list(copy_node_list(d)) context(false,box) done[d] = true else diff --git a/tex/context/base/mkiv/scrn-ini.mkvi b/tex/context/base/mkiv/scrn-ini.mkvi index 0e00fb456..93dde6962 100644 --- a/tex/context/base/mkiv/scrn-ini.mkvi +++ b/tex/context/base/mkiv/scrn-ini.mkvi @@ -177,15 +177,52 @@ %D Identity +% \def\scrn_identity_synchronize +% {\clf_setupidentity +% title {\interactionparameter\c!title}% +% subtitle {\interactionparameter\c!subtitle}% +% author {\interactionparameter\c!author}% +% % creator {ConTeXt - \contextversion}% +% date {\interactionparameter\c!date}% +% keywords {\interactionparameter\c!keyword}% +% \relax} + +\newconditional\c_scrn_identity_preroll + +\installtexdirective + {interaction.identity.preroll} + {\settrue \c_scrn_identity_preroll} + {\setfalse\c_scrn_identity_preroll} + +\def\scrn_identity_prerolled#1% + {\begingroup + \edef\tempstring{\interactionparameter#1}% + \ifx\tempstring\empty + \endgroup + \else + \the\everypreroll + \nodestostring\tempstring{\tempstring}% + \normalexpanded{\endgroup\setexpandedinteractionparameter{#1}{\tempstring}}% + \fi} + \def\scrn_identity_synchronize - {\clf_setupidentity + {\begingroup + \ifconditional\c_scrn_identity_preroll + \scrn_identity_prerolled\c!title + \scrn_identity_prerolled\c!subtitle + \scrn_identity_prerolled\c!author + \scrn_identity_prerolled\c!date + \scrn_identity_prerolled\c!keyword + \fi + \clf_setupidentity title {\interactionparameter\c!title}% subtitle {\interactionparameter\c!subtitle}% author {\interactionparameter\c!author}% - creator {ConTeXt - \contextversion}% + % creator {ConTeXt - \contextversion}% date {\interactionparameter\c!date}% keywords {\interactionparameter\c!keyword}% - \relax} + \relax + \endgroup} \appendtoks \scrn_identity_synchronize @@ -193,11 +230,18 @@ % this comes before starttext +\def\scrn_identity_document#1#2% + {\doifvariable{document}{metadata:#1}{\setupinteraction[#2=\documentvariable{metadata:#1}]}} + \appendtoks % not interfaced i.e. english - \doifvariable{document}{metadata:author} {\setupinteraction [\c!author=\documentvariable{metadata:author}]}% - \doifvariable{document}{metadata:title} {\setupinteraction [\c!title=\documentvariable{metadata:title}]}% - \doifvariable{document}{metadata:subject} {\setupinteraction[\c!subject=\documentvariable{metadata:subject}]}% - \doifvariable{document}{metadata:keywords}{\setupinteraction[\c!keyword=\documentvariable{metadata:keywords}]}% + \scrn_identity_document {title}\c!title + \scrn_identity_document {subject}\c!subtitle + \scrn_identity_document{subtitle}\c!subtitle + \scrn_identity_document {author}\c!author + \scrn_identity_document {authors}\c!author + \scrn_identity_document {keyword}\c!keyword + \scrn_identity_document{keywords}\c!keyword + \scrn_identity_document {date}\c!date \to \everysetupdocument \setupinteraction diff --git a/tex/context/base/mkiv/scrn-pag.lua b/tex/context/base/mkiv/scrn-pag.lua index dba5b4786..bd65e53d9 100644 --- a/tex/context/base/mkiv/scrn-pag.lua +++ b/tex/context/base/mkiv/scrn-pag.lua @@ -40,6 +40,7 @@ implement { { "bleedoffset", "dimen" }, { "artoffset", "dimen" }, { "trimoffset", "dimen" }, + { "copies", "integer" }, } } } diff --git a/tex/context/base/mkiv/scrn-pag.mkvi b/tex/context/base/mkiv/scrn-pag.mkvi index 7a7effdc4..b7e056e2b 100644 --- a/tex/context/base/mkiv/scrn-pag.mkvi +++ b/tex/context/base/mkiv/scrn-pag.mkvi @@ -227,6 +227,7 @@ trimoffset \canvastrimoffset bleedoffset \canvasbleedoffset artoffset \canvasartoffset + copies \numexpr\interactionscreenparameter\c!copies\relax \relax %\global\let\scrn_canvas_synchronize_simple \relax \global\let\scrn_canvas_synchronize_complex\relax} @@ -251,6 +252,7 @@ \c!veroffset=\zeropoint, \c!backspace=\backspace, \c!topspace=\topspace, + \c!copies=\plusone, % not the best place but backend anyway \c!option=\v!auto] \appendtoks diff --git a/tex/context/base/mkiv/scrn-wid.lua b/tex/context/base/mkiv/scrn-wid.lua index b9855546e..3ce904349 100644 --- a/tex/context/base/mkiv/scrn-wid.lua +++ b/tex/context/base/mkiv/scrn-wid.lua @@ -192,6 +192,7 @@ implement { { "symbol" }, { "buffer" }, { "layer" }, + { "space" }, } } } diff --git a/tex/context/base/mkiv/scrn-wid.mkvi b/tex/context/base/mkiv/scrn-wid.mkvi index f4679684c..f19da57f7 100644 --- a/tex/context/base/mkiv/scrn-wid.mkvi +++ b/tex/context/base/mkiv/scrn-wid.mkvi @@ -378,6 +378,7 @@ \c!depth=\v!fit, \c!nx=40, \c!ny=10, + \c!buffer=\v!comment, \c!location=\v!high] \appendtoks @@ -473,8 +474,9 @@ transparencyvalue \numexpr\thetransparencyattribute{\commentparameter\c!color}\relax option {\commentparameter\c!option}% % todo symbol {\commentparameter\c!symbol}% - buffer {\v!comment}% + buffer {\commentparameter\c!buffer}% {\v!comment}% layer {\commentparameter\c!textlayer}% + space {\commentparameter\c!space}% \relax \wd\b_scrn_comment_link\currentcommentwidth \ht\b_scrn_comment_link\currentcommentheight diff --git a/tex/context/base/mkiv/scrp-cjk.lua b/tex/context/base/mkiv/scrp-cjk.lua index 77c58b18a..d2ec201ca 100644 --- a/tex/context/base/mkiv/scrp-cjk.lua +++ b/tex/context/base/mkiv/scrp-cjk.lua @@ -14,8 +14,6 @@ if not modules then modules = { } end modules ['scrp-cjk'] = { -- sense either because otherwise a wanted space at the end of a -- line would have to be a hard coded ones. -local utfchar = utf.getchar - local nuts = nodes.nuts local tonut = nodes.tonut local tonode = nodes.tonode @@ -33,6 +31,7 @@ local getchar = nuts.getchar local getid = nuts.getid local getattr = nuts.getattr local getsubtype = nuts.getsubtype +local getwidth = nuts.getwidth local getfield = nuts.getfield local setchar = nuts.setchar @@ -59,7 +58,6 @@ local hash = scripts.hash local numbertodataset = scripts.numbertodataset local fonthashes = fonts.hashes -local fontdata = fonthashes.identifiers local quaddata = fonthashes.quads local spacedata = fonthashes.spaces @@ -534,7 +532,7 @@ end -- nodes.tasks.prependaction("processors","normalizers","scripts.decomposehangul") -local otffeatures = fonts.constructors.newfeatures("otf") +local otffeatures = fonts.constructors.features.otf local registerotffeature = otffeatures.register registerotffeature { @@ -961,7 +959,7 @@ local function process(head,first,last) local subtype = getsubtype(first) if subtype == userskip_code or subtype == spaceskip_code or subtype == xspaceskip_code then -- for the moment no distinction possible between space and userskip - local w = getfield(first,"width") + local w = getwidth(first) local s = spacedata[getfont(p)] if w == s then -- could be option if trace_details then diff --git a/tex/context/base/mkiv/sort-ini.lua b/tex/context/base/mkiv/sort-ini.lua index 3266425cb..7cd28d08f 100644 --- a/tex/context/base/mkiv/sort-ini.lua +++ b/tex/context/base/mkiv/sort-ini.lua @@ -50,7 +50,7 @@ just hook those into the replacer code that we reun beforehand.</p> have language etc properties that then can be used.</p> ]]-- -local gsub, rep, sub, sort, concat, tohash, format = string.gsub, string.rep, string.sub, table.sort, table.concat, table.tohash, string.format +local gsub, find, rep, sub, sort, concat, tohash, format = string.gsub, string.find, string.rep, string.sub, table.sort, table.concat, table.tohash, string.format local utfbyte, utfchar, utfcharacters, utfvalues = utf.byte, utf.char, utf.characters, utf.values local next, type, tonumber, rawget, rawset = next, type, tonumber, rawget, rawset local P, Cs, R, S, lpegmatch = lpeg.P, lpeg.Cs, lpeg.R, lpeg.S, lpeg.match @@ -557,7 +557,10 @@ function splitters.utf(str,checked) -- we could append m and u but this is clean -- todo make an lpeg for this for k=1,#replacements do local v = replacements[k] - str = gsub(str,v[1],v[2]) + local s = v[1] + if find(str,s) then + str = gsub(str,s,v[2]) + end end end local m_case, z_case, p_case, m_mapping, z_mapping, p_mapping, char, byte, n = { }, { }, { }, { }, { }, { }, { }, { }, 0 diff --git a/tex/context/base/mkiv/sort-lan.lua b/tex/context/base/mkiv/sort-lan.lua index e84692afc..21aabf3eb 100644 --- a/tex/context/base/mkiv/sort-lan.lua +++ b/tex/context/base/mkiv/sort-lan.lua @@ -59,7 +59,7 @@ definitions["en"] = { parent = "default" } definitions['nl'] = { parent = 'default', replacements = { - { "ij", 'y' }, { "IJ", 'Y' }, -- hm + -- { "ij", 'y' }, { "IJ", 'Y' }, -- no longer, or will be option }, } @@ -593,6 +593,35 @@ definitions["is"] = { --- Greek definitions["gr"] = { + replacements = { + { "α", "αa" }, { "ά", "αb" }, { "ὰ", "αc" }, { "ὰ", "αd" }, { "ᾳ", "αe" }, + { "ἀ", "αf" }, { "ἁ", "αg" }, { "ἄ", "αh" }, { "ἂ", "αi" }, { "ἆ", "αj" }, + { "ἁ", "αk" }, { "ἅ", "αl" }, { "ἃ", "αm" }, { "ἇ", "αn" }, { "ᾁ", "αo" }, + { "ᾴ", "αp" }, { "ᾲ", "αq" }, { "ᾷ", "αr" }, { "ᾄ", "αs" }, { "ὰ", "αt" }, + { "ᾅ", "αu" }, { "ᾃ", "αv" }, { "ᾆ", "αw" }, { "ᾇ", "αx" }, + { "ε", "εa" }, { "έ", "εb" }, { "ὲ", "εc" }, { "ἐ", "εd" }, { "ἔ", "εe" }, + { "ἒ", "εf" }, { "ἑ", "εg" }, { "ἕ", "εh" }, { "ἓ", "εi" }, + { "η", "ηa" }, { "η", "ηb" }, { "ή", "ηc" }, { "ὴ", "ηd" }, { "ῆ", "ηe" }, + { "ῃ", "ηf" }, { "ἠ", "ηg" }, { "ἤ", "ηh" }, { "ἢ", "ηi" }, { "ἦ", "ηj" }, + { "ᾐ", "ηk" }, { "ἡ", "ηl" }, { "ἥ", "ηm" }, { "ἣ", "ηn" }, { "ἧ", "ηo" }, + { "ᾑ", "ηp" }, { "ῄ", "ηq" }, { "ῂ", "ηr" }, { "ῇ", "ηs" }, { "ᾔ", "ηt" }, + { "ᾒ", "ηu" }, { "ᾕ", "ηv" }, { "ᾓ", "ηw" }, { "ᾖ", "ηx" }, { "ᾗ", "ηy" }, + { "ι", "ιa" }, { "ί", "ιb" }, { "ὶ", "ιc" }, { "ῖ", "ιd" }, { "ἰ", "ιe" }, + { "ἴ", "ιf" }, { "ἲ", "ιg" }, { "ἶ", "ιh" }, { "ἱ", "ιi" }, { "ἵ", "ιj" }, + { "ἳ", "ιk" }, { "ἷ", "ιl" }, { "ϊ", "ιm" }, { "ΐ", "ιn" }, { "ῒ", "ιo" }, + { "ῗ", "ιp" }, + { "ο", "οa" }, { "ό", "οb" }, { "ὸ", "οc" }, { "ὀ", "οd" }, { "ὄ", "οe" }, + { "ὂ", "οf" }, { "ὁ", "οg" }, { "ὅ", "οh" }, { "ὃ", "οi" }, + { "ρ", "ρa" }, { "ῤ", "ῤb" }, { "ῥ", "ῥc" }, + { "υ", "υa" }, { "ύ", "υb" }, { "ὺ", "υc" }, { "ῦ", "υd" }, { "ὐ", "υe" }, + { "ὔ", "υf" }, { "ὒ", "υg" }, { "ὖ", "υh" }, { "ὑ", "υi" }, { "ὕ", "υj" }, + { "ὓ", "υk" }, { "ὗ", "υl" }, { "ϋ", "υm" }, { "ΰ", "υn" }, { "ῢ", "υo" }, + { "ω", "ωa" }, { "ώ", "ωb" }, { "ὼ", "ωc" }, { "ῶ", "ωd" }, { "ῳ", "ωe" }, + { "ὠ", "ωf" }, { "ὤ", "ωg" }, { "ὢ", "ωh" }, { "ὦ", "ωi" }, { "ᾠ", "ωj" }, + { "ὡ", "ωk" }, { "ὥ", "ωl" }, { "ὣ", "ωm" }, { "ὧ", "ωn" }, { "ᾡ", "ωo" }, + { "ῴ", "ωp" }, { "ῲ", "ωq" }, { "ῷ", "ωr" }, { "ᾤ", "ωs" }, { "ᾢ", "ωt" }, + { "ᾥ", "ωu" }, { "ᾣ", "ωv" }, { "ᾦ", "ωw" }, { "ᾧ", "ωx" }, + }, entries = { ["α"] = "α", ["ά"] = "α", ["ὰ"] = "α", ["ᾶ"] = "α", ["ᾳ"] = "α", ["ἀ"] = "α", ["ἁ"] = "α", ["ἄ"] = "α", ["ἂ"] = "α", ["ἆ"] = "α", @@ -617,29 +646,34 @@ definitions["gr"] = { ["υ"] = "υ", ["ύ"] = "υ", ["ὺ"] = "υ", ["ῦ"] = "υ", ["ὐ"] = "υ", ["ὔ"] = "υ", ["ὒ"] = "υ", ["ὖ"] = "υ", ["ὑ"] = "υ", ["ὕ"] = "υ", ["ὓ"] = "υ", ["ὗ"] = "υ", ["ϋ"] = "υ", ["ΰ"] = "υ", ["ῢ"] = "υ", - ["ῧ"] = "υ", ["φ"] = "φ", ["χ"] = "χ", ["ψ"] = "ω", ["ω"] = "ω", + ["ῧ"] = "υ", ["φ"] = "φ", ["χ"] = "χ", ["ψ"] = "ψ", ["ω"] = "ω", ["ώ"] = "ω", ["ὼ"] = "ω", ["ῶ"] = "ω", ["ῳ"] = "ω", ["ὠ"] = "ω", ["ὤ"] = "ω", ["ὢ"] = "ω", ["ὦ"] = "ω", ["ᾠ"] = "ω", ["ὡ"] = "ω", ["ὥ"] = "ω", ["ὣ"] = "ω", ["ὧ"] = "ω", ["ᾡ"] = "ω", ["ῴ"] = "ω", ["ῲ"] = "ω", ["ῷ"] = "ω", ["ᾤ"] = "ω", ["ᾢ"] = "ω", ["ᾥ"] = "ω", ["ᾣ"] = "ω", ["ᾦ"] = "ω", ["ᾧ"] = "ω", }, + -- orders = { + -- "α", "ά", "ὰ", "ᾶ", "ᾳ", "ἀ", "ἁ", "ἄ", "ἂ", "ἆ", + -- "ἁ", "ἅ", "ἃ", "ἇ", "ᾁ", "ᾴ", "ᾲ", "ᾷ", "ᾄ", "ᾂ", + -- "ᾅ", "ᾃ", "ᾆ", "ᾇ", "β", "γ", "δ", "ε", "έ", "ὲ", + -- "ἐ", "ἔ", "ἒ", "ἑ", "ἕ", "ἓ", "ζ", "η", "η", "ή", + -- "ὴ", "ῆ", "ῃ", "ἠ", "ἤ", "ἢ", "ἦ", "ᾐ", "ἡ", "ἥ", + -- "ἣ", "ἧ", "ᾑ", "ῄ", "ῂ", "ῇ", "ᾔ", "ᾒ", "ᾕ", "ᾓ", + -- "ᾖ", "ᾗ", "θ", "ι", "ί", "ὶ", "ῖ", "ἰ", "ἴ", "ἲ", + -- "ἶ", "ἱ", "ἵ", "ἳ", "ἷ", "ϊ", "ΐ", "ῒ", "ῗ", "κ", + -- "λ", "μ", "ν", "ξ", "ο", "ό", "ὸ", "ὀ", "ὄ", "ὂ", + -- "ὁ", "ὅ", "ὃ", "π", "ρ", "ῤ", "ῥ", "σ", "ς", "τ", + -- "υ", "ύ", "ὺ", "ῦ", "ὐ", "ὔ", "ὒ", "ὖ", "ὑ", "ὕ", + -- "ὓ", "ὗ", "ϋ", "ΰ", "ῢ", "ῧ", "φ", "χ", "ψ", "ω", + -- "ώ", "ὼ", "ῶ", "ῳ", "ὠ", "ὤ", "ὢ", "ὦ", "ᾠ", "ὡ", + -- "ὥ", "ὣ", "ὧ", "ᾡ", "ῴ", "ῲ", "ῷ", "ᾤ", "ᾢ", "ᾥ", + -- "ᾣ", "ᾦ", "ᾧ", + -- }, orders = { - "α", "ά", "ὰ", "ᾶ", "ᾳ", "ἀ", "ἁ", "ἄ", "ἂ", "ἆ", - "ἁ", "ἅ", "ἃ", "ἇ", "ᾁ", "ᾴ", "ᾲ", "ᾷ", "ᾄ", "ᾂ", - "ᾅ", "ᾃ", "ᾆ", "ᾇ", "β", "γ", "δ", "ε", "έ", "ὲ", - "ἐ", "ἔ", "ἒ", "ἑ", "ἕ", "ἓ", "ζ", "η", "η", "ή", - "ὴ", "ῆ", "ῃ", "ἠ", "ἤ", "ἢ", "ἦ", "ᾐ", "ἡ", "ἥ", - "ἣ", "ἧ", "ᾑ", "ῄ", "ῂ", "ῇ", "ᾔ", "ᾒ", "ᾕ", "ᾓ", - "ᾖ", "ᾗ", "θ", "ι", "ί", "ὶ", "ῖ", "ἰ", "ἴ", "ἲ", - "ἶ", "ἱ", "ἵ", "ἳ", "ἷ", "ϊ", "ΐ", "ῒ", "ῗ", "κ", - "λ", "μ", "ν", "ξ", "ο", "ό", "ὸ", "ὀ", "ὄ", "ὂ", - "ὁ", "ὅ", "ὃ", "π", "ρ", "ῤ", "ῥ", "σ", "ς", "τ", - "υ", "ύ", "ὺ", "ῦ", "ὐ", "ὔ", "ὒ", "ὖ", "ὑ", "ὕ", - "ὓ", "ὗ", "ϋ", "ΰ", "ῢ", "ῧ", "φ", "χ", "ψ", "ω", - "ώ", "ὼ", "ῶ", "ῳ", "ὠ", "ὤ", "ὢ", "ὦ", "ᾠ", "ὡ", - "ὥ", "ὣ", "ὧ", "ᾡ", "ῴ", "ῲ", "ῷ", "ᾤ", "ᾢ", "ᾥ", - "ᾣ", "ᾦ", "ᾧ", + "α", "β", "γ", "δ", "ε", "ζ", "η", "θ", "ι", "κ", + "λ", "μ", "ν", "ξ", "ο", "π", "ρ", "σ", "ς", "τ", + "υ", "φ", "χ", "ψ", "ω", }, } @@ -722,12 +756,17 @@ definitions["es"] = { ["u"] = "u", ["ú"] = "u", ["ü"] = "u", ["v"] = "v", ["w"] = "w", ["x"] = "x", ["y"] = "y", ["z"] = "z", }, + -- orders = { + -- "a", "á", "b", "c", "d", "e", "é", "f", "g", "h", + -- "i", "í", "j", "k", "l", "m", "n", "ñ", "o", "ó", + -- "p", "q", "r", "s", "t", "u", "ú", "ü", "v", "w", + -- "x", "y", "z", + -- }, orders = { - "a", "á", "b", "c", "d", "e", "é", "f", "g", "h", - "i", "í", "j", "k", "l", "m", "n", "ñ", "o", "ó", - "p", "q", "r", "s", "t", "u", "ú", "ü", "v", "w", - "x", "y", "z", - } + "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", + "k", "l", "m", "n", "ñ", "o", "p", "q", "r", "s", + "t", "u", "v", "w", "x", "y", "z", + }, } --- Portuguese diff --git a/tex/context/base/mkiv/spac-adj.lua b/tex/context/base/mkiv/spac-adj.lua index cdf9b5051..3db59881b 100644 --- a/tex/context/base/mkiv/spac-adj.lua +++ b/tex/context/base/mkiv/spac-adj.lua @@ -8,16 +8,17 @@ if not modules then modules = { } end modules ['spac-adj'] = { -- sort of obsolete code -local a_vadjust = attributes.private('graphicvadjust') +local a_vadjust = attributes.private('graphicvadjust') -local nodecodes = nodes.nodecodes +local nodecodes = nodes.nodecodes -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist -local remove_node = nodes.remove -local hpack_node = node.hpack -local vpack_node = node.vpack +local remove_node = nodes.remove +local hpack_node = node.hpack + +local enableaction = nodes.tasks.enableaction function nodes.handlers.graphicvadjust(head,groupcode) -- we can make an actionchain for mvl only if groupcode == "" then -- mvl only @@ -61,6 +62,6 @@ interfaces.implement { name = "enablegraphicvadjust", onlyonce = true, actions = function() - nodes.tasks.enableaction("finalizers","nodes.handlers.graphicvadjust") + enableaction("finalizers","nodes.handlers.graphicvadjust") end } diff --git a/tex/context/base/mkiv/spac-adj.mkiv b/tex/context/base/mkiv/spac-adj.mkiv index ad0f92a1f..936e00624 100644 --- a/tex/context/base/mkiv/spac-adj.mkiv +++ b/tex/context/base/mkiv/spac-adj.mkiv @@ -23,7 +23,7 @@ \definesystemattribute [graphicvadjust] [public] \unexpanded\def\enablegraphicvadjust - {\writestatus\m!systems{graphicvadjusting is no longer needed!} + {\writestatus\m!system{graphicvadjusting is no longer needed!} \clf_enablegraphicvadjust %once anyway \glet\enablegraphicvadjust\relax} diff --git a/tex/context/base/mkiv/spac-ali.lua b/tex/context/base/mkiv/spac-ali.lua index a67a30133..bc77090cf 100644 --- a/tex/context/base/mkiv/spac-ali.lua +++ b/tex/context/base/mkiv/spac-ali.lua @@ -19,18 +19,18 @@ local tonode = nuts.tonode local tonut = nuts.tonut local getfield = nuts.getfield -local setfield = nuts.setfield local getnext = nuts.getnext local getprev = nuts.getprev local getid = nuts.getid local getlist = nuts.getlist local setlist = nuts.setlist -local getattr = nuts.getattr -local setattr = nuts.setattr +local setlink = nuts.setlink +local takeattr = nuts.takeattr local getsubtype = nuts.getsubtype +local getwidth = nuts.getwidth +local findtail = nuts.tail local hpack_nodes = nuts.hpack -local linked_nodes = nuts.linked local unsetvalue = attributes.unsetvalue @@ -71,7 +71,7 @@ local function handler(head,leftpage,realpageno) local id = getid(current) if id == hlist_code then if getsubtype(current) == line_code then - local a = getattr(current,a_realign) + local a = takeattr(current,a_realign) if not a or a == 0 then -- skip else @@ -87,12 +87,16 @@ local function handler(head,leftpage,realpageno) action = leftpage and 2 or 1 end if action == 1 then - setlist(current,hpack_nodes(linked_nodes(getlist(current),new_stretch(3)),getfield(current,"width"),"exactly")) + local head = getlist(current) + setlink(findtail(head),new_stretch(3)) -- append + setlist(current,hpack_nodes(head,getwidth(current),"exactly")) if trace_realign then report_realign("flushing left, align %a, page %a, realpage %a",align,pageno,realpageno) end elseif action == 2 then - setlist(current,hpack_nodes(linked_nodes(new_stretch(3),getlist(current)),getfield(current,"width"),"exactly")) + local list = getlist(current) + local head = setlink(new_stretch(3),list) -- prepend + setlist(current,hpack_nodes(head,getwidth(current),"exactly")) if trace_realign then report_realign("flushing right. align %a, page %a, realpage %a",align,pageno,realpageno) end @@ -102,7 +106,6 @@ local function handler(head,leftpage,realpageno) done = true nofrealigned = nofrealigned + 1 end - setattr(current,a_realign,unsetvalue) end end handler(getlist(current),leftpage,realpageno) @@ -115,7 +118,7 @@ local function handler(head,leftpage,realpageno) end function alignments.handler(head) - local leftpage = isleftpage(true,false) + local leftpage = isleftpage() local realpageno = texgetcount("realpageno") local head, done = handler(tonut(head),leftpage,realpageno) return tonode(head), done diff --git a/tex/context/base/mkiv/spac-ali.mkiv b/tex/context/base/mkiv/spac-ali.mkiv index 21714f07c..af02f76ae 100644 --- a/tex/context/base/mkiv/spac-ali.mkiv +++ b/tex/context/base/mkiv/spac-ali.mkiv @@ -86,16 +86,6 @@ \spac_directions_lefttoright_hmode \fi} -\unexpanded\def\spac_directions_lefttoright_vmode - {\settrue\displaylefttoright - \settrue\inlinelefttoright - \textdir TLT\relax - \pardir TLT\relax} - -\unexpanded\def\spac_directions_lefttoright_hmode - {\settrue\inlinelefttoright - \textdir TLT\relax} - \unexpanded\def\righttoleft {\ifvmode \spac_directions_righttoleft_vmode @@ -103,15 +93,71 @@ \spac_directions_righttoleft_hmode \fi} +\unexpanded\def\spac_directions_lefttoright_vmode + {\settrue\displaylefttoright + \settrue\inlinelefttoright + \textdir TLT\relax + \pardir TLT\relax} + \unexpanded\def\spac_directions_righttoleft_vmode {\setfalse\displaylefttoright \setfalse\inlinelefttoright \textdir TRT\relax \pardir TRT\relax} -\unexpanded\def\spac_directions_righttoleft_hmode - {\textdir TRT\relax - \setfalse\inlinelefttoright} +\newconditional\c_spac_auto_line_dir \settrue\c_spac_auto_line_dir + +\ifdefined\linedir + + \unexpanded\def\spac_directions_lefttoright_hmode + {\ifconditional\c_spac_auto_line_dir\linedir\else\textdir\fi TLT\relax % linedir keeps subtype + \setfalse\inlinerighttoleft} + + \unexpanded\def\spac_directions_righttoleft_hmode + {\ifconditional\c_spac_auto_line_dir\linedir\else\textdir\fi TRT\relax % linedir keeps subtype + \setfalse\inlinelefttoright} + +\else % keep this as reference + + \unexpanded\def\spac_directions_lefttoright_hmode + {\settrue\inlinelefttoright + \textdir TLT\relax} + + \unexpanded\def\spac_directions_righttoleft_hmode + {\textdir TRT\relax + \setfalse\inlinelefttoright} + + \unexpanded\def\spac_directions_lefttoright_hmode + {\ifconditional\c_spac_auto_line_dir + \ifzeropt\lastskip + \textdir TLT\relax + \else + \scratchskip\lastskip + \unskip + \textdir TLT\relax + \hskip\scratchskip + \fi + \else + \textdir TLT\relax + \fi + \setfalse\inlinerighttoleft} + + \unexpanded\def\spac_directions_righttoleft_hmode + {\ifconditional\c_spac_auto_line_dir + \ifzeropt\lastskip + \textdir TRT\relax + \else + \scratchskip\lastskip + \unskip + \textdir TRT\relax + \hskip\scratchskip + \fi + \else + \textdir TRT\relax + \fi + \setfalse\inlinelefttoright} + +\fi % \def\currentdirectionparameters % {\ifconditional\inlinelefttoright \else @@ -229,6 +275,8 @@ \fi \ifx\dohyphens\relax % was 2.5 in old implementation using scratch registers \hyphenpenalty\dimexpr2.8\hsize/\dimexpr#1\relax\relax % 50 in raggedright/raggedleft + %\else + % no need to do something as we're in \nohyphens \fi} \unexpanded\def\spac_align_set_tolerant @@ -291,6 +339,7 @@ \newconstant\c_spac_align_state_par_fill \def\v_spac_align_fill_amount {\plusone fil} +\def\v_spac_align_fill_amount_hard {\plusone fill} \def\v_spac_align_fill_amount_negative {\minusone fil} \def\v_spac_align_fill_amount_double {\plustwo fil} \def\v_spac_align_fill_amount_space {\plustwo fil} % can be added to xspace if we have a key @@ -406,6 +455,18 @@ \parindent \zeropoint \relax} +\unexpanded\def\spac_align_set_horizontal_flushedright_last_line + {\raggedstatus\zerocount + \attribute\alignstateattribute\attributeunsetvalue + \leftskip \plusone\leftskip \s!plus\v_spac_align_fill_amount\relax + \rightskip \plusone\rightskip\s!plus\v_spac_align_fill_amount_negative\relax + \spaceskip \zeropoint\relax + \xspaceskip \zeropoint\relax + \parfillskip \zeropoint + \parfillleftskip\zeropoint\s!plus\v_spac_align_fill_amount_hard\relax + \parindent \zeropoint + \relax} + \unexpanded\def\spac_align_set_horizontal_right_tt % a plain command {\tttf % brrr \raggedstatus\plusthree @@ -472,6 +533,10 @@ % 7 centered last line \spac_align_set_horizontal_centered_last_line \or + % 8 right aligned last line + \spac_align_set_horizontal_flushedright_last_line + \or + % 9 paragraph \parfillskip\zeropoint \fi \relax} @@ -694,7 +759,8 @@ \c_spac_align_state_broad \plustwo } \setvalue{\??aligncommand\v!disable }{\c_spac_align_state_horizontal\plussix } \setvalue{\??aligncommand\v!last }{\c_spac_align_state_horizontal\plusseven} -\setvalue{\??aligncommand\v!paragraph }{\c_spac_align_state_horizontal\pluseight} +\setvalue{\??aligncommand\v!end }{\c_spac_align_state_horizontal\pluseight} +\setvalue{\??aligncommand\v!paragraph }{\c_spac_align_state_horizontal\plusnine} \setvalue{\??aligncommand\v!lefttoright }{\c_spac_align_state_direction \plusone } @@ -758,18 +824,19 @@ % Visible commands: -\let\notragged \spac_align_set_horizontal_none -\let\raggedleft \spac_align_set_horizontal_left -\let\raggedcenter \spac_align_set_horizontal_center -\let\raggedright \spac_align_set_horizontal_right -\let\veryraggedleft \spac_align_set_horizontal_very_left -\let\veryraggedcenter\spac_align_set_horizontal_very_center -\let\veryraggedright \spac_align_set_horizontal_very_right -\let\raggedwidecenter\spac_align_set_horizontal_wide_center -\let\centeredlastline\spac_align_set_horizontal_centered_last_line -\let\ttraggedright \spac_align_set_horizontal_right_tt % a plain command +\let\notragged \spac_align_set_horizontal_none +\let\raggedleft \spac_align_set_horizontal_left +\let\raggedcenter \spac_align_set_horizontal_center +\let\raggedright \spac_align_set_horizontal_right +\let\veryraggedleft \spac_align_set_horizontal_very_left +\let\veryraggedcenter \spac_align_set_horizontal_very_center +\let\veryraggedright \spac_align_set_horizontal_very_right +\let\raggedwidecenter \spac_align_set_horizontal_wide_center +\let\centeredlastline \spac_align_set_horizontal_centered_last_line +\let\flushedrightlastline\spac_align_set_horizontal_flushedright_last_line +\let\ttraggedright \spac_align_set_horizontal_right_tt % a plain command -\let\forgetragged \spac_align_set_horizontal_none +\let\forgetragged \spac_align_set_horizontal_none \appendtoks \spac_align_set_horizontal_none @@ -889,7 +956,7 @@ \leftskip \rightskip \spaceskip \xspaceskip \parindent \parfillskip - \hyphenpenalty \exhyphenpenalty + \hyphenpenalty \exhyphenpenalty \automatichyphenpenalty \explicithyphenpenalty \displaywidowpenalty \widowpenalty \clubpenalty \brokenpenalty \doublehyphendemerits \finalhyphendemerits \adjdemerits \relax}% @@ -1229,10 +1296,11 @@ % Some obsolete (old) helpers: -\def\dodefinehbox[#1][#2]% +\unexpanded\def\definehbox + {\dodoubleargument\spac_align_definehbox} + +\def\spac_align_definehbox[#1][#2]% {\setvalue{hbox#1}##1{\hbox to #2{\begstrut##1\endstrut\hss}}} -\unexpanded\def\definehbox - {\dodoubleargument\dodefinehbox} \protect \endinput diff --git a/tex/context/base/mkiv/spac-chr.lua b/tex/context/base/mkiv/spac-chr.lua index 97b32c366..fe402ed87 100644 --- a/tex/context/base/mkiv/spac-chr.lua +++ b/tex/context/base/mkiv/spac-chr.lua @@ -36,6 +36,7 @@ local getnext = nuts.getnext local getprev = nuts.getprev local getattr = nuts.getattr local setattr = nuts.setattr +local setattrlist = nuts.setattrlist local getfont = nuts.getfont local getchar = nuts.getchar local setsubtype = nuts.setsubtype @@ -46,7 +47,6 @@ local setcolor = nodes.tracers.colors.set local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after local remove_node = nuts.remove -local copy_node_list = nuts.copy_list local traverse_id = nuts.traverse_id local tasks = nodes.tasks @@ -60,7 +60,6 @@ local new_rule = nodepool.rule local nodecodes = nodes.nodecodes local skipcodes = nodes.skipcodes local glyph_code = nodecodes.glyph -local glue_code = nodecodes.glue local space_skip_code = skipcodes["spaceskip"] @@ -88,36 +87,33 @@ local c_zero = byte('0') local c_period = byte('.') local function inject_quad_space(unicode,head,current,fraction) - local attr = getfield(current,"attr") if fraction ~= 0 then fraction = fraction * fontquads[getfont(current)] end local glue = new_glue(fraction) - setfield(glue,"attr",attr) - setfield(current,"attr",nil) + setattrlist(glue,current) + setattrlist(current) -- why reset all setattr(glue,a_character,unicode) head, current = insert_node_after(head,current,glue) return head, current end local function inject_char_space(unicode,head,current,parent) - local attr = getfield(current,"attr") local font = getfont(current) local char = fontcharacters[font][parent] local glue = new_glue(char and char.width or fontparameters[font].space) - setfield(glue,"attr",attr) - setfield(current,"attr",nil) + setattrlist(glue,current) + setattrlist(current) -- why reset all setattr(glue,a_character,unicode) head, current = insert_node_after(head,current,glue) return head, current end local function inject_nobreak_space(unicode,head,current,space,spacestretch,spaceshrink) - local attr = getfield(current,"attr") local glue = new_glue(space,spacestretch,spaceshrink) local penalty = new_penalty(10000) - setfield(glue,"attr",attr) - setfield(current,"attr",nil) + setattrlist(glue,current) + setattrlist(current) -- why reset all setattr(glue,a_character,unicode) -- bombs head, current = insert_node_after(head,current,penalty) if trace_nbsp then @@ -179,7 +175,9 @@ local methods = { -- The next one uses an attribute assigned to the character but still we -- don't have the 'local' value. - [0x001F] = function(head,current) + -- maybe also 0x0008 : backspace + + [0x001F] = function(head,current) -- kind of special local next = getnext(current) if next then local char = isglyph(next) diff --git a/tex/context/base/mkiv/spac-chr.mkiv b/tex/context/base/mkiv/spac-chr.mkiv index 562fb940c..c4aadd49f 100644 --- a/tex/context/base/mkiv/spac-chr.mkiv +++ b/tex/context/base/mkiv/spac-chr.mkiv @@ -62,6 +62,7 @@ % % "2003 % quad == \quad == \hskip\emwidth \edef\threeperemspace {\normalUchar"2004} % quad/3 \edef\fourperemspace {\normalUchar"2005} % quad/4 +%edef\fiveperemspace {\normalUchar"001E} % quad/5 (bonus) \edef\sixperemspace {\normalUchar"2006} % quad/6 \edef\figurespace {\normalUchar"2007} % width of zero \edef\punctuationspace {\normalUchar"2008} % width of period @@ -71,9 +72,12 @@ \edef\zerowidthnonjoiner {\normalUchar"200C} % 0 \edef\zerowidthjoiner {\normalUchar"200D} % 0 \edef\narrownobreakspace {\normalUchar"202F} % quad/8 -% % "205F % space/8 (math) -% \zerowidthnobreakspace {\normalUchar"FEFF} +%edef\mediummathspace {\normalUchar"205F} % space/8 (math) +%edef\zerowidthnobreakspace {\normalUchar"FEFF} +%edef\fiveperemspace {\normalUchar"001E} + \udef\zerowidthnobreakspace {\penalty\plustenthousand\kern\zeropoint} +\udef\fiveperemspace {\hskip\dimexpr\emwidth/5\relax} \let\zwnj\zerowidthnonjoiner \let\zwj \zerowidthjoiner @@ -87,9 +91,5 @@ \unexpanded\def~{\nobreakspace} -% Goodies: - -\unexpanded\def\fiveperemspace{\hskip\dimexpr\emwidth/5\relax} - \protect \endinput diff --git a/tex/context/base/mkiv/spac-def.mkiv b/tex/context/base/mkiv/spac-def.mkiv index 7ead3c63e..24913cbf7 100644 --- a/tex/context/base/mkiv/spac-def.mkiv +++ b/tex/context/base/mkiv/spac-def.mkiv @@ -29,6 +29,7 @@ \settopskip % factors set in \forgetverticalstretch \setmaxdepth % factors set in \forgetverticalstretch \synchronizeindenting + \synchronizeskipamounts \synchronizeblank \synchronizewhitespace \synchronizespacecodes % not needed, frozen factors diff --git a/tex/context/base/mkiv/spac-grd.mkiv b/tex/context/base/mkiv/spac-grd.mkiv index 7b3ee6d6c..899b6e890 100644 --- a/tex/context/base/mkiv/spac-grd.mkiv +++ b/tex/context/base/mkiv/spac-grd.mkiv @@ -150,7 +150,7 @@ \dp\scratchbox\strutdp \nointerlineskip \forgetall - \ruledvbox{\box\scratchbox}% + \ruledvpack{\box\scratchbox}% \egroup \prevdepth\strutdp}% \def\dotopbaselinecorrection @@ -300,4 +300,30 @@ \normalstartbaselinecorrection \fi} +% This is new (and experimental) and might replace some of the above. beware it doesn't always work +% out well, e.g. when used grouped and such (e.g. before display math doesn't work out well). + +\unexpanded\def\spac_fake_next_line_new + {\par + \begingroup + \reseteverypar + \dontleavehmode\hpack{\strut}\par + \clf_fakenextstrutline + \ifdim\pagetotal>\lineheight + \pagetotal\dimexpr\pagetotal-\lineheight\relax + \fi + \endgroup} + +% \unexpanded\def\spac_fake_next_line_old +% {\par +% \begingroup +% \reseteverypar +% \dontleavehmode\hpack to \zeropoint{\page_sides_anchor\hss\strut}% just a tracer +% \vskip-\parskip +% \vskip-\struttotal +% \endgroup} + +%let\fakenextstrutline\spac_fake_next_line_old +\let\fakenextstrutline\spac_fake_next_line_new + \protect \endinput diff --git a/tex/context/base/mkiv/spac-hor.lua b/tex/context/base/mkiv/spac-hor.lua index 5d5a43e31..17b104459 100644 --- a/tex/context/base/mkiv/spac-hor.lua +++ b/tex/context/base/mkiv/spac-hor.lua @@ -6,7 +6,6 @@ if not modules then modules = { } end modules ['spac-hor'] = { license = "see context related readme files" } -local utfbyte = utf.byte local lpegmatch, P, C = lpeg.match, lpeg.P, lpeg.C local context = context diff --git a/tex/context/base/mkiv/spac-hor.mkiv b/tex/context/base/mkiv/spac-hor.mkiv index 08e5f6343..405abcb5d 100644 --- a/tex/context/base/mkiv/spac-hor.mkiv +++ b/tex/context/base/mkiv/spac-hor.mkiv @@ -17,6 +17,9 @@ \registerctxluafile{spac-hor}{1.001} +\let \parfillrightskip \parfillskip +\newskip\parfillleftskip + \let\v_spac_indentation_current\empty % amount/keyword \newdimen \d_spac_indentation_par @@ -525,7 +528,7 @@ % but, since not all fonts have .5em digits: \unexpanded\def\fixedspace - {\setbox\scratchbox\hbox{\mathortext{0}{0}}% + {\setbox\scratchbox\hpack{\mathortext{0}{0}}% was \hbox \hskip\wd\scratchbox\relax} \unexpanded\def\fixedspaces @@ -605,6 +608,12 @@ \unexpanded\def\charspace{ } % the unexpandable \space (as space can also be delimiter for numbers) +\unexpanded\def\quads + {\dosingleempty\spac_quads} + +\def\spac_quads[#1]% + {\zwj\dorecurse{\iffirstargument#1\else\plusthree\fi}{\hskip\emwidth\zwj}} + % Suggested by GB (not the name -): \def\rapfillskip{.5\hsize plus .092\hsize minus .5\hsize} % D.A.'s value @@ -689,7 +698,7 @@ \global\s_spac_narrower_left \zeropoint \global\s_spac_narrower_right \zeropoint \global\s_spac_narrower_middle\zeropoint - \processcommalistwithparameters[#1]\spac_narrower_initialize + \normalexpanded{\processcommalistwithparameters[#1]}\spac_narrower_initialize \advance\leftskip \dimexpr\s_spac_narrower_left +\s_spac_narrower_middle\relax \advance\rightskip\dimexpr\s_spac_narrower_right+\s_spac_narrower_middle\relax \seteffectivehsize} @@ -764,14 +773,14 @@ \let\stopnarrow\spac_narrower_stop \newdimen\d_spac_effective_hsize \def\effectivehsize {\hsize} -\newdimen\d_spac_effective_leftskip \def\effectiveleftskip {\leftskip} -\newdimen\d_spac_effective_rightskip \def\effectiverightskip{\rightskip} +\newdimen\d_spac_effective_leftskip \def\effectiveleftskip {\dimexpr\leftskip \relax} +\newdimen\d_spac_effective_rightskip \def\effectiverightskip{\dimexpr\rightskip\relax} \unexpanded\def\seteffectivehsize {\setlocalhsize \d_spac_effective_hsize \localhsize - \d_spac_effective_leftskip \leftskip - \d_spac_effective_rightskip\rightskip + \d_spac_effective_leftskip 1\leftskip + \d_spac_effective_rightskip1\rightskip \let\effectivehsize \d_spac_effective_hsize \let\effectiveleftskip \d_spac_effective_leftskip \let\effectiverightskip\d_spac_effective_rightskip} @@ -782,15 +791,19 @@ \newskip\leftskipadaption \newskip\rightskipadaption -\setvalue{\??skipadaptionleft \v!standard}{\ifdim\d_spac_indentation_par=\zeropoint\narrowerparameter\c!left\else\d_spac_indentation_par\fi} -\setvalue{\??skipadaptionleft \v!yes }{\ifdim\d_spac_indentation_par=\zeropoint\narrowerparameter\c!left\else\d_spac_indentation_par\fi} +\setvalue{\??skipadaptionleft \v!yes }{\ifzeropt\d_spac_indentation_par\narrowerparameter\c!left\else\d_spac_indentation_par\fi} \letvalue{\??skipadaptionleft \v!no }\zeropoint \letvalue{\??skipadaptionleft \empty }\zeropoint -\setvalue{\??skipadaptionright\v!standard}{\narrowerparameter\c!right} \setvalue{\??skipadaptionright\v!yes }{\narrowerparameter\c!right} \letvalue{\??skipadaptionright\v!no }\zeropoint \letvalue{\??skipadaptionright\empty }\zeropoint +% \setvalue{\??skipadaptionleft \v!standard}{\ifdim\d_spac_indentation_par=\zeropoint\narrowerparameter\c!left\else\d_spac_indentation_par\fi} +% \setvalue{\??skipadaptionright\v!standard}{\narrowerparameter\c!right} + +\letcsnamecsname\csname\??skipadaptionleft \v!standard\endcsname\csname\??skipadaptionleft \v!yes\endcsname +\letcsnamecsname\csname\??skipadaptionright\v!standard\endcsname\csname\??skipadaptionright\v!yes\endcsname + % \unexpanded\def\dosetleftskipadaption #1{\leftskipadaption \ifcsname\??skipadaptionleft #1\endcsname\csname\??skipadaptionleft #1\endcsname\else#1\fi\relax} % \unexpanded\def\dosetrightskipadaption#1{\rightskipadaption\ifcsname\??skipadaptionright#1\endcsname\csname\??skipadaptionright#1\endcsname\else#1\fi\relax} @@ -1110,7 +1123,7 @@ {\futurelet\nexttoken\spac_spaces_auto_insert_next} \def\spac_spaces_auto_insert_next - {\clf_autonextspace{\meaning\nexttoken}} % todo, just consult nexttoken at the lua end + {\clf_autonextspace{\normalmeaning\nexttoken}} % todo, just consult nexttoken at the lua end %D Moved from bib module: diff --git a/tex/context/base/mkiv/spac-lin.mkiv b/tex/context/base/mkiv/spac-lin.mkiv index c4c6eb6d9..6558cb111 100644 --- a/tex/context/base/mkiv/spac-lin.mkiv +++ b/tex/context/base/mkiv/spac-lin.mkiv @@ -61,7 +61,7 @@ \appendtoks \setuevalue{\e!start\currentlines}{\spac_lines_start[\currentlines]}% - \setuevalue{\e!stop \currentlines}{\spac_lines_stop}% + \letvalue {\e!stop \currentlines }\spac_lines_stop \to \everydefinelines \unexpanded\def\spac_lines_start[#1]% @@ -107,14 +107,17 @@ \def\spac_lines_after_first_obeyed_line_a % tzt two pass, like itemize {\linesparameter\c!command + \linesparameter\c!left \glet\spac_after_first_obeyed_line\spac_lines_after_first_obeyed_line_b} \def\spac_lines_after_first_obeyed_line_b {\spac_lines_break - \linesparameter\c!command} + \linesparameter\c!command + \linesparameter\c!left} \def\spac_lines_obeyed_line - {\dostoptagged + {\ifdone\linesparameter\c!right\fi + \dostoptagged % can be a dummy one as we don't look ahead \par \dostarttagged\t!line\empty \futurelet\next\spac_lines_between} @@ -128,9 +131,13 @@ \egroup} \def\spac_lines_between - {\doifelsemeaning\next\obeyedline % brrr - {\linesparameter\c!inbetween} - {\spac_after_first_obeyed_line}} + {\ifx\next\spac_lines_stop + \donefalse + \else + \doifelsemeaning\next\obeyedline % brrr + {\donefalse\linesparameter\c!inbetween} + {\donetrue\spac_after_first_obeyed_line}% + \fi} \definelines[\v!lines] diff --git a/tex/context/base/mkiv/spac-prf.lua b/tex/context/base/mkiv/spac-prf.lua index 4cd39336e..841e5d271 100644 --- a/tex/context/base/mkiv/spac-prf.lua +++ b/tex/context/base/mkiv/spac-prf.lua @@ -34,13 +34,9 @@ local leaders_code = gluecodes.leaders local lineskip_code = gluecodes.lineskip local baselineskip_code = gluecodes.baselineskip local line_code = listcodes.line -local parskip_code = listcodes.parskip local texlists = tex.lists -local gettexdimen = tex.getdimen local settexattribute = tex.setattribute -local settexbox = tex.setbox -local taketexbox = tex.takebox local nuts = nodes.nuts local tonut = nodes.tonut @@ -54,11 +50,23 @@ local getprev = nuts.getprev local getsubtype = nuts.getsubtype local getlist = nuts.getlist local gettexbox = nuts.getbox +local getwhd = nuts.getwhd +local getglue = nuts.getglue +local getkern = nuts.getkern +local getshift = nuts.getshift +local getwidth = nuts.getwidth +local getheight = nuts.getheight +local getdepth = nuts.getdepth local setfield = nuts.setfield local setlink = nuts.setlink local setlist = nuts.setlist local setattr = nuts.setattr +local setwhd = nuts.setwhd +local setshift = nuts.setshift +local setwidth = nuts.setwidth +local setheight = nuts.setheight +local setdepth = nuts.setdepth local properties = nodes.properties.data local setprop = nuts.setprop @@ -72,7 +80,6 @@ local new_rule = nuts.pool.rule local new_glue = nuts.pool.glue local new_kern = nuts.pool.kern local hpack_nodes = nuts.hpack -local link_nodes = nuts.link local find_node_tail = nuts.tail local setglue = nuts.setglue @@ -89,6 +96,8 @@ local v_strict = variables.strict local setcolor = nodes.tracers.colors.set local settransparency = nodes.tracers.transparencies.set +local enableaction = nodes.tasks.enableaction + local profiling = { } builders.profiling = profiling @@ -120,7 +129,7 @@ local function getprofile(line,step) local step = step or 65536 -- * 2 -- 2pt local margin = step / 4 local min = 0 - local max = ceiling(getfield(line,"width")/step) + 1 + local max = ceiling(getwidth(line)/step) + 1 for i=min,max do heights[i] = 0 @@ -166,12 +175,10 @@ local function getprofile(line,step) while current do local id = getid(current) if id == glyph_code then - wd = getfield(current,"width") - ht = getfield(current,"height") - dp = getfield(current,"depth") + wd, ht, dp = getwhd(current) progress() elseif id == kern_code then - wd = getfield(current,"kern") + wd = getkern(current) ht = 0 dp = 0 progress() @@ -181,20 +188,26 @@ local function getprofile(line,step) process(replace) end elseif id == glue_code then - wd = getfield(current,"width") + local width, stretch, shrink, stretch_order, shrink_order = getglue(current) if glue_sign == 1 then - if getfield(current,"stretch_order") == glue_order then - wd = wd + getfield(current,"stretch") * glue_set + if stretch_order == glue_order then + wd = width + stretch * glue_set + else + wd = width end elseif glue_sign == 2 then - if getfield(current,"shrink_order") == glue_order then - wd = wd - getfield(current,"shrink") * glue_set + if shrink_order == glue_order then + wd = width - shrink * glue_set + else + wd = width end + else + wd = width end if getsubtype(current) >= leaders_code then local leader = getleader(current) - ht = getfield(leader,"height") - dp = getfield(leader,"depth") + local w + w, ht, dp = getwhd(leader) -- can become getwhd(current) after 1.003 else ht = 0 dp = 0 @@ -202,36 +215,34 @@ local function getprofile(line,step) progress() elseif id == hlist_code then -- we could do a nested check .. but then we need to push / pop glue - local shift = getfield(current,"shift") - wd = getfield(current,"width") + local shift = getshift(current) + local w, h, d = getwhd(current) -- if getattr(current,a_specialcontent) then if getprop(current,"specialcontent") then -- like a margin note, maybe check for wd + wd = w ht = 0 dp = 0 else - ht = getfield(current,"height") - shift - dp = getfield(current,"depth") + shift + wd = w + ht = h - shift + dp = d + shift end progress() elseif id == vlist_code or id == unset_code then - local shift = getfield(current,"shift") -- todo - wd = getfield(current,"width") - ht = getfield(current,"height") -- - shift - dp = getfield(current,"depth") -- + shift + local shift = getshift(current) -- todo + wd, ht, dp = getwhd(current) progress() elseif id == rule_code then - wd = getfield(current,"width") - ht = getfield(current,"height") - dp = getfield(current,"depth") + wd, ht, dp = getwhd(current) progress() elseif id == math_code then - wd = getfield(current,"surround") + wd = getkern(current) + getwidth(current) -- surround ht = 0 dp = 0 progress() elseif id == marginkern_code then - wd = getfield(current,"width") + wd = getwidth(current) ht = 0 dp = 0 progress() @@ -300,19 +311,15 @@ local function addstring(height,depth) local dptext = depth local httext = typesetters.tohpack(height,infofont) local dptext = typesetters.tohpack(depth,infofont) - setfield(httext,"shift",- 1.2 * exheight) - setfield(dptext,"shift", 0.6 * exheight) - local text = nuts.hpack( - nuts.linked( - new_kern(-getfield(httext,"width")-emwidth), - httext, - new_kern(-getfield(dptext,"width")), - dptext - ) - ) - setfield(text,"height",0) - setfield(text,"depth",0) - setfield(text,"width",0) + setshift(httext,- 1.2 * exheight) + setshift(dptext, 0.6 * exheight) + local text = hpack_nodes(setlink( + new_kern(-getwidth(httext)-emwidth), + httext, + new_kern(-getwidth(dptext)), + dptext + )) + setwhd(text,0,0,0) return text end @@ -389,15 +396,13 @@ local function addprofile(node,profile,step) local rule = hpack_nodes(head) - setfield(rule,"width", 0) - setfield(rule,"height",0) - setfield(rule,"depth", 0) + setwhd(rule,0,0,0) -- if texttoo then -- -- local text = addstring( - -- formatters["%0.4f"](getfield(rule,"height")/65536), - -- formatters["%0.4f"](getfield(rule,"depth") /65536) + -- formatters["%0.4f"](getheight(rule)/65536), + -- formatters["%0.4f"](getdepth(rule) /65536) -- ) -- -- setlink(text,rule) @@ -486,8 +491,8 @@ methods[v_strict] = function(top,bot,t_profile,b_profile,specification) local strutdp = specification.depth or texdimen.strutdp local lineheight = strutht + strutdp - local depth = getfield(top,"depth") - local height = getfield(bot,"height") + local depth = getdepth(top) + local height = getheight(bot) local total = depth + height local distance = specification.distance or 0 local delta = lineheight - total @@ -522,8 +527,8 @@ methods[v_fixed] = function(top,bot,t_profile,b_profile,specification) local strutdp = specification.depth or texdimen.strutdp local lineheight = strutht + strutdp - local depth = getfield(top,"depth") - local height = getfield(bot,"height") + local depth = getdepth(top) + local height = getheight(bot) local total = depth + height local distance = specification.distance or 0 local delta = lineheight - total @@ -535,8 +540,8 @@ methods[v_fixed] = function(top,bot,t_profile,b_profile,specification) -- no distance (yet) if delta < lineheight then - setfield(top,"depth",strutdp) - setfield(bot,"height",strutht) + setdepth(top,strutdp) + setheight(bot,strutht) return true end @@ -547,13 +552,13 @@ methods[v_fixed] = function(top,bot,t_profile,b_profile,specification) depth = depth - lineheight dp = dp + lineheight end - setfield(top,"depth",dp) + setdepth(top,dp) local ht = strutht while height > lineheight - strutht do height = height - lineheight ht = ht + lineheight end - setfield(bot,"height",ht) + setheight(bot,ht) local lines = floor(delta/lineheight) if lines > 0 then inject(top,bot,-lines * lineheight) @@ -564,17 +569,17 @@ methods[v_fixed] = function(top,bot,t_profile,b_profile,specification) end if total < lineheight then - setfield(top,"depth",strutdp) - setfield(bot,"height",strutht) + setdepth(top,strutdp) + setheight(bot,strutht) return true end if depth < strutdp then - setfield(top,"depth",strutdp) + setdepth(top,strutdp) total = total - depth + strutdp end if height < strutht then - setfield(bot,"height",strutht) + setheight(bot,strutht) total = total - height + strutht end @@ -674,7 +679,7 @@ local function profilelist(line,mvl) end break elseif id == glue_code then - local wd = getfield(current,"width") + local wd = getwidth(current) if not wd or wd == 0 then -- go on else @@ -748,7 +753,7 @@ local function profilelist(line,mvl) if top then local subtype = getsubtype(current) -- if subtype == lineskip_code or subtype == baselineskip_code then - local wd = getfield(current,"width") + local wd = getwidth(current) if wd > 0 then distance = wd lastglue = current @@ -792,9 +797,9 @@ local enabled = false function profiling.set(specification) if not enabled then - nodes.tasks.enableaction("mvlbuilders", "builders.profiling.pagehandler") + enableaction("mvlbuilders", "builders.profiling.pagehandler") -- too expensive so we expect that this happens explicitly, we keep for reference: - -- nodes.tasks.enableaction("vboxbuilders","builders.profiling.vboxhandler") + -- enableaction("vboxbuilders","builders.profiling.vboxhandler") enabled = true end local n = #specifications + 1 @@ -853,7 +858,7 @@ function profiling.profilebox(specification) local subtype = getsubtype(current) if subtype == lineskip_code or subtype == baselineskip_code then if top then - local wd = getfield(current,"width") + local wd = getwidth(current) if wd > 0 then distance = wd lastglue = current @@ -889,12 +894,12 @@ function profiling.profilebox(specification) end -local ignore = table.tohash { - "split_keep", - "split_off", - -- "vbox", -} - +-- local ignore = table.tohash { +-- "split_keep", +-- "split_off", +-- -- "vbox", +-- } +-- -- function profiling.vboxhandler(head,where) -- if head and not ignore[where] then -- local h = tonut(head) diff --git a/tex/context/base/mkiv/spac-ver.lua b/tex/context/base/mkiv/spac-ver.lua index e81e8b81d..2f0191e6a 100644 --- a/tex/context/base/mkiv/spac-ver.lua +++ b/tex/context/base/mkiv/spac-ver.lua @@ -30,6 +30,8 @@ if not modules then modules = { } end modules ['spac-ver'] = { -- todo: strip baselineskip around display math +-- todo: getglue(n,false) instead of getfield + local next, type, tonumber = next, type, tonumber local gmatch, concat = string.gmatch, table.concat local ceil, floor = math.ceil, math.floor @@ -39,8 +41,6 @@ local allocate = utilities.storage.allocate local todimen = string.todimen local formatters = string.formatters -local P, C, R, S, Cc, Carg = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cc, lpeg.Carg - local nodes = nodes local node = node local trackers = trackers @@ -49,13 +49,48 @@ local context = context local tex = tex local texlists = tex.lists +local texget = tex.get +local texgetcount = tex.getcount local texgetdimen = tex.getdimen +local texset = tex.set local texsetdimen = tex.setdimen local texnest = tex.nest local variables = interfaces.variables local implement = interfaces.implement +local v_local = variables["local"] +local v_global = variables["global"] +local v_box = variables.box +----- v_page = variables.page -- reserved for future use +local v_split = variables.split +local v_min = variables.min +local v_max = variables.max +local v_none = variables.none +local v_line = variables.line +local v_noheight = variables.noheight +local v_nodepth = variables.nodepth +local v_line = variables.line +local v_halfline = variables.halfline +local v_line_m = "-" .. variables.line +local v_halfline_m = "-" .. variables.halfline +local v_first = variables.first +local v_last = variables.last +local v_top = variables.top +local v_bottom = variables.bottom +local v_minheight = variables.minheight +local v_maxheight = variables.maxheight +local v_mindepth = variables.mindepth +local v_maxdepth = variables.maxdepth +local v_offset = variables.offset +local v_strut = variables.strut + +local v_hfraction = variables.hfraction +local v_dfraction = variables.dfraction +local v_bfraction = variables.bfraction +local v_tlines = variables.tlines +local v_blines = variables.blines + -- vertical space handler local trace_vbox_vspacing = false trackers.register("vspacing.vbox", function(v) trace_vbox_vspacing = v end) @@ -66,24 +101,22 @@ local trace_vspacing = false trackers.register("vspacing.spacing", fun local trace_vsnapping = false trackers.register("vspacing.snapping", function(v) trace_vsnapping = v end) local trace_specials = false trackers.register("vspacing.specials", function(v) trace_specials = v end) +local remove_math_skips = true directives.register("vspacing.removemathskips", function(v) remnove_math_skips = v end) + local report_vspacing = logs.reporter("vspacing","spacing") local report_collapser = logs.reporter("vspacing","collapsing") local report_snapper = logs.reporter("vspacing","snapping") local report_specials = logs.reporter("vspacing","specials") -local report_page_builder = logs.reporter("builders","page") local a_skipcategory = attributes.private('skipcategory') local a_skippenalty = attributes.private('skippenalty') local a_skiporder = attributes.private('skiporder') ------ snap_category = attributes.private('snapcategory') local a_snapmethod = attributes.private('snapmethod') local a_snapvbox = attributes.private('snapvbox') -local a_profilemethod = attributes.private("profilemethod") local nuts = nodes.nuts local tonode = nuts.tonode local tonut = nuts.tonut -local ntostring = nuts.tostring local getfield = nuts.getfield local setfield = nuts.setfield @@ -97,16 +130,29 @@ local getattr = nuts.getattr local setattr = nuts.setattr local getsubtype = nuts.getsubtype local getbox = nuts.getbox +local getwhd = nuts.getwhd +local setwhd = nuts.setwhd +local getprop = nuts.getprop +local setprop = nuts.setprop +local getglue = nuts.getglue +local setglue = nuts.setglue +local getkern = nuts.getkern +local getpenalty = nuts.getpenalty +local setshift = nuts.setshift +local setwidth = nuts.setwidth +local getwidth = nuts.getwidth +local setheight = nuts.setheight +local getheight = nuts.getheight +local setdepth = nuts.setdepth +local getdepth = nuts.getdepth local find_node_tail = nuts.tail -local free_node = nuts.free -local free_node_list = nuts.flush_list +local flush_node = nuts.flush_node local traverse_nodes = nuts.traverse local traverse_nodes_id = nuts.traverse_id local insert_node_before = nuts.insert_before -local insert_node_after = nuts.insert_after local remove_node = nuts.remove -local count_nodes = nuts.count +local count_nodes = nuts.countall local hpack_node = nuts.hpack local vpack_node = nuts.vpack ----- writable_spec = nuts.writable_spec @@ -129,6 +175,7 @@ local skipcodes = nodes.skipcodes local penalty_code = nodecodes.penalty local kern_code = nodecodes.kern local glue_code = nodecodes.glue +local insert_code = nodecodes.ins local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist local localpar_code = nodecodes.localpar @@ -156,19 +203,19 @@ vspacingdata.snapmethods = snapmethods storage.register("builders/vspacing/data/snapmethods", snapmethods, "builders.vspacing.data.snapmethods") local default = { - maxheight = true, - maxdepth = true, - strut = true, - hfraction = 1, - dfraction = 1, - bfraction = 0.25, + [v_maxheight] = true, + [v_maxdepth] = true, + [v_strut] = true, + [v_hfraction] = 1, + [v_dfraction] = 1, + [v_bfraction] = 0.25, } local fractions = { - minheight = "hfraction", maxheight = "hfraction", - mindepth = "dfraction", maxdepth = "dfraction", - box = "bfraction", - top = "tlines", bottom = "blines", + [v_minheight] = v_hfraction, [v_maxheight] = v_hfraction, + [v_mindepth] = v_dfraction, [v_maxdepth] = v_dfraction, + [v_box] = v_bfraction, + [v_top] = v_tlines, [v_bottom] = v_blines, } local values = { @@ -204,13 +251,14 @@ local function listtohash(str) else detail = tonumber("0" .. key) if detail then - t.hfraction, t.dfraction = detail, detail + t[v_hfraction] = detail + t[v_dfraction] = detail end end end if next(t) then - t.hfraction = t.hfraction or 1 - t.dfraction = t.dfraction or 1 + t[v_hfraction] = t[v_hfraction] or 1 + t[v_dfraction] = t[v_dfraction] or 1 return t else return default @@ -221,21 +269,11 @@ function vspacing.definesnapmethod(name,method) local n = #snapmethods + 1 local t = listtohash(method) snapmethods[n] = t - t.name, t.specification = name, method + t.name = name -- not interfaced + t.specification = method -- not interfaced context(n) end --- local rule_id = nodecodes.rule --- local vlist_id = nodecodes.vlist --- function nodes.makevtop(n) --- if getid(n) == vlist_id then --- local list = getlist(n) --- local height = (list and getid(list) <= rule_id and getfield(list,"height")) or 0 --- setfield(n,"depth",getfield(n,"depth") - height + getfield(n,"height") --- setfield(n,"height",height --- end --- end - local function validvbox(parentid,list) if parentid == hlist_code then local id = getid(list) @@ -270,28 +308,32 @@ local function validvbox(parentid,list) end end +-- we can use a property + local function already_done(parentid,list,a_snapmethod) -- todo: done when only boxes and all snapped -- problem: any snapped vbox ends up in a line if list and parentid == hlist_code then local id = getid(list) if id == localpar_code then -- check for initial par subtype list = getnext(list) - if not next then + if not list then return false end end ---~ local i = 0 for n in traverse_nodes(list) do local id = getid(n) ---~ i = i + 1 print(i,nodecodes[id],getattr(n,a_snapmethod)) if id == hlist_code or id == vlist_code then - local a = getattr(n,a_snapmethod) - if not a then - -- return true -- not snapped at all - elseif a == 0 then - return true -- already snapped + -- local a = getattr(n,a_snapmethod) + -- if not a then + -- -- return true -- not snapped at all + -- elseif a == 0 then + -- return true -- already snapped + -- end + local p = getprop(n,"snapper") + if p then + return p end - elseif id == glue_code or id == penalty_code then + elseif id == glue_code or id == penalty_code then -- or id == kern_code then -- go on else return false -- whatever @@ -301,7 +343,6 @@ local function already_done(parentid,list,a_snapmethod) -- todo: done when only return false end - -- quite tricky: ceil(-something) => -0 local function ceiled(n) @@ -327,7 +368,18 @@ local function fixedprofile(current) return profiling and profiling.fixedprofile(current) end -local function snap_hlist(where,current,method,height,depth) -- method.strut is default +-- local function onlyoneentry(t) +-- local n = 1 +-- for k, v in next, t do +-- if n > 1 then +-- return false +-- end +-- n = n + 1 +-- end +-- return true +-- end + +local function snap_hlist(where,current,method,height,depth) -- method[v_strut] is default if fixedprofile(current) then return end @@ -335,19 +387,18 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is local t = trace_vsnapping and { } if t then t[#t+1] = formatters["list content: %s"](listtoutf(list)) - t[#t+1] = formatters["parent id: %s"](nodereference(current)) - t[#t+1] = formatters["snap method: %s"](method.name) - t[#t+1] = formatters["specification: %s"](method.specification) + t[#t+1] = formatters["snap method: %s"](method.name) -- not interfaced + t[#t+1] = formatters["specification: %s"](method.specification) -- not interfaced end local snapht, snapdp - if method["local"] then + if method[v_local] then -- snapping is done immediately here snapht = texgetdimen("bodyfontstrutheight") snapdp = texgetdimen("bodyfontstrutdepth") if t then t[#t+1] = formatters["local: snapht %p snapdp %p"](snapht,snapdp) end - elseif method["global"] then + elseif method[v_global] then snapht = texgetdimen("globalbodyfontstrutheight") snapdp = texgetdimen("globalbodyfontstrutdepth") if t then @@ -368,32 +419,29 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is end end - local h = (method.noheight and 0) or height or getfield(current,"height") - local d = (method.nodepth and 0) or depth or getfield(current,"depth") - local hr = method.hfraction or 1 - local dr = method.dfraction or 1 - local br = method.bfraction or 0 + local wd, ht, dp = getwhd(current) + + local h = (method[v_noheight] and 0) or height or ht + local d = (method[v_nodepth] and 0) or depth or dp + local hr = method[v_hfraction] or 1 + local dr = method[v_dfraction] or 1 + local br = method[v_bfraction] or 0 local ch = h local cd = d - local tlines = method.tlines or 1 - local blines = method.blines or 1 + local tlines = method[v_tlines] or 1 + local blines = method[v_blines] or 1 local done = false local plusht = snapht local plusdp = snapdp local snaphtdp = snapht + snapdp + local extra = 0 --- local properties = theprop(current) --- local unsnapped = properties.unsnapped --- if not unsnapped then -- experiment --- properties.unsnapped = { --- height = h, --- depth = d, --- snapht = snapht, --- snapdp = snapdp, --- } --- end + if t then + t[#t+1] = formatters["hlist: wd %p ht %p (used %p) dp %p (used %p)"](wd,ht,h,dp,d) + t[#t+1] = formatters["fractions: hfraction %s dfraction %s bfraction %s tlines %s blines %s"](hr,dr,br,tlines,blines) + end - if method.box then + if method[v_box] then local br = 1 - br if br < 0 then br = 0 @@ -404,38 +452,75 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is local x = n * snaphtdp - h - d plusht = h + x / 2 plusdp = d + x / 2 - elseif method.max then + if t then + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_box,plusht,plusdp) + end + elseif method[v_max] then local n = ceiled((h+d)/snaphtdp) local x = n * snaphtdp - h - d plusht = h + x / 2 plusdp = d + x / 2 - elseif method.min then - local n = floored((h+d)/snaphtdp) - local x = n * snaphtdp - h - d - plusht = h + x / 2 - plusdp = d + x / 2 - elseif method.none then + if t then + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_max,plusht,plusdp) + end + elseif method[v_min] then + -- we catch a lone min + if method.specification ~= v_min then + local n = floored((h+d)/snaphtdp) + local x = n * snaphtdp - h - d + plusht = h + x / 2 + plusdp = d + x / 2 + if plusht < 0 then + plusht = 0 + end + if plusdp < 0 then + plusdp = 0 + end + end + if t then + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_min,plusht,plusdp) + end + elseif method[v_none] then plusht, plusdp = 0, 0 if t then - t[#t+1] = "none: plusht 0pt plusdp 0pt" + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_none,0,0) end end - if method.halfline then -- extra halfline - plusht = plusht + snaphtdp/2 - plusdp = plusdp + snaphtdp/2 + -- for now, we actually need to tag a box and then check at several points if something ended up + -- at the top of a page + if method[v_halfline] then -- extra halfline + extra = snaphtdp/2 + plusht = plusht + extra + plusdp = plusdp + extra if t then - t[#t+1] = formatters["halfline: plusht %p plusdp %p"](plusht,plusdp) + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_halfline,plusht,plusdp) end end - if method.line then -- extra line - plusht = plusht + snaphtdp - plusdp = plusdp + snaphtdp + if method[v_line] then -- extra line + extra = snaphtdp + plusht = plusht + extra + plusdp = plusdp + extra if t then - t[#t+1] = formatters["line: plusht %p plusdp %p"](plusht,plusdp) + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_line,plusht,plusdp) end end - - if method.first then + if method[v_halfline_m] then -- extra halfline + extra = - snaphtdp/2 + plusht = plusht + extra + plusdp = plusdp + extra + if t then + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_halfline_m,plusht,plusdp) + end + end + if method[v_line_m] then -- extra line + extra = - snaphtdp + plusht = plusht + extra + plusdp = plusdp + extra + if t then + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_line_m,plusht,plusdp) + end + end + if method[v_first] then local thebox = current local id = getid(thebox) if id == hlist_code then @@ -444,15 +529,13 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is end if thebox and id == vlist_code then local list = getlist(thebox) - local lh, ld + local lw, lh, ld for n in traverse_nodes_id(hlist_code,list) do - lh = getfield(n,"height") - ld = getfield(n,"depth") + lw, lh, ld = getwhd(n) break end if lh then - local ht = getfield(thebox,"height") - local dp = getfield(thebox,"depth") + local wd, ht, dp = getwhd(thebox) if t then t[#t+1] = formatters["first line: height %p depth %p"](lh,ld) t[#t+1] = formatters["dimensions: height %p depth %p"](ht,dp) @@ -461,7 +544,7 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is ch, cd = lh, delta + d h, d = ch, cd local shifted = hpack_node(getlist(current)) - setfield(shifted,"shift",delta) + setshift(shifted,delta) setlist(current,shifted) done = true if t then @@ -473,7 +556,7 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is elseif t then t[#t+1] = "first: not done, no vbox" end - elseif method.last then + elseif method[v_last] then local thebox = current local id = getid(thebox) if id == hlist_code then @@ -482,14 +565,12 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is end if thebox and id == vlist_code then local list = getlist(thebox) - local lh, ld + local lw, lh, ld for n in traverse_nodes_id(hlist_code,list) do - lh = getfield(n,"height") - ld = getfield(n,"depth") + lw, lh, ld = getwhd(n) end if lh then - local ht = getfield(thebox,"height") - local dp = getfield(thebox,"depth") + local wd, ht, dp = getwhd(thebox) if t then t[#t+1] = formatters["last line: height %p depth %p" ](lh,ld) t[#t+1] = formatters["dimensions: height %p depth %p"](ht,dp) @@ -498,7 +579,7 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is cd, ch = ld, delta + h h, d = ch, cd local shifted = hpack_node(getlist(current)) - setfield(shifted,"shift",delta) + setshift(shifted,delta) setlist(current,shifted) done = true if t then @@ -511,12 +592,12 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is t[#t+1] = "last: not done, no vbox" end end - if method.minheight then + if method[v_minheight] then ch = floored((h-hr*snapht)/snaphtdp)*snaphtdp + plusht if t then t[#t+1] = formatters["minheight: %p"](ch) end - elseif method.maxheight then + elseif method[v_maxheight] then ch = ceiled((h-hr*snapht)/snaphtdp)*snaphtdp + plusht if t then t[#t+1] = formatters["maxheight: %p"](ch) @@ -527,12 +608,12 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is t[#t+1] = formatters["set height: %p"](ch) end end - if method.mindepth then + if method[v_mindepth] then cd = floored((d-dr*snapdp)/snaphtdp)*snaphtdp + plusdp if t then t[#t+1] = formatters["mindepth: %p"](cd) end - elseif method.maxdepth then + elseif method[v_maxdepth] then cd = ceiled((d-dr*snapdp)/snaphtdp)*snaphtdp + plusdp if t then t[#t+1] = formatters["maxdepth: %p"](cd) @@ -543,42 +624,43 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is t[#t+1] = formatters["set depth: %p"](cd) end end - if method.top then + if method[v_top] then ch = ch + tlines * snaphtdp if t then t[#t+1] = formatters["top height: %p"](ch) end end - if method.bottom then + if method[v_bottom] then cd = cd + blines * snaphtdp if t then t[#t+1] = formatters["bottom depth: %p"](cd) end end - - local offset = method.offset + local offset = method[v_offset] if offset then -- we need to set the attr if t then - t[#t+1] = formatters["before offset: %p (width %p height %p depth %p)"](offset,getfield(current,"width") or 0,getfield(current,"height"),getfield(current,"depth")) + local wd, ht, dp = getwhd(current) + t[#t+1] = formatters["before offset: %p (width %p height %p depth %p)"](offset,wd,ht,dp) end local shifted = hpack_node(getlist(current)) - setfield(shifted,"shift",offset) + setshift(shifted,offset) setlist(current,shifted) if t then - t[#t+1] = formatters["after offset: %p (width %p height %p depth %p)"](offset,getfield(current,"width") or 0,getfield(current,"height"),getfield(current,"depth")) + local wd, ht, dp = getwhd(current) + t[#t+1] = formatters["after offset: %p (width %p height %p depth %p)"](offset,wd,ht,dp) end setattr(shifted,a_snapmethod,0) setattr(current,a_snapmethod,0) end if not height then - setfield(current,"height",ch) + setheight(current,ch) if t then t[#t+1] = formatters["forced height: %p"](ch) end end if not depth then - setfield(current,"depth",cd) + setdepth(current,cd) if t then t[#t+1] = formatters["forced depth: %p"](cd) end @@ -587,9 +669,9 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is if t then local original = (h+d)/snaphtdp local whatever = (ch+cd)/(texgetdimen("globalbodyfontstrutheight") + texgetdimen("globalbodyfontstrutdepth")) - t[#t+1] = formatters["final lines: %s -> %s (%s)"](original,lines,whatever) + t[#t+1] = formatters["final lines : %p -> %p (%p)"](original,lines,whatever) t[#t+1] = formatters["final height: %p -> %p"](h,ch) - t[#t+1] = formatters["final depth: %p -> %p"](d,cd) + t[#t+1] = formatters["final depth : %p -> %p"](d,cd) end -- todo: -- @@ -600,12 +682,16 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is if t then report_snapper("trace: %s type %s\n\t%\n\tt",where,nodecodes[getid(current)],t) end - return h, d, ch, cd, lines + if not method[v_split] then + -- so extra will not be compensated at the top of a page + extra = 0 + end + return h, d, ch, cd, lines, extra end local function snap_topskip(current,method) - local w = getfield(current,"width") or 0 - setfield(current,"width",0) + local w = getwidth(current) + setwidth(current,0) return w, 0 end @@ -652,7 +738,9 @@ vspacingdata.skip = vspacingdata.skip or { } -- allocate ? storage.register("builders/vspacing/data/map", vspacingdata.map, "builders.vspacing.data.map") storage.register("builders/vspacing/data/skip", vspacingdata.skip, "builders.vspacing.data.skip") -do -- todo: interface.variables +do -- todo: interface.variables and properties + + local P, C, R, S, Cc = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cc vspacing.fixed = false @@ -691,112 +779,6 @@ do -- todo: interface.variables local ctx_stopblankhandling = context.stopblankhandling local ctx_poplogger = context.poplogger - -- - - -- local function analyze(str,oldcategory) -- we could use shorter names - -- for s in gmatch(str,"([^ ,]+)") do - -- local amount, keyword, detail = lpegmatch(splitter,s) -- the comma splitter can be merged - -- if not keyword then - -- report_vspacing("unknown directive %a",s) - -- else - -- local mk = map[keyword] - -- if mk then - -- category = analyze(mk,category) -- category not used .. and we pass crap anyway - -- elseif keyword == k_fixed then - -- ctx_fixedblankskip() - -- elseif keyword == k_flexible then - -- ctx_flexibleblankskip() - -- elseif keyword == k_category then - -- local category = tonumber(detail) - -- if category then - -- ctx_setblankcategory(category) - -- if category ~= oldcategory then - -- ctx_flushblankhandling() - -- oldcategory = category - -- end - -- end - -- elseif keyword == k_order and detail then - -- local order = tonumber(detail) - -- if order then - -- ctx_setblankorder(order) - -- end - -- elseif keyword == k_penalty and detail then - -- local penalty = tonumber(detail) - -- if penalty then - -- ctx_setblankpenalty(penalty) - -- end - -- else - -- amount = tonumber(amount) or 1 - -- local sk = skip[keyword] - -- if sk then - -- ctx_addpredefinedblankskip(amount,keyword) - -- else -- no check - -- ctx_addaskedblankskip(amount,keyword) - -- end - -- end - -- end - -- end - -- return category - -- end - - -- local function analyze(str) -- we could use shorter names - -- for s in gmatch(str,"([^ ,]+)") do - -- local amount, keyword, detail = lpegmatch(splitter,s) -- the comma splitter can be merged - -- if not keyword then - -- report_vspacing("unknown directive %a",s) - -- else - -- local mk = map[keyword] - -- if mk then - -- analyze(mk) -- category not used .. and we pass crap anyway - -- elseif keyword == k_fixed then - -- ctx_fixedblankskip() - -- elseif keyword == k_flexible then - -- ctx_flexibleblankskip() - -- elseif keyword == k_category then - -- local category = tonumber(detail) - -- if category then - -- ctx_setblankcategory(category) - -- ctx_flushblankhandling() - -- end - -- elseif keyword == k_order and detail then - -- local order = tonumber(detail) - -- if order then - -- ctx_setblankorder(order) - -- end - -- elseif keyword == k_penalty and detail then - -- local penalty = tonumber(detail) - -- if penalty then - -- ctx_setblankpenalty(penalty) - -- end - -- else - -- amount = tonumber(amount) or 1 - -- local sk = skip[keyword] - -- if sk then - -- ctx_addpredefinedblankskip(amount,keyword) - -- else -- no check - -- ctx_addaskedblankskip(amount,keyword) - -- end - -- end - -- end - -- end - -- end - - -- function vspacing.analyze(str) - -- if trace_vspacing then - -- ctx_pushlogger(report_vspacing) - -- ctx_startblankhandling() - -- analyze(str,1) - -- ctx_stopblankhandling() - -- ctx_poplogger() - -- else - -- ctx_startblankhandling() - -- analyze(str,1) - -- ctx_stopblankhandling() - -- end - -- end - - -- alternative - local pattern = nil local function handler(amount, keyword, detail) @@ -880,11 +862,11 @@ local function nodes_to_string(head) local id = getid(current) local ty = nodecodes[id] if id == penalty_code then - t[#t+1] = formatters["%s:%s"](ty,getfield(current,"penalty")) + t[#t+1] = formatters["%s:%s"](ty,getpenalty(current)) elseif id == glue_code then - t[#t+1] = formatters["%s:%s:%p"](ty,skipcodes[getsubtype(current)],getfield(current,"width")) + t[#t+1] = formatters["%s:%s:%p"](ty,skipcodes[getsubtype(current)],getwidth(current)) elseif id == kern_code then - t[#t+1] = formatters["%s:%p"](ty,getfield(current,"kern")) + t[#t+1] = formatters["%s:%p"](ty,getkern(current)) else t[#t+1] = ty end @@ -898,12 +880,12 @@ local function reset_tracing(head) end local function trace_skip(str,sc,so,sp,data) - trace_list[#trace_list+1] = { "skip", formatters["%s | %p | category %s | order %s | penalty %s"](str, getfield(data,"width"), sc or "-", so or "-", sp or "-") } + trace_list[#trace_list+1] = { "skip", formatters["%s | %p | category %s | order %s | penalty %s"](str, getwidth(data), sc or "-", so or "-", sp or "-") } tracing_info = true end local function trace_natural(str,data) - trace_list[#trace_list+1] = { "skip", formatters["%s | %p"](str, getfield(data,"width")) } + trace_list[#trace_list+1] = { "skip", formatters["%s | %p"](str, getwidth(data)) } tracing_info = true end @@ -923,9 +905,9 @@ end local function trace_done(str,data) if getid(data) == penalty_code then - trace_list[#trace_list+1] = { "penalty", formatters["%s | %s"](str,getfield(data,"penalty")) } + trace_list[#trace_list+1] = { "penalty", formatters["%s | %s"](str,getpenalty(data)) } else - trace_list[#trace_list+1] = { "glue", formatters["%s | %p"](str,getfield(data,"width")) } + trace_list[#trace_list+1] = { "glue", formatters["%s | %p"](str,getwidth(data)) } end tracing_info = true end @@ -960,8 +942,7 @@ function vspacing.snapbox(n,how) -- report_snapper("box list not snapped, already done") end else - local ht = getfield(box,"height") - local dp = getfield(box,"depth") + local wd, ht, dp = getwhd(box) if false then -- todo: already_done -- assume that the box is already snapped if trace_vsnapping then @@ -969,9 +950,16 @@ function vspacing.snapbox(n,how) ht,dp,listtoutf(list)) end else - local h, d, ch, cd, lines = snap_hlist("box",box,sv,ht,dp) - setfield(box,"height",ch) - setfield(box,"depth",cd) + local h, d, ch, cd, lines, extra = snap_hlist("box",box,sv,ht,dp) +setprop(box,"snapper",{ + ht = h, + dp = d, + ch = ch, + cd = cd, + extra = extra, + current = current, +}) + setwhd(box,wd,ch,cd) if trace_vsnapping then report_snapper("box list snapped from (%p,%p) to (%p,%p) using method %a (%s) for %a (%s lines): %s", h,d,ch,cd,sv.name,sv.specification,"direct",lines,listtoutf(list)) @@ -998,10 +986,10 @@ end local w, h, d = 0, 0, 0 ----- w, h, d = 100*65536, 65536, 65536 -local function forced_skip(head,current,width,where,trace) +local function forced_skip(head,current,width,where,trace) -- looks old ... we have other tricks now if head == current then if getsubtype(head) == baselineskip_code then - width = width - (getfield(head,"width") or 0) + width = width - getwidth(head) end end if width == 0 then @@ -1025,16 +1013,17 @@ end -- penalty only works well when before skip -local discard = 0 -local largest = 1 -local force = 2 -local penalty = 3 -local add = 4 -local disable = 5 -local nowhite = 6 -local goback = 7 -local together = 8 -- not used (?) -local overlay = 9 +local discard = 0 +local largest = 1 +local force = 2 +local penalty = 3 +local add = 4 +local disable = 5 +local nowhite = 6 +local goback = 7 +local together = 8 -- not used (?) +local overlay = 9 +local enable = 10 -- [whatsits][hlist][glue][glue][penalty] @@ -1096,7 +1085,7 @@ specialmethods[1] = function(pagehead,pagetail,start,penalty) report_specials(" context penalty %a, higher level, continue",p) end else - local p = getfield(current,"penalty") + local p = getpenalty(current) if p < 10000 then -- assume some other mechanism kicks in so we seem to have content if trace_specials then @@ -1135,21 +1124,20 @@ local function check_experimental_overlay(head,current) local c = current local n = nil local function overlay(p,n,mvl) - local p_ht = getfield(p,"height") - local p_dp = getfield(p,"depth") - local n_ht = getfield(n,"height") + local p_wd, p_ht, p_dp = getwhd(p) + local n_wd, n_ht, n_dp = getwhd(n) local skips = 0 -- -- We deal with this at the tex end .. we don't see spacing .. enabling this code - -- is probably harmless btu then we need to test it. + -- is probably harmless but then we need to test it. -- local c = getnext(p) while c and c ~= n do local id = getid(c) if id == glue_code then - skips = skips + (getfield(c,"width") or 0) + skips = skips + getwidth(c) elseif id == kern_code then - skips = skips + getfield(c,"kern") + skips = skips + getkern(c) end c = getnext(c) end @@ -1159,7 +1147,7 @@ local function check_experimental_overlay(head,current) local k = new_kern(-delta) if n_ht > p_ht then -- we should adapt pagetotal ! (need a hook for that) .. now we have the wrong pagebreak - setfield(p,"height",n_ht) + setheight(p,n_ht) end insert_node_before(head,n,k) if p == head then @@ -1240,7 +1228,7 @@ end -- topskip -- splittopskip -local experiment = false directives.register("vspacing.experiment",function(v) experiment = v end) +local experiment = true directives.register("vspacing.experiment",function(v) experiment = v end) local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also pass tail if trace then @@ -1250,6 +1238,7 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also local glue_order, glue_data, force_glue = 0, nil, false local penalty_order, penalty_data, natural_penalty, special_penalty = 0, nil, nil, nil local parskip, ignore_parskip, ignore_following, ignore_whitespace, keep_together = nil, false, false, false, false + local lastsnap = nil -- -- todo: keep_together: between headers -- @@ -1260,12 +1249,78 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also if not pagehead then pagehead = texlists.page_head if pagehead then - pagehead = tonut(texlists.page_head) + pagehead = tonut(pagehead) pagetail = find_node_tail(pagehead) -- no texlists.page_tail yet-- no texlists.page_tail yet end end end -- + local function compensate(n) + local g = 0 + while n and getid(n) == glue_code do + g = g + getwidth(n) + n = getnext(n) + end + if n then + local p = getprop(n,"snapper") + if p then + local extra = p.extra + if extra and extra < 0 then -- hm, extra can be unset ... needs checking + local h = p.ch -- getheight(n) + -- maybe an extra check + -- if h - extra < g then + setheight(n,h-2*extra) + p.extra = 0 + if trace_vsnapping then + report_snapper("removed extra space at top: %p",extra) + end + -- end + end + end + return n + end + end + -- + local function removetopsnap() + getpagelist() + if pagehead then + local n = pagehead and compensate(pagehead) + if n and n ~= pagetail then + local p = getprop(pagetail,"snapper") + if p then + local e = p.extra + if e and e < 0 then + local t = texget("pagetotal") + if t > 0 then + local g = texget("pagegoal") -- 1073741823 is signal + local d = g - t + if d < -e then + local penalty = new_penalty(1000000) + setlink(penalty,head) + head = penalty + report_snapper("force pagebreak due to extra space at bottom: %p",e) + end + end + end + end + end + elseif head then + compensate(head) + end + end + -- + local function getavailable() + getpagelist() + if pagehead then + local t = texget("pagetotal") + if t > 0 then + local g = texget("pagegoal") + return g - t + end + end + return false + end + -- local function flush(why) if penalty_data then local p = new_penalty(penalty_data) @@ -1299,23 +1354,23 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also if trace then trace_done("flushed due to forced " .. why,glue_data) end - head = forced_skip(head,current,getfield(glue_data,"width") or 0,"before",trace) - free_node(glue_data) + head = forced_skip(head,current,getwidth(glue_data,width),"before",trace) + flush_node(glue_data) else - local w = getfield(glue_data,"width") - if w ~= 0 then + local width, stretch, shrink = getglue(glue_data) + if width ~= 0 then if trace then trace_done("flushed due to non zero " .. why,glue_data) end head = insert_node_before(head,current,glue_data) - elseif getfield(glue_data,"stretch") ~= 0 or getfield(glue_data,"shrink") ~= 0 then + elseif stretch ~= 0 or shrink ~= 0 then if trace then trace_done("flushed due to stretch/shrink in" .. why,glue_data) end head = insert_node_before(head,current,glue_data) else -- report_vspacing("needs checking (%s): %p",skipcodes[getsubtype(glue_data)],w) - free_node(glue_data) + flush_node(glue_data) end end end @@ -1328,45 +1383,26 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also parskip, ignore_parskip, ignore_following, ignore_whitespace = nil, false, false, false end -- - --- quick hack, can be done nicer --- local nobreakfound = nil --- local function checknobreak() --- local pagehead, pagetail = getpagelist() --- local current = pagetail --- while current do --- local id = getid(current) --- if id == hlist_code or id == vlist_code then --- return false --- elseif id == penalty_code then --- return getfield(current,"penalty") >= 10000 --- end --- current = getprev(current) --- end --- return false --- end - - -- if trace_vsnapping then report_snapper("global ht/dp = %p/%p, local ht/dp = %p/%p", - texgetdimen("globalbodyfontstrutheight"), texgetdimen("globalbodyfontstrutdepth"), - texgetdimen("bodyfontstrutheight"), texgetdimen("bodyfontstrutdepth") + texgetdimen("globalbodyfontstrutheight"), + texgetdimen("globalbodyfontstrutdepth"), + texgetdimen("bodyfontstrutheight"), + texgetdimen("bodyfontstrutdepth") ) end if trace then trace_info("start analyzing",where,what) end - --- local headprev = getprev(head) - + if snap and where == "page" then + removetopsnap() + end while current do local id = getid(current) if id == hlist_code or id == vlist_code then --- if nobreakfound == nil then --- nobreakfound = false --- end -- needs checking, why so many calls if snap then + lastsnap = nil local list = getlist(current) local s = getattr(current,a_snapmethod) if not s then @@ -1381,15 +1417,24 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also local sv = snapmethods[s] if sv then -- check if already snapped - if list and already_done(id,list,a_snapmethod) then - local ht = getfield(current,"height") - local dp = getfield(current,"depth") + local done = list and already_done(id,list,a_snapmethod) + if done then -- assume that the box is already snapped if trace_vsnapping then - report_snapper("mvl list already snapped at (%p,%p): %s",ht,dp,listtoutf(list)) + local w, h, d = getwhd(current) + report_snapper("mvl list already snapped at (%p,%p): %s",h,d,listtoutf(list)) end else - local h, d, ch, cd, lines = snap_hlist("mvl",current,sv) + local h, d, ch, cd, lines, extra = snap_hlist("mvl",current,sv,false,false) + lastsnap = { + ht = h, + dp = d, + ch = ch, + cd = cd, + extra = extra, + current = current, + } + setprop(current,"snapper",lastsnap) if trace_vsnapping then report_snapper("mvl %a snapped from (%p,%p) to (%p,%p) using method %a (%s) for %a (%s lines): %s", nodecodes[id],h,d,ch,cd,sv.name,sv.specification,where,lines,listtoutf(list)) @@ -1407,26 +1452,15 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also flush("list") current = getnext(current) elseif id == penalty_code then - -- natural_penalty = getfield(current,"penalty") + -- natural_penalty = getpenalty(current) -- if trace then -- trace_done("removed penalty",current) -- end -- head, current = remove_node(head, current, true) - --- if nobreakfound == nil then --- nobreakfound = checknobreak() --- end --- if nobreakfound and getfield(current,"penalty") <= 10000 then --- -- if trace then --- trace_done("removed penalty",current) --- -- end --- head, current = remove_node(head, current, true) --- end - current = getnext(current) elseif id == kern_code then - if snap and trace_vsnapping and getfield(current,"kern") ~= 0 then - report_snapper("kern of %p kept",getfield(current,"kern")) + if snap and trace_vsnapping and getkern(current) ~= 0 then + report_snapper("kern of %p kept",getkern(current)) end flush("kern") current = getnext(current) @@ -1449,12 +1483,6 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also special_penalty = sp sp = p end - --- else --- if nobreakfound == nil then --- nobreakfound = checknobreak() --- end - end if not penalty_data then penalty_data = sp @@ -1466,14 +1494,6 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also if trace then trace_skip("penalty in skip",sc,so,sp,current) end - --- if nobreakfound then --- penalty_data = 10000 --- if trace then --- trace_skip("nobreak found before penalty in skip",sc,so,sp,current) --- end --- end - head, current = remove_node(head, current, true) elseif not sc then -- if not sc then if glue_data then @@ -1490,11 +1510,10 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also -- todo: prev can be whatsit (latelua) local previous = getprev(current) if previous and getid(previous) == glue_code and getsubtype(previous) == userskip_code then - if getfield(previous,"stretch_order") == 0 and getfield(previous,"shrink_order") == 0 and - getfield(current, "stretch_order") == 0 and getfield(current, "shrink_order") == 0 then - setfield(previous,"width", (getfield(previous,"width") or 0) + (getfield(current,"width") or 0)) - setfield(previous,"stretch",(getfield(previous,"stretch") or 0) + (getfield(current,"stretch") or 0)) - setfield(previous,"shrink", (getfield(previous,"shrink") or 0) + (getfield(current,"shrink") or 0)) + local pwidth, pstretch, pshrink, pstretch_order, pshrink_order = getglue(previous) + local cwidth, cstretch, cshrink, cstretch_order, cshrink_order = getglue(current) + if pstretch_order == 0 and pshrink_order == 0 and cstretch_order == 0 and cshrink_order == 0 then + setglue(previous,pwidth + cwidth, pstretch + cstretch, pshrink + cshrink) if trace then trace_natural("removed",current) end @@ -1516,36 +1535,36 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also end end glue_order, glue_data = 0, nil - elseif sc == disable then -local next = getnext(current) -if not experiment or next then - ignore_following = true - if trace then - trace_skip("disable",sc,so,sp,current) + elseif sc == disable or sc == enable then + local next = getnext(current) + if not experiment or next then + ignore_following = sc == disable + if trace then + trace_skip(sc == disable and "disable" or "enable",sc,so,sp,current) + end + head, current = remove_node(head, current, true) + else + current = next end - head, current = remove_node(head, current, true) -else - current = next -end elseif sc == together then -local next = getnext(current) -if not experiment or next then - keep_together = true - if trace then - trace_skip("together",sc,so,sp,current) + local next = getnext(current) + if not experiment or next then + keep_together = true + if trace then + trace_skip("together",sc,so,sp,current) + end + head, current = remove_node(head, current, true) + else + current = next end - head, current = remove_node(head, current, true) -else - current = next -end elseif sc == nowhite then -local next = getnext(current) -if not experiment or next then - ignore_whitespace = true - head, current = remove_node(head, current, true) -else - current = next -end + local next = getnext(current) + if not experiment or next then + ignore_whitespace = true + head, current = remove_node(head, current, true) + else + current = next + end elseif sc == discard then if trace then trace_skip("discard",sc,so,sp,current) @@ -1575,18 +1594,18 @@ end trace_skip("force",sc,so,sp,current) end glue_order = so - free_node(glue_data) + flush_node(glue_data) head, current, glue_data = remove_node(head, current) elseif glue_order == so then -- is now exclusive, maybe support goback as combi, else why a set if sc == largest then - local cw = getfield(current,"width") or 0 - local gw = getfield(glue_data,"width") or 0 + local cw = getwidth(current) + local gw = getwidth(glue_data) if cw > gw then if trace then trace_skip("largest",sc,so,sp,current) end - free_node(glue_data) + flush_node(glue_data) head, current, glue_data = remove_node(head,current) else if trace then @@ -1598,7 +1617,7 @@ end if trace then trace_skip("goback",sc,so,sp,current) end - free_node(glue_data) + flush_node(glue_data) head, current, glue_data = remove_node(head,current) elseif sc == force then -- last one counts, some day we can provide an accumulator and largest etc @@ -1606,22 +1625,22 @@ end if trace then trace_skip("force",sc,so,sp,current) end - free_node(glue_data) + flush_node(glue_data) head, current, glue_data = remove_node(head, current) elseif sc == penalty then if trace then trace_skip("penalty",sc,so,sp,current) end - free_node(glue_data) + flush_node(glue_data) glue_data = nil head, current = remove_node(head, current, true) elseif sc == add then if trace then trace_skip("add",sc,so,sp,current) end - setfield(old,"width", (getfield(glue_data,"width") or 0) + (getfield(current,"width") or 0)) - setfield(old,"stretch",(getfield(glue_data,"stretch") or 0) + (getfield(current,"stretch") or 0)) - setfield(old,"shrink", (getfield(glue_data,"shrink") or 0) + (getfield(current,"shrink") or 0)) + local cwidth, cstretch, cshrink = getglue(current) + local gwidth, gstretch, gshrink = getglue(glue_data) + setglue(old,gwidth + cwidth, gstretch + cstretch, gshrink + cshrink) -- toto: order head, current = remove_node(head, current, true) else @@ -1644,7 +1663,7 @@ end local s = getattr(current,a_snapmethod) if s and s ~= 0 then setattr(current,a_snapmethod,0) - setfield(current,"width",0) + setwidth(current,0) if trace_vsnapping then report_snapper("lineskip set to zero") end @@ -1666,7 +1685,7 @@ end local s = getattr(current,a_snapmethod) if s and s ~= 0 then setattr(current,a_snapmethod,0) - setfield(current,"width",0) + setwidth(current,0) if trace_vsnapping then report_snapper("baselineskip set to zero") end @@ -1691,18 +1710,18 @@ end end head, current = remove_node(head, current, true) elseif glue_data then - local wp = getfield(current,"width") or 0 - if ((w ~= 0) and (w > (getfield(glue_data,"width") or 0))) then + local w = getwidth(current) + if (w ~= 0) and (w > getwidth(glue_data)) then glue_data = current - head, current = remove_node(head, current) if trace then trace_natural("taking parskip",current) end + head, current = remove_node(head, current) else - head, current = remove_node(head, current, true) if trace then trace_natural("removed parskip",current) end + head, current = remove_node(head, current, true) end else if trace then @@ -1737,7 +1756,7 @@ end flush("topskip") end current = getnext(current) - elseif subtype == abovedisplayskip_code then + elseif subtype == abovedisplayskip_code and remove_math_skips then -- if trace then trace_skip("above display skip (normal)",sc,so,sp,current) @@ -1745,7 +1764,7 @@ end flush("above display skip (normal)") current = getnext(current) -- - elseif subtype == belowdisplayskip_code then + elseif subtype == belowdisplayskip_code and remove_math_skips then -- if trace then trace_skip("below display skip (normal)",sc,so,sp,current) @@ -1753,7 +1772,7 @@ end flush("below display skip (normal)") current = getnext(current) -- - elseif subtype == abovedisplayshortskip_code then + elseif subtype == abovedisplayshortskip_code and remove_math_skips then -- if trace then trace_skip("above display skip (short)",sc,so,sp,current) @@ -1761,7 +1780,7 @@ end flush("above display skip (short)") current = getnext(current) -- - elseif subtype == belowdisplayshortskip_code then + elseif subtype == belowdisplayshortskip_code and remove_math_skips then -- if trace then trace_skip("below display skip (short)",sc,so,sp,current) @@ -1771,7 +1790,7 @@ end -- else -- other glue if snap and trace_vsnapping then - local w = getfield(current,"width") or 0 + local w = getwidth(current) if w ~= 0 then report_snapper("glue %p of type %a kept",w,skipcodes[subtype]) end @@ -1803,7 +1822,7 @@ end if trace then trace_done("result",p) end - head, tail = insert_node_after(head,tail,p) + setlink(tail,p) -- if penalty_data > special_penalty_min and penalty_data < special_penalty_max then local props = properties[p] if props then @@ -1821,11 +1840,13 @@ end trace_done("result",glue_data) end if force_glue then - head, tail = forced_skip(head,tail,getfield(glue_data,"width") or 0,"after",trace) - free_node(glue_data) + head, tail = forced_skip(head,tail,getwidth(glue_data),"after",trace) + flush_node(glue_data) glue_data = nil + elseif tail then + setlink(tail,glue_data) else - head, tail = insert_node_after(head,tail,glue_data) + head = glue_data end texnest[texnest.ptr].prevdepth = 0 -- appending to the list bypasses tex's prevdepth handler end @@ -1838,13 +1859,6 @@ end trace_info("head has been changed from %a to %a",nodecodes[getid(oldhead)],nodecodes[getid(head)]) end end - --- if headprev then --- setprev(head,headprev) --- setnext(headprev,head) --- end --- print("C HEAD",tonode(head)) - return head, true end @@ -1926,103 +1940,147 @@ function vspacing.pagehandler(newhead,where) return nil end -local ignore = table.tohash { - "split_keep", - "split_off", - -- "vbox", -} +do -function vspacing.vboxhandler(head,where) - if head and not ignore[where] then - local h = tonut(head) - if getnext(h) then -- what if a one liner and snapping? - h = collapser(h,"vbox",where,trace_vbox_vspacing,true,a_snapvbox) -- todo: local snapper - return tonode(h) + local ignore = table.tohash { + "split_keep", + "split_off", + -- "vbox", + } + + function vspacing.vboxhandler(head,where) + if head and not ignore[where] then + local h = tonut(head) + if getnext(h) then -- what if a one liner and snapping? + h = collapser(h,"vbox",where,trace_vbox_vspacing,true,a_snapvbox) -- todo: local snapper + return tonode(h) + end end + return head end - return head -end -function vspacing.collapsevbox(n,aslist) -- for boxes but using global a_snapmethod - local box = getbox(n) - if box then - local list = getlist(box) - if list then - list = collapser(list,"snapper","vbox",trace_vbox_vspacing,true,a_snapmethod) - if aslist then - setlist(box,list) -- beware, dimensions of box are wrong now - else - setlist(box,vpack_node(list)) + function vspacing.collapsevbox(n,aslist) -- for boxes but using global a_snapmethod + local box = getbox(n) + if box then + local list = getlist(box) + if list then + list = collapser(list,"snapper","vbox",trace_vbox_vspacing,true,a_snapmethod) + if aslist then + setlist(box,list) -- beware, dimensions of box are wrong now + else + setlist(box,vpack_node(list)) + end end end end + end -- This one is needed to prevent bleeding of prevdepth to the next page --- which doesn't work well with forced skips. - -local outer = texnest[0] - -function vspacing.resetprevdepth() - if texlists.hold_head then - outer.prevdepth = 0 +-- which doesn't work well with forced skips. I'm not that sure if the +-- following is a good way out. + +do + + local outer = texnest[0] + local reset = true + local trace = false + local report = logs.reporter("vspacing") + + directives.register("vspacing.resetprevdepth",function(v) reset = v end) + trackers.register ("vspacing.resetprevdepth",function(v) trace = v end) + + function vspacing.resetprevdepth() + if reset then + local head = texlists.hold_head + local skip = 0 + while head and head.id == insert_code do + head = head.next + skip = skip + 1 + end + if head then + outer.prevdepth = 0 + end + if trace then + report("prevdepth %s at page %i, skipped %i, value %p", + head and "reset" or "kept",texgetcount("realpageno"),skip,outer.prevdepth) + end + end end + end -- interface -implement { - name = "vspacing", - actions = vspacing.analyze, - scope = "private", - arguments = "string" -} - -implement { - name = "resetprevdepth", - actions = vspacing.resetprevdepth, - scope = "private" -} - -implement { - name = "vspacingsetamount", - actions = vspacing.setskip, - scope = "private", - arguments = "string", -} - -implement { - name = "vspacingdefine", - actions = vspacing.setmap, - scope = "private", - arguments = { "string", "string" } -} - -implement { - name = "vspacingcollapse", - actions = vspacing.collapsevbox, - scope = "private", - arguments = "integer" -} - -implement { - name = "vspacingcollapseonly", - actions = vspacing.collapsevbox, - scope = "private", - arguments = { "integer", true } -} - -implement { - name = "vspacingsnap", - actions = vspacing.snapbox, - scope = "private", - arguments = { "integer", "integer" } -} - -implement { - name = "definesnapmethod", - actions = vspacing.definesnapmethod, - scope = "private", - arguments = { "string", "string" } -} +do + + implement { + name = "vspacing", + actions = vspacing.analyze, + scope = "private", + arguments = "string" + } + + implement { + name = "resetprevdepth", + actions = vspacing.resetprevdepth, + scope = "private" + } + + implement { + name = "vspacingsetamount", + actions = vspacing.setskip, + scope = "private", + arguments = "string", + } + + implement { + name = "vspacingdefine", + actions = vspacing.setmap, + scope = "private", + arguments = { "string", "string" } + } + + implement { + name = "vspacingcollapse", + actions = vspacing.collapsevbox, + scope = "private", + arguments = "integer" + } + + implement { + name = "vspacingcollapseonly", + actions = vspacing.collapsevbox, + scope = "private", + arguments = { "integer", true } + } + + implement { + name = "vspacingsnap", + actions = vspacing.snapbox, + scope = "private", + arguments = { "integer", "integer" } + } + + implement { + name = "definesnapmethod", + actions = vspacing.definesnapmethod, + scope = "private", + arguments = { "string", "string" } + } + + local remove_node = nodes.remove + local find_node_tail = nodes.tail + + interfaces.implement { + name = "fakenextstrutline", + actions = function() + local head = texlists.page_head + if head then + local head = remove_node(head,find_node_tail(head),true) + texlists.page_head = head + end + end + } +end diff --git a/tex/context/base/mkiv/spac-ver.mkiv b/tex/context/base/mkiv/spac-ver.mkiv index 250e4e396..229963997 100644 --- a/tex/context/base/mkiv/spac-ver.mkiv +++ b/tex/context/base/mkiv/spac-ver.mkiv @@ -527,6 +527,7 @@ \unexpanded\def\spac_lines_start_correction[#1]% {\edef\m_spac_lines_around{#1}% + % todo: play with \fakenextstrutline \spac_lines_action_around \d_spac_prevdepth\prevdepth \spac_lines_initialize_corrections @@ -556,7 +557,10 @@ \unexpanded\def\spac_lines_stop_correction_ongrid {\directcheckedvspacing\v!white % \blank[\v!white]% - \snaptogrid\hpack{\box\scratchbox}} + \spac_lines_action_around + \snaptogrid\hpack{\box\scratchbox}% + \directcheckedvspacing\v!white + \spac_lines_action_around} \unexpanded\def\spac_lines_stop_correction_normal {\directcheckedvspacing\v!nowhite % \blank[\v!nowhite]% @@ -1256,14 +1260,14 @@ %D Keyword based strutting: -\letvalue{\??struts\v!yes }\setstrut % \setvalue{\??struts\v!yes }{\setstrut} -\letvalue{\??struts\v!auto }\setautostrut % \setvalue{\??struts\v!auto }{\setautostrut} -\letvalue{\??struts\v!no }\setnostrut % \setvalue{\??struts\v!no }{\setnostrut} -\letvalue{\??struts\v!cap }\setcapstrut % \setvalue{\??struts\v!cap }{\setcapstrut} -\letvalue{\??struts\v!fit }\setfontstrut % \setvalue{\??struts\v!fit }{\setfontstrut} -\letvalue{\??struts\v!line }\setstrut % \setvalue{\??struts\v!line }{\setstrut} -\letvalue{\??struts\s!default}\setstrut % \setvalue{\??struts\s!default}{\setstrut} -\letvalue{\??struts\empty }\setstrut % \setvalue{\??struts\empty }{\setstrut} +\letvalue{\??struts\v!yes }\setstrut +\letvalue{\??struts\v!auto }\setautostrut +\letvalue{\??struts\v!no }\setnostrut +\letvalue{\??struts\v!cap }\setcapstrut +\letvalue{\??struts\v!fit }\setfontstrut +\letvalue{\??struts\v!line }\setstrut +\letvalue{\??struts\s!default}\setstrut +\letvalue{\??struts\empty }\setstrut %D Handy: @@ -1439,12 +1443,13 @@ \installcorenamespace{gridsnappers} \installcorenamespace{gridsnapperattributes} +\installcorenamespace{gridsnappersets} \newskip \bodyfontlineheight \newdimen \bodyfontstrutheight \newdimen \bodyfontstrutdepth -\newskip \globalbodyfontlineheight +\newskip \globalbodyfontlineheight % why a skip \newdimen \globalbodyfontstrutheight \newdimen \globalbodyfontstrutdepth @@ -1458,12 +1463,34 @@ \attribute \snapvboxattribute \attribute\snapmethodattribute}% \fi} -\unexpanded\def\installsnapvalues#1#2% todo: a proper define - {\edef\currentsnapper{#1:#2}% - \ifcsname\??gridsnapperattributes\currentsnapper\endcsname \else - \setevalue{\??gridsnapperattributes\currentsnapper}{\clf_definesnapmethod{#1}{#2}}% +% \unexpanded\def\installsnapvalues#1#2% todo: a proper define +% {\edef\currentsnapper{#1:#2}% +% \ifcsname\??gridsnapperattributes\currentsnapper\endcsname \else +% \setevalue{\??gridsnapperattributes\currentsnapper}{\clf_definesnapmethod{#1}{#2}}% +% \fi +% \setevalue{\??gridsnappers#1}{\attribute\snapmethodattribute\csname\??gridsnapperattributes\currentsnapper\endcsname\space}} + +\def\spac_grids_expand_snapper#1% + {\edef\m_spac_snapper + {\ifx\m_spac_snapper\empty\else\m_spac_snapper,\fi + \ifcsname\??gridsnappersets#1\endcsname + \lastnamedcs\else#1% + \fi}} + +\unexpanded\def\installsnapvalues#1#2% + {\let\m_spac_snapper\empty + \rawprocesscommacommand[#2]\spac_grids_expand_snapper + \edef\currentsnapper{#1:\m_spac_snapper}% + \ifcsname\??gridsnapperattributes\currentsnapper\endcsname + \scratchcounter\lastnamedcs % already defined + \else + \scratchcounter\clf_definesnapmethod{#1}{\m_spac_snapper}% + \setevalue{\??gridsnapperattributes\currentsnapper}{\the\scratchcounter}% \fi - \setevalue{\??gridsnappers#1}{\attribute\snapmethodattribute\csname\??gridsnapperattributes\currentsnapper\endcsname\space}} + \setevalue{\??gridsnappers#1}{\attribute\snapmethodattribute\the\scratchcounter\relax}% + \letvalue{\??gridsnappersets#1}\m_spac_snapper} + +\def\theexpandedsnapperset#1{\begincsname\??gridsnappersets#1\endcsname} % only for manuals \unexpanded\def\usegridparameter#1% no checking here {\edef\m_spac_grid_asked{#1\c!grid}% @@ -1474,7 +1501,6 @@ \attribute \snapvboxattribute\attribute\snapmethodattribute \fi} - \unexpanded\def\definegridsnapping {\dodoubleargument\spac_grids_define} @@ -1515,6 +1541,9 @@ % offset:-3tp vertical shift within box % bottom:lines % top:lines +% box centers a box rounded upwards (box:.5 -> tolerance) +% min centers a box rounded downwards +% max centers a box rounded upwards %D We're not downward compatible with \MKII ! @@ -1540,15 +1569,18 @@ \definegridsnapping[\v!none] [\v!none] \definegridsnapping[\v!line] [\v!line] \definegridsnapping[\v!strut] [\v!strut] -\definegridsnapping[\v!box] [\v!box] % centers a box rounded upwards (box:.5 -> tolerance) -\definegridsnapping[\v!min] [\v!min] % centers a box rounded downwards -\definegridsnapping[\v!max] [\v!max] % centers a box rounded upwards - -\definegridsnapping[\v!max] [\v!maxdepth,\v!maxheight,\v!strut] -\definegridsnapping[\v!min] [\v!mindepth,\v!minheight,\v!strut] +\definegridsnapping[\v!box] [\v!box] +\definegridsnapping[\v!min] [\v!min] +\definegridsnapping[\v!max] [\v!max] \definegridsnapping[\v!middle] [\v!maxheight,\v!maxdepth] % used in placement +\definegridsnapping[\v!math] [\v!maxdepth:1.05,\v!maxheight:1.05,\v!strut] % experimental, maybe 1.1 +\definegridsnapping[\v!math:\v!line] [\v!math,\v!line,\v!split] +\definegridsnapping[\v!math:\v!halfline] [\v!math,\v!halfline,\v!split] +\definegridsnapping[\v!math:-\v!line] [\v!math,-\v!line,\v!split] +\definegridsnapping[\v!math:-\v!halfline][\v!math,-\v!halfline,\v!split] + \unexpanded\def\synchronizelocallinespecs {\bodyfontlineheight \normallineheight \bodyfontstrutheight\strutht @@ -1572,21 +1604,13 @@ \unexpanded\def\synchronizeskipamounts {\bigskipamount - \skipfactor\baselineskip - plus\skipgluefactor\baselineskip - minus\skipgluefactor\baselineskip + \skipfactor\baselineskip + \s!plus\skipgluefactor\baselineskip + \s!minus\skipgluefactor\baselineskip \relax \medskipamount \bigskipamount \divide\medskipamount \plustwo \smallskipamount\bigskipamount \divide\smallskipamount\plusfour} -\appendtoks - \synchronizeskipamounts -\to \everysetupglobalinterlinespace - -\appendtoks - \synchronizeskipamounts -\to \everysetuplocalinterlinespace - %D Snapping. \newif\ifgridsnapping @@ -1657,6 +1681,73 @@ \spac_grids_check_yes \fi\fi\fi} +\unexpanded\def\setupgridsnapping[#1]% less overhead than setuplayout (needs testing) + {\setlayoutparameter\c!grid{#1}\synchronizegridsnapping} + +\unexpanded\def\checkgridmethod#1% + {\edef\p_grid{#1}% + \ifx\p_grid\empty + \let\checkedgridmethod\empty + \let\checkedgridscope \v!local + \else + \splitatcolon\p_grid\checkedgridscope\checkedgridmethod + \ifx\checkedgridmethod\empty + \ifx\checkedgridscope\v!local\else\ifx\checkedgridscope\v!global\else + \let\checkedgridmethod\checkedgridscope + \let\checkedgridscope \v!local + \fi\fi + \fi + \fi} + +\unexpanded\def\applygridmethod#1#2#3% content localsettings (used in head rendering) + {\checkgridmethod{#1}% + \ifx\checkedgridscope\v!global + \ifx\checkedgridmethod\empty \else + % we assume that the call is grouped because grouping here has the side + % effect that the eventually constructed line will get the value outside + % the group + % + % overkill: \setupgridsnapping[\checkedgridmethod]% + % maybe : \spac_grids_snap_value_auto\checkedgridmethod + \spac_grids_snap_value_set\checkedgridmethod + \fi + \hbox{#3}% + \else + % the extra hbox will trigger the global snapper on top of the local and + % we really need that in this case (compatibility etc etc) so here we don't + % het an already done hit (otherwise we would not snap) + \hbox\bgroup + \ifx\checkedgridmethod\empty\else + \ifconditional\headisdisplay + #2% + \fi + \fi + \snaptogrid[\checkedgridmethod]\hbox{#3}% + \egroup + \fi} + +\unexpanded\gdef\page_layouts_calculate_overshoot + {\ifgridsnapping\ifcase\layoutlines + \getnoflines\textheight + \textovershoot\dimexpr\noflines\globalbodyfontlineheight-\textheight\relax + \fi\fi} + +\unexpanded\def\page_layouts_report_overshoot + {\page_layouts_calculate_overshoot + \ifdim\textovershoot>\zeropoint + \writestatus\m!layouts{gridmode,\space + noflines: \the\noflines,\space + textheight: \the\textheight,\space + textovershoot: \the\textovershoot\space + (maybe set number of lines instead)% + }% + \fi + \glet\page_layouts_report_overshoot\page_layouts_calculate_overshoot} + +\appendtoks + \page_layouts_report_overshoot +\to \everybeforepagebody + %D Visualization: \definepalet @@ -2071,6 +2162,8 @@ \definevspacing[\v!preference][penalty:-500] % goodbreak \definevspacing[\v!samepage] [penalty:10000] % nobreak + +\definevspacing[\v!always] [category:0] % hm, internally it's discard \definevspacing[\v!max] [category:1] \definevspacing[\v!force] [category:2] \definevspacing[\v!disable] [category:5] @@ -2078,7 +2171,8 @@ \definevspacing[\v!back] [category:7] % together [category:8] \definevspacing[\v!overlay] [category:9] -\definevspacing[\v!always] [category:0] % hm, internally it's discard +\definevspacing[\v!enable] [category:10] + \definevspacing[\v!weak] [order:0] \definevspacing[\v!strong] [order:100] diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex e1434d8c7..ccf6de7ab 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex 1a1577b9e..37f242020 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/status-mkiv.lua b/tex/context/base/mkiv/status-mkiv.lua index 3fe9e0d8e..ab1419c98 100644 --- a/tex/context/base/mkiv/status-mkiv.lua +++ b/tex/context/base/mkiv/status-mkiv.lua @@ -1,6386 +1,7441 @@ return { - todo = { - category = "lua", - filename = "core-run", - status = "idea", - }, - main = { + ["core"]={ { - category = "mkiv", - filename = "context", - loading = "parent", - status = "okay", + ["category"]="mkvi", + ["filename"]="font-gds", + ["loading"]="always", + ["status"]="okay", }, { - category = "lus", - comment = "stub file for context", - filename = "context", - loading = "parent", - status = "okay", + ["category"]="mkiv", + ["filename"]="cont-run", + ["loading"]="always", + ["status"]="okay", }, { - category = "tex", - filename = "metatex", - loading = "parent", - status = "pending", + ["category"]="mkvi", + ["filename"]="font-sel", + ["loading"]="always", + ["status"]="okay", }, { - category = "lus", - comment = "stub file for metatex", - filename = "metatex", - loading = "parent", - status = "pending", + ["category"]="mkiv", + ["filename"]="grph-pat", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "cont-cs", - loading = "parent", - status = "okay", + ["category"]="mkiv", + ["filename"]="grph-rul", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "cont-de", - loading = "parent", - status = "okay", + ["category"]="mkiv", + ["filename"]="lang-rep", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "cont-en", - loading = "parent", - status = "okay", + ["category"]="mkiv", + ["filename"]="luat-usr", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "cont-fr", - loading = "parent", - status = "okay", + ["category"]="mkiv", + ["filename"]="math-mis", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "cont-gb", - loading = "parent", - status = "okay", + ["category"]="mkvi", + ["filename"]="math-rad", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "cont-it", - loading = "parent", - status = "okay", + ["category"]="mkiv", + ["filename"]="page-cst", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "cont-nl", - loading = "parent", - status = "okay", + ["category"]="mkvi", + ["filename"]="page-inj", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "cont-pe", - loading = "parent", - status = "okay", + ["category"]="mkvi", + ["filename"]="page-lin", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "cont-ro", - loading = "parent", - status = "okay", + ["category"]="mkvi", + ["filename"]="publ-imp-author", + ["loading"]="always", + ["status"]="okay", }, { - category = "mpiv", - comment = "maybe more delayed loading", - filename = "metafun", - loading = "parent", - status = "okay", + ["category"]="mkvi", + ["filename"]="publ-imp-cite", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "we keep this around for historic reasons", - filename = "ppchtex", - loading = "never", - status = "okay", + ["category"]="mkvi", + ["filename"]="publ-imp-commands", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="mkvi", + ["filename"]="publ-imp-default", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="mkvi", + ["filename"]="publ-imp-definitions", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="mkvi", + ["filename"]="publ-imp-list", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="mkvi", + ["filename"]="publ-imp-page", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="spac-flr", + ["loading"]="always", + ["status"]="okay", }, - }, - core = { { - category = "mkiv", - filename = "syst-ini", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="spac-prf", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "norm-ctx", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="strc-not", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "syst-pln", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="toks-map", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "syst-mes", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="toks-tra", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "luat-cod", - loading = "luat-cod", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-chr", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "maybe combine (3)", - filename = "luat-bas", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-inj", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "maybe combine (3)", - filename = "luat-lib", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-lig", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "catc-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-lin", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "forward dependency", - filename = "catc-act", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-par", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "catc-def", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-wrp", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "catc-ctx", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="syst-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "catc-sym", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="norm-ctx", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "catc-xml", - loading = "module", - status = "okay", - comment = "only needed for mkii xml parser", + ["category"]="mkiv", + ["filename"]="syst-pln", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "maybe combine (1)", - filename = "cldf-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="syst-mes", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "syst-aux", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="luat-cod", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "maybe combine (1)", - filename = "syst-lua", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="maybe combine (3)", + ["filename"]="luat-bas", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "maybe combine (1)", - filename = "syst-con", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="maybe combine (3)", + ["filename"]="luat-lib", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "maybe combine (1)", - filename = "syst-fnt", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="catc-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "maybe combine (1)", - filename = "syst-rtp", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="forward dependency", + ["filename"]="catc-act", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "maybe combine (2)", - filename = "file-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="catc-def", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "maybe combine (2)", - filename = "file-res", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="catc-ctx", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "file-lib", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="catc-sym", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "supp-dir", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="only needed for mkii xml parser", + ["filename"]="catc-xml", + ["loading"]="module", + ["status"]="okay", }, { - category = "mkiv", - filename = "char-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="maybe combine (1)", + ["filename"]="cldf-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "char-utf", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="syst-aux", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "forward dependency", - filename = "char-act", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="maybe combine (1)", + ["filename"]="syst-lua", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "mult-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="maybe combine (1)", + ["filename"]="syst-con", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "mult-sys", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="maybe combine (1)", + ["filename"]="syst-fnt", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "mult-aux", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="maybe combine (1)", + ["filename"]="syst-rtp", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "mult-def", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="maybe combine (2)", + ["filename"]="file-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "mult-chk", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="maybe combine (2)", + ["filename"]="file-res", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "mult-dim", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="file-lib", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "cldf-int", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="supp-dir", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "luat-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="char-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "toks-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="char-utf", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "attr-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="forward dependency", + ["filename"]="char-act", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "attr-mkr", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="mult-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "code might move from here", - filename = "core-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="mult-sys", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "might need more redoing", - filename = "core-env", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="mult-aux", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "in due time more might move to here", - filename = "layo-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="mult-def", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "maybe this becomes a runtime module", - filename = "node-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="mult-chk", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "maybe use context.generics/context.sprint here", - filename = "cldf-bas", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="mult-dim", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "might need more redoing", - filename = "node-fin", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="cldf-int", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "needs integration and configuration", - filename = "node-mig", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="luat-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-bld", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="toks-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-sus", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="attr-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "node-pag", - loading = "never", - status = "okay", + ["category"]="mkiv", + ["filename"]="attr-mkr", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "back-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="code might move from here", + ["filename"]="core-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "attr-col", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="might need more redoing", + ["filename"]="core-env", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "attr-lay", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="in due time more might move to here", + ["filename"]="layo-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "attr-neg", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="maybe this becomes a runtime module", + ["filename"]="node-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "attr-eff", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="maybe use context.generics/context.sprint here", + ["filename"]="cldf-bas", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "needs more usage", - filename = "trac-tex", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="might need more redoing", + ["filename"]="node-fin", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "trac-deb", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="needs integration and configuration", + ["filename"]="node-mig", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "trac-ctx", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-bld", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "supp-box", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-sus", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "supp-ran", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="node-pag", + ["loading"]="never", + ["status"]="okay", }, { - category = "mkiv", - comment = "will be moved to the math-* modules", - filename = "supp-mat", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="back-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "will grow", - filename = "typo-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="attr-col", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "file-syn", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="attr-lay", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "file-mod", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="attr-neg", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "core-con", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="attr-eff", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "cont-fil", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="needs more usage", + ["filename"]="trac-tex", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "cont-nop", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="trac-deb", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "cont-yes", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="trac-ctx", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "regi-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="supp-box", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "enco-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="supp-ran", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "hand-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="will be moved to the math-* modules", + ["filename"]="supp-mat", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "lang-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="will grow", + ["filename"]="typo-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "namespace should be languages", - filename = "lang-lab", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="file-syn", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "lang-hyp", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="file-mod", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "unic-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="core-con", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "core-uti", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="cont-fil", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "maybe rename to core-two", - filename = "core-two", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="cont-nop", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "core-dat", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="cont-yes", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "colo-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="regi-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "colo-ext", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="enco-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "colo-grp", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="hand-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "node-bck", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="lang-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "pack-cut", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="namespace should be languages", + ["filename"]="lang-lab", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "lang-mis", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="lang-hyp", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "lang-url", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="unic-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "lang-def", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="core-uti", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "lang-hyp", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="maybe rename to core-two", + ["filename"]="core-two", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "lang-frq", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="core-dat", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "lang-frd", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="colo-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "lang-wrd", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="colo-ext", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "might need more redoing", - filename = "file-job", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="colo-grp", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "symb-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="node-bck", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "sort-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="pack-cut", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "pack-mis", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="lang-mis", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "pack-rul", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="lang-url", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "endpar experimental code", - filename = "pack-mrl", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="lang-def", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "pack-bck", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="lang-hyp", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "pack-fen", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="lang-frq", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "lxml-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="lang-frd", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "lxml-sor", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="lang-wrd", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "typo-prc", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="might need more redoing", + ["filename"]="file-job", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "strc-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="symb-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "strc-tag", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="sort-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "this module might go away when code has been moved", - filename = "strc-doc", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="pack-mis", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "still some rough edges", - filename = "strc-num", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="pack-rul", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "strc-mar", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="endpar experimental code", + ["filename"]="pack-mrl", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "strc-sbe", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="pack-bck", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "strc-lst", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="pack-fen", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "some of the local current and synchronization macros will be renamed", - filename = "strc-sec", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="lxml-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "strc-pag", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="lxml-sor", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "(support for) setups might get improved", - filename = "strc-ren", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="typo-prc", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "this module might go away", - filename = "strc-xml", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="strc-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "strc-def", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="strc-tag", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "some more low level names might change", - filename = "strc-ref", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="this module might go away when code has been moved", + ["filename"]="strc-doc", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "use setups for rendering", - filename = "strc-reg", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="still some rough edges", + ["filename"]="strc-num", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "strc-lev", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="strc-mar", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "maybe some tuning is needed / will happen", - filename = "spac-ali", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="strc-sbe", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "probably needs some more work", - filename = "spac-hor", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="strc-lst", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "maybe some changes will happen", - filename = "spac-ver", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="some of the local current and synchronization macros will be renamed", + ["filename"]="strc-sec", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "could be improved if needed", - filename = "spac-lin", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="strc-pag", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "this needs to be checked occasionally", - filename = "spac-pag", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="(support for) setups might get improved", + ["filename"]="strc-ren", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "spac-par", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="this module might go away", + ["filename"]="strc-xml", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "spac-def", - loading = "always", - status = "todo", + ["category"]="mkiv", + ["filename"]="strc-def", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "needs thinking and redoing", - filename = "spac-grd", - loading = "always", - status = "todo", + ["category"]="mkvi", + ["comment"]="some more low level names might change", + ["filename"]="strc-ref", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "in transition", - filename = "anch-pos", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="use setups for rendering", + ["filename"]="strc-reg", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "maybe change locationattribute names", - filename = "scrn-ini", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="strc-lev", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "namespace needs checking", - filename = "scrn-ref", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="maybe some tuning is needed / will happen", + ["filename"]="spac-ali", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "will change when we have objects at lua end", - filename = "pack-obj", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="probably needs some more work", + ["filename"]="spac-hor", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "strc-itm", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="maybe some changes will happen", + ["filename"]="spac-ver", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "maybe more common counter code here and setups need to be improved", - filename = "strc-con", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="could be improved if needed", + ["filename"]="spac-lin", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "strc-des", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="this needs to be checked occasionally", + ["filename"]="spac-pag", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "(interactive) coupling is not yet working", - filename = "strc-enu", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="spac-par", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "strc-ind", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="spac-def", + ["loading"]="always", + ["status"]="todo", }, { - category = "mkiv", - comment = "needs to be adapted when strc-con/des/enu changes", - filename = "strc-lab", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="needs thinking and redoing", + ["filename"]="spac-grd", + ["loading"]="always", + ["status"]="todo", }, { - category = "mkiv", - filename = "strc-syn", - loading = "always", - status = "todo", + ["category"]="mkiv", + ["comment"]="in transition", + ["filename"]="anch-pos", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "a funny mix", - filename = "core-sys", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="maybe change locationattribute names", + ["filename"]="scrn-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "page-var", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="namespace needs checking", + ["filename"]="scrn-ref", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "page-otr", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="will change when we have objects at lua end", + ["filename"]="pack-obj", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "code might end up elsewhere", - filename = "page-ini", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="strc-itm", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "dealing with insertions might change", - filename = "page-ins", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="maybe more common counter code here and setups need to be improved", + ["filename"]="strc-con", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "page-fac", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="strc-des", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "otr commands will be redone", - filename = "page-brk", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="(interactive) coupling is not yet working", + ["filename"]="strc-enu", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "helpers for columns", - filename = "page-col", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="strc-ind", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "room for improvement and extension", - filename = "page-inf", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="needs to be adapted when strc-con/des/enu changes", + ["filename"]="strc-lab", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "page-grd", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="strc-syn", + ["loading"]="always", + ["status"]="todo", }, { - category = "mkiv", - comment = "will be extended when columns are redone", - filename = "page-flt", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="a funny mix", + ["filename"]="core-sys", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "page-bck", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="page-var", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "page-not", - loading = "always", - status = "todo", + ["category"]="mkvi", + ["filename"]="page-otr", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "can probably be improved", - filename = "page-one", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="code might end up elsewhere", + ["filename"]="page-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "page-lay", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="dealing with insertions might change", + ["filename"]="page-ins", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "page-box", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="page-fac", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "a few things left", - filename = "page-txt", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="otr commands will be redone", + ["filename"]="page-brk", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "page-sid", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="helpers for columns", + ["filename"]="page-col", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "in due time we need a further cleanup", - filename = "strc-flt", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="room for improvement and extension", + ["filename"]="page-inf", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "page-pst", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="page-grd", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "might be extended", - filename = "page-mbk", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="will be extended when columns are redone", + ["filename"]="page-flt", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "will be reimplemented", - filename = "page-mul", - loading = "always", - status = "todo", + ["category"]="mkiv", + ["filename"]="page-bck", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "work in progress", - filename = "page-mix", - loading = "always", - status = "todo", + ["category"]="mkiv", + ["filename"]="page-not", + ["loading"]="always", + ["status"]="todo", }, { - category = "mkiv", - comment = "will be reimplemented", - filename = "page-set", - loading = "always", - status = "todo", + ["category"]="mkiv", + ["comment"]="can probably be improved", + ["filename"]="page-one", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "pack-lyr", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="page-lay", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "pack-pos", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="page-box", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "page-mak", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="a few things left", + ["filename"]="page-txt", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "will probably be overhauled some day", - filename = "page-lin", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="page-sid", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "might get extended", - filename = "page-par", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="in due time we need a further cleanup", + ["filename"]="strc-flt", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-pag", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="page-pst", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-mar", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="might be extended", + ["filename"]="page-mbk", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-itm", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="will be reimplemented", + ["filename"]="page-mul", + ["loading"]="always", + ["status"]="todo", }, { - category = "mkiv", - comment = "check other modules for buffer usage", - filename = "buff-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="work in progress", + ["filename"]="page-mix", + ["loading"]="always", + ["status"]="todo", }, { - category = "mkiv", - comment = "check obsolete processbuffer", - filename = "buff-ver", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="will be reimplemented", + ["filename"]="page-set", + ["loading"]="always", + ["status"]="todo", }, { - category = "mkvi", - comment = "experimental code", - filename = "buff-par", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="pack-lyr", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "buff-imp-tex", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="pack-pos", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "buff-imp-mp", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="page-mak", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "buff-imp-lua", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="might get extended", + ["filename"]="page-par", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "buff-imp-xml", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-pag", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "buff-imp-parsed-xml", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-mar", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "buff-imp-default", - loading = "indirect", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-itm", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "buff-imp-escaped", - loading = "indirect", - status = "okay", + ["category"]="mkiv", + ["comment"]="check other modules for buffer usage", + ["filename"]="buff-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "buff-imp-nested", - loading = "indirect", - status = "okay", + ["category"]="mkiv", + ["comment"]="check obsolete processbuffer", + ["filename"]="buff-ver", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "strc-blk", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="experimental code", + ["filename"]="buff-par", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "page-imp", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="symb-imp-cc", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkvi", - comment = "maybe some extensions and delayed loading, needs checking", - filename = "page-sel", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="buff-imp-default", + ["loading"]="indirect", + ["status"]="okay", }, { - category = "mkiv", - filename = "page-com", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="buff-imp-escaped", + ["loading"]="indirect", + ["status"]="okay", }, { - category = "mkvi", - comment = "namespace needs checking", - filename = "scrn-pag", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="buff-imp-nested", + ["loading"]="indirect", + ["status"]="okay", }, { - category = "mkvi", - comment = "functionality needs checking", - filename = "scrn-wid", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="strc-blk", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "namespace needs checking", - filename = "scrn-but", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="page-imp", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "namespace needs checking", - filename = "scrn-bar", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="maybe some extensions and delayed loading, needs checking", + ["filename"]="page-sel", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "strc-bkm", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="page-com", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-tal", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="namespace needs checking", + ["filename"]="scrn-pag", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "somewhat weird", - filename = "tabl-com", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="functionality needs checking", + ["filename"]="scrn-wid", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "unchecked", - filename = "tabl-pln", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="namespace needs checking", + ["filename"]="scrn-but", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "tabl-tab", - loading = "always", - status = "pending", + ["category"]="mkvi", + ["comment"]="namespace needs checking", + ["filename"]="scrn-bar", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "can probably be improved (names and such)", - filename = "tabl-tbl", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="strc-bkm", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "frozen functionaly so no drastic cleanup", - filename = "tabl-ntb", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-tal", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "tabl-mis", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="somewhat weird", + ["filename"]="tabl-com", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "tabl-nte", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="unchecked", + ["filename"]="tabl-pln", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "will be redone when needed", - filename = "tabl-ltb", - loading = "always", - status = "pending", + ["category"]="mkiv", + ["filename"]="tabl-tab", + ["loading"]="always", + ["status"]="pending", }, { - category = "mkiv", - comment = "will be adapted when needed (and rest is done)", - filename = "tabl-tsp", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="can probably be improved (names and such)", + ["filename"]="tabl-tbl", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "namespace needs checking", - filename = "tabl-xtb", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="frozen functionaly so no drastic cleanup", + ["filename"]="tabl-ntb", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "tabl-xnt", - loading = "module", - status = "okay", - loading = "always", - comment = "only when natural tables need a replacement", + ["category"]="mkiv", + ["filename"]="tabl-mis", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "java-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="tabl-nte", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "namespace needs checking", - filename = "scrn-fld", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="will be redone when needed", + ["filename"]="tabl-ltb", + ["loading"]="always", + ["status"]="pending", }, { - category = "mkvi", - comment = "namespace needs checking", - filename = "scrn-hlp", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="will be adapted when needed (and rest is done)", + ["filename"]="tabl-tsp", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "char-enc", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="namespace needs checking", + ["filename"]="tabl-xtb", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "font-lib", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="only when natural tables need a replacement", + ["filename"]="tabl-xnt", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "font-fil", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="java-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "font-var", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="namespace needs checking", + ["filename"]="scrn-fld", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "font-fea", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="namespace needs checking", + ["filename"]="scrn-hlp", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "font-mat", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="char-enc", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "needs occasional checking and upgrading", - filename = "font-ini", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="font-lib", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "font-sym", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="font-fil", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "font-sty", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="font-var", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "font-set", - status = "okay", + ["category"]="mkvi", + ["filename"]="font-fea", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "font-emp", - status = "okay", + ["category"]="mkvi", + ["filename"]="font-mat", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "font-col", - status = "okay", + ["category"]="mkvi", + ["comment"]="needs occasional checking and upgrading", + ["filename"]="font-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "font-pre", - status = "okay", + ["category"]="mkvi", + ["filename"]="font-sym", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "font-unk", - status = "okay", + ["category"]="mkvi", + ["filename"]="font-sty", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "likely this will become a module", - filename = "font-tra", - status = "okay", + ["category"]="mkvi", + ["filename"]="font-set", + ["status"]="okay", }, { - category = "mkiv", - comment = "this could become a module", - filename = "font-chk", - status = "okay", + ["category"]="mkvi", + ["filename"]="font-emp", + ["status"]="okay", }, { - category = "mkiv", - comment = "this one might be merged", - filename = "font-uni", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="font-col", + ["status"]="okay", }, { - category = "mkvi", - filename = "font-col", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="font-pre", + ["status"]="okay", }, { - category = "mkvi", - filename = "font-gds", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="font-unk", + ["status"]="okay", }, { - category = "mkvi", - filename = "font-aux", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="likely this will become a module", + ["filename"]="font-tra", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-lan", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="this could become a module", + ["filename"]="font-chk", + ["status"]="okay", }, { - category = "mkiv", - comment = "this is work in progress", - filename = "lxml-css", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="this one might be merged", + ["filename"]="font-uni", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "spac-chr", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="font-col", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "work in progress", - filename = "blob-ini", - loading = "always", - status = "pending", + ["category"]="mkvi", + ["filename"]="font-aux", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "trac-vis", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-lan", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "trac-jus", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="this is work in progress", + ["filename"]="lxml-css", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "trac-vis", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="spac-chr", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-cln", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="work in progress", + ["filename"]="blob-ini", + ["loading"]="always", + ["status"]="pending", }, { - category = "mkiv", - filename = "typo-spa", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="trac-jus", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "do we keep the style and color or not", - filename = "typo-krn", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="trac-vis", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "typo-itc", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-cln", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "maybe singular setup", - filename = "typo-dir", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-spa", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-brk", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="do we keep the style and color or not", + ["filename"]="typo-krn", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-cap", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="typo-itc", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-dig", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="maybe singular setup", + ["filename"]="typo-dir", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-rep", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-brk", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "maybe there will be a nicer interface", - filename = "typo-txt", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-cap", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-drp", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-dig", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-fln", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-rep", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "type-ini", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="maybe there will be a nicer interface", + ["filename"]="typo-txt", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-set", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-drp", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-def", - loading = "type-set", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-fln", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-fbk", - loading = "type-set", - status = "okay", + ["category"]="mkvi", + ["filename"]="type-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-lua", - loading = "type-set", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-set", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-one", - loading = "type-set", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-def", + ["loading"]="type-set", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-otf", - loading = "type-set", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-fbk", + ["loading"]="type-set", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-siz", - loading = "type-set", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-lua", + ["loading"]="type-set", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-tmf", - loading = "never", - status = "okay", - comment = "placeholder to prevent other loading", + ["category"]="mkiv", + ["filename"]="type-one", + ["loading"]="type-set", + ["status"]="okay", }, { - category = "mkiv", - filename = "scrp-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-otf", + ["loading"]="type-set", + ["status"]="okay", }, { - category = "mkiv", - comment = "this module is obsolete", - filename = "prop-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-siz", + ["loading"]="type-set", + ["status"]="okay", }, { - category = "mkiv", - filename = "mlib-ctx", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="placeholder to prevent other loading", + ["filename"]="type-tmf", + ["loading"]="never", + ["status"]="okay", }, { - category = "mkiv", - comment = "metapost code is always evolving", - filename = "meta-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="scrp-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "code used in a project", - filename = "meta-lua", - loading = "experimental", - status = "okay", + ["category"]="mkiv", + ["comment"]="this module is obsolete", + ["filename"]="prop-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "meta-fnt", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="mlib-ctx", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "meta-tex", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="metapost code is always evolving", + ["filename"]="meta-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "maybe this one will be merged", - filename = "meta-fun", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="code used in a project", + ["filename"]="meta-lua", + ["loading"]="experimental", + ["status"]="okay", }, { - category = "mkiv", - comment = "might get updated when mp code gets cleaned up", - filename = "meta-pag", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="meta-fnt", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "meta-grd", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="meta-tex", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "page-mrk", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="maybe this one will be merged", + ["filename"]="meta-fun", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "page-flw", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="might get updated when mp code gets cleaned up", + ["filename"]="meta-pag", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "page-spr", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="meta-grd", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "will be made better", - filename = "page-plg", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="page-mrk", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "needs more work (and thinking)", - filename = "page-str", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="page-flw", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "in transition", - filename = "anch-pgr", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="page-spr", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "in transition", - filename = "anch-bck", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="will be made better", + ["filename"]="page-plg", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "will stay experimental for a while", - filename = "anch-tab", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="needs more work (and thinking)", + ["filename"]="page-str", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "anch-bar", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="in transition", + ["filename"]="anch-pgr", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "interesting old mechanism to keep around (module?)", - filename = "anch-snc", - loading = "always", - status = "pending", + ["category"]="mkvi", + ["comment"]="in transition", + ["filename"]="anch-bck", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "math-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="will stay experimental for a while", + ["filename"]="anch-tab", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "this file might merge into others", - filename = "math-pln", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="anch-bar", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "math-for", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="interesting old mechanism to keep around (module?)", + ["filename"]="anch-snc", + ["loading"]="always", + ["status"]="pending", }, { - category = "mkiv", - comment = "eventually this will be split and spread", - filename = "math-def", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="math-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "will be checked and improved", - filename = "math-ali", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="this file might merge into others", + ["filename"]="math-pln", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "needs testing", - filename = "math-arr", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="math-for", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "math-stc", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="eventually this will be split and spread", + ["filename"]="math-def", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - filename = "math-acc", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="will be checked and improved", + ["filename"]="math-ali", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "at least for the moment", - filename = "math-frc", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="needs testing", + ["filename"]="math-arr", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "math-scr", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="math-stc", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "math-int", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="math-acc", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "code get replaced (by autodelimiters)", - filename = "math-del", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="at least for the moment", + ["filename"]="math-frc", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "math-fen", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="math-scr", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "math-rad", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="math-int", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "code might move to here", - filename = "math-inl", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="code get replaced (by autodelimiters)", + ["filename"]="math-del", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "code might move to here", - filename = "math-dis", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="math-fen", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "phys-dim", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="code might move to here", + ["filename"]="math-inl", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "some more functionality will end up here", - filename = "strc-mat", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="code might move to here", + ["filename"]="math-dis", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "chem-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="phys-dim", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "chem-str", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="some more functionality will end up here", + ["filename"]="strc-mat", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-scr", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="chem-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "maybe some cleanup is needed", - filename = "node-rul", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="chem-str", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "needs testing", - filename = "font-sol", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-scr", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvI", - filename = "strc-not", - loading = "always", - status = "todo", + ["category"]="mkiv", + ["comment"]="maybe some cleanup is needed", + ["filename"]="node-rul", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkvi", - comment = "will be extended as part of crited", - filename = "strc-lnt", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="needs testing", + ["filename"]="font-sol", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "pack-com", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["filename"]="strc-not", + ["loading"]="always", + ["status"]="todo", }, { - category = "mkiv", - filename = "typo-del", - loading = "always", - status = "okay", + ["category"]="mkvi", + ["comment"]="will be extended as part of crited", + ["filename"]="strc-lnt", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "grph-trf", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="pack-com", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "grph-inc", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="typo-del", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "grph-fig", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="grph-trf", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "grph-raw", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="grph-inc", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "pack-box", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="grph-fig", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "pack-bar", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="grph-raw", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "page-app", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="pack-box", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "meta-fig", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="pack-bar", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "more or less obsolete", - filename = "lang-spa", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="page-app", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "bibl-bib", - loading = "on demand", - status = "pending", + ["category"]="mkiv", + ["filename"]="meta-fig", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "bibl-tra", - loading = "on demand", - status = "pending", + ["category"]="mkiv", + ["comment"]="more or less obsolete", + ["filename"]="lang-spa", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "not needed", - filename = "meta-xml", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="bibl-bib", + ["loading"]="on demand", + ["status"]="pending", }, { - category = "mkiv", - filename = "cont-log", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="bibl-tra", + ["loading"]="on demand", + ["status"]="pending", }, { - category = "mkiv", - filename = "task-ini", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="not needed", + ["filename"]="meta-xml", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "cldf-ver", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="cont-log", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "cldf-com", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="task-ini", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "core-ctx", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="cldf-ver", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "will always be messy", - filename = "core-def", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="cldf-com", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "object related code might move or change", - filename = "back-pdf", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="core-ctx", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "back-swf", - loading = "never", - status = "okay", - comment = "no code, just an example of usage", + ["category"]="mkiv", + ["comment"]="will always be messy", + ["filename"]="core-def", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "back-u3d", - loading = "never", - status = "okay", - comment = "no code, just an example of usage", + ["category"]="mkiv", + ["comment"]="object related code might move or change", + ["filename"]="back-pdf", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "mlib-pdf", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="no code, just an example of usage", + ["filename"]="back-swf", + ["loading"]="never", + ["status"]="okay", }, { - category = "mkiv", - filename = "mlib-pps", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["comment"]="no code, just an example of usage", + ["filename"]="back-u3d", + ["loading"]="never", + ["status"]="okay", }, { - category = "mkiv", - filename = "meta-pdf", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="mlib-pdf", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "might need more work", - filename = "grph-epd", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="mlib-pps", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - comment = "some parameters might move from export to backend", - filename = "back-exp", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="meta-pdf", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["comment"]="might need more work", + ["filename"]="grph-epd", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["comment"]="some parameters might move from export to backend", + ["filename"]="back-exp", + ["loading"]="always", + ["status"]="okay", }, }, - extras = { + ["extras"]={ { - category = "tex", - comment = "add-on for mtx-context", - filename = "mtx-context-arrange", - loading = "on demand", - status = "okay", + ["category"]="tex", + ["comment"]="add-on for mtx-context", + ["filename"]="mtx-context-arrange", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "tex", - comment = "add-on for mtx-context", - filename = "mtx-context-combine", - loading = "on demand", - status = "okay", + ["category"]="tex", + ["comment"]="add-on for mtx-context", + ["filename"]="mtx-context-combine", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "tex", - comment = "add-on for mtx-context", - filename = "mtx-context-common", - loading = "on demand", - status = "okay", + ["category"]="tex", + ["comment"]="add-on for mtx-context", + ["filename"]="mtx-context-common", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "tex", - comment = "add-on for mtx-context", - filename = "mtx-context-ideas", - loading = "on demand", - status = "okay", + ["category"]="tex", + ["comment"]="add-on for mtx-context", + ["filename"]="mtx-context-ideas", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "tex", - comment = "add-on for mtx-context", - filename = "mtx-context-listing", - loading = "on demand", - status = "okay", + ["category"]="tex", + ["comment"]="add-on for mtx-context", + ["filename"]="mtx-context-listing", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "tex", - comment = "add-on for mtx-context", - filename = "mtx-context-markdown", - loading = "on demand", - status = "okay", + ["category"]="tex", + ["comment"]="add-on for mtx-context", + ["filename"]="mtx-context-markdown", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "tex", - comment = "add-on for mtx-context", - filename = "mtx-context-select", - loading = "on demand", - status = "okay", + ["category"]="tex", + ["comment"]="add-on for mtx-context", + ["filename"]="mtx-context-select", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "tex", - comment = "add-on for mtx-context", - filename = "mtx-context-timing", - loading = "on demand", - status = "okay", + ["category"]="tex", + ["comment"]="add-on for mtx-context", + ["filename"]="mtx-context-timing", + ["loading"]="on demand", + ["status"]="okay", }, }, - implementations = { + ["implementations"]={ + { + ["category"]="mkiv", + ["filename"]="symb-imp-fontawesome", + ["loading"]="on demand", + ["status"]="okay", + }, { - category = "mkiv", - filename = "colo-imp-dem", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-ebgaramond", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "colo-imp-ema", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-gentium", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "colo-imp-rgb", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-ipaex", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "colo-imp-x11", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-lato", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "colo-imp-xwi", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-libertinus", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "java-imp-exa", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-mathdigits", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "java-imp-fil", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-minion", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "java-imp-fld", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-opendyslexic", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "java-imp-rhh", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-source", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "java-imp-stp", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="buff-imp-tex", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "meta-imp-clp", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="buff-imp-mp", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "meta-imp-dum", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="buff-imp-lua", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "meta-imp-fen", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="buff-imp-xml", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "meta-imp-mis", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="buff-imp-parsed-xml", + ["loading"]="always", + ["status"]="okay", }, { - category = "mkiv", - filename = "meta-imp-nav", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="meta-imp-grid", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "meta-imp-pre", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="meta-imp-mat", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "meta-imp-txt", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="meta-imp-outlines", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "symb-imp-cow", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="meta-imp-tab", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "symb-imp-eur", - loading = "on demand", - status = "okay", + ["category"]="mkvi", + ["filename"]="publ-imp-apa", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "symb-imp-jmn", - loading = "on demand", - status = "okay", + ["category"]="mkvi", + ["filename"]="publ-imp-aps", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "symb-imp-mis", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="colo-imp-crayola", + ["status"]="okay", }, { - category = "mkiv", - filename = "symb-imp-mvs", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="colo-imp-rainbow", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "symb-imp-nav", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="colo-imp-ral", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-antykwa", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="colo-imp-dem", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-antykwapoltawskiego", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="colo-imp-ema", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-asana", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="colo-imp-rgb", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-averia", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="colo-imp-x11", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-buy", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="colo-imp-xwi", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-cambria", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="java-imp-exa", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-charter", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="java-imp-fil", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-cleartype", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="java-imp-fld", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-computer-modern-unicode", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="java-imp-rhh", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-cow", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="java-imp-stp", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-dejavu", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="meta-imp-clp", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-euler", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="meta-imp-dum", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-ghz", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="meta-imp-fen", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-hgz", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="meta-imp-mis", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-husayni", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="meta-imp-nav", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-hvmath", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="meta-imp-pre", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-inconsolata", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="meta-imp-txt", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-informal", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="symb-imp-cow", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-iwona", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="symb-imp-eur", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-kurier", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="symb-imp-jmn", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-latinmodern", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="symb-imp-mis", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-liberation", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="symb-imp-mvs", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-libertine", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="symb-imp-nav", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-lmnames", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-antykwa", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-lucida-opentype", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-antykwapoltawskiego", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-lucida-typeone", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-asana", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-mathdesign", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-averia", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-mathtimes", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-buy", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-mscore", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-cambria", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-osx", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-charter", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-postscript", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-cleartype", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-punknova", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-computer-modern-unicode", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-texgyre", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-cow", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-unfonts", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-dejavu", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-xits", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-euler", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-imp-xitsbidi", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="type-imp-ghz", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "publ-ini", - loading = "always", - status = "pending", + ["category"]="mkiv", + ["filename"]="type-imp-hgz", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "publ-old", - loading = "always", - status = "pending", + ["category"]="mkiv", + ["filename"]="type-imp-husayni", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "publ-tra", - loading = "always", - status = "pending", + ["category"]="mkiv", + ["filename"]="type-imp-hvmath", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "publ-usr", - loading = "always", - status = "pending", + ["category"]="mkiv", + ["filename"]="type-imp-inconsolata", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "publ-jrn", - loading = "always", - status = "pending", + ["category"]="mkiv", + ["filename"]="type-imp-informal", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "publ-xml", - loading = "always", - status = "pending", + ["category"]="mkiv", + ["filename"]="type-imp-iwona", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "publ-imp-apa", - loading = "always", - status = "pending", + ["category"]="mkiv", + ["filename"]="type-imp-kurier", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "publ-imp-cite", - loading = "always", - status = "pending", + ["category"]="mkiv", + ["filename"]="type-imp-latinmodern", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "publ-imp-definitions", - loading = "always", - status = "pending", + ["category"]="mkiv", + ["filename"]="type-imp-liberation", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "publ-imp-commands", - loading = "always", - status = "pending", + ["category"]="mkiv", + ["filename"]="type-imp-libertine", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="type-imp-lmnames", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="type-imp-lucida-opentype", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="type-imp-lucida-typeone", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="type-imp-mathdesign", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="type-imp-mathtimes", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="type-imp-mscore", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="type-imp-osx", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="type-imp-postscript", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="type-imp-punknova", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="type-imp-texgyre", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="type-imp-unfonts", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="type-imp-xits", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="type-imp-xitsbidi", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="publ-ini", + ["loading"]="always", + ["status"]="pending", + }, + { + ["category"]="mkiv", + ["filename"]="publ-old", + ["loading"]="always", + ["status"]="pending", + }, + { + ["category"]="mkiv", + ["filename"]="publ-tra", + ["loading"]="always", + ["status"]="pending", + }, + { + ["category"]="mkiv", + ["filename"]="publ-usr", + ["loading"]="always", + ["status"]="pending", + }, + { + ["category"]="mkiv", + ["filename"]="publ-xml", + ["loading"]="always", + ["status"]="pending", }, }, - lua = { + ["lua"]={ + { + ["category"]="lua", + ["filename"]="anch-pgr", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="bibl-tst", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="char-fio", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="cldf-prs", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="cldf-scn", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="cldf-stp", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="cont-run", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-cff", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-cft", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-dsp", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-gbn", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-hsh", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-mps", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-nod", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-ocl", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-odk", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-odv", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-off", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-one", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-onr", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-osd", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-otj", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-otl", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-oto", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-otr", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-ots", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-oup", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-sel", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-shp", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-ttf", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-web", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="font-xtx", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="good-ctx", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="good-gen", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="good-ini", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="good-mth", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="grph-con", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="grph-mem", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="grph-pat", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="grph-rul", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="l-gzip", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="l-lua", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="l-package", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="l-sandbox", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-cnt", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-frq-de", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-frq-en", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-frq-nl", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-frq-pt", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-rep", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="luat-usr", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lxml-ini", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="math-dir", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="mlib-int", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="mlib-lua", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="node-ltp", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="node-scn", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="node-met", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="node-nut", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="page-cst", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="page-inj", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="publ-imp-apa", + ["loading"]="on demand", + ["status"]="okay", + }, { - category = "lua", - filename = "anch-pos", - loading = "anch-pos", - status = "okay", + ["category"]="lua", + ["filename"]="publ-imp-aps", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "attr-col", - loading = "attr-col", - status = "okay", + ["category"]="lua", + ["filename"]="publ-imp-default", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "attr-eff", - loading = "attr-eff", - status = "okay", + ["category"]="lua", + ["filename"]="publ-imp-replacements", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "attr-ini", - loading = "attr-ini", - status = "okay", + ["category"]="lua", + ["filename"]="publ-jrn", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "attr-lay", - loading = "attr-lay", - status = "okay", + ["category"]="lua", + ["filename"]="publ-reg", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "attr-neg", - loading = "attr-neg", - status = "okay", + ["category"]="lua", + ["filename"]="publ-sor", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "attr-mkr", - loading = "attr-mkr", - status = "okay", + ["category"]="lua", + ["filename"]="regi-ibm", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - comment = "experimental code, maybe some will move elsewhere", - filename = "back-exp", - loading = "back-exp", - status = "pending", + ["category"]="lua", + ["filename"]="regi-pdfdoc", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "back-ini", - loading = "back-ini", - status = "okay", + ["category"]="lua", + ["filename"]="scrp-tha", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "back-pdf", - loading = "back-pdf", - status = "okay", + ["category"]="lua", + ["filename"]="spac-prf", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "bibl-bib", - loading = "on demand", + ["category"]="lua", + ["filename"]="toks-map", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "bibl-tra", - loading = "on demand", + ["category"]="lua", + ["filename"]="toks-tra", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "blob-ini", - status = "todo", + ["category"]="lua", + ["filename"]="trac-par", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "buff-imp-default", - loading = "buff-imp-default", - status = "okay", + ["category"]="lua", + ["filename"]="typo-chr", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "buff-imp-escaped", - loading = "buff-imp-escaped", - status = "okay", + ["category"]="lua", + ["filename"]="typo-duc", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - comment = "todo: colorization and nesting as in scite", - filename = "buff-imp-lua", - loading = "buff-imp-lua", - status = "okay", + ["category"]="lua", + ["filename"]="typo-inj", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - comment = "todo: colorization and nesting as in scite", - filename = "buff-imp-mp", - loading = "buff-imp-mp", - status = "okay", + ["category"]="lua", + ["filename"]="typo-lin", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "buff-imp-nested", - loading = "buff-imp-nested", - status = "okay", + ["category"]="lua", + ["filename"]="typo-tal", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "buff-imp-parsed-xml", - loading = "buff-imp-parsed-xml", - status = "okay", + ["category"]="lua", + ["filename"]="typo-wrp", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - comment = "todo: colorization and nesting as in scite", - filename = "buff-imp-tex", - loading = "buff-imp-tex", - status = "okay", + ["category"]="lua", + ["filename"]="util-fil", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - comment = "todo: colorization and nesting as in scite", - filename = "buff-imp-xml", - loading = "buff-imp-xml", - status = "okay", + ["category"]="lua", + ["filename"]="util-lib-imp-gm", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "buff-ini", - status = "okay", + ["category"]="lua", + ["filename"]="util-lib-imp-gs", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "buff-par", - status = "okay", + ["category"]="lua", + ["filename"]="util-ran", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - comment = "maybe we will provide a few more (nesting) methods", - filename = "buff-ver", - status = "okay", + ["category"]="lua", + ["filename"]="util-sac", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "catc-ini", - loading = "catc-ini", - status = "okay", + ["category"]="lua", + ["filename"]="util-sbx", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "char-cjk", - loading = "char-ini", - status = "okay", + ["category"]="lua", + ["filename"]="util-sci", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - filename = "char-def", - loading = "char-ini", - status = "okay", + ["category"]="lua", + ["filename"]="util-soc", + ["loading"]="always", + ["status"]="okay", }, { - category = "lua", - comment = "maybe dataonly", - filename = "char-enc", - loading = "char-enc", - status = "okay", + ["category"]="lua", + ["filename"]="util-sql-imp-client", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "char-ent", - loading = "char-ent", - status = "okay", + ["category"]="lua", + ["filename"]="util-sql-imp-library", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - comment = "maybe move blocks table to separate (dataonly) file", - filename = "char-ini", - loading = "char-ini", - status = "okay", + ["category"]="lua", + ["filename"]="util-sql-imp-sqlite", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "char-map", - loading = "char-ini", - status = "okay", + ["category"]="lua", + ["filename"]="util-sql-imp-swiglib", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "char-tex", - loading = "char-ini", - status = "okay", + ["category"]="lua", + ["filename"]="util-sql-loggers", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "char-utf", - loading = "char-utf", - status = "okay", + ["category"]="lua", + ["filename"]="util-sql-sessions", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "chem-ini", - loading = "chem-ini", - status = "okay", + ["category"]="lua", + ["filename"]="util-sql-tickets", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "chem-str", - loading = "chem-str", - status = "okay", + ["category"]="lua", + ["filename"]="util-sql-tracers", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - comment = "will be extended and can be optimized if needed", - filename = "cldf-bas", - loading = "cldf-bas", - status = "okay", + ["category"]="lua", + ["filename"]="util-sql-users", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - comment = "might change or even go away", - filename = "cldf-com", - loading = "cldf-com", - status = "okay", + ["category"]="lua", + ["filename"]="util-you", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "cldf-ini", - loading = "cldf-ini", - status = "okay", + ["category"]="lua", + ["filename"]="m-escrito", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "cldf-int", - loading = "cldf-int", - status = "pending", + ["category"]="lua", + ["filename"]="s-characters-properties", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - comment = "maybe this code can be redone more efficiently/robust", - filename = "cldf-ver", - loading = "cldf-ver", - status = "pending", + ["category"]="lua", + ["filename"]="s-languages-words", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - comment = "also used in mtx-*", - filename = "colo-icc", - loading = "colo-ini", - status = "okay", + ["category"]="lua", + ["filename"]="s-xml-analyzers", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "colo-ini", - loading = "colo-ini", - status = "okay", + ["category"]="lua", + ["filename"]="x-math-svg", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - comment = "this code might move to a module", - filename = "colo-run", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="anch-pos", + ["loading"]="anch-pos", + ["status"]="okay", }, { - category = "lua", - filename = "core-con", - loading = "core-con", - status = "okay", + ["category"]="lua", + ["filename"]="attr-col", + ["loading"]="attr-col", + ["status"]="okay", }, { - category = "lua", - filename = "core-ctx", - loading = "core-ctx", - status = "okay", + ["category"]="lua", + ["filename"]="attr-eff", + ["loading"]="attr-eff", + ["status"]="okay", }, { - category = "lua", - filename = "core-dat", - loading = "core-dat", - status = "okay", + ["category"]="lua", + ["filename"]="attr-ini", + ["loading"]="attr-ini", + ["status"]="okay", }, { - category = "lua", - comment = "maybe abusing the tex namespace is wrong", - filename = "core-env", - loading = "core-env", - status = "okay", + ["category"]="lua", + ["filename"]="attr-lay", + ["loading"]="attr-lay", + ["status"]="okay", }, { - category = "lua", - filename = "core-sys", - loading = "core-sys", - status = "okay", + ["category"]="lua", + ["filename"]="attr-neg", + ["loading"]="attr-neg", + ["status"]="okay", }, { - category = "lua", - commands = "this is in fact replaced by core-dat", - filename = "core-two", - loading = "core-two", - status = "okay", + ["category"]="lua", + ["filename"]="attr-mkr", + ["loading"]="attr-mkr", + ["status"]="okay", }, { - category = "lua", - comment = "some code will move to better places", - filename = "core-uti", - loading = "core-uti", - status = "okay", + ["category"]="lua", + ["comment"]="experimental code, maybe some will move elsewhere", + ["filename"]="back-exp", + ["loading"]="back-exp", + ["status"]="pending", }, { - category = "lua", - filename = "data-aux", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="back-ini", + ["loading"]="back-ini", + ["status"]="okay", }, { - category = "lua", - filename = "data-bin", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="back-pdf", + ["loading"]="back-pdf", + ["status"]="okay", }, { - category = "lua", - filename = "data-con", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="bibl-bib", + ["loading"]="on demand", }, { - category = "lua", - filename = "data-crl", - loading = "never", - status = "todo", + ["category"]="lua", + ["filename"]="bibl-tra", + ["loading"]="on demand", }, { - category = "lua", - filename = "data-ctx", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="blob-ini", + ["status"]="todo", }, { - category = "lua", - filename = "data-env", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="buff-imp-default", + ["loading"]="buff-imp-default", + ["status"]="okay", }, { - category = "lua", - filename = "data-exp", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="buff-imp-escaped", + ["loading"]="buff-imp-escaped", + ["status"]="okay", }, { - category = "lua", - filename = "data-fil", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["comment"]="todo: colorization and nesting as in scite", + ["filename"]="buff-imp-lua", + ["loading"]="buff-imp-lua", + ["status"]="okay", }, { - category = "lua", - filename = "data-gen", - status = "todo", + ["category"]="lua", + ["comment"]="todo: colorization and nesting as in scite", + ["filename"]="buff-imp-mp", + ["loading"]="buff-imp-mp", + ["status"]="okay", }, { - category = "lua", - filename = "data-ini", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="buff-imp-nested", + ["loading"]="buff-imp-nested", + ["status"]="okay", }, { - category = "lua", - filename = "data-inp", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="buff-imp-parsed-xml", + ["loading"]="buff-imp-parsed-xml", + ["status"]="okay", }, { - category = "lua", - filename = "data-lst", - status = "todo", + ["category"]="lua", + ["comment"]="todo: colorization and nesting as in scite", + ["filename"]="buff-imp-tex", + ["loading"]="buff-imp-tex", + ["status"]="okay", }, { - category = "lua", - filename = "data-lua", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["comment"]="todo: colorization and nesting as in scite", + ["filename"]="buff-imp-xml", + ["loading"]="buff-imp-xml", + ["status"]="okay", }, { - category = "lua", - filename = "data-met", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="buff-ini", + ["status"]="okay", }, { - category = "lua", - filename = "data-out", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="buff-par", + ["status"]="okay", }, { - category = "lua", - filename = "data-pre", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["comment"]="maybe we will provide a few more (nesting) methods", + ["filename"]="buff-ver", + ["status"]="okay", }, { - category = "lua", - filename = "data-res", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="catc-ini", + ["loading"]="catc-ini", + ["status"]="okay", }, { - category = "lua", - filename = "data-sch", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="char-cjk", + ["loading"]="char-ini", + ["status"]="okay", }, { - category = "lua", - filename = "data-tex", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="char-def", + ["loading"]="char-ini", + ["status"]="okay", }, { - category = "lua", - filename = "data-tmf", - status = "todo", + ["category"]="lua", + ["comment"]="maybe dataonly", + ["filename"]="char-enc", + ["loading"]="char-enc", + ["status"]="okay", }, { - category = "lua", - filename = "data-tmp", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="char-ent", + ["loading"]="char-ent", + ["status"]="okay", }, { - category = "lua", - filename = "data-tre", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["comment"]="maybe move blocks table to separate (dataonly) file", + ["filename"]="char-ini", + ["loading"]="char-ini", + ["status"]="okay", }, { - category = "lua", - filename = "data-use", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="char-map", + ["loading"]="char-ini", + ["status"]="okay", }, { - category = "lua", - filename = "data-vir", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="char-tex", + ["loading"]="char-ini", + ["status"]="okay", }, { - category = "lua", - filename = "data-zip", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="char-utf", + ["loading"]="char-utf", + ["status"]="okay", }, { - category = "lua", - filename = "file-ini", - loading = "file-ini", - status = "okay", + ["category"]="lua", + ["filename"]="chem-ini", + ["loading"]="chem-ini", + ["status"]="okay", }, { - category = "lua", - filename = "file-job", - loading = "file-job", - status = "okay", + ["category"]="lua", + ["filename"]="chem-str", + ["loading"]="chem-str", + ["status"]="okay", }, { - category = "lua", - filename = "file-lib", - loading = "file-lib", - status = "okay", + ["category"]="lua", + ["comment"]="will be extended and can be optimized if needed", + ["filename"]="cldf-bas", + ["loading"]="cldf-bas", + ["status"]="okay", }, { - category = "lua", - filename = "file-mod", - loading = "file-mod", - status = "okay", + ["category"]="lua", + ["comment"]="might change or even go away", + ["filename"]="cldf-com", + ["loading"]="cldf-com", + ["status"]="okay", }, { - category = "lua", - filename = "file-res", - loading = "file-res", - status = "okay", + ["category"]="lua", + ["filename"]="cldf-ini", + ["loading"]="cldf-ini", + ["status"]="okay", }, { - category = "lua", - filename = "file-syn", - loading = "file-syn", - status = "okay", + ["category"]="lua", + ["filename"]="cldf-int", + ["loading"]="cldf-int", + ["status"]="pending", }, { - category = "lua", - filename = "font-afm", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["comment"]="maybe this code can be redone more efficiently/robust", + ["filename"]="cldf-ver", + ["loading"]="cldf-ver", + ["status"]="pending", }, { - category = "lua", - filename = "font-afk", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["comment"]="also used in mtx-*", + ["filename"]="colo-icc", + ["loading"]="colo-ini", + ["status"]="okay", }, { - category = "lua", - comment = "only used in luatex-fonts", - filename = "font-age", - loading = "never", - status = "okay", + ["category"]="lua", + ["filename"]="colo-ini", + ["loading"]="colo-ini", + ["status"]="okay", }, { - category = "lua", - filename = "font-agl", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["comment"]="this code might move to a module", + ["filename"]="colo-run", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - comment = "needs some documentation in usage", - filename = "font-aux", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="core-con", + ["loading"]="core-con", + ["status"]="okay", }, { - category = "lua", - comment = "move more to the commands namespace", - filename = "font-chk", - loading = "font-chk", - status = "okay", + ["category"]="lua", + ["filename"]="core-ctx", + ["loading"]="core-ctx", + ["status"]="okay", }, { - category = "lua", - filename = "font-cid", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="core-dat", + ["loading"]="core-dat", + ["status"]="okay", }, { - category = "lua", - filename = "font-col", - loading = "font-col", - status = "okay", + ["category"]="lua", + ["comment"]="maybe abusing the tex namespace is wrong", + ["filename"]="core-env", + ["loading"]="core-env", + ["status"]="okay", }, { - category = "lua", - filename = "font-con", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="core-sys", + ["loading"]="core-sys", + ["status"]="okay", }, { - category = "lua", - comment = "will be improved over time", - filename = "font-ctx", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["commands"]="this is in fact replaced by core-dat", + ["filename"]="core-two", + ["loading"]="core-two", + ["status"]="okay", }, { - category = "lua", - filename = "font-def", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["comment"]="some code will move to better places", + ["filename"]="core-uti", + ["loading"]="core-uti", + ["status"]="okay", }, { - category = "lua", - comment = "part of this code is obsolete", - filename = "font-enc", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-aux", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - comment = "needs documentation at the tex end", - filename = "font-enh", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-bin", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - comment = "maybe some data tables can be be external", - filename = "font-ext", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-con", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - comment = "okay but can be improved", - filename = "font-fbk", - loading = "font-lib", - status = "pending", + ["category"]="lua", + ["filename"]="data-crl", + ["loading"]="never", + ["status"]="todo", }, { - category = "lua", - filename = "font-gds", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-ctx", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "mkvi", - filename = "font-hsh", - loading = "always", - status = "okay", + ["category"]="lua", + ["filename"]="data-env", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - filename = "font-ini", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-exp", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - filename = "font-inj", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-fil", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - filename = "font-ldr", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="data-gen", + ["status"]="todo", }, { - category = "lua", - filename = "font-log", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-ini", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - comment = "currently rather minimalistic", - filename = "font-lua", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-inp", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - comment = "the lum file support will be dropped / no map files anyway", - filename = "font-map", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-lst", + ["status"]="todo", }, { - category = "lua", - filename = "font-mis", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="data-lua", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "mkvi", - filename = "font-nod", - loading = "always", - status = "okay", + ["category"]="lua", + ["filename"]="data-met", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - comment = "when more scripts are supported we might end up with imp files", - filename = "font-ota", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-out", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - filename = "font-otb", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-pre", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - filename = "font-otc", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-res", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - filename = "font-otd", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-sch", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - filename = "font-otf", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-tex", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - filename = "font-oth", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-tmf", + ["status"]="todo", }, { - category = "lua", - filename = "font-oti", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-tmp", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - filename = "font-otn", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-tre", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - filename = "font-otp", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-use", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - filename = "font-ott", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-vir", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - comment = "is mostly replaced by lfg files", - filename = "font-pat", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="data-zip", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - filename = "font-sol", - loading = "font-sol", - status = "okay", + ["category"]="lua", + ["filename"]="file-ini", + ["loading"]="file-ini", + ["status"]="okay", }, { - category = "lua", - comment = "also loaded on demand", - filename = "font-syn", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="file-job", + ["loading"]="file-job", + ["status"]="okay", }, { - category = "lua", - filename = "font-tfm", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="file-lib", + ["loading"]="file-lib", + ["status"]="okay", }, { - category = "lua", - filename = "font-trt", - loading = "font-lib", - status = "okay", + ["category"]="lua", + ["filename"]="file-mod", + ["loading"]="file-mod", + ["status"]="okay", }, { - category = "lua", - filename = "font-vf", - loading = "font-lib", - status = "pending", + ["category"]="lua", + ["filename"]="file-res", + ["loading"]="file-res", + ["status"]="okay", }, { - category = "lua", - filename = "grph-epd", - loading = "grph-epd", - status = "okay", + ["category"]="lua", + ["filename"]="file-syn", + ["loading"]="file-syn", + ["status"]="okay", }, { - category = "lua", - filename = "grph-fil", - loading = "grph-inc", - status = "okay", + ["category"]="lua", + ["filename"]="font-afm", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "grph-inc", - loading = "grph-inc", - status = "todo", + ["category"]="lua", + ["filename"]="font-afk", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "grph-raw", - loading = "grph-raw", - status = "okay", + ["category"]="lua", + ["comment"]="only used in luatex-fonts", + ["filename"]="font-age", + ["loading"]="never", + ["status"]="okay", }, { - category = "lua", - filename = "grph-swf", - loading = "grph-swf", - status = "okay", + ["category"]="lua", + ["filename"]="font-agl", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "grph-u3d", - loading = "grph-u3d", - status = "okay", + ["category"]="lua", + ["comment"]="needs some documentation in usage", + ["filename"]="font-aux", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - comment = "experiment with graphic magick library", - filename = "grph-wnd", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["comment"]="move more to the commands namespace", + ["filename"]="font-chk", + ["loading"]="font-chk", + ["status"]="okay", }, { - category = "lua", - filename = "java-ini", - loading = "java-ini", - status = "okay", + ["category"]="lua", + ["filename"]="font-cid", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "l-boolean", - status = "todo", + ["category"]="lua", + ["filename"]="font-col", + ["loading"]="font-col", + ["status"]="okay", }, { - category = "lua", - filename = "l-dir", - status = "todo", + ["category"]="lua", + ["filename"]="font-con", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "l-file", - status = "todo", + ["category"]="lua", + ["comment"]="will be improved over time", + ["filename"]="font-ctx", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "l-function", - status = "todo", + ["category"]="lua", + ["filename"]="font-def", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "l-io", - status = "todo", + ["category"]="lua", + ["comment"]="part of this code is obsolete", + ["filename"]="font-enc", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "l-lpeg", - status = "todo", + ["category"]="lua", + ["comment"]="needs documentation at the tex end", + ["filename"]="font-enh", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "l-math", - status = "todo", + ["category"]="lua", + ["comment"]="maybe some data tables can be be external", + ["filename"]="font-ext", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "l-md5", - status = "todo", + ["category"]="lua", + ["comment"]="okay but can be improved", + ["filename"]="font-fbk", + ["loading"]="font-lib", + ["status"]="pending", }, { - category = "lua", - filename = "l-number", - status = "todo", + ["category"]="lua", + ["filename"]="font-ini", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "l-os", - status = "todo", + ["category"]="lua", + ["filename"]="font-inj", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "l-pdfview", - status = "todo", + ["category"]="lua", + ["filename"]="font-ldr", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "l-set", - status = "todo", + ["category"]="lua", + ["filename"]="font-log", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "l-string", - status = "todo", + ["category"]="lua", + ["comment"]="currently rather minimalistic", + ["filename"]="font-lua", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "l-table", - status = "todo", + ["category"]="lua", + ["comment"]="the lum file support will be dropped / no map files anyway", + ["filename"]="font-map", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "l-unicode", - status = "todo", + ["category"]="lua", + ["filename"]="font-mis", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "l-url", - status = "todo", + ["category"]="lua", + ["comment"]="when more scripts are supported we might end up with imp files", + ["filename"]="font-ota", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "l-xml", - status = "todo", + ["category"]="lua", + ["filename"]="font-otb", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "lang-def", - loading = "lang-def", - status = "okay", + ["category"]="lua", + ["filename"]="font-otc", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "lang-dis", - loading = "lang-ini", - status = "okay", + ["category"]="lua", + ["filename"]="font-otd", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "lang-hyp", - loading = "lang-hyp", - status = "okay", + ["category"]="lua", + ["filename"]="font-otf", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "lang-ini", - loading = "lang-ini", - status = "okay", + ["category"]="lua", + ["filename"]="font-oth", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "lang-lab", - loading = "lang-lab", - status = "okay", + ["category"]="lua", + ["filename"]="font-oti", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "lang-hyp", - loading = "lang-hyp", - status = "okay", + ["category"]="lua", + ["filename"]="font-otn", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "lang-txt", - loading = "lang-lab", - status = "okay", + ["category"]="lua", + ["filename"]="font-otp", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - comment = "maybe another approach is nicer", - filename = "lang-url", - loading = "lang-url", - status = "pending", + ["category"]="lua", + ["filename"]="font-ott", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "lang-wrd", - loading = "lang-wrd", - status = "okay", + ["category"]="lua", + ["comment"]="is mostly replaced by lfg files", + ["filename"]="font-pat", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - comment = "more will end up here", - filename = "layo-ini", - loading = "layo-ini", - status = "okay", + ["category"]="lua", + ["filename"]="font-sol", + ["loading"]="font-sol", + ["status"]="okay", }, { - category = "lua", - filename = "lpdf-ano", - status = "todo", + ["category"]="lua", + ["comment"]="also loaded on demand", + ["filename"]="font-syn", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "lpdf-res", - status = "todo", + ["category"]="lua", + ["filename"]="font-tfm", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "lpdf-col", - status = "todo", + ["category"]="lua", + ["filename"]="font-trt", + ["loading"]="font-lib", + ["status"]="okay", }, { - category = "lua", - filename = "lpdf-enc", - status = "todo", + ["category"]="lua", + ["filename"]="font-vf", + ["loading"]="font-lib", + ["status"]="pending", }, { - category = "lua", - filename = "lpdf-epa", - status = "todo", + ["category"]="lua", + ["filename"]="grph-epd", + ["loading"]="grph-epd", + ["status"]="okay", }, { - category = "lua", - filename = "lpdf-epd", - status = "todo", + ["category"]="lua", + ["filename"]="grph-fil", + ["loading"]="grph-inc", + ["status"]="okay", }, { - category = "lua", - filename = "lpdf-fld", - status = "todo", + ["category"]="lua", + ["filename"]="grph-inc", + ["loading"]="grph-inc", + ["status"]="todo", }, { - category = "lua", - filename = "lpdf-fmt", - status = "todo", + ["category"]="lua", + ["filename"]="grph-raw", + ["loading"]="grph-raw", + ["status"]="okay", }, { - category = "lua", - filename = "lpdf-grp", - status = "todo", + ["category"]="lua", + ["filename"]="grph-swf", + ["loading"]="grph-swf", + ["status"]="okay", }, { - category = "lua", - filename = "lpdf-ini", - status = "todo", + ["category"]="lua", + ["filename"]="grph-u3d", + ["loading"]="grph-u3d", + ["status"]="okay", }, { - category = "lua", - filename = "lpdf-mis", - status = "todo", + ["category"]="lua", + ["comment"]="experiment with graphic magick library", + ["filename"]="grph-wnd", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "lpdf-mov", - status = "todo", + ["category"]="lua", + ["filename"]="java-ini", + ["loading"]="java-ini", + ["status"]="okay", }, { - category = "lua", - filename = "lpdf-nod", - status = "todo", + ["category"]="lua", + ["filename"]="l-boolean", + ["status"]="todo", }, { - category = "lua", - filename = "lpdf-ren", - status = "todo", + ["category"]="lua", + ["filename"]="l-dir", + ["status"]="todo", }, { - category = "lua", - filename = "lpdf-swf", - status = "todo", + ["category"]="lua", + ["filename"]="l-file", + ["status"]="todo", }, { - category = "lua", - filename = "lpdf-tag", - status = "todo", + ["category"]="lua", + ["filename"]="l-function", + ["status"]="todo", }, { - category = "lua", - filename = "lpdf-u3d", - status = "todo", + ["category"]="lua", + ["filename"]="l-io", + ["status"]="todo", }, { - category = "lua", - filename = "lpdf-wid", - status = "todo", + ["category"]="lua", + ["filename"]="l-lpeg", + ["status"]="todo", }, { - category = "lua", - filename = "lpdf-xmp", - status = "todo", + ["category"]="lua", + ["filename"]="l-math", + ["status"]="todo", }, { - category = "lua", - comment = "replacement code for wd/ht/dp", - filename = "luat-bwc", - loading = "luat-lib", - status = "okay", + ["category"]="lua", + ["filename"]="l-md5", + ["status"]="todo", }, { - category = "lua", - filename = "luat-cbk", - loading = "luat-lib", - status = "okay", + ["category"]="lua", + ["filename"]="l-number", + ["status"]="todo", }, { - category = "lua", - filename = "luat-cnf", - loading = "luat-lib", - status = "okay", + ["category"]="lua", + ["filename"]="l-os", + ["status"]="todo", }, { - category = "lua", - comment = "maybe some code should move", - filename = "luat-cod", - loading = "luat-cod", - status = "okay", + ["category"]="lua", + ["filename"]="l-pdfview", + ["status"]="todo", }, { - category = "lua", - filename = "luat-env", - loading = "luat-lib", - status = "okay", + ["category"]="lua", + ["filename"]="l-set", + ["status"]="todo", }, { - category = "lua", - filename = "luat-exe", - loading = "luat-lib", - status = "okay", + ["category"]="lua", + ["filename"]="l-string", + ["status"]="todo", }, { - category = "lua", - filename = "luat-fio", - loading = "luat-lib", - status = "okay", + ["category"]="lua", + ["filename"]="l-table", + ["status"]="todo", }, { - category = "lua", - filename = "luat-fmt", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="l-unicode", + ["status"]="todo", }, { - category = "lua", - comment = "will be upgraded when we have Lua 5.2", - filename = "luat-ini", - loading = "luat-lib", - status = "pending", + ["category"]="lua", + ["filename"]="l-url", + ["status"]="todo", }, { - category = "lua", - comment = "will be upgraded when we have Lua 5.2", - filename = "util-env", - loading = "luat-lib", - status = "pending", + ["category"]="lua", + ["filename"]="l-xml", + ["status"]="todo", }, { - category = "lua", - filename = "luat-iop", - loading = "luat-lib", - status = "okay", + ["category"]="lua", + ["filename"]="lang-def", + ["loading"]="lang-def", + ["status"]="okay", }, { - category = "lua", - comment = "this is likely to change some day", - filename = "luat-lua", - loading = "luat-lib", - status = "okay", + ["category"]="lua", + ["filename"]="lang-dis", + ["loading"]="lang-ini", + ["status"]="okay", }, { - category = "lua", - filename = "luat-mac", - loading = "luat-lib", - status = "okay", + ["category"]="lua", + ["filename"]="lang-hyp", + ["loading"]="lang-hyp", + ["status"]="okay", }, { - category = "lua", - filename = "luat-run", - loading = "luat-lib", - status = "okay", + ["category"]="lua", + ["filename"]="lang-ini", + ["loading"]="lang-ini", + ["status"]="okay", }, { - category = "lua", - comment = "related to the socket code", - filename = "luat-soc", - loading = "on demand", - status = "pending", + ["category"]="lua", + ["filename"]="lang-lab", + ["loading"]="lang-lab", + ["status"]="okay", }, { - category = "lua", - filename = "luat-sta", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="lang-hyp", + ["loading"]="lang-hyp", + ["status"]="okay", }, { - category = "lua", - filename = "luat-sto", - loading = "luat-lib", - status = "okay", + ["category"]="lua", + ["filename"]="lang-txt", + ["loading"]="lang-lab", + ["status"]="okay", }, { - category = "lua", - filename = "lxml-aux", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["comment"]="maybe another approach is nicer", + ["filename"]="lang-url", + ["loading"]="lang-url", + ["status"]="pending", }, { - category = "lua", - filename = "lxml-css", - status = "todo", + ["category"]="lua", + ["filename"]="lang-wrd", + ["loading"]="lang-wrd", + ["status"]="okay", }, { - category = "lua", - filename = "lxml-ctx", - status = "todo", + ["category"]="lua", + ["comment"]="more will end up here", + ["filename"]="layo-ini", + ["loading"]="layo-ini", + ["status"]="okay", }, { - category = "lua", - filename = "lxml-dir", - status = "todo", + ["category"]="lua", + ["filename"]="lpdf-ano", + ["status"]="todo", }, { - category = "lua", - filename = "lxml-ent", - status = "todo", + ["category"]="lua", + ["filename"]="lpdf-res", + ["status"]="todo", }, { - category = "lua", - filename = "lxml-inf", - status = "todo", + ["category"]="lua", + ["filename"]="lpdf-col", + ["status"]="todo", }, { - category = "lua", - filename = "lxml-lpt", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="lpdf-enc", + ["status"]="todo", }, { - category = "lua", - filename = "lxml-mis", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="lpdf-epa", + ["status"]="todo", }, { - category = "lua", - filename = "lxml-sor", - status = "todo", + ["category"]="lua", + ["filename"]="lpdf-epd", + ["status"]="todo", }, { - category = "lua", - filename = "lxml-tab", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="lpdf-fld", + ["status"]="todo", }, { - category = "lua", - filename = "lxml-tex", - status = "todo", + ["category"]="lua", + ["filename"]="lpdf-fmt", + ["status"]="todo", }, { - category = "lua", - filename = "lxml-xml", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="lpdf-grp", + ["status"]="todo", }, { - category = "lua", - filename = "m-chart", - status = "todo", + ["category"]="lua", + ["filename"]="lpdf-ini", + ["status"]="todo", }, { - category = "lua", - filename = "m-database", - status = "okay", + ["category"]="lua", + ["filename"]="lpdf-mis", + ["status"]="todo", }, { - category = "lua", - filename = "m-nodechart", - status = "okay", + ["category"]="lua", + ["filename"]="lpdf-mov", + ["status"]="todo", }, { - category = "lua", - filename = "m-markdown", - status = "todo", + ["category"]="lua", + ["filename"]="lpdf-nod", + ["status"]="todo", }, { - category = "lua", - filename = "m-pstricks", - status = "todo", + ["category"]="lua", + ["filename"]="lpdf-ren", + ["status"]="todo", }, { - category = "lua", - filename = "m-spreadsheet", - status = "todo", + ["category"]="lua", + ["filename"]="lpdf-swf", + ["status"]="todo", }, { - category = "lua", - filename = "m-steps", - status = "todo", + ["category"]="lua", + ["filename"]="lpdf-tag", + ["status"]="todo", }, { - category = "lua", - filename = "math-act", - loading = "math-ini", - status = "okay", + ["category"]="lua", + ["filename"]="lpdf-u3d", + ["status"]="todo", }, { - category = "lua", - filename = "math-frc", - loading = "math-frc", - status = "okay", + ["category"]="lua", + ["filename"]="lpdf-wid", + ["status"]="todo", }, { - category = "lua", - comment = "could be made look nicer, but who cares", - filename = "math-dim", - loading = "math-ini", - status = "okay", + ["category"]="lua", + ["filename"]="lpdf-xmp", + ["status"]="todo", }, { - category = "lua", - comment = "the code is related to math-vfu", - filename = "math-ext", - loading = "math-ini", - status = "okay", + ["category"]="lua", + ["comment"]="replacement code for wd/ht/dp", + ["filename"]="luat-bwc", + ["loading"]="luat-lib", + ["status"]="okay", }, { - category = "lua", - filename = "math-fbk", - loading = "math-ini", - status = "okay", + ["category"]="lua", + ["filename"]="luat-cbk", + ["loading"]="luat-lib", + ["status"]="okay", }, { - category = "lua", - filename = "math-frc", - loading = "math-frc", - status = "okay", + ["category"]="lua", + ["filename"]="luat-cnf", + ["loading"]="luat-lib", + ["status"]="okay", }, { - category = "lua", - comment = "okay, but we might have a few more low level definers some day", - filename = "math-ini", - loading = "math-ini", - status = "pending", + ["category"]="lua", + ["comment"]="maybe some code should move", + ["filename"]="luat-cod", + ["loading"]="luat-cod", + ["status"]="okay", }, { - category = "lua", - filename = "math-map", - loading = "math-ini", - status = "okay", + ["category"]="lua", + ["filename"]="luat-env", + ["loading"]="luat-lib", + ["status"]="okay", }, { - category = "lua", - filename = "math-noa", - loading = "math-ini", - status = "okay", + ["category"]="lua", + ["filename"]="luat-exe", + ["loading"]="luat-lib", + ["status"]="okay", }, { - category = "lua", - filename = "math-ren", - loading = "math-ini", - status = "okay", + ["category"]="lua", + ["filename"]="luat-fio", + ["loading"]="luat-lib", + ["status"]="okay", }, { - category = "lua", - filename = "math-tag", - loading = "math-ini", - status = "okay", + ["category"]="lua", + ["filename"]="luat-fmt", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "math-ttv", - loading = "math-ini", - status = "okay", + ["category"]="lua", + ["comment"]="will be upgraded when we have Lua 5.2", + ["filename"]="luat-ini", + ["loading"]="luat-lib", + ["status"]="pending", }, { - category = "lua", - filename = "math-vfu", - loading = "math-ini", - status = "okay", + ["category"]="lua", + ["comment"]="will be upgraded when we have Lua 5.2", + ["filename"]="util-env", + ["loading"]="luat-lib", + ["status"]="pending", }, { - category = "lua", - comment = "this is just a first version", - filename = "meta-fun", - loading = "meta-fun", - status = "okay", + ["category"]="lua", + ["filename"]="luat-iop", + ["loading"]="luat-lib", + ["status"]="okay", }, { - category = "lua", - filename = "meta-ini", - loading = "meta-ini", - status = "okay", + ["category"]="lua", + ["comment"]="this is likely to change some day", + ["filename"]="luat-lua", + ["loading"]="luat-lib", + ["status"]="okay", }, { - category = "lua", - filename = "meta-lua", - loading = "meta-lua", - status = "okay", + ["category"]="lua", + ["filename"]="luat-mac", + ["loading"]="luat-lib", + ["status"]="okay", }, { - category = "lua", - filename = "meta-fnt", - loading = "meta-fnt", - status = "okay", + ["category"]="lua", + ["filename"]="luat-run", + ["loading"]="luat-lib", + ["status"]="okay", }, { - category = "lua", - comment = "could be done nicer nowadays but who needs it", - filename = "meta-pdf", - loading = "meta-pdf", - status = "okay", + ["category"]="lua", + ["comment"]="related to the socket code", + ["filename"]="luat-soc", + ["loading"]="on demand", + ["status"]="pending", }, { - category = "lua", - filename = "meta-pdh", - loading = "meta-pdh", - status = "okay", - loading = "never", - comment = "this is historic code that we keep around", + ["category"]="lua", + ["filename"]="luat-sta", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "meta-tex", - loading = "meta-tex", - status = "okay", + ["category"]="lua", + ["filename"]="luat-sto", + ["loading"]="luat-lib", + ["status"]="okay", }, { - category = "lua", - filename = "mlib-ctx", - loading = "mlib-ctx", - status = "okay", + ["category"]="lua", + ["filename"]="lxml-aux", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - filename = "mlib-pdf", - loading = "mlib-pdf", - status = "okay", + ["category"]="lua", + ["filename"]="lxml-css", + ["status"]="todo", }, { - category = "lua", - filename = "mlib-pps", - loading = "mlib-pdf", - status = "okay", + ["category"]="lua", + ["filename"]="lxml-ctx", + ["status"]="todo", }, { - category = "lua", - filename = "mlib-run", - loading = "mlib-ctx", - status = "okay", + ["category"]="lua", + ["filename"]="lxml-dir", + ["status"]="todo", }, { - category = "lua", - comment = "this is an experiment, namespaces need to be dealt with properly", - filename = "mult-aux", - loading = "mult-aux", - status = "pending", + ["category"]="lua", + ["filename"]="lxml-ent", + ["status"]="todo", }, { - category = "lua", - comment = "this is an experiment", - filename = "mult-chk", - loading = "mult-chk", - status = "pending", + ["category"]="lua", + ["filename"]="lxml-inf", + ["status"]="todo", }, { - category = "lua", - filename = "mult-def", - loading = "mult-ini", - status = "okay", + ["category"]="lua", + ["filename"]="lxml-lpt", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - comment = "used for generating editor lexing files", - filename = "mult-fun", - loading = "never", - status = "okay", + ["category"]="lua", + ["filename"]="lxml-mis", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - filename = "mult-ini", - loading = "mult-ini", - status = "okay", + ["category"]="lua", + ["filename"]="lxml-sor", + ["status"]="todo", }, { - category = "lua", - comment = "used for generating editor lexing files", - filename = "mult-low", - loading = "never", - status = "okay", + ["category"]="lua", + ["filename"]="lxml-tab", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - comment = "all messages need to be checked", - filename = "mult-mes", - loading = "mult-ini", - status = "pending", + ["category"]="lua", + ["filename"]="lxml-tex", + ["status"]="todo", }, { - category = "lua", - comment = "used for generating editor lexing files", - filename = "mult-mps", - loading = "never", - status = "okay", + ["category"]="lua", + ["filename"]="lxml-xml", + ["loading"]="luat-lib", + ["status"]="todo", }, { - category = "lua", - comment = "used for generating editor lexing files", - filename = "mult-prm", - loading = "never", - status = "okay", + ["category"]="lua", + ["filename"]="m-chart", + ["status"]="todo", }, { - category = "lua", - filename = "node-acc", - status = "todo", + ["category"]="lua", + ["filename"]="m-database", + ["status"]="okay", }, { - category = "lua", - filename = "node-aux", - status = "todo", + ["category"]="lua", + ["filename"]="m-nodechart", + ["status"]="okay", }, { - category = "lua", - filename = "node-bck", - status = "todo", + ["category"]="lua", + ["filename"]="m-markdown", + ["status"]="todo", }, { - category = "lua", - filename = "node-dir", - status = "todo", + ["category"]="lua", + ["filename"]="m-pstricks", + ["status"]="todo", }, { - category = "lua", - filename = "node-ext", - status = "todo", + ["category"]="lua", + ["filename"]="m-spreadsheet", + ["status"]="todo", }, { - category = "lua", - filename = "node-fin", - status = "todo", + ["category"]="lua", + ["filename"]="m-steps", + ["status"]="todo", }, { - category = "lua", - filename = "node-fnt", - loading = "font-lib", - status = "todo", + ["category"]="lua", + ["filename"]="math-act", + ["loading"]="math-ini", + ["status"]="okay", }, { - category = "lua", - filename = "node-ini", - status = "todo", + ["category"]="lua", + ["filename"]="math-frc", + ["loading"]="math-frc", + ["status"]="okay", }, { - category = "lua", - filename = "node-inj", - loading = "font-lib", - status = "todo", + ["category"]="lua", + ["comment"]="could be made look nicer, but who cares", + ["filename"]="math-dim", + ["loading"]="math-ini", + ["status"]="okay", }, { - category = "lua", - filename = "node-mig", - status = "todo", + ["category"]="lua", + ["comment"]="the code is related to math-vfu", + ["filename"]="math-ext", + ["loading"]="math-ini", + ["status"]="okay", }, { - category = "lua", - filename = "node-pag", - status = "todo", + ["category"]="lua", + ["filename"]="math-fbk", + ["loading"]="math-ini", + ["status"]="okay", }, { - category = "lua", - filename = "node-ppt", - status = "todo", + ["category"]="lua", + ["filename"]="math-frc", + ["loading"]="math-frc", + ["status"]="okay", }, { - category = "lua", - filename = "node-pro", - status = "todo", + ["category"]="lua", + ["comment"]="okay, but we might have a few more low level definers some day", + ["filename"]="math-ini", + ["loading"]="math-ini", + ["status"]="pending", }, { - category = "lua", - filename = "node-ref", - status = "todo", + ["category"]="lua", + ["filename"]="math-map", + ["loading"]="math-ini", + ["status"]="okay", }, { - category = "lua", - filename = "node-res", - status = "todo", + ["category"]="lua", + ["filename"]="math-noa", + ["loading"]="math-ini", + ["status"]="okay", }, { - category = "lua", - filename = "node-rul", - status = "todo", + ["category"]="lua", + ["filename"]="math-ren", + ["loading"]="math-ini", + ["status"]="okay", }, { - category = "lua", - filename = "node-ser", - status = "todo", + ["category"]="lua", + ["filename"]="math-tag", + ["loading"]="math-ini", + ["status"]="okay", }, { - category = "lua", - filename = "node-shp", - status = "todo", + ["category"]="lua", + ["filename"]="math-ttv", + ["loading"]="math-ini", + ["status"]="okay", }, { - category = "lua", - filename = "node-tex", - status = "todo", + ["category"]="lua", + ["filename"]="math-vfu", + ["loading"]="math-ini", + ["status"]="okay", }, { - category = "lua", - filename = "node-tra", - status = "todo", + ["category"]="lua", + ["comment"]="this is just a first version", + ["filename"]="meta-fun", + ["loading"]="meta-fun", + ["status"]="okay", }, { - category = "lua", - filename = "node-snp", - status = "todo", + ["category"]="lua", + ["filename"]="meta-ini", + ["loading"]="meta-ini", + ["status"]="okay", }, { - category = "lua", - filename = "node-tsk", - status = "todo", + ["category"]="lua", + ["filename"]="meta-lua", + ["loading"]="meta-lua", + ["status"]="okay", }, { - category = "lua", - filename = "node-tst", - status = "todo", + ["category"]="lua", + ["filename"]="meta-fnt", + ["loading"]="meta-fnt", + ["status"]="okay", }, { - category = "lua", - filename = "node-typ", - status = "todo", + ["category"]="lua", + ["comment"]="could be done nicer nowadays but who needs it", + ["filename"]="meta-pdf", + ["loading"]="meta-pdf", + ["status"]="okay", }, { - category = "lua", - comment = "will be extended when we have opened up pdf objects", - filename = "pack-obj", - loading = "pack-obj", - status = "okay", + ["category"]="lua", + ["comment"]="this is historic code that we keep around", + ["filename"]="meta-pdh", + ["loading"]="never", + ["status"]="okay", }, { - category = "lua", - filename = "pack-rul", - loading = "pack-rul", - status = "okay", + ["category"]="lua", + ["filename"]="meta-tex", + ["loading"]="meta-tex", + ["status"]="okay", }, { - category = "lua", - filename = "page-otr", - loading = "page-otr", - status = "okay", + ["category"]="lua", + ["filename"]="mlib-ctx", + ["loading"]="mlib-ctx", + ["status"]="okay", }, { - category = "lua", - filename = "page-flt", - status = "todo", + ["category"]="lua", + ["filename"]="mlib-pdf", + ["loading"]="mlib-pdf", + ["status"]="okay", }, { - category = "lua", - filename = "page-ins", - status = "todo", + ["category"]="lua", + ["filename"]="mlib-pps", + ["loading"]="mlib-pdf", + ["status"]="okay", }, { - category = "lua", - filename = "page-lin", - status = "todo", + ["category"]="lua", + ["filename"]="mlib-run", + ["loading"]="mlib-ctx", + ["status"]="okay", }, { - category = "lua", - filename = "page-mix", - status = "todo", + ["category"]="lua", + ["comment"]="this is an experiment, namespaces need to be dealt with properly", + ["filename"]="mult-aux", + ["loading"]="mult-aux", + ["status"]="pending", }, { - category = "lua", - filename = "page-pst", - status = "todo", + ["category"]="lua", + ["comment"]="this is an experiment", + ["filename"]="mult-chk", + ["loading"]="mult-chk", + ["status"]="pending", }, { - category = "lua", - filename = "page-str", - status = "todo", + ["category"]="lua", + ["filename"]="mult-def", + ["loading"]="mult-ini", + ["status"]="okay", }, { - category = "lua", - filename = "phys-dim", - loading = "phys-dim", - status = "okay", + ["category"]="lua", + ["comment"]="used for generating editor lexing files", + ["filename"]="mult-fun", + ["loading"]="never", + ["status"]="okay", }, { - category = "lua", - filename = "regi-8859-1", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="mult-ini", + ["loading"]="mult-ini", + ["status"]="okay", }, { - category = "lua", - filename = "regi-8859-10", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["comment"]="used for generating editor lexing files", + ["filename"]="mult-low", + ["loading"]="never", + ["status"]="okay", }, { - category = "lua", - filename = "regi-8859-11", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["comment"]="all messages need to be checked", + ["filename"]="mult-mes", + ["loading"]="mult-ini", + ["status"]="pending", }, { - category = "lua", - filename = "regi-8859-13", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["comment"]="used for generating editor lexing files", + ["filename"]="mult-mps", + ["loading"]="never", + ["status"]="okay", }, { - category = "lua", - filename = "regi-8859-14", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["comment"]="used for generating editor lexing files", + ["filename"]="mult-prm", + ["loading"]="never", + ["status"]="okay", }, { - category = "lua", - filename = "regi-8859-15", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-acc", + ["status"]="todo", }, { - category = "lua", - filename = "regi-8859-16", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-aux", + ["status"]="todo", }, { - category = "lua", - filename = "regi-8859-2", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-bck", + ["status"]="todo", }, { - category = "lua", - filename = "regi-8859-3", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-dir", + ["status"]="todo", }, { - category = "lua", - filename = "regi-8859-4", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-ext", + ["status"]="todo", }, { - category = "lua", - filename = "regi-8859-5", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-fin", + ["status"]="todo", }, { - category = "lua", - filename = "regi-8859-6", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-fnt", + ["loading"]="font-lib", + ["status"]="todo", }, { - category = "lua", - filename = "regi-8859-7", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-ini", + ["status"]="todo", }, { - category = "lua", - filename = "regi-8859-8", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-mig", + ["status"]="todo", }, { - category = "lua", - filename = "regi-8859-9", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-pag", + ["status"]="todo", }, { - category = "lua", - filename = "regi-cp1250", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-ppt", + ["status"]="todo", }, { - category = "lua", - filename = "regi-cp1251", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-pro", + ["status"]="todo", }, { - category = "lua", - filename = "regi-cp1252", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-ref", + ["status"]="todo", }, { - category = "lua", - filename = "regi-cp1253", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-res", + ["status"]="todo", }, { - category = "lua", - filename = "regi-cp1254", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-rul", + ["status"]="todo", }, { - category = "lua", - filename = "regi-cp1255", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-ser", + ["status"]="todo", }, { - category = "lua", - filename = "regi-cp1256", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-shp", + ["status"]="todo", }, { - category = "lua", - filename = "regi-cp1257", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-tex", + ["status"]="todo", }, { - category = "lua", - filename = "regi-cp1258", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="node-tra", + ["status"]="todo", }, { - category = "lua", - comment = "just a demo file", - filename = "regi-demo", - loading = "never", - status = "okay", + ["category"]="lua", + ["filename"]="node-snp", + ["status"]="todo", }, { - category = "lua", - filename = "regi-ini", - loading = "regi-ini", - status = "okay", + ["category"]="lua", + ["filename"]="node-tsk", + ["status"]="todo", }, { - category = "lua", - filename = "s-fonts-coverage", - status = "okay", + ["category"]="lua", + ["filename"]="node-tst", + ["status"]="todo", }, { - category = "lua", - filename = "s-fonts-features", - status = "okay", + ["category"]="lua", + ["filename"]="node-typ", + ["status"]="todo", }, { - category = "lua", - filename = "s-fonts-missing", - status = "okay", + ["category"]="lua", + ["comment"]="will be extended when we have opened up pdf objects", + ["filename"]="pack-obj", + ["loading"]="pack-obj", + ["status"]="okay", }, { - category = "lua", - filename = "s-fonts-shapes", - status = "okay", + ["category"]="lua", + ["filename"]="pack-rul", + ["loading"]="pack-rul", + ["status"]="okay", }, { - category = "lua", - filename = "s-fonts-system", - status = "okay", + ["category"]="lua", + ["filename"]="page-otr", + ["loading"]="page-otr", + ["status"]="okay", }, { - category = "lua", - filename = "s-fonts-tables", - status = "okay", + ["category"]="lua", + ["filename"]="page-flt", + ["status"]="todo", }, { - category = "lua", - filename = "s-fonts-vectors", - status = "okay", + ["category"]="lua", + ["filename"]="page-ins", + ["status"]="todo", }, { - category = "lua", - filename = "s-languages-counters", - status = "okay", + ["category"]="lua", + ["filename"]="page-lin", + ["status"]="todo", }, { - category = "lua", - filename = "s-languages-frequencies", - status = "okay", + ["category"]="lua", + ["filename"]="page-mix", + ["status"]="todo", }, { - category = "lua", - filename = "s-languages-hyphenation", - status = "okay", + ["category"]="lua", + ["filename"]="page-pst", + ["status"]="todo", }, { - category = "lua", - filename = "s-languages-sorting", - status = "okay", + ["category"]="lua", + ["filename"]="page-str", + ["status"]="todo", }, { - category = "lua", - filename = "s-languages-system", - status = "okay", + ["category"]="lua", + ["filename"]="phys-dim", + ["loading"]="phys-dim", + ["status"]="okay", }, { - category = "lua", - filename = "s-math-characters", - status = "okay", + ["category"]="lua", + ["filename"]="regi-8859-1", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "s-math-coverage", - status = "okay", + ["category"]="lua", + ["filename"]="regi-8859-10", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "s-math-extensibles", - status = "okay", + ["category"]="lua", + ["filename"]="regi-8859-11", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "s-fonts-goodies", - status = "okay", + ["category"]="lua", + ["filename"]="regi-8859-13", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "s-math-parameters", - status = "okay", + ["category"]="lua", + ["filename"]="regi-8859-14", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "s-physics-units", - status = "okay", + ["category"]="lua", + ["filename"]="regi-8859-15", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "s-pre-71", - status = "todo", + ["category"]="lua", + ["filename"]="regi-8859-16", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "s-sql-tables", - status = "okay", + ["category"]="lua", + ["filename"]="regi-8859-2", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "scrn-but", - status = "todo", + ["category"]="lua", + ["filename"]="regi-8859-3", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "scrn-fld", - status = "todo", + ["category"]="lua", + ["filename"]="regi-8859-4", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "scrn-hlp", - status = "todo", + ["category"]="lua", + ["filename"]="regi-8859-5", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "scrn-ini", - status = "todo", + ["category"]="lua", + ["filename"]="regi-8859-6", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "scrn-pag", - status = "todo", + ["category"]="lua", + ["filename"]="regi-8859-7", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "scrn-ref", - status = "todo", + ["category"]="lua", + ["filename"]="regi-8859-8", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "scrn-wid", - status = "todo", + ["category"]="lua", + ["filename"]="regi-8859-9", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - comment = "we can speed this up", - filename = "scrp-cjk", - loading = "scrp-ini", - status = "okay", + ["category"]="lua", + ["filename"]="regi-cp1250", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - comment = "we can speed this up", - filename = "scrp-eth", - loading = "scrp-ini", - status = "okay", + ["category"]="lua", + ["filename"]="regi-cp1251", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "scrp-ini", - loading = "scrp-ini", - status = "okay", + ["category"]="lua", + ["filename"]="regi-cp1252", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "sort-ini", - status = "todo", + ["category"]="lua", + ["filename"]="regi-cp1253", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "sort-lan", - status = "todo", + ["category"]="lua", + ["filename"]="regi-cp1254", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "spac-adj", - status = "todo", + ["category"]="lua", + ["filename"]="regi-cp1255", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "spac-ali", - status = "todo", + ["category"]="lua", + ["filename"]="regi-cp1256", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "spac-chr", - status = "todo", + ["category"]="lua", + ["filename"]="regi-cp1257", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "spac-hor", - status = "todo", + ["category"]="lua", + ["filename"]="regi-cp1258", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "spac-ver", - status = "todo", + ["category"]="lua", + ["comment"]="just a demo file", + ["filename"]="regi-demo", + ["loading"]="never", + ["status"]="okay", }, { - category = "lua", - filename = "status-mkiv", - status = "todo", + ["category"]="lua", + ["filename"]="regi-ini", + ["loading"]="regi-ini", + ["status"]="okay", }, { - category = "lua", - filename = "strc-bkm", - status = "todo", + ["category"]="lua", + ["filename"]="s-fonts-coverage", + ["status"]="okay", }, { - category = "lua", - filename = "strc-blk", - status = "todo", + ["category"]="lua", + ["filename"]="s-fonts-features", + ["status"]="okay", }, { - category = "lua", - filename = "strc-con", - status = "todo", + ["category"]="lua", + ["filename"]="s-fonts-missing", + ["status"]="okay", }, { - category = "lua", - filename = "strc-doc", - status = "todo", + ["category"]="lua", + ["filename"]="s-fonts-shapes", + ["status"]="okay", }, { - category = "lua", - filename = "strc-flt", - status = "todo", + ["category"]="lua", + ["filename"]="s-fonts-system", + ["status"]="okay", }, { - category = "lua", - filename = "strc-ini", - status = "todo", + ["category"]="lua", + ["filename"]="s-fonts-tables", + ["status"]="okay", }, { - category = "lua", - filename = "strc-itm", - status = "todo", + ["category"]="lua", + ["filename"]="s-fonts-vectors", + ["status"]="okay", }, { - category = "lua", - filename = "strc-lev", - status = "todo", + ["category"]="lua", + ["filename"]="s-languages-counters", + ["status"]="okay", }, { - category = "lua", - filename = "strc-lst", - status = "todo", + ["category"]="lua", + ["filename"]="s-languages-frequencies", + ["status"]="okay", }, { - category = "lua", - filename = "strc-mar", - status = "todo", + ["category"]="lua", + ["filename"]="s-languages-hyphenation", + ["status"]="okay", }, { - category = "lua", - filename = "strc-mat", - status = "todo", + ["category"]="lua", + ["filename"]="s-languages-sorting", + ["status"]="okay", }, { - category = "lua", - filename = "strc-not", - status = "todo", + ["category"]="lua", + ["filename"]="s-languages-system", + ["status"]="okay", }, { - category = "lua", - filename = "strc-num", - status = "todo", + ["category"]="lua", + ["filename"]="s-math-characters", + ["status"]="okay", }, { - category = "lua", - filename = "strc-pag", - status = "todo", + ["category"]="lua", + ["filename"]="s-math-coverage", + ["status"]="okay", }, { - category = "lua", - filename = "strc-ref", - status = "todo", + ["category"]="lua", + ["filename"]="s-fonts-goodies", + ["status"]="okay", }, { - category = "lua", - filename = "strc-reg", - status = "todo", + ["category"]="lua", + ["filename"]="s-math-parameters", + ["status"]="okay", }, { - category = "lua", - filename = "strc-rsc", - status = "todo", + ["category"]="lua", + ["filename"]="s-pre-71", + ["status"]="todo", }, { - category = "lua", - filename = "strc-syn", - status = "todo", + ["category"]="lua", + ["filename"]="s-sql-tables", + ["status"]="okay", }, { - category = "lua", - filename = "strc-tag", - status = "todo", + ["category"]="lua", + ["filename"]="scrn-but", + ["status"]="todo", }, { - category = "lua", - filename = "supp-box", - loading = "supp-box", - status = "okay", + ["category"]="lua", + ["filename"]="scrn-fld", + ["status"]="todo", }, { - category = "lua", - filename = "supp-ran", - loading = "supp-ran", - status = "okay", + ["category"]="lua", + ["filename"]="scrn-hlp", + ["status"]="todo", }, { - category = "lua", - filename = "symb-ini", - loading = "symb-ini", - status = "okay", + ["category"]="lua", + ["filename"]="scrn-ini", + ["status"]="todo", }, { - category = "lua", - comment = "there will be more in here", - filename = "syst-aux", - loading = "syst-aux", - status = "okay", + ["category"]="lua", + ["filename"]="scrn-pag", + ["status"]="todo", }, { - category = "lua", - comment = "do some tests with speedups (sprint)", - filename = "syst-con", - loading = "syst-con", - status = "pending", + ["category"]="lua", + ["filename"]="scrn-ref", + ["status"]="todo", }, { - category = "lua", - comment = "do some tests with speedups (less tokens)", - filename = "syst-lua", - loading = "syst-lua", - status = "pending", + ["category"]="lua", + ["filename"]="scrn-wid", + ["status"]="todo", }, { - category = "lua", - filename = "tabl-tbl", - loading = "tabl-tbl", - status = "okay", + ["category"]="lua", + ["comment"]="we can speed this up", + ["filename"]="scrp-cjk", + ["loading"]="scrp-ini", + ["status"]="okay", }, { - category = "lua", - comment = "work in progress", - filename = "tabl-xtb", - loading = "tabl-xtb", - status = "okay", + ["category"]="lua", + ["comment"]="we can speed this up", + ["filename"]="scrp-eth", + ["loading"]="scrp-ini", + ["status"]="okay", }, { - category = "lua", - comment = "we need a well defined defintion moment", - filename = "task-ini", - loading = "task-ini", - status = "pending", + ["category"]="lua", + ["filename"]="scrp-ini", + ["loading"]="scrp-ini", + ["status"]="okay", }, { - category = "lua", - filename = "toks-ini", - loading = "toks-ini", - status = "okay", + ["category"]="lua", + ["filename"]="sort-ini", + ["status"]="todo", }, { - category = "lua", - filename = "toks-scn", - loading = "toks-ini", - status = "okay", + ["category"]="lua", + ["filename"]="sort-lan", + ["status"]="todo", }, { - category = "lua", - comment = "must be applied in more places", - filename = "trac-ctx", - loading = "trac-ctx", - status = "okay", + ["category"]="lua", + ["filename"]="spac-adj", + ["status"]="todo", }, { - category = "lua", - filename = "trac-deb", - loading = "trac-deb", - status = "okay", + ["category"]="lua", + ["filename"]="spac-ali", + ["status"]="todo", }, { - category = "lua", - comment = "for the moment somewhat private", - filename = "trac-fil", - loading = "never", - status = "okay", + ["category"]="lua", + ["filename"]="spac-chr", + ["status"]="todo", }, { - category = "lua", - filename = "trac-inf", - loading = "luat-lib", - status = "okay", + ["category"]="lua", + ["filename"]="spac-hor", + ["status"]="todo", }, { - category = "lua", - comment = "will be redone and extended", - filename = "trac-lmx", - loading = "luat-lib", - status = "pending", + ["category"]="lua", + ["filename"]="spac-ver", + ["status"]="todo", }, { - category = "lua", - filename = "trac-log", - loading = "luat-lib", - status = "okay", + ["category"]="lua", + ["filename"]="status-mkiv", + ["status"]="todo", }, { - category = "lua", - filename = "trac-xml", - loading = "mtxrun", - status = "okay", + ["category"]="lua", + ["filename"]="strc-bkm", + ["status"]="todo", }, { - category = "lua", - filename = "trac-exp", - loading = "mtxrun", - status = "okay", + ["category"]="lua", + ["filename"]="strc-blk", + ["status"]="todo", }, { - category = "lua", - comment = "experimental code, will be redone when lua 5.2", - filename = "trac-pro", - loading = "luat-lib", - status = "pending", + ["category"]="lua", + ["filename"]="strc-con", + ["status"]="todo", }, { - category = "lua", - comment = "some code can better be in util-set", - filename = "trac-set", - loading = "luat-lib", - status = "pending", + ["category"]="lua", + ["filename"]="strc-doc", + ["status"]="todo", }, { - category = "lua", - filename = "trac-tex", - loading = "trac-tex", - status = "okay", + ["category"]="lua", + ["filename"]="strc-flt", + ["status"]="todo", }, { - category = "lua", - filename = "trac-tim", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="strc-ini", + ["status"]="todo", }, { - category = "lua", - filename = "trac-vis", - loading = "trac-vis", - status = "okay", + ["category"]="lua", + ["filename"]="strc-itm", + ["status"]="todo", }, { - category = "lua", - filename = "trac-jus", - loading = "trac-jus", - status = "okay", + ["category"]="lua", + ["filename"]="strc-lev", + ["status"]="todo", }, { - category = "lua", - filename = "type-ini", - loading = "type-ini", - status = "okay", + ["category"]="lua", + ["filename"]="strc-lst", + ["status"]="todo", }, { - category = "lua", - filename = "typo-bld", - status = "todo", + ["category"]="lua", + ["filename"]="strc-mar", + ["status"]="todo", }, { - category = "lua", - filename = "typo-sus", - status = "okay", + ["category"]="lua", + ["filename"]="strc-mat", + ["status"]="todo", }, { - category = "lua", - filename = "typo-brk", - status = "todo", + ["category"]="lua", + ["filename"]="strc-not", + ["status"]="todo", }, { - category = "lua", - filename = "typo-cap", - status = "todo", + ["category"]="lua", + ["filename"]="strc-num", + ["status"]="todo", }, { - category = "lua", - filename = "typo-cln", - status = "todo", + ["category"]="lua", + ["filename"]="strc-pag", + ["status"]="todo", }, { - category = "lua", - filename = "typo-dig", - status = "todo", + ["category"]="lua", + ["filename"]="strc-ref", + ["status"]="todo", }, { - category = "lua", - filename = "typo-dir", - loading = "typo-dir", - status = "okay", + ["category"]="lua", + ["filename"]="strc-reg", + ["status"]="todo", }, { - category = "lua", - comment = "work in progress", - filename = "typo-dha", - loading = "typo-dir", - status = "todo", + ["category"]="lua", + ["filename"]="strc-rsc", + ["status"]="todo", }, { - category = "lua", - filename = "typo-dua", - loading = "typo-dir", - status = "okay", + ["category"]="lua", + ["filename"]="strc-syn", + ["status"]="todo", }, { - category = "lua", - comment = "work in progress", - filename = "typo-dub", - loading = "typo-dir", - status = "okay", + ["category"]="lua", + ["filename"]="strc-tag", + ["status"]="todo", }, { - category = "lua", - filename = "typo-ini", - status = "todo", + ["category"]="lua", + ["filename"]="supp-box", + ["loading"]="supp-box", + ["status"]="okay", }, { - category = "mkiv", - filename = "typo-tal", - loading = "typo-tal", - status = "okay", + ["category"]="lua", + ["filename"]="supp-ran", + ["loading"]="supp-ran", + ["status"]="okay", }, { - category = "lua", - filename = "typo-itc", - status = "todo", + ["category"]="lua", + ["filename"]="symb-ini", + ["loading"]="symb-ini", + ["status"]="okay", }, { - category = "lua", - filename = "typo-krn", - status = "todo", + ["category"]="lua", + ["comment"]="there will be more in here", + ["filename"]="syst-aux", + ["loading"]="syst-aux", + ["status"]="okay", }, { - category = "lua", - filename = "typo-mar", - status = "todo", + ["category"]="lua", + ["comment"]="do some tests with speedups (sprint)", + ["filename"]="syst-con", + ["loading"]="syst-con", + ["status"]="pending", }, { - category = "lua", - filename = "typo-pag", - status = "todo", + ["category"]="lua", + ["comment"]="do some tests with speedups (less tokens)", + ["filename"]="syst-lua", + ["loading"]="syst-lua", + ["status"]="pending", }, { - category = "lua", - filename = "typo-drp", - status = "okay", + ["category"]="lua", + ["filename"]="tabl-tbl", + ["loading"]="tabl-tbl", + ["status"]="okay", }, { - category = "lua", - filename = "typo-fln", - status = "okay", + ["category"]="lua", + ["comment"]="work in progress", + ["filename"]="tabl-xtb", + ["loading"]="tabl-xtb", + ["status"]="okay", }, { - category = "lua", - filename = "typo-man", - status = "todo", + ["category"]="lua", + ["comment"]="we need a well defined defintion moment", + ["filename"]="task-ini", + ["loading"]="task-ini", + ["status"]="pending", }, { - category = "lua", - filename = "typo-prc", - status = "todo", + ["category"]="lua", + ["filename"]="toks-ini", + ["loading"]="toks-ini", + ["status"]="okay", }, { - category = "lua", - filename = "typo-lan", - status = "okay", + ["category"]="lua", + ["filename"]="toks-scn", + ["loading"]="toks-ini", + ["status"]="okay", }, { - category = "lua", - filename = "typo-rep", - status = "todo", + ["category"]="lua", + ["comment"]="must be applied in more places", + ["filename"]="trac-ctx", + ["loading"]="trac-ctx", + ["status"]="okay", }, { - category = "lua", - filename = "typo-spa", - status = "todo", + ["category"]="lua", + ["filename"]="trac-deb", + ["loading"]="trac-deb", + ["status"]="okay", }, { - category = "lua", - filename = "unic-ini", - loading = "unic-ini", - status = "okay", + ["category"]="lua", + ["comment"]="for the moment somewhat private", + ["filename"]="trac-fil", + ["loading"]="never", + ["status"]="okay", }, { - category = "lua", - filename = "util-deb", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="trac-inf", + ["loading"]="luat-lib", + ["status"]="okay", }, { - category = "lua", - filename = "util-dim", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["comment"]="will be redone and extended", + ["filename"]="trac-lmx", + ["loading"]="luat-lib", + ["status"]="pending", }, { - category = "lua", - filename = "util-fmt", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="trac-log", + ["loading"]="luat-lib", + ["status"]="okay", }, { - category = "lua", - filename = "util-jsn", - loading = "m-json", - status = "todo", + ["category"]="lua", + ["filename"]="trac-xml", + ["loading"]="mtxrun", + ["status"]="okay", }, { - category = "lua", - filename = "util-lua", - loading = "luat-lib", - status = "okay", + ["category"]="lua", + ["filename"]="trac-exp", + ["loading"]="mtxrun", + ["status"]="okay", }, { - category = "lua", - filename = "util-lib", - loading = "luat-lib", - status = "okay", + ["category"]="lua", + ["comment"]="experimental code, will be redone when lua 5.2", + ["filename"]="trac-pro", + ["loading"]="luat-lib", + ["status"]="pending", }, { - category = "lua", - filename = "util-mrg", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["comment"]="some code can better be in util-set", + ["filename"]="trac-set", + ["loading"]="luat-lib", + ["status"]="pending", }, { - category = "lua", - filename = "util-pck", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="trac-tex", + ["loading"]="trac-tex", + ["status"]="okay", }, { - category = "lua", - filename = "util-prs", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="trac-tim", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lua", - filename = "util-seq", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="trac-vis", + ["loading"]="trac-vis", + ["status"]="okay", }, { - category = "lua", - filename = "util-sql", - loading = "m-sql", - status = "todo", + ["category"]="lua", + ["filename"]="trac-jus", + ["loading"]="trac-jus", + ["status"]="okay", }, { - category = "lua", - filename = "util-sta", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="type-ini", + ["loading"]="type-ini", + ["status"]="okay", }, { - category = "lua", - filename = "util-sto", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="typo-bld", + ["status"]="todo", }, { - category = "lua", - filename = "util-str", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="typo-sus", + ["status"]="okay", }, { - category = "lua", - filename = "util-tab", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="typo-brk", + ["status"]="todo", }, { - category = "lua", - filename = "util-tpl", - loading = "luat-lib", - status = "todo", + ["category"]="lua", + ["filename"]="typo-cap", + ["status"]="todo", }, { - category = "lua", - filename = "x-asciimath", - status = "todo", + ["category"]="lua", + ["filename"]="typo-cln", + ["status"]="todo", }, { - category = "lua", - filename = "x-calcmath", - status = "todo", + ["category"]="lua", + ["filename"]="typo-dig", + ["status"]="todo", }, { - category = "lua", - filename = "x-cals", - status = "todo", + ["category"]="lua", + ["filename"]="typo-dir", + ["loading"]="typo-dir", + ["status"]="okay", }, { - category = "lua", - filename = "x-chemml", - status = "todo", + ["category"]="lua", + ["comment"]="work in progress", + ["filename"]="typo-dha", + ["loading"]="typo-dir", + ["status"]="todo", }, { - category = "lua", - filename = "x-ct", - status = "todo", + ["category"]="lua", + ["filename"]="typo-dua", + ["loading"]="typo-dir", + ["status"]="okay", }, { - category = "lua", - filename = "x-ldx", - status = "todo", + ["category"]="lua", + ["comment"]="work in progress", + ["filename"]="typo-dub", + ["loading"]="typo-dir", + ["status"]="okay", }, { - category = "lua", - filename = "x-mathml", - status = "todo", + ["category"]="lua", + ["filename"]="typo-ini", + ["status"]="todo", }, { - category = "lua", - filename = "publ-ini", - loading = "publ-ini.mkiv", - status = "pending", + ["category"]="mkiv", + ["filename"]="typo-tal", + ["loading"]="typo-tal", + ["status"]="okay", }, { - category = "lua", - filename = "publ-aut", - loading = "publ-ini.mkiv", - status = "pending", + ["category"]="lua", + ["filename"]="typo-itc", + ["status"]="todo", }, { - category = "lua", - filename = "publ-dat", - loading = "publ-ini.mkiv", - status = "pending", + ["category"]="lua", + ["filename"]="typo-krn", + ["status"]="todo", }, { - category = "lua", - filename = "publ-oth", - loading = "publ-ini.mkiv", - status = "pending", + ["category"]="lua", + ["filename"]="typo-mar", + ["status"]="todo", }, { - category = "lua", - filename = "publ-fnd", - loading = "publ-ini.mkiv", - status = "pending", + ["category"]="lua", + ["filename"]="typo-pag", + ["status"]="todo", }, { - category = "lua", - filename = "publ-tra", - loading = "publ-ini.mkiv", - status = "pending", + ["category"]="lua", + ["filename"]="typo-drp", + ["status"]="okay", }, { - category = "lua", - filename = "publ-usr", - loading = "publ-ini.mkiv", - status = "pending", + ["category"]="lua", + ["filename"]="typo-fln", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="typo-man", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="typo-prc", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="typo-lan", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="typo-rep", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="typo-spa", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="unic-ini", + ["loading"]="unic-ini", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="util-deb", + ["loading"]="luat-lib", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="util-dim", + ["loading"]="luat-lib", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="util-fmt", + ["loading"]="luat-lib", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="util-jsn", + ["loading"]="m-json", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="util-lua", + ["loading"]="luat-lib", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="util-lib", + ["loading"]="luat-lib", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="util-mrg", + ["loading"]="luat-lib", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="util-pck", + ["loading"]="luat-lib", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="util-prs", + ["loading"]="luat-lib", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="util-seq", + ["loading"]="luat-lib", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="util-sql", + ["loading"]="m-sql", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="util-sta", + ["loading"]="luat-lib", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="util-sto", + ["loading"]="luat-lib", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="util-str", + ["loading"]="luat-lib", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="util-tab", + ["loading"]="luat-lib", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="util-tpl", + ["loading"]="luat-lib", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="x-asciimath", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="x-calcmath", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="x-cals", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="x-chemml", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="x-ct", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="x-ldx", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="x-mathml", + ["status"]="todo", + }, + { + ["category"]="lua", + ["filename"]="publ-ini", + ["loading"]="publ-ini.mkiv", + ["status"]="pending", + }, + { + ["category"]="lua", + ["filename"]="publ-aut", + ["loading"]="publ-ini.mkiv", + ["status"]="pending", + }, + { + ["category"]="lua", + ["filename"]="publ-dat", + ["loading"]="publ-ini.mkiv", + ["status"]="pending", + }, + { + ["category"]="lua", + ["filename"]="publ-oth", + ["loading"]="publ-ini.mkiv", + ["status"]="pending", + }, + { + ["category"]="lua", + ["filename"]="publ-fnd", + ["loading"]="publ-ini.mkiv", + ["status"]="pending", + }, + { + ["category"]="lua", + ["filename"]="publ-tra", + ["loading"]="publ-ini.mkiv", + ["status"]="pending", + }, + { + ["category"]="lua", + ["filename"]="publ-usr", + ["loading"]="publ-ini.mkiv", + ["status"]="pending", }, }, - metafun = { + ["main"]={ + { + ["category"]="mkiv", + ["filename"]="context", + ["loading"]="parent", + ["status"]="okay", + }, + { + ["category"]="lus", + ["comment"]="stub file for context", + ["filename"]="context", + ["loading"]="parent", + ["status"]="okay", + }, + { + ["category"]="tex", + ["filename"]="metatex", + ["loading"]="parent", + ["status"]="pending", + }, { - category = "mpiv", - filename = "mp-base", - loading = "always", - status = "okay", + ["category"]="lus", + ["comment"]="stub file for metatex", + ["filename"]="metatex", + ["loading"]="parent", + ["status"]="pending", }, { - category = "mpiv", - filename = "mp-tool", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="cont-cs", + ["loading"]="parent", + ["status"]="okay", }, { - category = "mpiv", - filename = "mp-mlib", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="cont-de", + ["loading"]="parent", + ["status"]="okay", }, { - category = "mpiv", - comment = "sort of obsolete", - filename = "mp-core", - status = "okay", + ["category"]="mkiv", + ["filename"]="cont-en", + ["loading"]="parent", + ["status"]="okay", }, { - category = "mpiv", - comment = "maybe some nicer synonyms", - filename = "mp-page", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="cont-fr", + ["loading"]="parent", + ["status"]="okay", }, { - category = "mpiv", - filename = "mp-butt", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="cont-gb", + ["loading"]="parent", + ["status"]="okay", }, { - category = "mpiv", - filename = "mp-shap", - loading = "always", - status = "okay", + ["category"]="mkiv", + ["filename"]="cont-it", + ["loading"]="parent", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="cont-nl", + ["loading"]="parent", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="cont-pe", + ["loading"]="parent", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="cont-ro", + ["loading"]="parent", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["comment"]="we keep this around for historic reasons", + ["filename"]="ppchtex", + ["loading"]="never", + ["status"]="okay", + }, + }, + ["metafun"]={ + { + ["category"]="mpiv", + ["comment"]="maybe more delayed loading", + ["filename"]="metafun", + ["loading"]="parent", + ["status"]="okay", }, { - category = "mpiv", - filename = "mp-grph", - loading = "always", - status = "okay", + ["category"]="mpiv", + ["filename"]="mp-base", + ["loading"]="always", + ["status"]="okay", }, { - category = "mpiv", - filename = "mp-grid", - loading = "always", - status = "okay", + ["category"]="mpiv", + ["filename"]="mp-tool", + ["loading"]="always", + ["status"]="okay", }, { - category = "mpiv", - comment = "a hack anyway", - filename = "mp-form", - loading = "always", - status = "okay", + ["category"]="mpiv", + ["filename"]="mp-mlib", + ["loading"]="always", + ["status"]="okay", }, { - category = "mpiv", - filename = "mp-figs", - loading = "always", - status = "okay", + ["category"]="mpiv", + ["comment"]="sort of obsolete", + ["filename"]="mp-core", + ["status"]="okay", }, { - category = "mpiv", - filename = "mp-func", - loading = "always", - status = "okay", + ["category"]="mpiv", + ["comment"]="maybe some nicer synonyms", + ["filename"]="mp-page", + ["loading"]="always", + ["status"]="okay", }, { - category = "mpiv", - filename = "mp-text", - loading = "on demand", - status = "todo", + ["category"]="mpiv", + ["filename"]="mp-butt", + ["loading"]="always", + ["status"]="okay", }, { - category = "mpiv", - filename = "mp-crop", - loading = "on demand", - status = "okay", + ["category"]="mpiv", + ["filename"]="mp-shap", + ["loading"]="always", + ["status"]="okay", }, { - category = "mpiv", - comment = "follows m-chart", - filename = "mp-char", - loading = "on demand", - status = "okay", + ["category"]="mpiv", + ["filename"]="mp-grph", + ["loading"]="always", + ["status"]="okay", }, { - category = "mpiv", - comment = "follows m-steps", - filename = "mp-step", - loading = "on demand", - status = "okay", + ["category"]="mpiv", + ["filename"]="mp-grid", + ["loading"]="always", + ["status"]="okay", }, { - category = "mpiv", - filename = "mp-chem", - loading = "on demand", - status = "okay", + ["category"]="mpiv", + ["comment"]="a hack anyway", + ["filename"]="mp-form", + ["loading"]="always", + ["status"]="okay", }, { - category = "mpiv", - comment = "maybe some namespace changes", - filename = "mp-abck", - loading = "on demand", - status = "okay", + ["category"]="mpiv", + ["filename"]="mp-figs", + ["loading"]="always", + ["status"]="okay", }, { - category = "mpiv", - comment = "maybe some namespace changes", - filename = "mp-apos", - loading = "on demand", - status = "okay", + ["category"]="mpiv", + ["filename"]="mp-func", + ["loading"]="always", + ["status"]="okay", }, { - category = "mpiv", - comment = "will be done when needed", - filename = "mp-asnc", - loading = "on demand", - status = "todo", + ["category"]="mpiv", + ["filename"]="mp-text", + ["loading"]="on demand", + ["status"]="todo", + }, + { + ["category"]="mpiv", + ["filename"]="mp-crop", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mpiv", + ["comment"]="follows m-chart", + ["filename"]="mp-char", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mpiv", + ["comment"]="follows m-steps", + ["filename"]="mp-step", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mpiv", + ["filename"]="mp-chem", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mpiv", + ["comment"]="maybe some namespace changes", + ["filename"]="mp-abck", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mpiv", + ["comment"]="maybe some namespace changes", + ["filename"]="mp-apos", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mpiv", + ["comment"]="will be done when needed", + ["filename"]="mp-asnc", + ["loading"]="on demand", + ["status"]="todo", + }, + { + ["category"]="mpiv", + ["filename"]="mp-back", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="mpiv", + ["filename"]="mp-bare", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="mpiv", + ["filename"]="mp-cows", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mpiv", + ["filename"]="mp-fobg", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mpiv", + ["filename"]="mp-grap", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="mpiv", + ["filename"]="mp-idea", + ["loading"]="on demand", + ["status"]="unknown", + }, + { + ["category"]="mpiv", + ["filename"]="mp-luas", + ["loading"]="always", + ["status"]="okay", + }, + { + ["category"]="mpiv", + ["filename"]="mp-symb", + ["loading"]="on demand", + ["status"]="okay", }, }, - modules = { + ["modules"]={ + { + ["category"]="mkiv", + ["comment"]="best use m-zint instead", + ["filename"]="m-barcodes", + ["loading"]="module", + ["status"]="okay", + }, + { + ["category"]="mkvi", + ["filename"]="m-chart", + ["loading"]="module", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["comment"]="this is a placeholder (chemistry is built-in)", + ["filename"]="m-chemic", + ["loading"]="never", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["filename"]="m-cweb", + ["status"]="todo", + }, + { + ["category"]="mkiv", + ["filename"]="m-database", + ["status"]="okay", + }, + { + ["category"]="mkvi", + ["filename"]="m-nodechart", + ["status"]="okay", + }, + { + ["category"]="mkiv", + ["comment"]="add-on for mtx-context", + ["filename"]="m-directives", + ["loading"]="on demand", + ["status"]="okay", + }, { - category = "mkiv", - comment = "best use m-zint instead", - filename = "m-barcodes", - loading = "module", - status = "okay", + ["category"]="mkiv", + ["filename"]="m-educat", + ["status"]="todo", }, { - category = "mkvi", - filename = "m-chart", - loading = "module", - status = "okay", + ["category"]="mkiv", + ["filename"]="m-fields", + ["status"]="todo", }, { - category = "mkiv", - comment = "this is a placeholder (chemistry is built-in)", - filename = "m-chemic", - loading = "never", - status = "okay", + ["category"]="mkiv", + ["filename"]="m-format", + ["status"]="todo", }, { - category = "tex", - filename = "m-cweb", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-graph", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-database", - status = "okay", + ["category"]="mkiv", + ["filename"]="m-ipsum", + ["loading"]="module", + ["status"]="okay", }, { - category = "mkiv", - filename = "m-nodechart", - status = "okay", + ["category"]="mkiv", + ["filename"]="m-json", + ["loading"]="module", + ["status"]="okay", }, { - category = "tex", - filename = "m-datastrc", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-layout", + ["status"]="todo", }, { - category = "mkiv", - comment = "add-on for mtx-context", - filename = "m-directives", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["comment"]="add-on for mtx-context", + ["filename"]="m-logcategories", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "tex", - filename = "m-educat", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-markdown", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-fields", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-mathcrap", + ["status"]="todo", }, { - category = "tex", - filename = "m-format", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-mkii", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-graph", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-mkivhacks", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-ipsum", - loading = "module", - status = "okay", + ["category"]="mkvi", + ["filename"]="m-morse", + ["loading"]="module", + ["status"]="okay", }, { - category = "mkiv", - filename = "m-json", - loading = "module", - status = "okay", + ["category"]="mkiv", + ["filename"]="m-narrowtt", + ["loading"]="module", + ["status"]="okay", }, { - category = "tex", - filename = "m-layout", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-ntb-to-xtb", + ["status"]="okay", }, { - category = "mkiv", - comment = "add-on for mtx-context", - filename = "m-logcategories", - loading = "on demand", - status = "okay", + ["category"]="mkiv", + ["filename"]="m-obsolete", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-markdown", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-oldfun", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-mathcrap", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-oldnum", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-mkii", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-pictex", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-mkivhacks", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-pstricks", + ["status"]="todo", }, { - category = "mkvi", - filename = "m-morse", - loading = "module", - status = "okay", + ["category"]="mkiv", + ["comment"]="keep an eye on changes in lua code", + ["filename"]="m-punk", + ["status"]="okay", }, { - category = "tex", - filename = "m-narrowtt", - loading = "module", - status = "okay", + ["category"]="mkiv", + ["filename"]="m-spreadsheet", + ["status"]="okay", }, { - category = "tex", - filename = "m-newmat", - status = "todo", + ["category"]="mkvi", + ["filename"]="m-steps", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-ntb-to-xtb", - status = "okay", + ["category"]="mkiv", + ["filename"]="m-subsub", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-obsolete", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-sql", + ["loading"]="module", + ["status"]="okay", }, { - category = "mkiv", - filename = "m-oldfun", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-timing", + ["status"]="okay", }, { - category = "mkiv", - filename = "m-oldnum", - status = "todo", + ["category"]="mkiv", + ["comment"]="add-on for mtx-context", + ["filename"]="m-trackers", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "tex", - filename = "m-pictex", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-translate", + ["status"]="okay", }, { - category = "mkiv", - filename = "m-pstricks", - status = "todo", + ["category"]="xsd", + ["filename"]="x-chemml", + ["status"]="todo", }, { - category = "mkiv", - comment = "keep an eye on changes in lua code", - filename = "m-punk", - status = "okay", + ["category"]="xsd", + ["filename"]="x-contml", + ["status"]="todo", }, { - category = "tex", - filename = "m-r", - status = "todo", + ["category"]="rng", + ["filename"]="x-corres", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-spreadsheet", - status = "okay", + ["category"]="dtd", + ["filename"]="x-fig-00", + ["status"]="todo", }, { - category = "mkvi", - filename = "m-steps", - status = "todo", + ["category"]="xsd", + ["filename"]="x-fig-00", + ["status"]="todo", }, { - category = "tex", - filename = "m-streams", - status = "todo", + ["category"]="ctx", + ["filename"]="x-ldx", + ["status"]="todo", }, { - category = "tex", - filename = "m-subsub", - status = "todo", + ["category"]="xsd", + ["filename"]="x-mathml", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-sql", - loading = "module", - status = "okay", + ["category"]="xsl", + ["filename"]="x-om2cml", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-timing", - status = "okay", + ["category"]="xsl", + ["filename"]="x-openmath", + ["status"]="todo", }, { - category = "mkiv", - comment = "add-on for mtx-context", - filename = "m-trackers", - loading = "on demand", - status = "okay", + ["category"]="ctx", + ["comment"]="runner for x-pfs-01", + ["filename"]="x-pfsense", + ["status"]="okay", }, { - category = "mkiv", - filename = "m-translate", - status = "okay", + ["category"]="xsd", + ["filename"]="x-physml", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-units", - status = "todo", + ["category"]="xsl", + ["filename"]="x-sm2om", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-visual", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-units", + ["status"]="todo", }, { - category = "mkiv", - filename = "m-zint", - status = "okay", + ["category"]="mkiv", + ["filename"]="m-visual", + ["status"]="todo", }, { - category = "tex", - filename = "s-abr-01", - status = "todo", + ["category"]="mkiv", + ["filename"]="m-zint", + ["status"]="okay", }, { - category = "tex", - filename = "s-abr-02", - status = "todo", + ["category"]="tex", + ["filename"]="s-abr-01", + ["status"]="todo", }, { - category = "tex", - filename = "s-abr-03", - status = "todo", + ["category"]="tex", + ["filename"]="s-abr-02", + ["status"]="todo", }, { - category = "tex", - filename = "s-abr-04", - status = "todo", + ["category"]="tex", + ["filename"]="s-abr-03", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-art-01", - status = "todo", + ["category"]="tex", + ["filename"]="s-abr-04", + ["status"]="todo", }, { - category = "tex", - filename = "s-cdr-01", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-art-01", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-def-01", - status = "todo", + ["category"]="tex", + ["filename"]="s-cdr-01", + ["status"]="todo", }, { - category = "tex", - filename = "s-faq-00", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-def-01", + ["status"]="todo", }, { - category = "tex", - filename = "s-faq-01", - status = "todo", + ["category"]="tex", + ["filename"]="s-faq-00", + ["status"]="todo", }, { - category = "tex", - filename = "s-faq-02", - status = "todo", + ["category"]="tex", + ["filename"]="s-faq-01", + ["status"]="todo", }, { - category = "tex", - filename = "s-faq-03", - status = "todo", + ["category"]="tex", + ["filename"]="s-faq-02", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-fnt-10", - status = "todo", + ["category"]="tex", + ["filename"]="s-faq-03", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-fnt-20", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-fnt-10", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-fnt-21", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-fnt-20", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-fnt-24", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-fnt-21", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-fnt-30", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-fnt-24", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-fonts-coverage", - loading = "s-fonts-coverage", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-fonts-coverage", + ["loading"]="s-fonts-coverage", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-fonts-features", - loading = "s-fonts-features", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-fonts-features", + ["loading"]="s-fonts-features", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-fonts-goodies", - loading = "s-fonts-goodies", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-fonts-goodies", + ["loading"]="s-fonts-goodies", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-fonts-missing", - loading = "s-fonts-missing", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-fonts-missing", + ["loading"]="s-fonts-missing", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-fonts-shapes", - loading = "s-fonts-shapes", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-fonts-shapes", + ["loading"]="s-fonts-shapes", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-fonts-system", - loading = "s-fonts-system", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-fonts-system", + ["loading"]="s-fonts-system", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-fonts-tables", - loading = "s-fonts-tables", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-fonts-tables", + ["loading"]="s-fonts-tables", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-fonts-vectors", - loading = "s-fonts-vectors", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-fonts-vectors", + ["loading"]="s-fonts-vectors", + ["status"]="okay", }, { - category = "mkvi", - filename = "s-inf-01", - status = "okay", + ["category"]="mkvi", + ["filename"]="s-inf-01", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-inf-02", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-inf-02", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-inf-03", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-inf-03", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-inf-04", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-inf-04", + ["status"]="todo", }, { - category = "lua", - filename = "s-languages-counters", - loading = "s-languages-counters", - status = "okay", + ["category"]="lua", + ["filename"]="s-languages-counters", + ["loading"]="s-languages-counters", + ["status"]="okay", }, { - category = "lua", - filename = "s-languages-frequencies", - loading = "s-languages-frequencies", - status = "okay", + ["category"]="lua", + ["filename"]="s-languages-frequencies", + ["loading"]="s-languages-frequencies", + ["status"]="okay", }, { - category = "lua", - filename = "s-languages-hyphenation", - loading = "s-languages-hyphenation", - status = "okay", + ["category"]="lua", + ["filename"]="s-languages-hyphenation", + ["loading"]="s-languages-hyphenation", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-languages-sorting", - loading = "s-languages-sorting", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-languages-sorting", + ["loading"]="s-languages-sorting", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-languages-system", - loading = "s-languages-system", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-languages-system", + ["loading"]="s-languages-system", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-lan-03", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-mag-01", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-lan-04", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-map-10", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-lan-06", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-math-characters", + ["loading"]="s-math-characters", + ["status"]="okay", }, { - category = "tex", - filename = "s-mag-01", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-math-coverage", + ["loading"]="s-math-coverage", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-map-10", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-math-extensibles", + ["loading"]="s-math-extensibles", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-math-characters", - loading = "s-math-characters", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-math-parameters", + ["loading"]="s-math-parameters", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-math-coverage", - loading = "s-math-coverage", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-math-repertoire", + ["loading"]="s-math-repertoire", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-math-extensibles", - loading = "s-math-extensibles", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-mod-00", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-math-parameters", - loading = "s-math-parameters", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-mod-01", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-math-repertoire", - loading = "s-math-repertoire", - status = "okay", + ["category"]="mkiv", + ["filename"]="s-mod-02", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-mod-00", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-pages-statistics", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-mod-01", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-physics-units", + ["loading"]="s-physics-units", + ["status"]="okay", }, { - category = "mkiv", - filename = "s-mod-02", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-00", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-pages-statistics", - status = "okay", + ["category"]="tex", + ["filename"]="s-pre-01", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-physics-units", - loading = "s-physics-units", - status = "okay", + ["category"]="tex", + ["filename"]="s-pre-02", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-00", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-03", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-01", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-04", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-02", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-05", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-03", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-06", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-04", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-07", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-05", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-08", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-06", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-09", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-07", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-10", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-08", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-11", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-09", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-12", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-10", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-13", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-11", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-14", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-12", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-15", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-13", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-16", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-14", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-pre-17", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-15", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-18", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-16", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-19", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-17", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-22", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-18", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-23", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-19", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-26", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-22", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-27", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-23", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-pre-30", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-26", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-present-tiles", + ["status"]="okay", }, { - category = "tex", - filename = "s-pre-27", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-50", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-pre-30", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-pre-60", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-present-tiles", - status = "okay", + ["category"]="tex", + ["filename"]="s-pre-61", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-50", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-62", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-pre-60", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-63", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-61", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-64", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-62", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-66", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-63", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-67", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-64", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-68", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-66", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-pre-69", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-67", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-pre-70", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-68", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-pre-71", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-pre-69", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-93", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-pre-70", - status = "todo", + ["category"]="tex", + ["filename"]="s-pre-96", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-pre-71", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-reg-01", + ["status"]="todo", }, { - category = "tex", - filename = "s-pre-93", - status = "todo", + ["category"]="mkiv", + ["filename"]="s-sql-tables", + ["loading"]="s-sql-tables", + ["status"]="okay", }, { - category = "tex", - filename = "s-pre-96", - status = "todo", + ["category"]="mkiv", + ["filename"]="x-asciimath", + ["status"]="okay", }, { - category = "tex", - filename = "s-ptj-01", - status = "todo", + ["category"]="mkiv", + ["filename"]="x-calcmath", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-reg-01", - status = "todo", + ["category"]="mkiv", + ["filename"]="x-cals", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-set-31", - status = "todo", + ["category"]="mkiv", + ["filename"]="x-chemml", + ["status"]="todo", }, { - category = "tex", - filename = "s-syn-01", - status = "todo", + ["category"]="mkiv", + ["filename"]="x-ct", + ["status"]="todo", }, { - category = "mkiv", - filename = "s-sql-tables", - loading = "s-sql-tables", - status = "okay", + ["category"]="mkiv", + ["filename"]="x-entities", + ["status"]="okay", }, { - category = "mkiv", - filename = "x-asciimath", - status = "okay", + ["category"]="mkiv", + ["filename"]="x-foxet", + ["status"]="todo", }, { - category = "mkiv", - filename = "x-calcmath", - status = "todo", + ["category"]="mkiv", + ["filename"]="x-ldx", + ["status"]="todo", }, { - category = "mkiv", - filename = "x-cals", - status = "todo", + ["category"]="mkiv", + ["filename"]="x-mathml", + ["status"]="todo", }, { - category = "mkiv", - filename = "x-chemml", - status = "todo", + ["category"]="mkiv", + ["filename"]="x-newmml", + ["status"]="todo", }, { - category = "mkiv", - filename = "x-ct", - status = "todo", + ["category"]="mkiv", + ["comment"]="pfsense xml configuration rendering", + ["filename"]="x-pfs-01", + ["status"]="okay", }, { - category = "tex", - filename = "x-dir-01", - status = "todo", + ["category"]="mkiv", + ["filename"]="x-physml", + ["status"]="todo", }, { - category = "mkiv", - filename = "x-dir-05", - status = "todo", + ["category"]="mkiv", + ["filename"]="x-res-01", + ["status"]="todo", }, { - category = "mkiv", - filename = "x-entities", - status = "okay", + ["category"]="mkiv", + ["filename"]="x-res-50", + ["status"]="todo", }, { - category = "mkiv", - filename = "x-foxet", - status = "todo", + ["category"]="mkiv", + ["filename"]="x-udhr", + ["status"]="okay", }, + }, + ["optional"]={ { - category = "mkiv", - filename = "x-ldx", - status = "todo", + ["category"]="mkiv", + ["filename"]="bxml-apa", + ["status"]="todo", }, { - category = "mkiv", - filename = "x-mathml", - status = "todo", + ["category"]="mkiv", + ["filename"]="colo-run", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "x-newmml", - status = "todo", + ["category"]="mkiv", + ["comment"]="always needs some work", + ["filename"]="cont-new", + ["loading"]="runtime", + ["status"]="todo", }, { - category = "mkiv", - comment = "pfsense xml configuration rendering", - filename = "x-pfs-01", - status = "okay", + ["category"]="mkiv", + ["filename"]="font-run", + ["loading"]="on demand", + ["status"]="todo", }, { - category = "mkiv", - filename = "x-physml", - status = "todo", + ["category"]="mkiv", + ["comment"]="this is an experimental module", + ["filename"]="lxml-ctx", + ["status"]="okay", }, { - category = "mkiv", - filename = "x-res-01", - status = "todo", + ["category"]="mkiv", + ["comment"]="this is historic code that we keep around", + ["filename"]="meta-pdh", + ["loading"]="never", + ["status"]="okay", }, { - category = "mkiv", - filename = "x-res-50", - status = "todo", + ["category"]="mkiv", + ["comment"]="this is just a helper for generating files", + ["filename"]="mult-prm", + ["loading"]="never", + ["status"]="okay", }, { - category = "mkiv", - filename = "x-set-11", - status = "todo", + ["category"]="mkiv", + ["filename"]="page-run", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "x-set-12", - status = "todo", + ["category"]="mkiv", + ["filename"]="spac-adj", + ["loading"]="never", + ["status"]="obsolete", }, { - category = "mkiv", - filename = "x-udhr", - status = "okay", + ["category"]="mkiv", + ["comment"]="replaced by a more modern variant", + ["filename"]="supp-vis", + ["loading"]="never", + ["status"]="obsolete", }, { - category = "mkiv", - filename = "x-xtag", - status = "todo", + ["category"]="mkiv", + ["filename"]="symb-run", + ["loading"]="on demand", + ["status"]="okay", }, }, - optional = { + ["patterns"]={ { - category = "mkiv", - filename = "bxml-apa", - status = "todo", + ["category"]="lua", + ["filename"]="lang-af", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "colo-run", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="lang-agr", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - comment = "always needs some work", - filename = "cont-new", - loading = "runtime", - status = "todo", + ["category"]="lua", + ["filename"]="lang-ala", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "font-run", - loading = "on demand", - status = "todo", + ["category"]="lua", + ["filename"]="lang-bg", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "lxml-ctx", - status = "okay", - comment = "this is an experimental module", + ["category"]="lua", + ["filename"]="lang-ca", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "meta-pdh", - loading = "never", - status = "okay", - comment = "this is historic code that we keep around", + ["category"]="lua", + ["filename"]="lang-cs", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "mult-prm", - loading = "never", - status = "okay", - comment = "this is just a helper for generating files", + ["category"]="lua", + ["filename"]="lang-cy", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "page-run", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="lang-da", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "spac-adj", - loading = "never", - status = "obsolete", + ["category"]="lua", + ["filename"]="lang-de", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "supp-vis", - loading = "never", - status = "obsolete", - comment = "replaced by a more modern variant", + ["category"]="lua", + ["filename"]="lang-deo", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "symb-run", - loading = "on demand", - status = "okay", + ["category"]="lua", + ["filename"]="lang-es", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "mkiv", - filename = "type-run", - loading = "on demand", - status = "todo", + ["category"]="lua", + ["filename"]="lang-et", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-eu", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-fi", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-fr", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-gb", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-hr", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-hu", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-is", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-it", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-la", + ["loading"]="on demand", + ["status"]="okay", + }, + { + ["category"]="lua", + ["filename"]="lang-lt", + ["loading"]="on demand", + ["status"]="okay", }, - }, - resources = { { - category = "ori", - comment = "template for a user configuration file (with suffix mkiv)", - filename = "cont-sys", - loading = "runtime", - status = "okay", + ["category"]="lua", + ["filename"]="lang-lv", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lmx", - filename = "context-base", - status = "todo", + ["category"]="lua", + ["filename"]="lang-ml", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lmx", - filename = "context-characters", - status = "todo", + ["category"]="lua", + ["filename"]="lang-mn", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lmx", - filename = "context-debug", - status = "todo", + ["category"]="lua", + ["filename"]="lang-nb", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lmx", - filename = "context-error", - status = "todo", + ["category"]="lua", + ["filename"]="lang-nl", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lmx", - filename = "context-fonttest", - status = "todo", + ["category"]="lua", + ["filename"]="lang-nn", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lmx", - filename = "context-help", - status = "todo", + ["category"]="lua", + ["filename"]="lang-pl", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "lmx", - filename = "context-timing", - status = "todo", + ["category"]="lua", + ["filename"]="lang-pt", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "pdf", - filename = "context-version", - status = "todo", + ["category"]="lua", + ["filename"]="lang-ro", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "png", - filename = "context-version", - status = "todo", + ["category"]="lua", + ["filename"]="lang-ru", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "css", - comment = "layout specification for debug and error pages and web services", - filename = "context", - status = "okay", + ["category"]="lua", + ["filename"]="lang-sk", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "rme", - comment = "readme file", - filename = "context", - status = "okay", + ["category"]="lua", + ["filename"]="lang-sl", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "ctx", - comment = "example of a ctx file (for mtx-context)", - filename = "core-ctx", - status = "okay", + ["category"]="lua", + ["filename"]="lang-sr", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "css", - filename = "export-example", - status = "todo", + ["category"]="lua", + ["filename"]="lang-sv", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "rng", - filename = "export-example", - status = "todo", + ["category"]="lua", + ["filename"]="lang-th", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "tex", - filename = "export-example", - status = "todo", + ["category"]="lua", + ["filename"]="lang-tk", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "xml", - comment = "this file is auto-generated by mtx-language", - filename = "lang-all", - status = "okay", + ["category"]="lua", + ["filename"]="lang-tr", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "xml", - filename = "lpdf-pda", - status = "todo", + ["category"]="lua", + ["filename"]="lang-uk", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "xml", - filename = "lpdf-pdx", - status = "todo", + ["category"]="lua", + ["filename"]="lang-us", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "rlx", - filename = "rlxcache", - status = "todo", + ["category"]="lua", + ["filename"]="lang-zh", + ["loading"]="on demand", + ["status"]="okay", }, { - category = "rlx", - filename = "rlxtools", - status = "todo", + ["category"]="lua", + ["filename"]="word-xx", + ["loading"]="on demand", + ["status"]="okay", + }, + }, + ["resources"]={ + { + ["category"]="ori", + ["comment"]="template for a user configuration file (with suffix mkiv)", + ["filename"]="cont-sys", + ["loading"]="runtime", + ["status"]="okay", + }, + { + ["category"]="lmx", + ["filename"]="context-base", + ["status"]="todo", + }, + { + ["category"]="lmx", + ["filename"]="context-characters", + ["status"]="todo", + }, + { + ["category"]="lmx", + ["filename"]="context-debug", + ["status"]="todo", + }, + { + ["category"]="lmx", + ["filename"]="context-error", + ["status"]="todo", }, { - category = "ctx", - filename = "s-mod", - status = "todo", + ["category"]="lmx", + ["filename"]="context-fonttest", + ["status"]="todo", }, { - category = "pdf", - filename = "status-files", - status = "todo", + ["category"]="lmx", + ["filename"]="context-help", + ["status"]="todo", }, { - category = "pdf", - filename = "status-lua", - status = "todo", + ["category"]="lmx", + ["filename"]="context-timing", + ["status"]="todo", }, { - category = "tex", - filename = "status-mkiv", - status = "todo", + ["category"]="pdf", + ["filename"]="context-version", + ["status"]="todo", }, { - category = "xsd", - filename = "x-chemml", - status = "todo", + ["category"]="png", + ["filename"]="context-version", + ["status"]="todo", }, { - category = "xsd", - filename = "x-contml", - status = "todo", + ["category"]="css", + ["comment"]="layout specification for debug and error pages and web services", + ["filename"]="context", + ["status"]="okay", }, { - category = "rng", - filename = "x-corres", - status = "todo", + ["category"]="rme", + ["comment"]="readme file", + ["filename"]="context", + ["status"]="okay", }, { - category = "dtd", - filename = "x-fig-00", - status = "todo", + ["category"]="ctx", + ["comment"]="example of a ctx file (for mtx-context)", + ["filename"]="core-ctx", + ["status"]="okay", }, { - category = "xsd", - filename = "x-fig-00", - status = "todo", + ["category"]="css", + ["filename"]="export-example", + ["status"]="todo", }, { - category = "ctx", - filename = "x-ldx", - status = "todo", + ["category"]="rng", + ["filename"]="export-example", + ["status"]="todo", }, { - category = "xsd", - filename = "x-mathml", - status = "todo", + ["category"]="tex", + ["filename"]="export-example", + ["status"]="todo", }, { - category = "xsl", - filename = "x-om2cml", - status = "todo", + ["category"]="xml", + ["comment"]="this file is auto-generated by mtx-language", + ["filename"]="lang-all", + ["status"]="okay", }, { - category = "xsl", - filename = "x-openmath", - status = "todo", + ["category"]="xml", + ["filename"]="lpdf-pda", + ["status"]="todo", }, { - category = "ctx", - comment = "runner for x-pfs-01", - filename = "x-pfsense", - status = "okay", + ["category"]="xml", + ["filename"]="lpdf-pdx", + ["status"]="todo", }, { - category = "xsd", - filename = "x-physml", - status = "todo", + ["category"]="rlx", + ["filename"]="rlxcache", + ["status"]="todo", }, { - category = "xsl", - filename = "x-sm2om", - status = "todo", + ["category"]="rlx", + ["filename"]="rlxtools", + ["status"]="todo", + }, + { + ["category"]="ctx", + ["filename"]="s-mod", + ["status"]="todo", + }, + { + ["category"]="pdf", + ["filename"]="status-files", + ["status"]="todo", + }, + { + ["category"]="pdf", + ["filename"]="status-lua", + ["status"]="todo", + }, + { + ["category"]="tex", + ["filename"]="status-mkiv", + ["status"]="todo", + }, + }, + ["todo"]={ + { + ["category"]="lua", + ["filename"]="core-run", + ["status"]="idea", }, }, } diff --git a/tex/context/base/mkiv/strc-bkm.lua b/tex/context/base/mkiv/strc-bkm.lua index a055a97a1..e30a91820 100644 --- a/tex/context/base/mkiv/strc-bkm.lua +++ b/tex/context/base/mkiv/strc-bkm.lua @@ -18,7 +18,6 @@ if not modules then modules = { } end modules ['strc-bkm'] = { local next, type = next, type local gsub, lower = string.gsub, string.lower local concat = table.concat -local utfvalues = utf.values local settings_to_hash = utilities.parsers.settings_to_hash local trace_bookmarks = false trackers.register("references.bookmarks", function(v) trace_bookmarks = v end) @@ -113,11 +112,13 @@ end function bookmarks.place() if next(names) then - local levels = { } - local noflevels = 0 - local lastlevel = 1 - local nofblocks = #lists.sectionblocks -- always >= 1 + local levels = { } + local noflevels = 0 + local lastlevel = 1 + local nofblocks = #lists.sectionblocks -- always >= 1 local showblocktitle = toboolean(numberspec.showblocktitle,true) +-- local allsections = sections.collected + local allblocks = sections.sectionblockdata for i=1,nofblocks do local block = lists.sectionblocks[i] local blockdone = nofblocks == 1 @@ -156,9 +157,9 @@ function bookmarks.place() if not blockdone then if showblocktitle then -- add block entry - local blockdata = sections.sectionblockdata[block] - noflevels = noflevels + 1 + local blockdata = allblocks[block] local references = li.references + noflevels = noflevels + 1 levels[noflevels] = { level = 1, -- toplevel title = stripped(blockdata.bookmark ~= "" and blockdata.bookmark or block), @@ -185,19 +186,29 @@ function bookmarks.place() title = titledata.title or "?" -- end end - if numbered[name] then - local sectiondata = sections.collected[li.references.section] - local numberdata = li.numberdata - if sectiondata and numberdata then - if not numberdata.hidenumber then - -- we could typeset the number and convert it - local number = sections.typesetnumber(sectiondata,"direct",numberspec,sectiondata) - if number and #number > 0 then - title = concat(number) .. " " .. title - end - end - end - end +-- if numbered[name] then +-- local sectiondata = allsections[li.references.section] +-- if sectiondata then +-- local numberdata = li.numberdata +-- if numberdata and not numberdata.hidenumber then +-- -- we could typeset the number and convert it +-- local number = sections.typesetnumber(sectiondata,"direct",numberspec,sectiondata) +-- if number and #number > 0 then +-- title = concat(number) .. " " .. title +-- end +-- end +-- end +-- end +if numbered[name] then + local numberdata = li.numberdata + if numberdata and not numberdata.hidenumber then + -- we could typeset the number and convert it + local number = sections.typesetnumber(numberdata,"direct",numberspec,numberdata) + if number and #number > 0 then + title = concat(number) .. " " .. title + end + end +end noflevels = noflevels + 1 local references = li.references levels[noflevels] = { diff --git a/tex/context/base/mkiv/strc-con.mkvi b/tex/context/base/mkiv/strc-con.mkvi index 25e26bf73..18ce17355 100644 --- a/tex/context/base/mkiv/strc-con.mkvi +++ b/tex/context/base/mkiv/strc-con.mkvi @@ -692,8 +692,7 @@ \edef\p_strc_constructions_inbetween{\constructionparameter\c!inbetween}% \ifx\p_strc_constructions_inbetween\empty \else \p_strc_constructions_inbetween - \par - \nobreak + \directcheckedvspacing\v!samepage \fi \useconstructionstyleandcolor\c!style\c!color \ignorespaces @@ -914,6 +913,9 @@ \global\let\currentconstructionexpansion\v!no \fi % + \ifx\currentconstructionreferenceprefix\empty + \global\let\currentconstructionreferenceprefix\referenceprefix + \fi \ifx\currentconstructionexpansion\s!xml \xmlstartraw \xdef\currentconstructiontitle {\constructionparameter\c!title}% @@ -969,10 +971,10 @@ catcodes \catcodetable } references { - internal \nextinternalreference - order \nextinternalorderreference + internal \locationcount + order \locationorder reference {\currentconstructionreference} - prefix {\referenceprefix} + prefix {\currentconstructionreferenceprefix} % block {\currentsectionblock} % section structures.sections.currentid(), } @@ -1014,7 +1016,7 @@ \clf_setinternalreference prefix {\referenceprefix}% reference {\currentconstructionreference}% - internal \nextinternalreference + internal \locationcount view {\interactionparameter\c!focus}% \relax \normalexpanded{% diff --git a/tex/context/base/mkiv/strc-def.mkiv b/tex/context/base/mkiv/strc-def.mkiv index 962c46b48..b2e86c140 100644 --- a/tex/context/base/mkiv/strc-def.mkiv +++ b/tex/context/base/mkiv/strc-def.mkiv @@ -193,6 +193,7 @@ \c!header=, \c!style=\tfc, \c!distance=.75\emwidth, + \c!textdistance=\emwidth plus \emwidth minus .25\emwidth, \c!before={\blank[2*\v!big]}, \c!after={\blank[2*\v!big]}] @@ -202,6 +203,7 @@ %\c!indentnext=\v!no, \c!style=\tfa, \c!distance=.75\emwidth, + \c!textdistance=\emwidth plus \emwidth minus .25\emwidth, \c!before={\blank[2*\v!big]}, \c!after=\blank] diff --git a/tex/context/base/mkiv/strc-des.mkvi b/tex/context/base/mkiv/strc-des.mkvi index 4376d9cdc..76f878f5f 100644 --- a/tex/context/base/mkiv/strc-des.mkvi +++ b/tex/context/base/mkiv/strc-des.mkvi @@ -21,11 +21,11 @@ \let\setupdescriptions\setupdescription -% \setupdescriptions % check with old +% \setupdescription % check with old % [\c!alternative=\descriptionparameter\c!location, % \c!location=\v!left] -\setupdescriptions % check with old +\setupdescription % check with old [\c!alternative=\v!left, \c!headstyle=\v!bold, \c!titlestyle=\v!bold, diff --git a/tex/context/base/mkiv/strc-doc.lua b/tex/context/base/mkiv/strc-doc.lua index 885e2de0b..57fff5a21 100644 --- a/tex/context/base/mkiv/strc-doc.lua +++ b/tex/context/base/mkiv/strc-doc.lua @@ -16,7 +16,7 @@ if not modules then modules = { } end modules ['strc-doc'] = { -- in lists however zero's are ignored, so there numbersegments=2:4 gives result local next, type, tonumber, select = next, type, tonumber, select -local format, gsub, find, gmatch, match = string.format, string.gsub, string.find, string.gmatch, string.match +local find, match = string.find, string.match local concat, fastcopy, insert, remove = table.concat, table.fastcopy, table.insert, table.remove local max, min = math.max, math.min local allocate, mark, accesstable = utilities.storage.allocate, utilities.storage.mark, utilities.tables.accesstable @@ -37,7 +37,6 @@ local v_auto = variables.auto local v_strict = variables.strict local v_all = variables.all local v_positive = variables.positive -local v_by = variables.by local trace_sectioning = false trackers.register("structures.sectioning", function(v) trace_sectioning = v end) local trace_detail = false trackers.register("structures.detail", function(v) trace_detail = v end) @@ -64,8 +63,6 @@ local strippedprocessor = processors.stripped local convertnumber = converters.convert -local a_internal = attributes.private('internal') - local ctx_convertnumber = context.convertnumber local ctx_sprint = context.sprint local ctx_finalizeauto = context.finalizeautostructurelevel @@ -327,7 +324,7 @@ function sections.setentry(given) local mappedlevel = levelmap[givenname] local newdepth = tonumber(mappedlevel or (olddepth > 0 and olddepth) or 1) -- hm, levelmap only works for section-* local resetset = directives and directives.resetset or "" - -- local resetter = sets.getall("structure:resets",data.block,resetset) + -- local resetter = sets.getall("structure:resets",data.block,resetset) -- a trick to permit userdata to overload title, ownnumber and reference -- normally these are passed as argument but nowadays we provide several -- interfaces (we need this because we want to be compatible) @@ -414,16 +411,17 @@ function sections.setentry(given) v[2](k) end end - local n = { } - for i=1,newdepth do - n[i] = numbers[i] - end - numberdata.numbers = n +-- local n = { } +-- for i=1,newdepth do +-- n[i] = numbers[i] +-- end +-- numberdata.numbers = n + numberdata.numbers = { unpack(numbers,1,newdepth) } if not numberdata.block then numberdata.block = getcurrentblock() -- also in references end if #ownnumbers > 0 then - numberdata.ownnumbers = fastcopy(ownnumbers) + numberdata.ownnumbers = fastcopy(ownnumbers) -- { unpack(ownnumbers) } end if trace_detail then report_structure("name %a, numbers % a, own numbers % a",givenname,numberdata.numbers,numberdata.ownnumbers) diff --git a/tex/context/base/mkiv/strc-doc.mkiv b/tex/context/base/mkiv/strc-doc.mkiv index c453f199e..5f40521fa 100644 --- a/tex/context/base/mkiv/strc-doc.mkiv +++ b/tex/context/base/mkiv/strc-doc.mkiv @@ -23,10 +23,10 @@ {\clf_setinternalreference prefix {\currentstructurereferenceprefix}% reference {\currentstructurereference} - internal \nextinternalreference + internal \locationcount view {\interactionparameter\c!focus}% \relax \xdef\currentstructureattribute {\the\lastdestinationattribute}% - \xdef\currentstructuresynchronize{\strc_lists_inject_enhance{#1}{\nextinternalreference}}} + \xdef\currentstructuresynchronize{\strc_lists_inject_enhance{#1}{\the\locationcount}}} \protect \endinput diff --git a/tex/context/base/mkiv/strc-enu.mkvi b/tex/context/base/mkiv/strc-enu.mkvi index 832bdaf82..8eff706bb 100644 --- a/tex/context/base/mkiv/strc-enu.mkvi +++ b/tex/context/base/mkiv/strc-enu.mkvi @@ -79,7 +79,7 @@ \let\setupenumerations\setupenumeration -\setupenumerations % check with old +\setupenumeration % check with old [\c!alternative=\v!top, \c!headstyle=\v!bold, \c!titlestyle=\v!bold, @@ -366,7 +366,7 @@ \strc_enumerations_full_number_yes \edef\p_coupling{\constructionparameter\c!coupling}% \ifx\p_coupling\empty \else - \symbolreference[order(construction:\p_coupling:\nextinternalorderreference)]% + \symbolreference[order(construction:\p_coupling:\the\locationorder)]% \fi \fi} diff --git a/tex/context/base/mkiv/strc-flt.mkvi b/tex/context/base/mkiv/strc-flt.mkvi index e83e036fa..3ad2e86fc 100644 --- a/tex/context/base/mkiv/strc-flt.mkvi +++ b/tex/context/base/mkiv/strc-flt.mkvi @@ -126,6 +126,7 @@ \c!strut=\v!no, \c!radius=.5\bodyfontsize, \c!corner=\v!rectangular, + \c!grid=, %\c!background=, %\c!backgroundcolor=, \c!backgroundoffset=\!!zeropoint, @@ -153,12 +154,13 @@ \c!outermargin=\zeropoint, % idem \c!leftmargindistance=\zeropoint, \c!rightmargindistance=\floatparameter\c!leftmargindistance, - \c!step=\v!big, % the flish side float step (big=line, medium=halfline, small=quarterline, depth=halfline with normaldepth) + \c!step=\v!big, % the flush side float step (big=line, medium=halfline, small=quarterline, depth=halfline with normaldepth) \c!ntop=2, \c!nbottom=0, \c!nlines=4, % used? \c!topoffset=\zeropoint, \c!bottomoffset=\zeropoint, + \c!freeregion=\v!yes, %\c!local=, %\c!bottombefore=, % e.g. \vfill %\c!bottomafter=, @@ -584,9 +586,11 @@ \edef\savedfloatlocation{\floatcaptionparameter\c!location}% \setexpandedfloatcaptionparameter\c!topoffset {\floatparameter\c!topoffset}% \setexpandedfloatcaptionparameter\c!bottomoffset{\floatparameter\c!bottomoffset}% + \setexpandedfloatcaptionparameter\c!freeregion {\floatparameter\c!freeregion}% \setupcurrentfloatcaption[\c!location=,\c!reference=,\c!title=,\c!marking=,\c!list=,\c!bookmark=,#settings]% \setexpandedfloatparameter\c!topoffset {\floatcaptionparameter\c!topoffset}% \setexpandedfloatparameter\c!bottomoffset{\floatcaptionparameter\c!bottomoffset}% + \setexpandedfloatparameter\c!freeregion {\floatcaptionparameter\c!freeregion}% \def\m_strc_floats_saved_userdata{#2}% \edef\floatlocation{\floatcaptionparameter\c!location}% \setfloatcaptionparameter\c!location{\savedfloatlocation}% not expanded @@ -744,7 +748,7 @@ \global\setfalse\c_strc_floats_par_float \else \doifelsecommon\floatlocation\flushfloatslist - {\global\settrue \c_strc_floats_par_float} + {\global\settrue \c_strc_floats_par_float}% {\global\setfalse\c_strc_floats_par_float}% \fi \global\d_page_sides_shift \zeropoint @@ -779,21 +783,26 @@ \global\advance\d_page_sides_bottomskip\floatparameter\c!bottomoffset \else \processallactionsinset - [\floatlocation] + [\floatlocation]% [ 90=>\global\c_strc_floats_rotation\commalistelement\relax,% 180=>\global\c_strc_floats_rotation\commalistelement\relax,% 270=>\global\c_strc_floats_rotation\commalistelement\relax]% \fi \doifelseinset\v!nonumber\floatlocation - {\global\nofloatnumbertrue} + {\global\nofloatnumbertrue}% {\doifelse{\floatcaptionparameter\c!number}\v!yes - {\global\nofloatnumberfalse} + {\global\nofloatnumberfalse}% {\global\nofloatnumbertrue}}% \doifelseinset\v!none\floatlocation - {\global\nofloatcaptiontrue} + {\global\nofloatcaptiontrue}% {\global\nofloatcaptionfalse}% \doif{\floatcaptionparameter\c!number}\v!none % new {\global\nofloatcaptiontrue}% + \doifinset\v!effective\floatlocation + {\letfloatparameter \c!leftmargin \effectiveleftskip + \letfloatparameter \c!rightmargin\effectiverightskip + \letfloatcaptionparameter\c!leftmargin \effectiveleftskip + \letfloatcaptionparameter\c!rightmargin\effectiverightskip}% \ifemptyfloatcaption \ifnofloatnumber \global\nofloatcaptiontrue \fi \fi} @@ -807,6 +816,8 @@ \else \doifelseinset\v!local\floatlocation\settrue\setfalse\c_page_floats_center_box_local \fi + \doifelse{\floatparameter\c!freeregion}\v!yes + \settrue\setfalse\c_strc_floats_mark_as_free \doifnotcommon{\v!always,\v!here,\v!force}\floatlocation % ! ! ! ! ! ! {\setfalse\c_page_floats_center_box_global \setfalse\c_page_floats_center_box_local}} @@ -1173,8 +1184,8 @@ \strc_floats_calculate_skip\d_page_sides_topskip {\rootfloatparameter\c!sidespacebefore}% \strc_floats_calculate_skip\d_page_sides_bottomskip{\rootfloatparameter\c!sidespaceafter }% \global\d_strc_floats_margin \rootfloatparameter\c!margin - \global\d_page_sided_leftshift \floatparameter \c!leftmargindistance - \global\d_page_sided_rightshift \floatparameter \c!rightmargindistance + \global\d_page_sides_leftshift \floatparameter \c!leftmargindistance + \global\d_page_sides_rightshift \floatparameter \c!rightmargindistance \global\c_page_floats_n_of_top \rootfloatparameter\c!ntop \global\c_page_floats_n_of_bottom\rootfloatparameter\c!nbottom \endgroup} @@ -1309,20 +1320,66 @@ % minwidth=fit,width=max : no overshoot, as wide as graphic +% keep these as reference: +% +% \def\strc_floats_align_content_indeed +% {\alignstrutmode\zerocount +% \doifnotcommon{\floatcaptionparameter\c!location}{\v!outermargin,\v!innermargin,\v!leftmargin,\v!rightmargin} +% {\shiftalignedline +% {\floatparameter\c!leftmargin }{\floatparameter\c!rightmargin}% +% {\floatparameter\c!innermargin}{\floatparameter\c!outermargin}}% +% \alignedline{\floatparameter\c!location}\v!middle} +% +% \def\strc_floats_align_caption_indeed +% {\alignstrutmode\zerocount +% \shiftalignedline +% {\floatcaptionparameter\c!leftmargin }{\floatcaptionparameter\c!rightmargin}% +% {\floatcaptionparameter\c!innermargin}{\floatcaptionparameter\c!outermargin}% +% \alignedline{\floatparameter\c!location}\v!middle} +% +% Test case: +% +% \setupfloats[location=left] +% \setupfloatcaption[width=max] +% +% \startfloatcombination +% \placefigure{}{} +% \placefigure{}{} +% \stopfloatcombination + +%D In a floatcombination we ignore the margins .. if that is ever needed we need another +%D state (instead of local). + +\def\strc_floats_align_indeed + {\alignedline{\floatparameter\c!location}\v!middle} + +\def\strc_floats_shift_indeed#1% + {\shiftalignedline{#1\c!leftmargin}{#1\c!rightmargin}{#1\c!innermargin}{#1\c!outermargin}} + \def\strc_floats_align_content_indeed {\alignstrutmode\zerocount - \doifnotcommon{\floatcaptionparameter\c!location}{\v!outermargin,\v!innermargin,\v!leftmargin,\v!rightmargin} - {\shiftalignedline - {\floatparameter\c!leftmargin }{\floatparameter\c!rightmargin}% - {\floatparameter\c!innermargin}{\floatparameter\c!outermargin}}% - \alignedline{\floatparameter\c!location}\v!middle} + \ifx\forcedfloatmethod\v!local \else + \doifnotcommon{\floatcaptionparameter\c!location}{\v!outermargin,\v!innermargin,\v!leftmargin,\v!rightmargin} + {\strc_floats_shift_indeed\floatparameter}% + \expandafter\strc_floats_align_indeed + \fi} \def\strc_floats_align_caption_indeed {\alignstrutmode\zerocount - \shiftalignedline - {\floatcaptionparameter\c!leftmargin }{\floatcaptionparameter\c!rightmargin}% - {\floatcaptionparameter\c!innermargin}{\floatcaptionparameter\c!outermargin}% - \alignedline{\floatparameter\c!location}\v!middle} + \ifx\forcedfloatmethod\v!local + \expandafter\strc_floats_align_indeed_local + \else + \strc_floats_shift_indeed\floatcaptionparameter + \expandafter\strc_floats_align_indeed + \fi} + +% \def\strc_floats_align_indeed_local#1% +% {\begingroup +% \hsize\wd\floatbox +% \strc_floats_align_indeed{#1}% +% \endgroup} + +\let\strc_floats_align_indeed_local\firstofoneargument \newdimen\d_strc_floats_content \newdimen\d_strc_float_temp_height @@ -1331,6 +1388,8 @@ \def\captionminwidth {15\bodyfontsize} \def\captionovershoot{2\emwidth} +\let\strc_floats_mark_pag_as_free\relax + \def\strc_floats_set_page_variant {\bgroup \strc_floats_set_local_hsize @@ -1369,10 +1428,13 @@ \fi \ifcase\c_strc_floats_rotation \doifnotinset\v!margin\floatlocation % brr, really needed! see wm - {\postcenterfloatbox\d_strc_floats_content}% + {\postcenterfloatbox\d_strc_floats_content + \strc_floats_mark_pag_as_free}% + % mark as free not done here \else \global\setbox\floatbox\vpack {\rotate[\c!rotation=\number\c_strc_floats_rotation]{\box\floatbox}}% + \strc_floats_mark_pag_as_free \fi \egroup} @@ -1618,7 +1680,7 @@ {\strc_floats_build_box_next_right_margin_indeed\rightmargindistance} \def\strc_floats_build_box_next_left_margin - {\strc_floats_build_box_next_left_margin_indeed \leftmargindistance } + {\strc_floats_build_box_next_left_margin_indeed \leftmargindistance} \def\strc_floats_build_box_next_outer_margin {\doifelserightpagefloat @@ -1835,6 +1897,8 @@ \unexpanded\def\installfloatboxbuilder#1#2{\setvalue{\??floatbuilder#1}{#2}} +\let\strc_floats_mark_box_as_free\relax + \def\strc_floats_build_box {\global\setbox\floatbox\vbox % pack ? probably not {\strc_floats_set_local_hsize @@ -1865,17 +1929,28 @@ \v!outer=>\doifelserightpagefloat{\let\next\strc_floats_relocate_caption_right}{\let\next\strc_floats_relocate_caption_left }]% \next} -\installfloatboxbuilder \v!none \strc_floats_build_box_default -\installfloatboxbuilder \s!default \strc_floats_build_box_default -\installfloatboxbuilder \v!high \strc_floats_build_box_high -\installfloatboxbuilder \v!low \strc_floats_build_box_low -\installfloatboxbuilder \v!middle \strc_floats_build_box_middle +\installfloatboxbuilder \v!none \strc_floats_build_box_default +\installfloatboxbuilder \s!default \strc_floats_build_box_default +\installfloatboxbuilder \v!high \strc_floats_build_box_high +\installfloatboxbuilder \v!low \strc_floats_build_box_low +\installfloatboxbuilder \v!middle \strc_floats_build_box_middle + +\installfloatboxbuilder \v!rightmargin \strc_floats_build_box_side % added 2016-08-23 +\installfloatboxbuilder \v!leftmargin \strc_floats_build_box_side % added 2016-08-23 +\installfloatboxbuilder \v!innermargin \strc_floats_build_box_side % added 2016-08-23 +\installfloatboxbuilder \v!outermargin \strc_floats_build_box_side % added 2016-08-23 + +\installfloatboxbuilder \v!left \strc_floats_build_box_side +\installfloatboxbuilder \v!right \strc_floats_build_box_side +\installfloatboxbuilder \v!inner \strc_floats_build_box_side % added 2016-08-23 +\installfloatboxbuilder \v!outer \strc_floats_build_box_side % added 2016-08-23 -\installfloatboxbuilder \v!left \strc_floats_build_box_side -\installfloatboxbuilder \v!right \strc_floats_build_box_side +\installfloatboxbuilder \v!lefthanging \strc_floats_build_box_side % added 2016-08-23 +\installfloatboxbuilder \v!righthanging \strc_floats_build_box_side % added 2016-08-23 +\installfloatboxbuilder \v!hang \strc_floats_build_box_side % added 2016-08-23 -\installfloatboxbuilder \v!top \strc_floats_build_box_top -\installfloatboxbuilder \v!bottom \strc_floats_build_box_bottom +\installfloatboxbuilder \v!top \strc_floats_build_box_top +\installfloatboxbuilder \v!bottom \strc_floats_build_box_bottom % \setuplayout[grid=yes] \showgrid \setupcaptions[style=smallbodyfont,location=grid,inbetween=] % @@ -1885,7 +1960,7 @@ % test \placefigure{} {\externalfigure[cow.pdf][frame=on,grid=depth]} test \page % test \placefigure{\input zapf\relax}{\externalfigure[cow.pdf][frame=on,grid=depth]} test \page % \stoptext - + % This might move to page-flt: \newif\ifpostponecolumnfloats \postponecolumnfloatsfalse % don't change @@ -1968,11 +2043,12 @@ \def\strc_floats_prepare_side_caption_fit % or center when smaller {\ifdim\wd\b_strc_floats_caption>\wd\b_strc_floats_content\relax - \setbox\b_strc_floats_caption\vbox + \setbox\b_strc_floats_caption\vbox {\forgetall % needed? \hsize\wd\b_strc_floats_content \strc_floats_make_complete_caption}% \else + % maybe we should listen to the align option here (now side floats need the max option \setbox\b_strc_floats_caption\hpack to \wd\b_strc_floats_content {\hss\hbox{\strc_floats_make_complete_caption}\hss}% \fi} @@ -2086,7 +2162,7 @@ \let\floatlabel \empty % set by lua \let\floatcolumn \empty % set by lua \let\floatrow \empty % set by lua -\let\forcedfloatmethod\empty % set by lua +\let\forcedfloatmethod\empty % set by lua and floatcombinations \def\setfloatmethodvariables#1% \floatmethod \floatlabel \floatrow \floatcolumn {\clf_analysefloatmethod{#1}} diff --git a/tex/context/base/mkiv/strc-itm.mkvi b/tex/context/base/mkiv/strc-itm.mkvi index 48c8e1a30..a28193415 100644 --- a/tex/context/base/mkiv/strc-itm.mkvi +++ b/tex/context/base/mkiv/strc-itm.mkvi @@ -23,6 +23,10 @@ %D no surprise that I had that cd running several times when updating this %D code. One of the highlights of 2011. +%D This module needs to be rewritten but that is tricky with respect to +%D compatibilitity. Basically each major variant (regular, text, columns, +%D horizontal, etc) needs to be on its own. + % todo: check breaks % todo: check grouping % todo: fixedconversion @@ -121,6 +125,11 @@ % \noitem \startitemize[a] \item Item 2.a. \item Item 2.b. \stopitemize % \stopitemize % +% \startitemize[n,repeat][width=0pt] +% \noitem \startitemize[a][width=2em] \item Item 1.a. \item Item 1.b. \stopitemize +% \noitem \startitemize[a][width=2em] \item Item 2.a. \item Item 2.b. \stopitemize +% \stopitemize +% % \startbuffer % \item % \startitemize[n] @@ -265,7 +274,7 @@ catcodes \catcodetable }% references {% - internal \nextinternalreference % no: this spoils references + internal \locationcount % no: this spoils references % block {\currentsectionblock}% view {\interactionparameter\c!focus}% prefix {\referenceprefix}% @@ -384,7 +393,7 @@ \def\strc_itemgroups_process_option#option% {\edef\itemgroupconstantvalue{#option}% \ifx\itemgroupconstantvalue\empty\else - \splitstring\itemgroupconstantvalue\at*\to\itemgroupfirst\and\itemgroupsecond + \splitatasterisk\itemgroupconstantvalue\itemgroupfirst\itemgroupsecond \ifx\itemgroupsecond\empty \let\itemgroupsecond\itemgroupfirst \let\itemgroupfirst\!!plusone @@ -401,70 +410,70 @@ \settrue\c_strc_itemgroups_pack \fi} -\setvalue{\??itemgroupkeyword\!!zerocount}{} % ignore 0 -\setvalue{\??itemgroupkeyword\v!packed }{\strc_itemgroups_process_set_option_pack} -\setvalue{\??itemgroupkeyword\v!intro }{\settrue\c_strc_itemgroups_intro} % here? not set to false -\setvalue{\??itemgroupkeyword\v!autointro}{\settrue\c_strc_itemgroups_auto_intro} -\setvalue{\??itemgroupkeyword\v!broad }{\ifx\itemgroupfirst\empty - \let\itemgroupfirst\!!plusone - \fi - \letitemgroupparameter\c!factor\itemgroupfirst} -\setvalue{\??itemgroupkeyword\v!text }{\settrue\c_strc_itemgroups_text - \settrue\c_strc_itemgroups_inline - \settrue\c_strc_itemgroups_joined - \strc_itemgroups_process_set_option_pack} -\setvalue{\??itemgroupkeyword\v!before }{\settrue\c_strc_itemgroups_before} -\setvalue{\??itemgroupkeyword\v!after }{\settrue\c_strc_itemgroups_after} -\setvalue{\??itemgroupkeyword\v!nowhite }{\settrue\c_strc_itemgroups_nowhite} -\setvalue{\??itemgroupkeyword\v!margin }{\setitemgroupparameter\c!width{-2em}} % signal -\setvalue{\??itemgroupkeyword\v!inmargin }{\setitemgroupparameter\c!width{-2em}} % signal -\setvalue{\??itemgroupkeyword\v!atmargin }{\ifnum\c_strc_itemgroups_nesting>\plusone - \setitemgroupparameter\c!width{0em}% - \fi} % signal -\setvalue{\??itemgroupkeyword\v!intext }{\settrue\c_strc_itemgroups_inline} -\setvalue{\??itemgroupkeyword\v!loose }{\setfalse\c_strc_itemgroups_optimize} -\setvalue{\??itemgroupkeyword\v!fit }{\settrue\c_strc_itemgroups_fitting} -\setvalue{\??itemgroupkeyword\v!nofit }{\setfalse\c_strc_itemgroups_fitting} -\setvalue{\??itemgroupkeyword\v!paragraph}{\settrue\c_strc_itemgroups_paragraph - \strc_itemgroups_process_set_option_pack} -\setvalue{\??itemgroupkeyword\v!joinedup }{\settrue\c_strc_itemgroups_joined - \strc_itemgroups_process_set_option_pack} -\setvalue{\??itemgroupkeyword\v!serried }{\edef\itemgroupfirst{-\ifx\itemgroupfirst\empty1\else\itemgroupfirst\fi}% - \letitemgroupparameter\c!factor\itemgroupfirst} -\setvalue{\??itemgroupkeyword\v!stopper }{\letitemgroupparameter\c!placestopper\v!yes} % keep {} -\setvalue{\??itemgroupkeyword\v!unpacked }{\setfalse\c_strc_itemgroups_pack} -\setvalue{\??itemgroupkeyword\v!repeat }{\settrue\c_strc_itemgroups_repeat} -\setvalue{\??itemgroupkeyword\v!norepeat }{\setfalse\c_strc_itemgroups_repeat} -\setvalue{\??itemgroupkeyword\v!reverse }{\settrue\c_strc_itemgroups_reverse} -\setvalue{\??itemgroupkeyword\v!columns }{\settrue\c_strc_itemgroups_columns} -\setvalue{\??itemgroupkeyword\v!one }{\letitemgroupparameter\c!n\plusone} -\setvalue{\??itemgroupkeyword\v!two }{\letitemgroupparameter\c!n\plustwo} -\setvalue{\??itemgroupkeyword\v!three }{\letitemgroupparameter\c!n\plusthree} -\setvalue{\??itemgroupkeyword\v!four }{\letitemgroupparameter\c!n\plusfour} -\setvalue{\??itemgroupkeyword\v!five }{\letitemgroupparameter\c!n\plusfive} -\setvalue{\??itemgroupkeyword\v!six }{\letitemgroupparameter\c!n\plussix} -\setvalue{\??itemgroupkeyword\v!seven }{\letitemgroupparameter\c!n\plusseven} -\setvalue{\??itemgroupkeyword\v!eight }{\letitemgroupparameter\c!n\pluseight} -\setvalue{\??itemgroupkeyword\v!nine }{\letitemgroupparameter\c!n\plusnine} -%setvalue{\??itemgroupkeyword\v!standard }{\setupcurrentitemgroup -% [\c!width =1.5\emwidth,% -% \c!distance =.5\emwidth,% -% \c!factor =0,% -% \c!inner =,% -% \c!beforehead=,% -% \c!afterhead =\blank,% -% \c!before =\blank,% -% \c!inbetween =\blank,% -% \c!after =\blank]} -\setvalue{\??itemgroupkeyword\v!standard }{\setitemgroupparameter\c!width {1.5\emwidth}% - \setitemgroupparameter\c!distance {.5\emwidth}% - \letitemgroupparameter\c!factor \!!zerocount - \letitemgroupparameter\c!inner \empty - \letitemgroupparameter\c!beforehead\empty - \letitemgroupparameter\c!afterhead \blank - \letitemgroupparameter\c!before \blank - \letitemgroupparameter\c!inbetween \blank - \letitemgroupparameter\c!after \blank} +\setvalue{\??itemgroupkeyword\!!zerocount }{} % ignore 0 +\setvalue{\??itemgroupkeyword\v!packed }{\strc_itemgroups_process_set_option_pack} +\setvalue{\??itemgroupkeyword\v!intro }{\settrue\c_strc_itemgroups_intro} % here? not set to false +\setvalue{\??itemgroupkeyword\v!autointro }{\settrue\c_strc_itemgroups_auto_intro} +\setvalue{\??itemgroupkeyword\v!broad }{\ifx\itemgroupfirst\empty + \let\itemgroupfirst\!!plusone + \fi + \letitemgroupparameter\c!factor\itemgroupfirst} +\setvalue{\??itemgroupkeyword\v!text }{\settrue\c_strc_itemgroups_text + \settrue\c_strc_itemgroups_inline + \settrue\c_strc_itemgroups_joined + \strc_itemgroups_process_set_option_pack} +\setvalue{\??itemgroupkeyword\v!before }{\settrue\c_strc_itemgroups_before} +\setvalue{\??itemgroupkeyword\v!after }{\settrue\c_strc_itemgroups_after} +\setvalue{\??itemgroupkeyword\v!nowhite }{\settrue\c_strc_itemgroups_nowhite} +\setvalue{\??itemgroupkeyword\v!margin }{\setitemgroupparameter\c!width{-2em}} % signal +\setvalue{\??itemgroupkeyword\v!inmargin }{\setitemgroupparameter\c!width{-2em}} % signal +\setvalue{\??itemgroupkeyword\v!atmargin }{\ifnum\c_strc_itemgroups_nesting>\plusone + \setitemgroupparameter\c!width{0em}% + \fi} % signal +\setvalue{\??itemgroupkeyword\v!intext }{\settrue\c_strc_itemgroups_inline} +\setvalue{\??itemgroupkeyword\v!loose }{\setfalse\c_strc_itemgroups_optimize} +\setvalue{\??itemgroupkeyword\v!fit }{\settrue\c_strc_itemgroups_fitting} +\setvalue{\??itemgroupkeyword\v!nofit }{\setfalse\c_strc_itemgroups_fitting} +\setvalue{\??itemgroupkeyword\v!paragraph }{\settrue\c_strc_itemgroups_paragraph + \strc_itemgroups_process_set_option_pack} +\setvalue{\??itemgroupkeyword\v!joinedup }{\settrue\c_strc_itemgroups_joined + \strc_itemgroups_process_set_option_pack} +\setvalue{\??itemgroupkeyword\v!notjoinedup}{\setfalse\c_strc_itemgroups_joined} +\setvalue{\??itemgroupkeyword\v!serried }{\edef\itemgroupfirst{-\ifx\itemgroupfirst\empty1\else\itemgroupfirst\fi}% + \letitemgroupparameter\c!factor\itemgroupfirst} +\setvalue{\??itemgroupkeyword\v!stopper }{\letitemgroupparameter\c!placestopper\v!yes} % keep {} +\setvalue{\??itemgroupkeyword\v!repeat }{\settrue\c_strc_itemgroups_repeat} +\setvalue{\??itemgroupkeyword\v!norepeat }{\setfalse\c_strc_itemgroups_repeat} +\setvalue{\??itemgroupkeyword\v!reverse }{\settrue\c_strc_itemgroups_reverse} +\setvalue{\??itemgroupkeyword\v!columns }{\settrue\c_strc_itemgroups_columns} +\setvalue{\??itemgroupkeyword\v!one }{\letitemgroupparameter\c!n\plusone} +\setvalue{\??itemgroupkeyword\v!two }{\letitemgroupparameter\c!n\plustwo} +\setvalue{\??itemgroupkeyword\v!three }{\letitemgroupparameter\c!n\plusthree} +\setvalue{\??itemgroupkeyword\v!four }{\letitemgroupparameter\c!n\plusfour} +\setvalue{\??itemgroupkeyword\v!five }{\letitemgroupparameter\c!n\plusfive} +\setvalue{\??itemgroupkeyword\v!six }{\letitemgroupparameter\c!n\plussix} +\setvalue{\??itemgroupkeyword\v!seven }{\letitemgroupparameter\c!n\plusseven} +\setvalue{\??itemgroupkeyword\v!eight }{\letitemgroupparameter\c!n\pluseight} +\setvalue{\??itemgroupkeyword\v!nine }{\letitemgroupparameter\c!n\plusnine} +%setvalue{\??itemgroupkeyword\v!standard }{\setupcurrentitemgroup +% [\c!width =1.5\emwidth,% +% \c!distance =.5\emwidth,% +% \c!factor =0,% +% \c!inner =,% +% \c!beforehead=,% +% \c!afterhead =\blank,% +% \c!before =\blank,% +% \c!inbetween =\blank,% +% \c!after =\blank]} +\setvalue{\??itemgroupkeyword\v!standard }{\setitemgroupparameter\c!width {1.5\emwidth}% + \setitemgroupparameter\c!distance {.5\emwidth}% + \letitemgroupparameter\c!factor \!!zerocount + \letitemgroupparameter\c!inner \empty + \letitemgroupparameter\c!beforehead\empty + \letitemgroupparameter\c!afterhead \blank + \letitemgroupparameter\c!before \blank + \letitemgroupparameter\c!inbetween \blank + \letitemgroupparameter\c!after \blank} \def\strc_itemgroups_initialize_local @@ -1118,6 +1127,7 @@ \dostarttagged\t!itemcontent\empty \strut \nobreak % else problems with intext items + \seteffectivehsize % NEW ! \hskip\d_strc_itemgroups_signal % concat \itemgroupparameter\c!command} @@ -1183,8 +1193,13 @@ \unexpanded\def\strc_itemgroups_start_do_item {\startitemgroupitem} -\unexpanded\def\strc_itemgroups_start_no_item % ? - {\startitemgroupitem} +\unexpanded\def\strc_itemgroups_start_no_item + {\let\currentitemreference\empty + \strc_itemgroups_increment_item_counter + %\advance\c_strc_itemgroups_n_of_items\plusone + \setbox\b_strc_itemgroups\emptyhbox + \strc_itemgroups_check_for_repeated + \ignorespaces} \unexpanded\def\strc_itemgroups_start_button[#destination]% {\edef\m_strc_itemgroups_destination{#destination}% @@ -1653,7 +1668,14 @@ \c_strc_itemgroups_collected_done \zerocount \c_strc_itemgroups_collected_current\zerocount \ifnum\c_strc_itemgroups_collected_stored>\zerocount - \doubleexpandafter\strc_itemgroups_collected_flush + \ifconditional\c_strc_itemgroups_horizontal + \strc_itemgroups_before_command + \setfalse\c_strc_itemgroups_first + \strc_itemgroups_collected_flush + %\strc_itemgroups_after_command % triggered elsewhere + \else + \strc_itemgroups_collected_flush + \fi \fi \fi} diff --git a/tex/context/base/mkiv/strc-lev.lua b/tex/context/base/mkiv/strc-lev.lua index ec5dcf6f0..c06e209f6 100644 --- a/tex/context/base/mkiv/strc-lev.lua +++ b/tex/context/base/mkiv/strc-lev.lua @@ -16,7 +16,6 @@ local sections = structures.sections local implement = interfaces.implement local v_default = interfaces.variables.default -local v_auto = interfaces.variables.auto sections.levels = sections.levels or { } @@ -36,6 +35,11 @@ local function definesectionlevels(category,list) levels[category] = list end +local ctx_nostarthead = context.nostarthead +local ctx_dostarthead = context.dostarthead +local ctx_nostophead = context.nostophead +local ctx_dostophead = context.dostophead + local function startsectionlevel(n,category,current) category = category ~= "" and category or v_default local lc = levels[category] @@ -48,13 +52,13 @@ local function startsectionlevel(n,category,current) end level = level + 1 if not lc or level > #lc then - context.nostarthead { f_two_colon(category,level) } + ctx_nostarthead { f_two_colon(category,level) } else local lcl = lc[level] if n > #lcl then n = #lcl end - context.dostarthead { lc[level][n] } + ctx_dostarthead { lc[level][n] } end insert(categories,{ category, n }) end @@ -66,9 +70,9 @@ local function stopsectionlevel() local n = top[2] local lc = levels[category] if not lc or level > #lc then - context.nostophead { f_two_colon(category,level) } + ctx_nostophead { f_two_colon(category,level) } else - context.dostophead { lc[level][n] } + ctx_dostophead { lc[level][n] } end level = level - 1 else diff --git a/tex/context/base/mkiv/strc-lev.mkvi b/tex/context/base/mkiv/strc-lev.mkvi index ac106f999..6e08e7c07 100644 --- a/tex/context/base/mkiv/strc-lev.mkvi +++ b/tex/context/base/mkiv/strc-lev.mkvi @@ -37,7 +37,7 @@ \unexpanded\def\strc_levels_start_section[#category]% {\doifelseassignment{#category}% {\clf_startsectionlevel\plusone{\v!default}{\currentnamedsection}[#category]}% - {\clf_startsectionlevel\plusone {}{\currentnamedsection}{#category}}} + {\clf_startsectionlevel\plusone {#category}{\currentnamedsection}}} \unexpanded\def\strc_levels_start_subject[#category]% {\doifelseassignment{#category}% diff --git a/tex/context/base/mkiv/strc-lst.lua b/tex/context/base/mkiv/strc-lst.lua index 0f5d8e0d7..be8e07112 100644 --- a/tex/context/base/mkiv/strc-lst.lua +++ b/tex/context/base/mkiv/strc-lst.lua @@ -83,12 +83,10 @@ local variables = interfaces.variables local v_all = variables.all local v_reference = variables.reference local v_title = variables.title -local v_number = variables.reference local v_command = variables.command local v_text = variables.text local v_current = variables.current local v_previous = variables.previous -local v_next = variables.next local v_intro = variables.intro local v_here = variables.here local v_component = variables.component diff --git a/tex/context/base/mkiv/strc-lst.mkvi b/tex/context/base/mkiv/strc-lst.mkvi index 5c2bd74e5..08e56a700 100644 --- a/tex/context/base/mkiv/strc-lst.mkvi +++ b/tex/context/base/mkiv/strc-lst.mkvi @@ -145,7 +145,7 @@ {\endgroup} \unexpanded\def\strc_lists_inject_enhance#listindex#internal% - {\normalexpanded{\ctxlatecommand{enhancelist(#listindex)}}} + {\normalexpanded{\ctxlatecommand{enhancelist(\number#listindex)}}} \unexpanded\def\strc_lists_inject_yes[#settings][#userdata]% can be used directly {\setupcurrentlist[\c!type=userdata,\c!location=\v!none,#settings]% grouped (use \let... @@ -153,7 +153,7 @@ \setnextinternalreference \scratchcounter\clf_addtolist references { - internal \nextinternalreference + internal \locationcount % block {\currentsectionblock} % section structures.sections.currentid() % location {\p_location} @@ -167,12 +167,12 @@ userdata {\detokenize\expandafter{\normalexpanded{#userdata}}} \relax \edef\currentlistnumber{\the\scratchcounter}% -\setxvalue{\??listlocations\currentlist}{\nextinternalreference}% +\setxvalue{\??listlocations\currentlist}{\the\locationcount}% \ifx\p_location\v!here % this branch injects nodes ! - \strc_lists_inject_enhance{\currentlistnumber}{\nextinternalreference}% + \strc_lists_inject_enhance{\currentlistnumber}{\the\locationcount}% \clf_setinternalreference - internal \nextinternalreference + internal \locationcount view {\interactionparameter\c!focus}% \relax % this will change \xdef\currentstructurelistattribute{\the\lastdestinationattribute}% @@ -271,6 +271,7 @@ \def\strc_lists_place_indeed#tag#list#settings% {\begingroup + \the\t_lists_every_renderingcleanup % \let\currentlistentrylocation\empty \edef\currentlist{#tag}% \setupcurrentlist[#settings]% \the\everystructurelist @@ -308,7 +309,7 @@ {\strc_lists_complete_indeed[#tag][#tag][#settings]} \def\strc_lists_complete_indeed[#singular][#plural][#settings]% - {\normalexpanded{\startnamedsection[\v!title][\c!title=\headtext{#plural},\c!reference=#singular]}% + {\normalexpanded{\startnamedsection[\v!title][\c!title=\headtext{#plural},\c!reference=#singular]}% {} around ref ? \strc_lists_place[#singular][#settings]% \stopnamedsection} @@ -349,7 +350,7 @@ \endgroup} \def\strc_lists_combined_complete[#tag][#settings]% - {\normalexpanded{\startnamedsection[\v!title][\c!title={\headtext{#tag}},\c!reference=#tag]}% + {\normalexpanded{\startnamedsection[\v!title][\c!title={\headtext{#tag}},\c!reference=#tag]}% {} around ref ? \strc_lists_combined_place[#tag][#settings]% \stopnamedsection} @@ -527,6 +528,7 @@ \unexpanded\def\strclistsentryprocess#tag#method#index#extra% This one is called at the lua end! {\clf_pushlist#index\relax + %\let\currentlistentrylocation\empty \edef\currentlist {#tag}% \edef\currentlistmethod{#method}% \edef\currentlistindex {#index}% diff --git a/tex/context/base/mkiv/strc-mar.lua b/tex/context/base/mkiv/strc-mar.lua index 8b30e8514..624972af4 100644 --- a/tex/context/base/mkiv/strc-mar.lua +++ b/tex/context/base/mkiv/strc-mar.lua @@ -31,7 +31,8 @@ local getlist = nuts.getlist local getattr = nuts.getattr local getbox = nuts.getbox -local traverse_nodes = nuts.traverse +local traverse = nuts.traverse +local traverse_id = nuts.traverse_id local nodecodes = nodes.nodecodes local glyph_code = nodecodes.glyph @@ -117,7 +118,7 @@ end -- identify range local function sweep(head,first,last) - for n in traverse_nodes(head) do + for n in traverse(head) do local id = getid(n) if id == glyph_code then local a = getattr(n,a_marks) diff --git a/tex/context/base/mkiv/strc-mat.mkiv b/tex/context/base/mkiv/strc-mat.mkiv index 85870d547..4308666f3 100644 --- a/tex/context/base/mkiv/strc-mat.mkiv +++ b/tex/context/base/mkiv/strc-mat.mkiv @@ -33,13 +33,14 @@ %\c!margin=, %\c!align=, %\c!separator=, - %\c!grid=, + \c!grid=\v!math, \c!location=\v!right, \c!left=(, \c!right=), \c!expansion=\v!yes, % maybe automatically \c!spacebefore=\v!big, \c!spaceafter=\formulaparameter\c!spacebefore, + \c!width=\hsize, \c!leftmargin=\zeropoint, \c!rightmargin=\zeropoint, \c!indentnext=\v!no, @@ -47,6 +48,12 @@ \c!strut=\v!no, \c!distance=2\emwidth] +\setupformulaframed + [%c!location=<auto set>, + %c!width=<auto set>, + %c!align=<auto set>, + \c!offset=.5\exheight] + \ifdefined\matheqnogapstep % we're ok, now we have that quad in the distance which is % more consistent and not depending on the text font in math @@ -219,7 +226,6 @@ \to \everyresetformulas \newconditional\c_strc_formulas_handle_number -\newconditional\c_strc_formulas_increment \newconditional\c_strc_formulas_inside_place \newconditional\c_strc_formulas_inside_place_sub \newconditional\c_strc_formulas_inside_formulas @@ -230,12 +236,6 @@ \global\setfalse\c_strc_formulas_inside_place_sub \to \everyresetformulas -% \def\strc_formulas_place_numbering % place formula -% {\settrue\c_strc_formulas_handle_number -% \strc_formulas_check_reference\c_strc_formulas_place_number_mode\currentplaceformulareference -% \glet\strc_formulas_place_number\strc_formulas_place_number_indeed -% \glet\strc_formulas_place_number_nested\strc_formulas_place_number_nested_indeed} - \def\strc_formulas_place_numbering % place formula {\settrue\c_strc_formulas_handle_number \strc_formulas_check_reference\c_strc_formulas_place_number_mode\currentplaceformulareference @@ -271,21 +271,6 @@ \let\strc_formulas_reference_trace\relax \let\strc_formulas_reference_show \relax -% \def\strc_formulas_reference_trace -% {\rlap{\hbox{\quad\tt\txx[% -% \number\c_strc_formulas_place_number_mode,% -% \number\c_strc_formulas_number_mode,% -% \number\c_strc_formulas_sub_number_mode,% -% \number\c_strc_formulas_nested_number_mode -% ]}}} - -% \def\strc_formulas_reference_show -% {\writestatus{\v!formula}% -% {place: \number\c_strc_formulas_place_number_mode,\space -% formula: \number\c_strc_formulas_number_mode,\space -% subformula: \number\c_strc_formulas_sub_number_mode,\space -% nested: \number\c_strc_formulas_nested_number_mode]}} - \unexpanded\def\placecurrentformulanumber {\begingroup \rm % determines the distance and main font @@ -313,9 +298,6 @@ {\strc_formulas_handle_current_references \labeltexts\currentformula{\convertedcounter[\v!formula][]}} -% \def\theboxdestinationattribute#1{\iflocation\ifx#1\relax\else\ifx#1\empty\else attr \destinationattribute#1\fi\fi\fi} -% \def\thedestinationattribute #1{\iflocation\ifx#1\relax\else\ifx#1\empty\else \attribute\destinationattribute#1\fi\fi\fi} - \def\theformuladestinationattribute#1% {\iflocation\ifx#1\relax\else\ifx#1\empty\else \attribute\destinationattribute#1% @@ -479,7 +461,7 @@ \strc_formulas_handle_sub_numbering \fi \fi - \strc_formulas_reference_trace + \strc_formulas_reference_trace \egroup \fi} @@ -501,12 +483,19 @@ %D %D Otherwise we get a missing \type {$$} error reported. -\let\reqno\eqno +\let\reqno\eqno % no longer valid as we just nil it -\unexpanded\def\resetdisplaymatheq % when used? - {\let\normalleqno\gobbleoneargument \let\leqno\gobbleoneargument - \let\normalreqno\gobbleoneargument \let\eqno \gobbleoneargument - \let\strc_formulas_place_number\relax} +\let\math_native_leqno\leqno +\let\math_native_reqno\reqno + +\unexpanded\def\normaleqno#1{\writestatus\m!system{no native (l)eqno equation number support}} + +\let\normalleqno\normaleqno +\let\normalreqno\normaleqno + +\let\leqno\normaleqno +\let\reqno\normaleqno +\let\eqno \normaleqno %D \macros %D {startsubformulas} @@ -529,49 +518,181 @@ %D Tricky stuff: -\newdimen\lastlinewidth - \abovedisplayskip \zeropoint \abovedisplayshortskip \zeropoint % evt. 0pt minus 3pt \belowdisplayskip \zeropoint \belowdisplayshortskip \zeropoint % evt. 0pt minus 3pt \predisplaypenalty \zerocount -\postdisplaypenalty \zerocount % -5000 gaat mis, zie penalty bij \paragraaf +\postdisplaypenalty \zerocount % -5000 goes wrong, see penalty at \section +\mathdisplayskipmode \plusthree % because align also adds -% we don't use the skip's +% \predisplaygapfactor \zerocount % default is 2000 \unexpanded\def\strc_formulas_forget_display_skips - {\abovedisplayskip \zeropoint + {\mathdisplayskipmode \plusthree + \abovedisplayskip \zeropoint \belowdisplayskip \zeropoint \abovedisplayshortskip\zeropoint \belowdisplayshortskip\zeropoint} -% \def\predisplaysizethreshhold{2\emwidth} % was 3\emwidth - \newdimen\d_strc_formulas_display_skip_left \newdimen\d_strc_formulas_display_skip_right \newdimen\d_strc_formulas_display_margin_left \newdimen\d_strc_formulas_display_margin_right \newdimen\d_strc_formulas_display_pre_threshold -\newskip \d_strc_formulas_display_skip_par +\newdimen\d_strc_formulas_display_width -\unexpanded\def\beforedisplayspace - {\edef\p_spacebefore{\formulaparameter\c!spacebefore}% - \ifx\p_spacebefore\v!none \else - \blank[\p_spacebefore]% +\newconstant\c_strc_formulas_mode % this will go away +\newconstant\c_strc_formulas_space_model + +\c_strc_formulas_mode \plustwo % 0=native 1=simple (old) 2=align (new) +\c_strc_formulas_space_model\plusthree % replaces \plusone + +\newconditional\c_strc_formulas_tight + +\newbox\b_strc_formulas_number +\newbox\b_strc_formulas_content + +\def\strc_formulas_flush_content_and_number + {\noindentation + % \dontleavehmode + \kern\d_strc_formulas_display_margin_left + \ifcase\wd\b_strc_formulas_number + \hbox to \displaywidth \bgroup + \hfill + \box\b_strc_formulas_content + \hfill + \egroup + \else\ifdim\dimexpr\wd\b_strc_formulas_content+\wd\b_strc_formulas_number\relax>\displaywidth + \vbox \bgroup + \hsize\displaywidth + \box\b_strc_formulas_content + \par + \ifx\p_location\v!left + \box\b_strc_formulas_number\hfill + \else + \hfill\box\b_strc_formulas_number + \fi + \egroup + \else + \hbox to \displaywidth \bgroup + \ifx\p_location\v!left + \rlap{\box\b_strc_formulas_number}% + \hfill\box\b_strc_formulas_content\hfill + \else + \hfill\box\b_strc_formulas_content\hfill + \llap{\box\b_strc_formulas_number}% + \fi + \egroup + \fi\fi} + +\installcorenamespace{mathdisplayspacemodel} + +\setvalue{\??mathdisplayspacemodel\v!before:1}% old + {\ifx\p_spacebefore\v!none + % nothing + \else + \directvspacing\p_spacebefore + \fi} + +\setvalue{\??mathdisplayspacemodel\v!after:1}% old + {\prevdepth .5\strutdp + \edef\p_spaceafter{\formulaparameter\c!spaceafter}% + \ifx\p_spaceafter\v!none + % nothing + \else + \directvspacing\p_spaceafter \fi} +\setvalue{\??mathdisplayspacemodel\v!before:2}% old + {\ifx\p_spacebefore\v!none + % nothing + \else + \directvspacing\p_spacebefore + \fi + \prevdepth-\maxdimen} % texbook pagina 79-80 + +\setvalue{\??mathdisplayspacemodel\v!after:2}% old + {\prevdepth\lineheight + \edef\p_spaceafter{\formulaparameter\c!spaceafter}% + \ifx\p_spaceafter\v!none + % nothing + \else + \directvspacing\p_spaceafter + \fi} + +\def\strc_math_obey_depth + {\ifvmode\ifdim\prevdepth<\zeropoint\else\ifdim\prevdepth<\strutdp + % maybe add a tracing option here + \ifgridsnapping + \directvspacing\v!depth + \else + \kern\dimexpr\strutdp-\prevdepth\relax + \prevdepth\strutdp + \fi + \fi\fi\fi} + +\setvalue{\??mathdisplayspacemodel\v!before:3}% + {% not ok, try \stopformula\par\startformula vs \stopformula\startformula + \ifdim\lastskip>\zeropoint + % bah + \else + \strc_math_obey_depth % somehow \fakenextstrutline doesn't work here + \nointerlineskip + \fi + \ifx\p_spacebefore\v!none + % nothing + \else\ifx\p_spaceafter\empty + \directvspacing\currentvspacing + \else + \directvspacing\p_spacebefore + \fi\fi} + +\setvalue{\??mathdisplayspacemodel\v!after:3}% + {\prevdepth\strutdp % \directvspacing\v!depth + \ifx\p_spaceafter\v!none + % nothing + \else\ifx\p_spaceafter\empty + \directvspacing\currentvspacing + \else + \directvspacing\p_spaceafter + \fi\fi} + +% \newtoks\everybeforedisplay +% \appendtoks\page_sides_check_floats_indeed\to\everybeforedisplay + +\unexpanded\def\beforedisplayspace + {\ifhmode + \par + \fi + \ifvmode + \edef\p_spacebefore{\formulaparameter\c!spacebefore}% + \begincsname\??mathdisplayspacemodel\v!before:\number\c_strc_formulas_space_model\endcsname + \fi + \ifhmode + \par + \fi + \page_sides_check_floats_indeed} % probably needs more + \unexpanded\def\afterdisplayspace - {\edef\p_spaceafter{\formulaparameter\c!spaceafter}% - \ifx\p_spaceafter\v!none \else - \blank[\p_spaceafter]% + {\ifhmode + \par + \fi + \ifvmode + \edef\p_spaceafter{\formulaparameter\c!spaceafter}% + \begincsname\??mathdisplayspacemodel\v!after:\number\c_strc_formulas_space_model\endcsname + \fi + \ifhmode + \par \fi} \unexpanded\def\setdisplaydimensions - {\displayindent\d_strc_formulas_display_skip_left - \advance\displayindent\d_strc_formulas_display_margin_left - \displaywidth\hsize + {\displayindent\dimexpr + \d_strc_formulas_display_skip_left + +\d_strc_formulas_display_margin_left + \relax + \displaywidth\d_strc_formulas_display_width %\setlocalhsize %\displaywidth\localhsize \ifdim\hangindent>\zeropoint @@ -579,7 +700,11 @@ \else \advance\displaywidth\hangindent \fi - \advance\displaywidth\dimexpr-\displayindent-\d_strc_formulas_display_skip_right-\d_strc_formulas_display_margin_right\relax + \advance\displaywidth\dimexpr + -\displayindent + -\d_strc_formulas_display_skip_right + -\d_strc_formulas_display_margin_right + \relax \hsize\displaywidth} % new, else overfull in itemize \unexpanded\def\strc_formulas_start_formula#1% @@ -595,40 +720,69 @@ %D %D \typebuffer \getbuffer +\setvalue{\??formulaoption\v!packed}% + {\c_strc_formulas_space_model\zerocount} + +\setvalue{\??formulaoption\v!tight}% + {\settrue\c_strc_formulas_tight} + +\setvalue{\??formulaoption\v!middle}% + {\d_strc_formulas_display_skip_left \zeropoint + \d_strc_formulas_display_skip_right\zeropoint} + +\setvalue{\??formulaoption\v!line}% + {\ifgridsnapping + \setformulaparameter\c!grid{\v!math:\v!line}% + \fi} + +\setvalue{\??formulaoption\v!halfline}% + {\ifgridsnapping + \setformulaparameter\c!grid{\v!math:\v!halfline}% + \fi} + +\setvalue{\??formulaoption-\v!line}% + {\ifgridsnapping + \setformulaparameter\c!grid{\v!math:-\v!line}% + \fi} + +\setvalue{\??formulaoption-\v!halfline}% + {\ifgridsnapping + \setformulaparameter\c!grid{\v!math:-\v!halfline}% + \fi} + \unexpanded\def\strc_formulas_start_formula_indeed[#1][#2]% setting leftskip adaption is slow ! - {\bgroup % HERE + {\ifhmode + \par + \fi + \bgroup % HERE \def\currentformula{#1}% \dostarttaggedchained\t!formula\currentformula\??formula - \the\everybeforedisplayformula - \d_strc_formulas_display_skip_par\parskip\relax - %\formulastrutdp\strutdepth - %\formulastrutht\strutheight - \edef\p_option {\formulaparameter\c!option}% - \edef\p_margin {\formulaparameter\c!margin}% - \edef\p_bodyfont{#2}% - %\ifx\p_bodyfont\empty - % \edef\p_bodyfont{\formulaparameter\c!bodyfont}% - %\fi - \ifx\p_bodyfont\empty \else - \switchtoformulabodyfont[#2]% - \fi - \parskip\d_strc_formulas_display_skip_par\relax - \ifx\p_option\v!middle - \d_strc_formulas_display_skip_left \zeropoint - \d_strc_formulas_display_skip_right\zeropoint + \setfalse\c_strc_formulas_tight + \d_strc_formulas_display_skip_left \leftskip + \d_strc_formulas_display_skip_right \rightskip + \d_strc_formulas_display_width \formulaparameter\c!width\relax + \d_strc_formulas_display_margin_left \formulaparameter\c!leftmargin\relax + \d_strc_formulas_display_margin_right\formulaparameter\c!rightmargin\relax + \ifsecondargument + \doifelseassignment{#2}% this is new, so that we can also set the grid + {\setupcurrentformula[#2]% + \edef\p_option{\formulaparameter\c!option}}% + {\edef\p_option{\formulaparameter\c!option}% + \edef\p_option{\ifx\p_option\empty\else\p_option,\fi#2}}% \else - \d_strc_formulas_display_skip_left \leftskip - \d_strc_formulas_display_skip_right\rightskip + \edef\p_option{\formulaparameter\c!option} \fi - \d_strc_formulas_display_margin_left \formulaparameter\c!leftmargin \relax - \d_strc_formulas_display_margin_right\formulaparameter\c!rightmargin\relax + \ifx\p_option\empty \else + \rawprocesscommacommand[\p_option]\strc_formulas_option + \fi + \edef\p_margin{\formulaparameter\c!margin}% \ifx\p_margin\empty \else \dosetleftskipadaption\p_margin \d_strc_formulas_display_margin_left\leftskipadaption \fi \let\strc_formulas_start_formula\strc_formulas_start_formula_nested - %\freezedimenmacro\predisplaysizethreshhold \strc_formulas_forget_display_skips + \the\everybeforedisplayformula \csname\e!start\formulaparameter\c!alternative\v!formula\endcsname} \unexpanded\def\strc_formulas_start_formula_nested#1% @@ -643,9 +797,8 @@ % tagging of formulanumbers is not ok (we get two display maths blobs) \unexpanded\def\strc_formulas_stop_formula - {\dostarttagged\t!formulacaption\empty - \strc_formulas_place_number - \dostoptagged + {\strc_formulas_place_number % in case it hasn't happened yet + \strc_formulas_flush_number % in case we are in native mode \dostarttagged\t!formulacontent\empty \csname\e!stop\formulaparameter\c!alternative\v!formula\endcsname \dostoptagged @@ -661,23 +814,28 @@ % experiment: -\appendtoks - \edef\p_grid{\formulaparameter\c!grid}% +\def\strc_formulas_set_grid_snapping + {\edef\p_grid{\formulaparameter\c!grid}% \ifx\p_grid\empty \else \spac_grids_snap_value_auto\p_grid - \fi + \fi} + +\appendtoks + \ifgridsnapping + \strc_formulas_set_grid_snapping + \fi \to \everybeforedisplayformula -\unexpanded\def\switchtoformulabodyfont - {\switchtobodyfont} +% \unexpanded\def\switchtoformulabodyfont +% {\switchtobodyfont} \setuvalue{\v!formula}{\dosingleempty\strc_formulas_formula} \def\strc_formulas_formula[#1]#2% todo: tagged {\begingroup - \edef\p_bodyfont{#1}% - \ifx\p_bodyfont\empty \else - \switchtoformulabodyfont[\p_bodyfont]% + \edef\p_direct{#1}% + \ifx\p_direct\empty \else + \rawprocesscommalist[\p_direct]\strc_formulas_option \fi % not : \def\strc_formulas_formula[##1]##2{\mathematics{##2}}% \mathematics{#2}% @@ -690,68 +848,40 @@ %D \startformula x \stopformula % now has \noindent (in mkii we messed with baselineskip) %D \stoptyping -% \unexpanded\def\startdisplaymath -% {\bgroup -% \par -% \informulatrue -% \beforedisplayspace -% \par -% \ifvmode -% \prevdepth-\maxdimen % texbook pagina 79-80 -% \fi -% \noindent % else funny hlist with funny baselineskip -% $$% \Ucheckedstartdisplaymath -% \setdisplaydimensions -% \startinnermath} -% -% \unexpanded\def\stopdisplaymath -% {\stopinnermath -% $$% \Ucheckedstopdisplaymath -% \par -% \afterdisplayspace -% \par -% \egroup} - -\newconstant\c_strc_formulas_space_model - -\c_strc_formulas_space_model\plusone -%c_strc_formulas_space_model\plustwo % needs chdcking with spac-ver - \unexpanded\def\startdisplaymath - {\bgroup - \par + {\ifhmode + \par + \fi + \bgroup \informulatrue \beforedisplayspace - \par - \ifvmode - \ifcase\c_strc_formulas_space_model - % nothing - \or - % nothing yet - \or - \prevdepth-\maxdimen % texbook pagina 79-80 - \fi - \fi - \noindent % else funny hlist with funny baselineskip - \Ucheckedstartdisplaymath \setdisplaydimensions - \startinnermath} + \ifcase\c_strc_formulas_mode + \noindent % prevents that tex injects empty line (when using native display mechanism) + \Ucheckedstartdisplaymath + \the\everydisplay % new (probably too much) + \or + \setbox\b_strc_formulas_content\hbox\bgroup + \normalUstartmath + \displaystyle + \the\everydisplay % new (probably too much) + \else + \expandafter\startinnermath + \fi + \begingroup} % less interference with upcoming a \over b \unexpanded\def\stopdisplaymath - {\stopinnermath - \Ucheckedstopdisplaymath - \par - \ifvmode - \ifcase\c_strc_formulas_space_model - % nothing - \or - \prevdepth .5\strutdp - \or - \prevdepth\lineheight - \fi + {\endgroup % less interference with upcoming a \over b + \ifcase\c_strc_formulas_mode + \Ucheckedstopdisplaymath + \or + \normalUstopmath + \egroup + \strc_formulas_flush_content_and_number + \else + \expandafter\stopinnermath \fi \afterdisplayspace - \par \egroup} % already defined @@ -821,49 +951,51 @@ \unexpanded\def\startformulas {\dosingleempty\strc_formulas_start_formulas} -\def\strc_formulas_start_formulas[#1]#2\stopformulas % new / to be internationalized - {\bgroup +\expandafter\let\csname\e!stop\v!formulas\endcsname\relax + +\unexpanded\def\strc_formulas_nested_formula_start + {\hbox to \displaywidth \bgroup + \hsize\displaywidth + \hss + %\Ustartmath + \dostarttagged\t!formulacontent\empty + \csname\e!start\formulaparameter\c!alternative\v!formula\endcsname} + +\unexpanded\def\strc_formulas_nested_formula_stop + {\csname\e!stop\formulaparameter\c!alternative\v!formula\endcsname + \dostoptagged + %\Ustopmath + \hss + \egroup + \hss} + +\normalexpanded{\def\noexpand\strc_formulas_start_formulas[#1]#2\csname\e!stop\v!formulas\endcsname}% + {\startformula \dostarttagged\t!formulaset\empty \global\settrue\c_strc_formulas_inside_formulas \edef\currentformulasreference{#1}% \strc_formulas_handle_number \let\currentformula\empty \strc_formulas_forget_display_skips - \startdisplaymath - \setlocalhsize - \unexpanded\def\startformula##1\stopformula - {\advance\scratchcounter\plusone}% + \unexpanded\def\startformula + {\advance\scratchcounter\plusone + \expandafter\gobbleuntil\csname\e!stop\v!formula\endcsname}% \scratchcounter\zerocount #2% preroll - \ifcase\scratchcounter\else - \divide \hsize \scratchcounter - \fi - \hbox to \localhsize \bgroup + \hbox to \displaywidth \bgroup + \divide\displaywidth\scratchcounter \hss \let\startformula\strc_formulas_nested_formula_start \let\stopformula \strc_formulas_nested_formula_stop #2% - \egroup - \stopdisplaymath + \egroup \global\setfalse\c_strc_formulas_inside_formulas \dostoptagged - \egroup + \stopformula \the\everyresetformulas \hangafter\minusone % added for side floats \hangindent\zeropoint} % added for side floats -\unexpanded\def\strc_formulas_nested_formula_start - {\Ustartmath - \vcenter\bgroup - \vskip-\strutdepth - \Ustartdisplaymath} - -\unexpanded\def\strc_formulas_nested_formula_stop - {\Ustopdisplaymath - \egroup - \Ustopmath - \hss} - % place \def\m_strc_formulas_flag_inhibit{-} @@ -890,16 +1022,14 @@ \unexpanded\def\strc_formulas_number_again[#1]% {\def\currentformulareference{#1}% - \strc_formulas_number_indeed} + \strc_formulas_place_number_in_box} \unexpanded\def\placeformula {\global\settrue\c_strc_formulas_inside_place - \settrue\c_strc_formulas_increment \dosingleempty\strc_formulas_place} \unexpanded\def\placesubformula {\global\settrue\c_strc_formulas_inside_place_sub - \setfalse\c_strc_formulas_increment \dosingleempty\strc_formulas_place} \unexpanded\def\strc_formulas_place[#1]% @@ -985,23 +1115,39 @@ \def\strc_formulas_place_number_nested_indeed#1#2% {\def\currentnestedformulareference{#1}% \def\currentnestedformulasuffix{#2}% - \glet\strc_formulas_place_number\relax \strc_formulas_check_reference\c_strc_formulas_nested_number_mode\currentnestedformulareference \ifcase\c_strc_formulas_nested_number_mode % nothing \or - \strc_formulas_number % hm, looks ahead for [] + \glet\strc_formulas_place_number\relax + \expandafter\strc_formulas_number % hm, looks ahead for [] \or % nothing \or - \strc_formulas_number % hm, looks ahead for [] + \glet\strc_formulas_place_number\relax + \expandafter\strc_formulas_number % hm, looks ahead for [] \fi} \def\strc_formulas_place_number_indeed - {\glet\strc_formulas_place_number\relax - \doifelse{\formulaparameter\c!location}\v!left - {\normalleqno{\strc_formulas_number_indeed}} - {\normalreqno{\strc_formulas_number_indeed}}} + {\strc_formulas_place_number_in_box} + +\def\strc_formulas_place_number_in_box + {\dostarttagged\t!formulacaption\empty + \global\setbox\b_strc_formulas_number\naturalhbox{\strc_formulas_number_indeed}% + \dostoptagged} + +\def\strc_formulas_flush_number + {\ifcase\c_strc_formulas_mode + \ifzeropt\wd\b_strc_formulas_number + % nothing to be done + \else + \ifx\p_location\v!left + \math_native_leqno{\box\b_strc_formulas_number}% + \else + \math_native_reqno{\box\b_strc_formulas_number}% + \fi + \fi + \fi} % todo diff --git a/tex/context/base/mkiv/strc-not.lua b/tex/context/base/mkiv/strc-not.lua index ddbd2ae06..eff357eea 100644 --- a/tex/context/base/mkiv/strc-not.lua +++ b/tex/context/base/mkiv/strc-not.lua @@ -26,8 +26,11 @@ local counterspecials = counters.specials local texgetcount = tex.getcount local texgetbox = tex.getbox +-- todo: allocate + notes.states = notes.states or { } lists.enhancers = lists.enhancers or { } +notes.numbers = notes.numbers or { } storage.register("structures/notes/states", notes.states, "structures.notes.states") @@ -143,6 +146,8 @@ end notes.setstate = setstate notes.getstate = getstate + + implement { name = "setnotestate", actions = setstate, @@ -157,6 +162,7 @@ implement { function notes.define(tag,kind,number) local state = setstate(tag,kind) + notes.numbers[number] = state state.number = number end @@ -448,3 +454,42 @@ function notes.internalid(tag,n) return r.internal end end + +-- for the moment here but better in some builder modules + +-- gets register "n" and location "i" (where 1 is before) + +-- this is an experiment, we will make a more general handler instead +-- of the current note one + +local report_insert = logs.reporter("pagebuilder","insert") +local trace_insert = false trackers.register("pagebuilder.insert",function(v) trace_insert = v end) + +local texgetglue = tex.getglue +local texsetglue = tex.setglue + +local function check_spacing(n,i) + local gn, pn, mn = texgetglue(n) + local gi, pi, mi = texgetglue(i > 1 and "s_strc_notes_inbetween" or "s_strc_notes_before") + local gt, pt, mt = gn+gi, pn+pi, mn+mi + if trace_insert then + report_insert("%s %i: %p plus %p minus %p","always ",n,gn,pn,mn) + report_insert("%s %i: %p plus %p minus %p",i > 1 and "inbetween" or "before ",n,gi,pi,mi) + report_insert("%s %i: %p plus %p minus %p","effective",n,gt,pt,mt) + end + return gt, pt, mt +end + +notes.check_spacing = check_spacing + +callback.register("build_page_insert", function(n,i) + local state = notes.numbers[n] + if state then + -- only notes, kind of hardcoded .. bah + local gt, pt, mt = check_spacing(n,i) + texsetglue(0,gt,pt,mt) -- for the moment we use skip register 0 + return 0 + else + return n + end +end) diff --git a/tex/context/base/mkiv/strc-not.mkvi b/tex/context/base/mkiv/strc-not.mkvi index 81d534937..db27cb5af 100644 --- a/tex/context/base/mkiv/strc-not.mkvi +++ b/tex/context/base/mkiv/strc-not.mkvi @@ -404,7 +404,11 @@ \setexpandednoteparameter\s!insert{\namednoteparameter\currentnoteparent\s!insert}% \definenotation[\currentnote][\currentnoteparent][\c!type=\v!note]% \fi - \clf_definenote{\currentnote}{insert}\currentnoteinsertionnumber\relax + \clf_definenote + {\currentnote}% + {insert}% + \currentnoteinsertionnumber + \relax \to \everydefinenote % maybe we will share this at some point: @@ -1053,17 +1057,55 @@ \newskip \s_strc_notes_distance % we need to implement stretch \newcount\c_strc_notes_columns +% \def\strc_notes_set_distance +% {\begingroup +% \setbox\scratchbox\vbox % no reuse as it can mirror +% {\forgetall +% \restoreglobalbodyfont % really needed +% \dontcomplain +% \noteparameter\c!before +% \placenoterule +% \noteparameter\c!after}% +% \expandafter\endgroup\expandafter +% \s_strc_notes_distance\the\htdp\scratchbox\relax} % also dp now + +\newskip \s_strc_notes_before +\newskip \s_strc_notes_inbetween +\newconditional\c_strc_notes_first_flushed + +\appendtoks + \edef\p_spacebefore{\rootnoteparameter\c!spacebefore}% + \ifx\p_spacebefore\empty + \global\s_strc_notes_before\zeropoint + \else + \setbox\scratchbox\vbox{\blank[\p_spacebefore]\global\s_strc_notes_before\lastskip}% + \fi + \edef\p_spaceinbetween{\rootnoteparameter\c!spaceinbetween}% + \ifx\p_spaceinbetween\empty + \global\s_strc_notes_inbetween\zeropoint + \else + \setbox\scratchbox\vbox{\blank[\p_spaceinbetween]\global\s_strc_notes_inbetween\lastskip}% + \fi +\to \everysynchronizenote + \def\strc_notes_set_distance {\begingroup + \restoreglobalbodyfont \setbox\scratchbox\vbox % no reuse as it can mirror {\forgetall - % \strc_notes_set_bodyfont \dontcomplain \noteparameter\c!before \placenoterule + \strut \noteparameter\c!after}% + % also dp now + \scratchdimen\dimexpr\htdp\scratchbox-\lineheight\relax + \ifgridsnapping + \getnoflines\scratchdimen + \scratchdimen\noflines\lineheight + \fi \expandafter\endgroup\expandafter - \s_strc_notes_distance\the\ht\scratchbox\relax} + \s_strc_notes_distance\the\scratchdimen\relax} \def\strc_notes_set_columns {\c_strc_notes_columns\noteparameter\c!n\relax @@ -1324,10 +1366,24 @@ \inheritmaintextcolor % but we do want to obey the textcolor \to \everybeforenoteinsert +% \def\strc_notes_set_penalties +% {\doif{\noteparameter\c!scope}\v!page{\floatingpenalty\maxdimen}% experiment +% %\interlinepenalty\maxdimen % todo +% \penalty\currentnotepenalty} + +\def\strc_notes_set_penalties + {% stored in insert node + \floatingpenalty \currentnotepenalty + % used when typesetting + \interlinepenalty\plushundred % plain value + % used when we need to split in columns + \ifnum\noteparameter\c!n>\plusone + \penalty\zerocount % otherwise no split in columns, maybe just always (tex just adds it to accumulated) + \fi} + + \appendtoks - \doif{\noteparameter\c!scope}\v!page{\floatingpenalty\maxdimen}% experiment - \penalty\currentnotepenalty - %\interlinepenalty\maxdimen % todo + \strc_notes_set_penalties \forgetall \strc_notes_set_bodyfont \redoconvertfont % to undo \undo calls in in headings etc @@ -1356,14 +1412,18 @@ % % \dorecurse{6}{\input tufte\footnote{\input ward \input tufte \relax}} +\newconditional\c_strc_notes_first_placed + \unexpanded\def\placenoteinserts - {\strc_notes_process\strc_notes_place_inserts} + {\setfalse\c_strc_notes_first_placed + \strc_notes_process\strc_notes_place_inserts} \def\strc_notes_place_inserts {\strc_notes_set_delayed % \strc_notes_synchronize % we need to know if it's delayed \ifconditional\c_strc_notes_delayed \else \ifdim\ht\currentnoteinsertionnumber>\zeropoint % or a faster delayed test \strc_notes_place_inserts_indeed + \settrue\c_strc_notes_first_placed \fi \fi} @@ -1373,6 +1433,17 @@ \endgraf \ifvmode \whitespace + \ifconditional\c_strc_notes_first_placed + \edef\p_spaceinbetween{\noteparameter\c!spaceinbetween}% + \ifx\p_spaceinbetween\empty\else + \blank[\p_spaceinbetween]% + \fi + \else + \edef\p_spacebefore{\noteparameter\c!spacebefore}% + \ifx\p_spacebefore\empty\else + \blank[\p_spacebefore]% + \fi + \fi \noteparameter\c!before \fi \placenoterule diff --git a/tex/context/base/mkiv/strc-num.lua b/tex/context/base/mkiv/strc-num.lua index 0203334ff..98db1b42d 100644 --- a/tex/context/base/mkiv/strc-num.lua +++ b/tex/context/base/mkiv/strc-num.lua @@ -9,6 +9,7 @@ if not modules then modules = { } end modules ['strc-num'] = { local format = string.format local next, type = next, type local min, max = math.min, math.max +local insert, remove, copy = table.insert, table.remove, table.copy local texsetcount = tex.setcount -- Counters are managed here. They can have multiple levels which makes it easier to synchronize @@ -16,6 +17,7 @@ local texsetcount = tex.setcount local allocate = utilities.storage.allocate local setmetatableindex = table.setmetatableindex +local setmetatablecall = table.setmetatablecall local trace_counters = false trackers.register("structures.counters", function(v) trace_counters = v end) local report_counters = logs.reporter("structure","counters") @@ -38,9 +40,6 @@ local v_previous = variables.previous local v_prev = variables.prev local v_last = variables.last ----- v_no = variables.no -local v_backward = variables.backward -local v_forward = variables.forward ------ v_subs = variables.subs or "subs" -- states: start stop none reset @@ -166,7 +165,7 @@ local function enhance() enhance = nil end -local function allocate(name,i) -- can be metatable +local function allocate(name,i) -- can be metatable but it's a bit messy local cd = counterdata[name] if not cd then cd = { @@ -183,20 +182,24 @@ local function allocate(name,i) -- can be metatable cd = cd.data local ci = cd[i] if not ci then - ci = { - number = 0, - start = 0, - saved = 0, - step = 1, - range = 1, - offset = false, - stop = 0, -- via metatable: last, first, stop only for tracing - } - setmetatableindex(ci, function(t,s) return constructor[s](t,name,i) end) - cd[i] = ci - tobesaved[name][i] = { } - else - if enhance then enhance() end -- not stored in bytecode + for i=1,i do + if not cd[i] then + ci = { + number = 0, + start = 0, + saved = 0, + step = 1, + range = 1, + offset = false, + stop = 0, -- via metatable: last, first, stop only for tracing + } + setmetatableindex(ci, function(t,s) return constructor[s](t,name,i) end) + cd[i] = ci + tobesaved[name][i] = { } + end + end + elseif enhance then + enhance() -- not stored in bytecode end return ci end @@ -432,14 +435,23 @@ end function counters.save(name) -- or just number local cd = counterdata[name] if cd then - table.insert(cd.saved,table.copy(cd.data)) + insert(cd.saved,copy(cd.data)) end end function counters.restore(name) local cd = counterdata[name] - if cd and cd.saved then - cd.data = table.remove(cd.saved) + if not cd then + report_counters("invalid restore, no counter %a",name) + return + end + local saved = cd.saved + if not saved then + -- is ok + elseif #saved > 0 then + cd.data = remove(saved) + else + report_counters("restore without save for counter %a",name) end end @@ -623,7 +635,7 @@ implement { name = "countervalue", actions = { counters.value , con implement { name = "lastcountervalue", actions = { counters.last , context }, arguments = { "string", 1 } } implement { name = "firstcountervalue", actions = { counters.first , context }, arguments = { "string", 1 } } implement { name = "nextcountervalue", actions = { counters.next , context }, arguments = { "string", 1 } } -implement { name = "prevcountervalue", actions = { counters.previous, context }, arguments = { "string", 1 } } +implement { name = "previouscountervalue", actions = { counters.previous, context }, arguments = { "string", 1 } } implement { name = "subcountervalues", actions = { counters.subs , context }, arguments = { "string", 1 } } implement { name = "rawsubcountervalue", actions = { counters.raw , context }, arguments = { "string", "integer" } } @@ -643,7 +655,7 @@ implement { name = "decrementedcounter", actions = { add, context }, argume implement { name = "showcounter", actions = showcounter, arguments = "string" } -- todo implement { name = "checkcountersetup", actions = checkcountersetup, arguments = { "string", "integer", "integer", "string" } } -table.setmetatablecall(counterdata,function(t,k) return t[k] end) +setmetatablecall(counterdata,function(t,k) return t[k] end) implement { name = "doifelsecounter", actions = { counterdata, commands.doifelse }, arguments = "string" } implement { name = "doifcounter", actions = { counterdata, commands.doif }, arguments = "string" } diff --git a/tex/context/base/mkiv/strc-num.mkiv b/tex/context/base/mkiv/strc-num.mkiv index 2418130f9..4b222801a 100644 --- a/tex/context/base/mkiv/strc-num.mkiv +++ b/tex/context/base/mkiv/strc-num.mkiv @@ -545,7 +545,7 @@ \clf_setdestinationattribute {% references {% - internal \nextinternalreference + internal \locationcount % block {\currentsectionblock}% move to lua view {\interactionparameter\c!focus}% prefix {\currentstructurecomponentreferenceprefix}% @@ -621,7 +621,7 @@ \fi } references { - internal \nextinternalreference + internal \locationcount % block {\currentsectionblock} reference {\currentstructurecomponentreference} prefix {\currentstructurecomponentreferenceprefix} @@ -670,10 +670,10 @@ \relax \xdef\m_strc_counters_last_registered_index{\the\scratchcounter}% \clf_setinternalreference - internal \nextinternalreference + internal \locationcount \relax \xdef\m_strc_counters_last_registered_attribute {\the\lastdestinationattribute}% - \xdef\m_strc_counters_last_registered_synchronize{\strc_lists_inject_enhance{\m_strc_counters_last_registered_index}{\nextinternalreference}}} + \xdef\m_strc_counters_last_registered_synchronize{\strc_lists_inject_enhance{\m_strc_counters_last_registered_index}{\the\locationcount}}} \let\m_strc_counters_last_registered_index \relax \let\m_strc_counters_last_registered_attribute \relax diff --git a/tex/context/base/mkiv/strc-pag.mkiv b/tex/context/base/mkiv/strc-pag.mkiv index 0a55fb45f..21758d671 100644 --- a/tex/context/base/mkiv/strc-pag.mkiv +++ b/tex/context/base/mkiv/strc-pag.mkiv @@ -23,7 +23,7 @@ \countdef\realpageno \zerocount \realpageno \plusone \countdef\userpageno \plusone \userpageno \plusone -\countdef\subpageno \plustwo \subpageno \zerocount % ! +\countdef\subpageno \plustwo \subpageno \plusone % was \zerocount but that doesn't work well with bytext \countdef\arrangeno \plusthree \arrangeno \zerocount % ! \countdef\pagenoshift\plusfour \pagenoshift\zerocount % ! \countdef\lastpageno \plusfive \lastpageno \zerocount % ! @@ -307,12 +307,16 @@ \installdirectcommandhandler \??pagenumbering {pagenumbering} +% some day ifsinglesided and ifdoublesided will become obsolete + \appendtoks \singlesidedfalse \setfalse\layoutisdoublesided \doublesidedfalse \setfalse\layoutissinglesided + \resetsystemmode\v!singlesided + \resetsystemmode\v!doublesided \processallactionsinset[\directpagenumberingparameter\c!alternative] - [ \v!singlesided=>\singlesidedtrue\settrue\layoutissinglesided, - \v!doublesided=>\doublesidedtrue\settrue\layoutisdoublesided]% + [ \v!singlesided=>\setsystemmode\v!singlesided\singlesidedtrue\settrue\layoutissinglesided, + \v!doublesided=>\setsystemmode\v!doublesided\doublesidedtrue\settrue\layoutisdoublesided]% \ifdefined\trackingmarginnotestrue \ifdoublesided \trackingmarginnotestrue diff --git a/tex/context/base/mkiv/strc-ref.lua b/tex/context/base/mkiv/strc-ref.lua index 70d79dc57..a9a7c7121 100644 --- a/tex/context/base/mkiv/strc-ref.lua +++ b/tex/context/base/mkiv/strc-ref.lua @@ -20,6 +20,7 @@ local rawget, tonumber, type = rawget, tonumber, type local lpegmatch = lpeg.match local insert, remove, copytable = table.insert, table.remove, table.copy local formatters = string.formatters +local P, Cs, lpegmatch = lpeg.P, lpeg.Cs, lpeg.match local allocate = utilities.storage.allocate local mark = utilities.storage.mark @@ -33,9 +34,7 @@ local trace_empty = false trackers.register("structures.referencing.empt local check_duplicates = true -directives.register("structures.referencing.checkduplicates", function(v) - check_duplicates = v -end) +directives.register("structures.referencing.checkduplicates", function(v) check_duplicates = v end) local report_references = logs.reporter("references") local report_unknown = logs.reporter("references","unknown") @@ -44,10 +43,6 @@ local report_importing = logs.reporter("references","importing") local report_empty = logs.reporter("references","empty") local variables = interfaces.variables -local v_default = variables.default -local v_url = variables.url -local v_file = variables.file -local v_unknown = variables.unknown local v_page = variables.page local v_auto = variables.auto local v_yes = variables.yes @@ -127,20 +122,18 @@ local componentsplitter = references.componentsplitter local currentreference = nil local txtcatcodes = catcodes.numbers.txtcatcodes -- or just use "txtcatcodes" -local context_delayed = context.delayed - -local ctx_pushcatcodes = context.pushcatcodes -local ctx_popcatcodes = context.popcatcodes -local ctx_dofinishreference = context.dofinishreference -local ctx_dofromurldescription = context.dofromurldescription -local ctx_dofromurlliteral = context.dofromurlliteral -local ctx_dofromfiledescription = context.dofromfiledescription -local ctx_dofromfileliteral = context.dofromfileliteral -local ctx_expandreferenceoperation = context.expandreferenceoperation -local ctx_expandreferencearguments = context.expandreferencearguments -local ctx_getreferencestructureprefix = context.getreferencestructureprefix -local ctx_convertnumber = context.convertnumber -local ctx_emptyreference = context.emptyreference + +local ctx_pushcatcodes = context.pushcatcodes +local ctx_popcatcodes = context.popcatcodes +local ctx_dofinishreference = context.dofinishreference +local ctx_dofromurldescription = context.dofromurldescription +local ctx_dofromurlliteral = context.dofromurlliteral +local ctx_dofromfiledescription = context.dofromfiledescription +local ctx_dofromfileliteral = context.dofromfileliteral +local ctx_expandreferenceoperation = context.expandreferenceoperation +local ctx_expandreferencearguments = context.expandreferencearguments +local ctx_convertnumber = context.convertnumber +local ctx_emptyreference = context.emptyreference storage.register("structures/references/defined", references.defined, "structures.references.defined") @@ -586,13 +579,24 @@ end) -- urls -local urls = references.urls or { } -references.urls = urls -local urldata = urls.data or { } -urls.data = urldata +local urls = references.urls or { } +references.urls = urls +local urldata = urls.data or { } +urls.data = urldata + +local p_untexurl = Cs ( ( + P("\\")/"" * (P("%")/"%%" + P(1)) + + P(" ")/"%%20" + + P(1) +)^1 ) + +function urls.untex(url) + return lpegmatch(p_untexurl,url) or url +end function urls.define(name,url,file,description) if name and name ~= "" then + -- url = lpegmatch(replacer,url) urldata[name] = { url or "", file or "", description or url or file or ""} end end @@ -790,10 +794,6 @@ implement { -- shared by urls and files --- function references.whatfrom(name) --- context((urldata[name] and v_url) or (filedata[name] and v_file) or v_unknown) --- end - function references.from(name) local u = urldata[name] if u then @@ -896,6 +896,26 @@ local function resolve(prefix,reference,args,set) -- we start with prefix,refere if var then var.reference = ri local vo, vi = var.outer, var.inner + -- we catch this here .. it's a way to pass references with commas + if vi == "name" then + local arguments = var.arguments + if arguments then + vi = arguments + var.inner = arguments + var.reference = arguments + var.arguments = nil + end + elseif var.special == "name" then + local operation = var.operation + if operation then + vi = operation + var.inner = operation + var.reference = operation + var.operation = nil + var.special = nil + end + end + -- end of catch if not vo and vi then -- to be checked d = defined[prefix][vi] or defined[""][vi] @@ -2507,8 +2527,8 @@ implement { arguments = { "string", "boolean", "boolean" } } -local function referencerealpage(actions) - actions = actions or references.currentset +local function referencerealpage() + local actions = references.currentset return not actions and 0 or actions.realpage or setreferencerealpage(actions) end diff --git a/tex/context/base/mkiv/strc-ref.mkvi b/tex/context/base/mkiv/strc-ref.mkvi index 96cb61b4a..9f2a7b91c 100644 --- a/tex/context/base/mkiv/strc-ref.mkvi +++ b/tex/context/base/mkiv/strc-ref.mkvi @@ -219,7 +219,7 @@ \clf_setdestinationattribute {% references {% - internal \nextinternalreference + internal \locationcount % block {\currentsectionblock}% view {\interactionparameter\c!focus}% \ifx\referenceprefix\empty\else @@ -281,7 +281,7 @@ \clf_setdestinationattribute {% references {% - internal \nextinternalreference + internal \locationcount % block {\currentsectionblock}% view {\interactionparameter\c!focus}% \ifx\referenceprefix\empty\else @@ -310,7 +310,7 @@ \clf_setdestinationattribute {% references {% - internal \nextinternalreference + internal \locationcount % block {\currentsectionblock}% view {\interactionparameter\c!focus}% \ifx\referenceprefix\empty\else @@ -401,7 +401,7 @@ prefix {\referenceprefix}% \fi reference {#label}% - internal \nextinternalreference + internal \locationcount }% metadata {% kind {\s!page}% @@ -424,7 +424,7 @@ references {% view {\interactionparameter\c!focus}% reference {#label}% - internal \nextinternalreference + internal \locationcount }% metadata {% kind {\s!page}% @@ -847,7 +847,7 @@ \letvalue{\??savedinternalreference\s!default}\!!zerocount \unexpanded\def\storeinternalreference#1#2% - {\setxvalue{\??savedinternalreference\currentstructurename}{#2}} + {\setxvalue{\??savedinternalreference\currentstructurename}{\number#2}} \newconditional\preferpagereferences diff --git a/tex/context/base/mkiv/strc-reg.lua b/tex/context/base/mkiv/strc-reg.lua index 66c264a49..32924ad81 100644 --- a/tex/context/base/mkiv/strc-reg.lua +++ b/tex/context/base/mkiv/strc-reg.lua @@ -9,8 +9,7 @@ if not modules then modules = { } end modules ['strc-reg'] = { local next, type = next, type local format, gmatch = string.format, string.gmatch local equal, concat, remove = table.are_equal, table.concat, table.remove -local utfchar = utf.char -local lpegmatch = lpeg.match +local lpegmatch, P, C, Ct = lpeg.match, lpeg.P, lpeg.C, lpeg.Ct local allocate = utilities.storage.allocate local trace_registers = false trackers.register("structures.registers", function(v) trace_registers = v end) @@ -43,7 +42,6 @@ local v_yes = variables.yes local v_packed = variables.packed local v_current = variables.current local v_previous = variables.previous -local v_next = variables.next local v_first = variables.first local v_last = variables.last local v_text = variables.text @@ -64,9 +62,6 @@ local internalreferences = references.internals local setinternalreference = references.setinternalreference local setmetatableindex = table.setmetatableindex -local texsetattribute = tex.setattribute - -local a_destination = attributes.private('destination') local absmaxlevel = 5 -- \c_strc_registers_maxlevel @@ -441,7 +436,13 @@ implement { arguments = { "string", "string" } } -local entrysplitter = lpeg.tsplitat('+') -- & obsolete in mkiv + +local p_s = P("+") +local p_e = P("&") * (1-P(";"))^0 * P(";") +local p_r = C((p_e + (1-p_s))^0) + +local entrysplitter_xml = Ct(p_r * (p_s * p_r)^0) -- bah +local entrysplitter_tex = lpeg.tsplitat('+') -- & obsolete in mkiv local tagged = { } @@ -472,6 +473,7 @@ local function preprocessentries(rawdata) local kt = entries.keys local entryproc = processors and processors.entry local pageproc = processors and processors.page + local coding = rawdata.metadata.coding if entryproc == "" then entryproc = nil end @@ -483,14 +485,14 @@ local function preprocessentries(rawdata) if p then entryproc = p end - et = lpegmatch(entrysplitter,e) + et = lpegmatch(coding == "xml" and entrysplitter_xml or entrysplitter_tex,e) end if not kt then local p, k = splitprocessor(entries.key or "") if p then pageproc = p end - kt = lpegmatch(entrysplitter,k) + kt = lpegmatch(coding == "xml" and entrysplitter_xml or entrysplitter_tex,k) end -- entries = { } @@ -1071,6 +1073,8 @@ local function collapsepages(pages) return #pages end +-- todo: create an intermediate structure and flush that + function registers.flush(data,options,prefixspec,pagespec) local compress = options.compress local collapse_singles = compress == v_yes diff --git a/tex/context/base/mkiv/strc-reg.mkiv b/tex/context/base/mkiv/strc-reg.mkiv index 5b32c6fc8..380cc9f22 100644 --- a/tex/context/base/mkiv/strc-reg.mkiv +++ b/tex/context/base/mkiv/strc-reg.mkiv @@ -298,7 +298,7 @@ userdata {\detokenize\expandafter{\normalexpanded{#3}}} }% \clf_setinternalreference - internal \nextinternalreference + internal \locationcount view {\interactionparameter\c!focus}% \relax % this will change \ifx\currentregisterownnumber\v!yes @@ -337,7 +337,7 @@ }% % overlap with the above % \clf_setinternalreference - % internal \nextinternalreference + % internal \locationcount % view {\interactionparameter\c!focus}% \relax % this will change \xdef\currentregistersynchronize{\ctxlatecommand{enhanceregister("\currentregister",\currentregisternumber)}}% @@ -524,7 +524,7 @@ }% }}% \clf_setinternalreference - internal \nextinternalreference + internal \locationcount view {\interactionparameter\c!focus}% \relax % this will change \dostarttagged\t!registerlocation\currentregister diff --git a/tex/context/base/mkiv/strc-ren.mkiv b/tex/context/base/mkiv/strc-ren.mkiv index 6bdd05de9..132f0f115 100644 --- a/tex/context/base/mkiv/strc-ren.mkiv +++ b/tex/context/base/mkiv/strc-ren.mkiv @@ -82,24 +82,24 @@ \def\headreferenceattributes {\iflocation - % \ctxlua{structures.lists.taglocation(\nextinternalreference)}% maybe ... tags entry as used + % \ctxlua{structures.lists.taglocation(\the\locationcount)}% maybe ... tags entry as used attr \destinationattribute \currentstructureattribute attr \referenceattribute \currentstructurereferenceattribute - % attr \internalattribute \nextinternalreference + % attr \internalattribute \locationcount \fi} \def\setinlineheadreferenceattributes {\ifconditional\headisdisplay \else \iflocation \attribute\destinationattribute\currentstructureattribute \attribute\referenceattribute \currentstructurereferenceattribute - % \attribute\internalattribute \nextinternalreference + % \attribute\internalattribute \locationcount \fi \fi} \def\docheckheadreference {\edef\currentheadinteraction{\headparameter\c!interaction}% \ifx\currentheadinteraction\v!list % setuphead[<section>][interaction=list,...] - \strc_references_get_simple_reference{*\nextinternalreference}% + \strc_references_get_simple_reference{*\the\locationcount}% \let\currentstructurereferenceattribute\currentreferenceattribute \else\ifx\currentheadinteraction\v!reference % setuphead[<section>][interaction=reference,...] start<section>[backreference=abc,...] @@ -167,18 +167,6 @@ % helpers -% \defineinmargin [ChapterInMargin] [outer] [normal] [distance=0.3em] -% -% \defineheadplacement[MyTest][horizontal]#1#2% -% {\startlocalheadsetup -% %\ChapterInMargin{\headhbox{\strut#2}}% proper destination, ref okay -% \ChapterInMargin{\strut#2}% zero destination, ref okay -% \stoplocalheadsetup} -% -% \setuphead -% [chapter] -% [alternative=MyTest] - \unexpanded\def\headhbox{\hbox\headreferenceattributes} \unexpanded\def\headvbox{\vbox\headreferenceattributes} @@ -320,28 +308,88 @@ \d_strc_rendering_hang_height\zeropoint \fi} +% \def\strc_rendering_stop_placement +% {\n_strc_rendering_hang_lines\zerocount +% \ifconditional\headisdisplay +% \strc_rendering_initialize_line_hang +% % kind of special, we want to snap heads also according to local specs local +% \ifgridsnapping +% \hbox\bgroup % extra hbox will trigger global snapper on top of local +% \edef\p_grid{\headparameter\c!grid}% +% \ifconditional\headisdisplay +% \ifx\p_grid\empty\else +% \useheadstyleandcolor\c!style\c!color +% \setupinterlinespace +% \useheadstyleandcolor\c!textstyle\c!textcolor +% \setupinterlinespace +% \fi +% \fi +% \snaptogrid[\p_grid]\hbox +% {\hskip\dimexpr\d_strc_rendering_local_leftoffset+\headparameter\c!margin\relax\box\b_strc_rendering_head}% +% \egroup +% \else +% \hbox +% {\hskip\dimexpr\d_strc_rendering_local_leftoffset+\headparameter\c!margin\relax\box\b_strc_rendering_head}% +% \fi +% \flushnotes % new, not really needed +% \endgraf +% \ifvmode +% \ifnum\n_strc_rendering_hang_lines>\zerocount +% \dorecurse\n_strc_rendering_hang_lines{\nointerlineskip\dosomebreak\nobreak\strut\endgraf}% to be checked +% \fi +% \nointerlineskip +% \dosomebreak\nobreak +% \fi +% \getheadsyncs +% \else +% % somehow this goes ok even when we push in the margin probably because we gobble pars +% % in the process of collecting index entries etc +% \strut +% \flushnotes % new, here since we're in par mode +% \unhbox\b_strc_rendering_head +% \getheadsyncs +% \ifconditional\headissomewhere +% % nothing special +% \else +% %\hskip\headnumberdistance\s!plus\headnumberdistance\s!minus.25\dimexpr\headnumberdistance\relax +% \hskip\headtextdistance\relax +% \strc_sectioning_inject_continuous_signal +% \fi +% \fi +% \ifconditional\headisdisplay +% \ifvmode +% \ifgridsnapping % important, font related depth, see comment +% \prevdepth\strutdp +% \else +% \prevdepth\d_strc_rendering_local_depth +% \fi +% \fi +% \fi +% \egroup +% \egroup +% \ifconditional\headisdisplay +% \useindentnextparameter\headparameter +% \else +% \nonoindentation % recently added, was a bug +% \fi} + \def\strc_rendering_stop_placement {\n_strc_rendering_hang_lines\zerocount \ifconditional\headisdisplay \strc_rendering_initialize_line_hang % kind of special, we want to snap heads also according to local specs local + \setbox\b_strc_rendering_head\hbox + {\hskip\dimexpr\d_strc_rendering_local_leftoffset+\headparameter\c!margin\relax + \box\b_strc_rendering_head}% \ifgridsnapping - \hbox\bgroup % extra hbox will trigger global snapper on top of local - \edef\p_grid{\headparameter\c!grid}% - \ifconditional\headisdisplay - \ifx\p_grid\empty\else - \useheadstyleandcolor\c!style\c!color - \setupinterlinespace - \useheadstyleandcolor\c!textstyle\c!textcolor - \setupinterlinespace - \fi - \fi - \snaptogrid[\p_grid]\hbox - {\hskip\dimexpr\d_strc_rendering_local_leftoffset+\headparameter\c!margin\relax\box\b_strc_rendering_head}% - \egroup + \applygridmethod + {\headparameter\c!grid}% + {\ifconditional\headisdisplay + \strc_rendering_initialize_style_and_color_display\c!textstyle\c!textcolor + \fi}% + {\box\b_strc_rendering_head} \else - \hbox - {\hskip\dimexpr\d_strc_rendering_local_leftoffset+\headparameter\c!margin\relax\box\b_strc_rendering_head}% + \box\b_strc_rendering_head \fi \flushnotes % new, not really needed \endgraf @@ -354,12 +402,19 @@ \fi \getheadsyncs \else + % somehow this goes ok even when we push in the margin probably because we gobble pars + % in the process of collecting index entries etc \strut \flushnotes % new, here since we're in par mode \unhbox\b_strc_rendering_head \getheadsyncs - \hskip\headnumberdistance\s!plus\headnumberdistance\s!minus.25\dimexpr\headnumberdistance\relax - \strc_sectioning_inject_continuous_signal + \ifconditional\headissomewhere + % nothing special + \else + %\hskip\headnumberdistance\s!plus\headnumberdistance\s!minus.25\dimexpr\headnumberdistance\relax + \hskip\headtextdistance\relax + \strc_sectioning_inject_continuous_signal + \fi \fi \ifconditional\headisdisplay \ifvmode @@ -453,6 +508,7 @@ \newdimen\headwidth \newdimen\headtextwidth +\newskip \headtextdistance \newdimen\headnumberdistance \newdimen\headnumberwidth @@ -470,16 +526,22 @@ \let\currentheadrenderingalternative\v!vertical \fi \ifx\currentheadrenderingalternative\v!horizontal - \global\setfalse\headisdisplay % global + \global\setfalse\headisdisplay % global + \global\setfalse\headissomewhere % global + \else\ifx\currentheadrenderingalternative\v!somewhere + \global\setfalse\headisdisplay % global + \global\settrue \headissomewhere % global \else - \global\settrue\headisdisplay % global - \fi} + \global\settrue \headisdisplay % global + \global\setfalse\headissomewhere % global + \fi\fi} \unexpanded\def\strc_rendering_initialize_dimensions - {\headwidth \headparameter\c!width \relax % \zeropoint == unset - \headnumberwidth \headparameter\c!numberwidth\relax % \zeropoint == unset - \headnumberdistance\headparameter\c!distance \relax - \headtextwidth \headparameter\c!textwidth \relax} % \zeropoint == unset + {\headwidth \headparameter\c!width \relax % \zeropoint == unset + \headnumberwidth \headparameter\c!numberwidth \relax % \zeropoint == unset + \headnumberdistance\headparameter\c!distance \relax + \headtextdistance \headparameter\c!textdistance\relax + \headtextwidth \headparameter\c!textwidth \relax} % \zeropoint == unset \unexpanded\def\headtextcontent {\begingroup @@ -626,23 +688,57 @@ [\c!alternative=\v!vertical, \c!renderingsetup=\??headrenderings:\v!inmargin] +% \startsetups[\??headrenderings:\v!inmargin] +% \vbox { +% \headsetupspacing +% \begstrut % use one \strut here! +% \dontleavehmode % in case there is no strut, else side effects with llap +% \ifconditional\headshownumber +% \llap { +% \signalrightpage +% \hbox { +% \hfill +% \headnumbercontent +% \doifelserightpage{ +% \scratchdistance\leftmargindistance +% } { +% \scratchdistance\rightmargindistance +% } +% \hskip\dimexpr\d_strc_rendering_local_leftoffset+\scratchdistance\relax +% } +% } +% \else +% \fakeheadnumbercontent % will also be done in the other ones (force consistency with numbered) +% \fi +% \headtextcontent +% } +% \stopsetups + \startsetups[\??headrenderings:\v!inmargin] \vbox { \headsetupspacing - \begstrut % use one \strut here! \dontleavehmode % in case there is no strut, else side effects with llap + \begstrut % use one \strut here! \ifconditional\headshownumber - \llap { - \signalrightpage - \hbox { - \hfill + \doifelsesomething {\headparameter\c!location} { + % kind of new + \margindata [\headparameter\c!location] { \headnumbercontent - \doifelserightpage{ - \scratchdistance\leftmargindistance - } { - \scratchdistance\rightmargindistance + } + } { + % normal backward compatible variant + \llap { + \signalrightpage + \hbox { + \hfill + \headnumbercontent + \doifelserightpage{ + \scratchdistance\leftmargindistance + } { + \scratchdistance\rightmargindistance + } + \hskip\dimexpr\d_strc_rendering_local_leftoffset+\scratchdistance\relax } - \hskip\dimexpr\d_strc_rendering_local_leftoffset+\scratchdistance\relax } } \else @@ -786,4 +882,9 @@ \fi \stopsetups +% see typo-mar.mkiv: +% +% \defineheadalternative +% [\v!margintext] + \protect \endinput diff --git a/tex/context/base/mkiv/strc-rsc.lua b/tex/context/base/mkiv/strc-rsc.lua index ee7f885e0..d7dc47827 100644 --- a/tex/context/base/mkiv/strc-rsc.lua +++ b/tex/context/base/mkiv/strc-rsc.lua @@ -125,6 +125,10 @@ references.splitcomponent = splitcomponent -- inspect(splitprefix([[component:::inner]])) -- inspect(splitprefix([[component:inner]])) +-- inspect(splitreference([[name(foo)]])) +-- inspect(splitreference([[name{foo}]])) +-- inspect(splitreference([[xx::name(foo, bar and me)]])) + -- inspect(splitreference([[ ]])) -- inspect(splitreference([[ inner ]])) -- inspect(splitreference([[ special ( operation { argument, argument } ) ]])) diff --git a/tex/context/base/mkiv/strc-sec.mkiv b/tex/context/base/mkiv/strc-sec.mkiv index 657e6c866..b0771b475 100644 --- a/tex/context/base/mkiv/strc-sec.mkiv +++ b/tex/context/base/mkiv/strc-sec.mkiv @@ -176,11 +176,11 @@ \globallet\currentstructurecoding\s!tex \fi \setnextinternalreference - \storeinternalreference\currentstructurename\nextinternalreference % + \storeinternalreference\currentstructurename{\the\locationcount}% \strc_sectioning_set_reference_prefix \clf_setsectionentry references { - internal \nextinternalreference\space + internal \locationcount % block {\currentsectionblock} prefix {\currentstructurereferenceprefix} reference {\currentstructurereference} @@ -225,7 +225,7 @@ numberdata { % block {\currentsectionblock} \ifx\currentstructureshownumber\v!no - hidenumber \space true\space + hidenumber \space true\space % space needed for parser \fi separatorset {\structureparameter\c!sectionseparatorset} conversionset {\structureparameter\c!sectionconversionset} @@ -345,6 +345,7 @@ %\c!deeptextcommand=, %\c!default=, \c!distance=\zeropoint, + \c!textdistance=\zeropoint, \c!textwidth=\zeropoint, % signal too \c!numberwidth=\zeropoint, % signal too \c!width=\zeropoint, % signal too @@ -444,7 +445,7 @@ \clf_registersection {\currenthead} { coupling {\currentsectionheadcoupling} section {\currentsectionheadsection} - level \currentsectionlevel + level \space \currentsectionlevel \space % space needed for parser parent {\currentheadparent} }% \endgroup @@ -660,8 +661,9 @@ \newconditional\c_strc_sectioning_empty \newconditional\c_strc_sectioning_hidden -\newconditional\headshownumber % public -\newconditional\headisdisplay % public +\newconditional\headshownumber % public +\newconditional\headisdisplay % public +\newconditional\headissomewhere % public \setvalue{\??headincrement\v!yes }{\settrue \c_strc_sectioning_increment\settrue \c_strc_sectioning_to_list} \setvalue{\??headincrement\v!no }{\setfalse\c_strc_sectioning_increment\setfalse\c_strc_sectioning_to_list} @@ -796,7 +798,7 @@ {\dontleavehmode \begingroup \unexpanded\def\\{\space}% messy here, but the default (and needs to be grouped) - \settrue\headisdisplay % triggers interlinespace checking + \global\settrue\headisdisplay % triggers interlinespace checking \edef\currenthead{#1}% \strc_rendering_initialize_style_and_color\c!textstyle\c!textcolor \relax @@ -807,7 +809,7 @@ \def\strc_sectioning_place_head_number[#1]% {\dontleavehmode \begingroup - \settrue\headisdisplay % triggers interlinespace checking + \global\settrue\headisdisplay % triggers interlinespace checking \edef\currenthead{#1}% \strc_rendering_initialize_style_and_color\c!numberstyle\c!numbercolor \relax diff --git a/tex/context/base/mkiv/strc-syn.lua b/tex/context/base/mkiv/strc-syn.lua index 5f3557a69..ecc5e19ae 100644 --- a/tex/context/base/mkiv/strc-syn.lua +++ b/tex/context/base/mkiv/strc-syn.lua @@ -227,7 +227,6 @@ function synonyms.flush(data,options) local result = data.result for i=1,#result do local sublist = result[i] - local letter = sublist.tag local data = sublist.data for d=1,#data do local entry = data[d].definition diff --git a/tex/context/base/mkiv/strc-tag.lua b/tex/context/base/mkiv/strc-tag.lua index 8f2e18978..9d1fec33e 100644 --- a/tex/context/base/mkiv/strc-tag.lua +++ b/tex/context/base/mkiv/strc-tag.lua @@ -315,7 +315,7 @@ function tags.start(tag,specification) metadata = nil end local userdata = specification.userdata - if user ~= "" and type(userdata) == "string" then + if userdata ~= "" and type(userdata) == "string" then specification.userdata = settings_to_hash(userdata) end local detail = specification.detail diff --git a/tex/context/base/mkiv/strc-tag.mkiv b/tex/context/base/mkiv/strc-tag.mkiv index c9132bf04..7fdfd7afa 100644 --- a/tex/context/base/mkiv/strc-tag.mkiv +++ b/tex/context/base/mkiv/strc-tag.mkiv @@ -215,8 +215,23 @@ \unexpanded\def\strc_tags_element_stop_nop {} +\def\strc_tags_report_hyphen#1% + {\writestatus\m!languages{setting #1 to U+00AD}} + +\unexpanded\def\strc_tags_patch_hyphen + {% for the moment here + \ifnum\languageparameter\s!lefthyphenchar>\zerocount + \setuplanguage[\s!default][\s!lefthyphenchar="AD]% + \strc_tags_report_hyphen\s!lefthyphenchar + \fi + \ifnum\languageparameter\s!righthyphenchar>\zerocount + \setuplanguage[\s!default][\s!righthyphenchar="AD]% + \strc_tags_report_hyphen\s!righthyphenchar + \fi + \let\strc_tags_report_hyphen\gobbleoneargument} + \unexpanded\def\strc_tags_enable_elements - {\setuplanguage[\s!default][\s!righthyphenchar="AD]% for the moment here + {\strc_tags_patch_hyphen \let\startelement\strc_tags_element_start_yes \let\stopelement \strc_tags_element_stop_yes \let\dosettagproperty\strc_tags_set_aspect_yes} diff --git a/tex/context/base/mkiv/supp-box.lua b/tex/context/base/mkiv/supp-box.lua index d3a4f57e5..b9bf0ccf0 100644 --- a/tex/context/base/mkiv/supp-box.lua +++ b/tex/context/base/mkiv/supp-box.lua @@ -12,66 +12,68 @@ local lpegmatch = lpeg.match local report_hyphenation = logs.reporter("languages","hyphenation") -local tex = tex -local context = context -local nodes = nodes - -local implement = interfaces.implement - -local splitstring = string.split - -local nodecodes = nodes.nodecodes - -local disc_code = nodecodes.disc -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local glue_code = nodecodes.glue -local kern_code = nodecodes.kern -local glyph_code = nodecodes.glyph - -local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode - -local getfield = nuts.getfield -local getnext = nuts.getnext -local getprev = nuts.getprev -local getdisc = nuts.getdisc -local getid = nuts.getid -local getlist = nuts.getlist -local getattribute = nuts.getattribute -local getbox = nuts.getbox - -local setfield = nuts.setfield -local setlink = nuts.setlink -local setboth = nuts.setboth -local setnext = nuts.setnext -local setbox = nuts.setbox -local setlist = nuts.setlist - -local free_node = nuts.free -local flush_list = nuts.flush_list -local copy_node = nuts.copy -local copy_list = nuts.copy_list -local find_tail = nuts.tail -local traverse_id = nuts.traverse_id -local link_nodes = nuts.linked -local dimensions = nuts.dimensions - -local listtoutf = nodes.listtoutf - -local nodepool = nuts.pool -local new_penalty = nodepool.penalty -local new_hlist = nodepool.hlist -local new_glue = nodepool.glue -local new_rule = nodepool.rule -local new_kern = nodepool.kern - -local setlistcolor = nodes.tracers.colors.setlist - -local texget = tex.get -local texgetbox = tex.getbox -local texsetdimen = tex.setdimen +local tex = tex +local context = context +local nodes = nodes + +local implement = interfaces.implement + +local nodecodes = nodes.nodecodes + +local disc_code = nodecodes.disc +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local glue_code = nodecodes.glue +local glyph_code = nodecodes.glyph + +local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode + +local getfield = nuts.getfield +local getnext = nuts.getnext +local getprev = nuts.getprev +local getdisc = nuts.getdisc +local getid = nuts.getid +local getlist = nuts.getlist +local getattribute = nuts.getattribute +local getbox = nuts.getbox +local getdir = nuts.getdir +local getwidth = nuts.getwidth +local takebox = nuts.takebox + +local setfield = nuts.setfield +local setlink = nuts.setlink +local setboth = nuts.setboth +local setnext = nuts.setnext +local setbox = nuts.setbox +local setlist = nuts.setlist +local setdisc = nuts.setdisc +local setwidth = nuts.setwidth +local setheight = nuts.setheight +local setdepth = nuts.setdepth + +local flush_node = nuts.flush_node +local flush_list = nuts.flush_list +local copy_node = nuts.copy +local copy_list = nuts.copy_list +local find_tail = nuts.tail +local traverse_id = nuts.traverse_id +local list_dimensions = nuts.dimensions +local hpack = nuts.hpack + +local listtoutf = nodes.listtoutf + +local nodepool = nuts.pool +local new_penalty = nodepool.penalty +local new_hlist = nodepool.hlist +local new_glue = nodepool.glue + +local setlistcolor = nodes.tracers.colors.setlist + +local texget = tex.get +local texgetbox = tex.getbox +local texsetdimen = tex.setdimen local function hyphenatedlist(head,usecolor) local current = head and tonut(head) @@ -81,12 +83,6 @@ local function hyphenatedlist(head,usecolor) local prev = getprev(current) if id == disc_code then local pre, post, replace = getdisc(current) - if pre then - setfield(current,"pre",nil) - end - if post then - setfield(current,"post",nil) - end if not usecolor then -- nothing fancy done elseif pre and post then @@ -99,25 +95,33 @@ local function hyphenatedlist(head,usecolor) end if replace then flush_list(replace) - setfield(current,"replace",nil) end - -- setfield(current,"replace",new_rule(65536)) -- new_kern(65536*2)) + setdisc(current) setboth(current) - local list = link_nodes ( +-- local list = setlink ( +-- pre and new_penalty(10000), +-- pre, +-- current, +-- post, +-- post and new_penalty(10000) +-- ) +-- local tail = find_tail(list) +-- if prev then +-- setlink(prev,list) +-- end +-- if next then +-- setlink(tail,next) +-- end + setlink ( + prev, -- there had better be one pre and new_penalty(10000), pre, current, post, - post and new_penalty(10000) + post and new_penalty(10000), + next ) - local tail = find_tail(list) - if prev then - setlink(prev,list) - end - if next then - setlink(tail,next) - end - -- free_node(current) + -- flush_node(current) elseif id == vlist_code or id == hlist_code then hyphenatedlist(getlist(current)) end @@ -335,7 +339,7 @@ implement { else tail = prev end - free_node(temp) + flush_node(temp) end -- done setnext(tail) @@ -354,9 +358,9 @@ implement { arguments = "integer", actions = function(n) local b = getbox(n) - local factor = texget("baselineskip").width / texget("hsize") - setfield(b,"depth",0) - setfield(b,"height",getfield(b,"width") * factor) + local factor = texget("baselineskip",false) / texget("hsize") + setdepth(b,0) + setheight(b,getwidth(b) * factor) end } @@ -372,7 +376,7 @@ local function getnaturaldimensions(n) local w, h, d = 0, 0, 0 local l = getlist(getbox(n)) if l then - w, h, d = dimensions(l) + w, h, d = list_dimensions(l) end texsetdimen("lastnaturalboxwd",w) texsetdimen("lastnaturalboxht",h) @@ -395,13 +399,42 @@ interfaces.implement { end } +interfaces.implement { + name = "getnaturalwd", + arguments = "integer", + actions = function(n) + local w, h, d = 0, 0, 0 + local l = getlist(getbox(n)) + if l then + w, h, d = list_dimensions(l) + end + context("\\dimexpr%i\\scaledpoint\\relax",w) + end +} + +local function setboxtonaturalwd(n) + local old = takebox(n) + local new = hpack(getlist(old)) + setlist(old,nil) + flush_node(old) + setbox(n,new) +end + +interfaces.implement { + name = "setnaturalwd", + arguments = "integer", + actions = setboxtonaturalwd +} + +nodes.setboxtonaturalwd = setboxtonaturalwd + local function firstdirinbox(n) local b = getbox(n) if b then local l = getlist(b) if l then for h in traverse_id(hlist_code,l) do - return getfield(h,"dir") + return getdir(h) end end end @@ -418,3 +451,166 @@ interfaces.implement { doifelse(firstdirinbox(n) == "TRT") end } + +-- new (handy for mp) .. might move to its own module + +do + + local flush_list = nodes.flush_list + local copy_list = nodes.copy_list + local takebox = nodes.takebox + local texsetbox = tex.setbox + + local new_hlist = nodes.pool.hlist + + local boxes = { } + nodes.boxes = boxes + local cache = table.setmetatableindex("table") + local report = logs.reporter("boxes","cache") + local trace = false + + trackers.register("nodes.boxes",function(v) trace = v end) + + function boxes.save(category,name,box) + name = tonumber(name) or name + local b = takebox(box) + if trace then + report("category %a, name %a, %s (%s)",category,name,"save",b and "content" or "empty") + end + cache[category][name] = b or false + end + + function boxes.found(category,name) + name = tonumber(name) or name + return cache[category][name] and true or false + end + + function boxes.direct(category,name,copy) + name = tonumber(name) or name + local c = cache[category] + local b = c[name] + if not b then + -- do nothing, maybe trace + elseif copy then + b = copy_list(b) + else + c[name] = false + end + if trace then + report("category %a, name %a, %s (%s)",category,name,"direct",b and "content" or "empty") + end + return b or nil + end + + function boxes.restore(category,name,box,copy) + name = tonumber(name) or name + local c = cache[category] + local b = takebox(box) + if b then + flush_list(b) + end + local b = c[name] + if not b then + -- do nothing, maybe trace + elseif copy then + b = copy_list(b) + else + c[name] = false + end + if trace then + report("category %a, name %a, %s (%s)",category,name,"restore",b and "content" or "empty") + end + texsetbox(box,b or nil) + end + + local getwhd = nodes.getwhd + + function boxes.dimensions(category,name) + name = tonumber(name) or name + local b = cache[category][name] + if b then + return getwhd(b) + else + return 0, 0, 0 + end + end + + function boxes.reset(category,name) + name = tonumber(name) or name + local c = cache[category] + if name and name ~= "" then + local b = c[name] + if b then + flush_list(b) + c[name] = false + end + if trace then + report("category %a, name %a, reset",category,name) + end + else + for k, b in next, c do + if b then + flush_list(b) + end + end + cache[category] = { } + if trace then + report("category %a, reset",category) + end + end + end + + implement { + name = "putboxincache", + arguments = { "string", "string", "integer" }, + actions = boxes.save, + } + + implement { + name = "getboxfromcache", + arguments = { "string", "string", "integer" }, + actions = boxes.restore, + } + + implement { + name = "directboxfromcache", + arguments = { "string", "string" }, + actions = { boxes.direct, context }, + -- actions = function(category,name) local b = boxes.direct(category,name) if b then context(b) end end, + } + + implement { + name = "directcopyboxfromcache", + arguments = { "string", "string", true }, + actions = { boxes.direct, context }, + -- actions = function(category,name) local b = boxes.direct(category,name,true) if b then context(b) end end, + } + + implement { + name = "copyboxfromcache", + arguments = { "string", "string", "integer", true }, + actions = boxes.restore, + } + + implement { + name = "doifelseboxincache", + arguments = { "string", "string" }, + actions = { boxes.found, doifelse }, + } + + implement { + name = "resetboxesincache", + arguments = { "string" }, + actions = boxes.reset, + } + + implement { + name = "lastlinewidth", + actions = function() + local head = tex.lists.page_head + -- list dimensions returns 3 value but we take the first + context(head and list_dimensions(getlist(find_tail(tonut(tex.lists.page_head)))) or 0) + end + } + +end diff --git a/tex/context/base/mkiv/supp-box.mkiv b/tex/context/base/mkiv/supp-box.mkiv index 9f4c58ad7..9d2817cee 100644 --- a/tex/context/base/mkiv/supp-box.mkiv +++ b/tex/context/base/mkiv/supp-box.mkiv @@ -905,7 +905,7 @@ \ifzeropt\ht\oldshapebox % \ifdim\ht\oldshapebox=\zeropoint \setbox\newshapebox\emptyvbox \else - \setbox\newshapebox\vbox + \setbox\newshapebox\vbox % can be \vpack {\unvcopy\oldshapebox \setbox\newshapebox\emptybox \shapecounter\zerocount @@ -915,7 +915,7 @@ \ifx\originalshapebox\undefined \let\originalshapebox\oldshapebox \fi -% We will turn this into a \MKIV\ variant. +% We will turn this into a \MKIV\ variant (we can use \type {\vpack} too). \unexpanded\def\insertshapesignal {\hpack to \shapesignal{\strut\hss}% plus \strut @@ -1313,8 +1313,7 @@ \egroup} \unexpanded\def\limitatetext#1#2#3% \expanded added 2003/01/16 - {\expanded{\beforesplitstring#2}\at,\to\leftlimit - \expanded{\aftersplitstring #2}\at,\to\rightlimit + {\splitatcomma{#2}\leftlimit\rightlimit \ifx\rightlimit\empty \normallimitatetext {#1}\leftlimit {#3}% \else @@ -1727,7 +1726,7 @@ {\ifnum\rigidcolumns=1 % tzt ook h/d correctie \ifinner\ifhmode\box\else\unvbox\fi\else\unvbox\fi#1\relax \else - \vbox + \vbox % \vpack {\forgetall \nopenalties \dontcomplain @@ -2550,9 +2549,15 @@ \fi \setstackbox{#1}{#2}} +\unexpanded\def\flushbox#1#2% unwrapped + {\ifcsname\??stackbox#1:#2\endcsname + \box\lastnamedcs + \else + \emptybox + \fi} + \unexpanded\def\restorebox#1#2% unwrapped {\ifcsname\??stackbox#1:#2\endcsname - %\copy\csname\??stackbox#1:#2\endcsname \copy\lastnamedcs \else \emptybox @@ -2561,16 +2566,18 @@ \unexpanded\def\foundbox#1#2% wrapped {\vpack {\ifcsname\??stackbox#1:#2\endcsname - %\copy\csname\??stackbox#1:#2\endcsname \copy\lastnamedcs \fi}} -\unexpanded\def\doifelsebox#1#2#3#4% +\unexpanded\def\doifelsebox#1#2% {\ifcsname\??stackbox#1:#2\endcsname - %\ifvoid\csname\??stackbox#1:#2\endcsname#4\else#3\fi - \ifvoid\lastnamedcs#4\else#3\fi + \ifvoid\lastnamedcs + \doubleexpandafter\secondoftwoarguments + \else + \doubleexpandafter\firstoftwoarguments + \fi \else - #4% + \expandafter\secondoftwoarguments \fi} \let\doifboxelse\doifelsebox @@ -2604,6 +2611,33 @@ \unexpanded\def\globalpushbox{\syst_boxes_push\global} \unexpanded\def\globalpopbox {\syst_boxes_pop \global} +%D And here is a more modern one (not yet in i-*): +%D +%D \starttyping +%D \dorecurse {100} { +%D \setbox\zerocount\hbox{test \recurselevel} +%D \putboxincache{foo}{\recurselevel}\zerocount +%D \copyboxfromcache{foo}{\recurselevel}\zerocount +%D \iftrue +%D \setbox\zerocount\hbox{\directboxfromcache{foo}{\recurselevel}}% +%D \else +%D \getboxfromcache{foo}{\recurselevel}\zerocount +%D \fi +%D } +%D \resetboxesincache{foo} +%D \stoptyping + +\unexpanded\def\putboxincache #1#2#3{\clf_putboxincache {#1}{#2}#3\relax} +\unexpanded\def\getboxfromcache #1#2#3{\clf_getboxfromcache {#1}{#2}#3\relax} +\unexpanded\def\doifelseboxincache #1#2{\clf_doifelseboxincache {#1}{#2}} +\unexpanded\def\copyboxfromcache #1#2#3{\clf_copyboxfromcache {#1}{#2}#3\relax} +\unexpanded\def\directboxfromcache #1#2{\clf_directboxfromcache {#1}{#2}} +\unexpanded\def\directcopyboxfromcache#1#2{\clf_directcopyboxfromcache{#1}{#2}} +\unexpanded\def\resetboxesincache #1{\clf_resetboxesincache {#1}} + +\unexpanded\def\putnextboxincache#1#2% + {\dowithnextbox{\putboxincache{#1}{#2}\nextbox}} + %D \macros %D {removedepth, obeydepth} %D @@ -2619,13 +2653,11 @@ \fi} \unexpanded\def\obeydepth - {\par - \ifvmode - \ifdim\prevdepth>\zeropoint - \kern-\prevdepth - \fi - \kern\strutdp - \fi} + {\par % watch out for changes in math formulas + \ifvmode\ifdim\prevdepth<\zeropoint\else\ifdim\prevdepth<\strutdp + \kern\dimexpr\strutdp-\prevdepth\relax + \prevdepth\strutdp + \fi\fi\fi} \unexpanded\def\undepthed {\dowithnextbox{\dp\nextbox\zeropoint\box\nextbox}\hbox} @@ -2885,10 +2917,64 @@ \let\getnaturaldimensions\clf_getnaturaldimensions % sets three dimensions \let\naturalwd \clf_naturalwd % calculates and returns wd +\let\getnaturalwd\clf_getnaturalwd % no intermediate +\let\setnaturalwd\clf_setnaturalwd % no intermediate + \unexpanded\def\doifelserighttoleftinbox{\clf_doifelserighttoleftinbox} \let\doifrighttoleftinboxelse\doifelserighttoleftinbox +%D New, used in high/low: + +\definesystemattribute [runningtext] [public] + +%unexpanded\def\runninghbox{\hbox attr \runningtextattribute \plusone} % not yet in i-* +\unexpanded\def\runninghbox{\hbox attr \runningtextattribute \fontid\font} % not yet in i-* + +%D To complement lua (yet undocumented): + +\unexpanded\def\beginhbox{\hbox\bgroup} \let\endhbox\egroup +\unexpanded\def\beginvbox{\vbox\bgroup} \let\endvbox\egroup +\unexpanded\def\beginvtop{\vtop\bgroup} \let\endvtop\egroup + +\unexpanded\def\sethboxregister#1{\setbox#1\hbox} +\unexpanded\def\setvboxregister#1{\setbox#1\vbox} +\unexpanded\def\setvtopregister#1{\setbox#1\vtop} + +\unexpanded\def\flushboxregister#1{\box\numexpr#1\relax} + +\unexpanded\def\starthboxregister#1{\setbox#1\hbox\bgroup} \let\stophboxregister\egroup +\unexpanded\def\startvboxregister#1{\setbox#1\vbox\bgroup} \let\stopvboxregister\egroup +\unexpanded\def\startvtopregister#1{\setbox#1\vtop\bgroup} \let\stopvtopregister\egroup + +%D For whatever third party package needs it: +%D +%D \starttyping +%D \newlocalbox\BoxOne +%D \newlocalbox\BoxTwo +%D +%D \setbox\BoxOne\hbox{Box One} +%D \setbox\BoxTwo\hbox{Box Two} +%D +%D [\box\BoxTwo] [\box\BoxOne] +%D \stoptyping + +\installcorenamespace{localbox} + +\unexpanded\def\newlocalbox#1% + {\expandafter\let\expandafter#1\csname\??localbox\string#1\endcsname + \ifx#1\relax + \syst_aux_new_localbox#1% + \fi} + +\def\syst_aux_new_localbox#1% + {\expandafter\newbox\csname\??localbox\string#1\endcsname + \newlocalbox#1} + +%D Who knows when this comes in handy: + +\unexpanded\def\lastlinewidth{\dimexpr\clf_lastlinelength\scaledpoint\relax} + \protect \endinput % a bit of test code: diff --git a/tex/context/base/mkiv/supp-ran.lua b/tex/context/base/mkiv/supp-ran.lua index 4968e8cfc..8bfc09e58 100644 --- a/tex/context/base/mkiv/supp-ran.lua +++ b/tex/context/base/mkiv/supp-ran.lua @@ -10,8 +10,8 @@ if not modules then modules = { } end modules ['supp-ran'] = { local report_system = logs.reporter("system","randomizer") -local trace_random = false trackers.register("system.randomizer", function(v) trace_random = v end) -local trace_random_mp = false trackers.register("system.randomizer.mp",function(v) trace_random_mp = v end) +local trace_random = false trackers.register("system.randomizer", function(v) trace_random = v end) +local trace_detail = false trackers.register("system.randomizer.detail",function(v) trace_detail = v end) local insert, remove = table.insert, table.remove @@ -26,6 +26,14 @@ local stack = { } local last = 1 local maxcount = 2^30-1 -- 1073741823 +math.random = function(...) + local n = random(...) + if trace_detail then + report_system("math %s",n) + end + return n +end + local function setrandomseedi(n) if n <= 1 then n = n * maxcount @@ -33,17 +41,22 @@ local function setrandomseedi(n) n = n * 1000 end n = round(n) - if trace_random then - report_system("setting seed to %s",n) - end randomseed(n) last = random(0,maxcount) -- we need an initial value + if trace_detail then + report_system("seed %s from %s",last,n) + elseif trace_random then + report_system("setting seed %s",n) + end end math.setrandomseedi = setrandomseedi local function getrandomnumber(min,max) last = random(min,max) + if trace_detail then + report_system("number %s",last) + end return last end @@ -56,19 +69,19 @@ local function getrandomseed() return last end -local function getmprandomnumber() - last = random(0,4095) - if trace_random_mp then - report_system("using mp seed %s",last) - end - return last -end +-- local function getmprandomnumber() +-- last = random(0,4095) +-- if trace_detail then +-- report_system("mp number %s",last) +-- end +-- return last +-- end -- maybe stack local function pushrandomseed() insert(stack,last) - if trace_random then + if trace_random or trace_detail then report_system("pushing seed %s",last) end end @@ -76,7 +89,7 @@ end local function reuserandomseed(n) local seed = stack[#stack] if seed then - if trace_random then + if trace_random or trace_detail then report_system("reusing seed %s",last) end randomseed(seed) @@ -86,19 +99,47 @@ end local function poprandomseed() local seed = remove(stack) if seed then - if trace_random then + if trace_random or trace_detail then report_system("popping seed %s",seed) end randomseed(seed) end end +local function getrandom(where,...) + if type(where) == "string" then + local n = random(...) + if trace_detail then + report_system("%s %s",where,n) + end + return n + else + local n = random(where,...) + if trace_detail then + report_system("utilities %s",n) + end + return n + end +end + +utilities.randomizer = { + setseedi = setrandomseedi, + getnumber = getrandomnumber, + setseed = setrandomseed, + getseed = getrandomseed, + -- getmpnumber = getmprandomnumber, + pushseed = pushrandomseed, + reuseseed = reuserandomseed, + popseed = poprandomseed, + get = getrandom, +} + -- todo: also open up in utilities.randomizer.* implement { name = "getrandomnumber", actions = { getrandomnumber, context }, arguments = { "integer", "integer" } } implement { name = "getrandomdimen", actions = { getrandomnumber, context }, arguments = { "dimen", "dimen" } } implement { name = "getrandomfloat", actions = { getrandomnumber, context }, arguments = { "number", "number" } } -implement { name = "getmprandomnumber", actions = { getmprandomnumber, context } } +--------- { name = "getmprandomnumber", actions = { getmprandomnumber, context } } implement { name = "setrandomseed", actions = { setrandomseed }, arguments = { "integer" } } implement { name = "getrandomseed", actions = { getrandomseed, context } } implement { name = "pushrandomseed", actions = { pushrandomseed } } diff --git a/tex/context/base/mkiv/supp-ran.mkiv b/tex/context/base/mkiv/supp-ran.mkiv index f7cfd6e73..5b70a075f 100644 --- a/tex/context/base/mkiv/supp-ran.mkiv +++ b/tex/context/base/mkiv/supp-ran.mkiv @@ -20,11 +20,11 @@ \unprotect -\unexpanded\def\getrandomcount #1#2#3{#1=\clf_getrandomnumber#2 #3\relax} -\unexpanded\def\getrandomdimen #1#2#3{#1=\clf_getrandomdimen#2 #3 \scaledpoint\relax} -\unexpanded\def\getrandomnumber#1#2#3{\edef#1{\clf_getrandomnumber#2 #3}} -\unexpanded\def\getrandomfloat #1#2#3{\edef#1{\clf_getrandomfloat#2 #3}} -\unexpanded\def\setrandomseed #1{\clf_setrandomseed#1\relax} +\unexpanded\def\getrandomcount #1#2#3{#1=\clf_getrandomnumber\numexpr#2\relax\numexpr#3\relax\relax} +\unexpanded\def\getrandomdimen #1#2#3{#1=\clf_getrandomdimen\dimexpr#2\relax\dimexpr#3\relax\scaledpoint\relax} +\unexpanded\def\getrandomnumber#1#2#3{\edef#1{\clf_getrandomnumber\numexpr#2\relax\numexpr#3\relax}} +\unexpanded\def\getrandomfloat #1#2#3{\edef#1{\clf_getrandomfloat\dimexpr#2\relax\dimexpr#3\relax}} +\unexpanded\def\setrandomseed #1{\clf_setrandomseed\numexpr#1\relax} \unexpanded\def\getrandomseed #1{\edef#1{\clf_getrandomseed}} \unexpanded\def\pushrandomseed {\clf_pushrandomseed} \unexpanded\def\poprandomseed {\clf_poprandomseed} diff --git a/tex/context/base/mkiv/supp-vis.mkiv b/tex/context/base/mkiv/supp-vis.mkiv index 8b9420162..e12c4c534 100644 --- a/tex/context/base/mkiv/supp-vis.mkiv +++ b/tex/context/base/mkiv/supp-vis.mkiv @@ -1360,7 +1360,7 @@ %D \ShowBufferedExample \def\supp_visualizers_hglue_indeed - {\leavevmode + {\leavevmode % plain tex uses this \scratchcounter\spacefactor \visualvrule\s!width\zeropoint \normalpenalty\plustenthousand diff --git a/tex/context/base/mkiv/symb-emj.lua b/tex/context/base/mkiv/symb-emj.lua new file mode 100644 index 000000000..3075e0985 --- /dev/null +++ b/tex/context/base/mkiv/symb-emj.lua @@ -0,0 +1,82 @@ +if not modules then modules = { } end modules ['symb-emj'] = { + version = 1.001, + comment = "companion to symb-emj.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local symbols = fonts.symbols + +-- emoji + +-- processors.hpack_filter does it all + +local resolvedemoji = characters.emoji.resolve +local processfeatures = fonts.handlers.otf.featuresprocessor +local injectspacing = nodes.injections.handler +local protectglyphs = nodes.handlers.protectglyphs +local tonodes = nodes.tonodes +local currentfont = font.current + +-- fast enough, no need to memoize + +local glyph_code = nodes.nodecodes.glyph +local remove_node = nodes.remove +local getid = nodes.getid +local getnext = nodes.getnext +local getchar = nodes.getchar + +local function removemodifiers(head) + local current = head + while current do + if getid(current) == glyph_code then + local char = getchar(current) -- using categories is too much + if char == 0x200D or (char >= 0x1F3FB and char <= 0x1F3FF) then + head, current = remove_node(head,current,true) + else + current = getnext(current) + end + else + current = getnext(current) + end + end + return head +end + +-- attributes + +local function checkedemoji(name,id) + local str = resolvedemoji(name) + if str then + if not id then + id = currentfont() + end + local head = tonodes(str,id,nil,nil,true) -- use current attributes + head = processfeatures(head,id,false) + if head then + head = injectspacing(head) + protectglyphs(head) + return removemodifiers(head) + end + end +end + +symbols.emoji = { + resolved = resolvedemoji, + checked = checkedemoji, +} + +interfaces.implement { + name = "resolvedemoji", + actions = { resolvedemoji, context.escaped }, + arguments = "string", +} + +interfaces.implement { + name = "checkedemoji", + actions = { checkedemoji, context }, + arguments = "string", +} + + diff --git a/tex/context/base/mkiv/symb-emj.mkiv b/tex/context/base/mkiv/symb-emj.mkiv new file mode 100644 index 000000000..22d8b4a07 --- /dev/null +++ b/tex/context/base/mkiv/symb-emj.mkiv @@ -0,0 +1,27 @@ +%D \module +%D [ file=symb-emj, +%D version=2017.04.21, +%D title=\CONTEXT\ Symbol Libraries, +%D subtitle=Emoji, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Symbol Libraries / Emoji} + +\registerctxluafile{symb-emj}{1.001} + +\unprotect + + \def\expandedemoji#1{\clf_resolvedemoji{#1}} +\unexpanded\def\resolvedemoji#1{\clf_resolvedemoji{#1}} +\unexpanded\def\checkedemoji #1{\clf_checkedemoji {#1}} +\unexpanded\def\emoji #1{\dontleavehmode{\setdirectsymbolicfont{emoji}\clf_resolvedemoji{#1}}} +\unexpanded\def\robustemoji #1{\dontleavehmode{\setdirectsymbolicfont{emoji}\clf_checkedemoji {#1}}} + + +\protect \endinput diff --git a/tex/context/base/mkiv/syst-aux.lua b/tex/context/base/mkiv/syst-aux.lua index 98b92cef3..34e5c4e88 100644 --- a/tex/context/base/mkiv/syst-aux.lua +++ b/tex/context/base/mkiv/syst-aux.lua @@ -121,6 +121,7 @@ implement { -- \gdef\setpercentdimen#1#2% -- {#1=\ctxcommand{percentageof("#2",\number#1)}\relax} +local space = P(" ") / "" local spaces = P(" ")^0 / "" local nohash = 1 - P("#") local digit = R("09") @@ -130,27 +131,147 @@ local sentinel = spaces * (nohash^1 / "\\%0") local sargument = (single * digit)^1 local dargument = (double * digit)^1 -local usespaces = nil -local texpreamble = nil - -local pattern = Cs( -- ^-1 - ( P("spaces") / function() usespaces = true return "" end )^0 - * spaces - * ( P("nospaces") / function() usespaces = false return "" end )^0 - * spaces - * ( P("global") / "\\global" )^0 - * spaces - * ( P("unexpanded") / "\\unexpanded" )^0 - * spaces - * Cc("\\expandafter\\") - * spaces - * ( P("expanded") / "e" )^0 - * spaces - * ( P((1-S(" #"))^1) / "def\\csname %0\\endcsname" ) - * spaces - * ( - -- (double * digit)^1 * sentinel^-1 * double^-1 - -- + (single * digit)^1 * sentinel^-1 * single^-1 +-- first variant: +-- +-- local texpreamble = nil +-- local usespaces = nil +-- +-- local pattern = Cs( -- ^-1 +-- ( P("spaces") / function() usespaces = true return "" end )^0 +-- * spaces +-- * ( P("nospaces") / function() usespaces = false return "" end )^0 +-- * spaces +-- * ( P("global") / "\\global" )^0 +-- * spaces +-- * ( P("unexpanded") / "\\unexpanded" )^0 +-- * spaces +-- * Cc("\\expandafter\\") +-- * spaces +-- * ( P("expanded") / "e" )^0 +-- * spaces +-- * ( P((1-S(" #"))^1) / "def\\csname %0\\endcsname" ) +-- * spaces +-- * ( +-- -- (double * digit)^1 * sentinel^-1 * double^-1 +-- -- + (single * digit)^1 * sentinel^-1 * single^-1 +-- ( P("[") * dargument * P("]") + dargument)^1 * sentinel^-1 * double^-1 +-- + ( P("[") * sargument * P("]") + sargument)^1 * sentinel^-1 * single^-1 +-- + sentinel^-1 * (double+single)^-1 +-- ) +-- ) +-- +-- local ctx_dostarttexdefinition = context.dostarttexdefinition +-- +-- local function texdefinition_one(str) +-- usespaces = nil +-- texpreamble = lpegmatch(pattern,str) +-- if usespaces == true then +-- setcatcode(32,10) -- space +-- setcatcode(13, 5) -- endofline +-- elseif usespaces == false then +-- setcatcode(32, 9) -- ignore +-- setcatcode(13, 9) -- ignore +-- else +-- -- this is default +-- -- setcatcode(32,10) -- space +-- -- setcatcode(13, 9) -- ignore +-- end +-- ctx_dostarttexdefinition() +-- end +-- +-- local function texdefinition_two() +-- context(texpreamble) +-- end + +-- second variant: +-- +-- -- default: +-- -- +-- -- setcatcode(32,10) -- space +-- -- setcatcode(13, 9) -- ignore +-- +-- local function catcodes_s() +-- setcatcode(32,10) -- space +-- setcatcode(13, 5) -- endofline +-- return "" +-- end +-- +-- local function catcodes_n() +-- setcatcode(32, 9) -- ignore +-- setcatcode(13, 9) -- ignore +-- return "" +-- end +-- +-- local pattern = Cs( -- ^-1 +-- ( P("spaces") * space / catcodes_s )^0 +-- * spaces * ( P("nospaces") * space / catcodes_n )^0 +-- * spaces * ( P("global") * space / "\\global" )^0 +-- * spaces * ( P("unexpanded") * space / "\\unexpanded" )^0 +-- * spaces * Cc("\\expandafter\\") +-- * spaces * ( P("expanded") / "e" )^0 +-- * spaces * ( P((1-S(" #["))^1) / "def\\csname %0\\endcsname" ) +-- * spaces * ( +-- -- (double * digit)^1 * sentinel^-1 * double^-1 +-- -- + (single * digit)^1 * sentinel^-1 * single^-1 +-- ( P("[") * dargument * P("]") + dargument)^1 * sentinel^-1 * double^-1 +-- + ( P("[") * sargument * P("]") + sargument)^1 * sentinel^-1 * single^-1 +-- + sentinel^-1 * (double+single)^-1 +-- ) +-- ) +-- +-- local texpreamble = nil +-- +-- local ctx_dostarttexdefinition = context.dostarttexdefinition +-- +-- local function texdefinition_one(str) +-- texpreamble = lpegmatch(pattern,str) +-- ctx_dostarttexdefinition() +-- end +-- +-- local function texdefinition_two() +-- context(texpreamble) +-- end + +-- third variant: + +local global = nil +local unexpanded = nil +local expanded = nil +local optional = nil +local csname = nil +local rest = nil + +local function catcodes_s() + setcatcode(32,10) -- space + setcatcode(13, 5) -- endofline +end + +local function catcodes_n() + setcatcode(32, 9) -- ignore + setcatcode(13, 9) -- ignore +end + +local space = P(" ") +local spaces = space^0 + +local option = ( + P("single") + + P("double") + + P("triple") + + P("quadruple") + + P("quintuple") + + P("sixtuple") + ) * (P("empty") + P("argument")) + +local pattern = ( + ( P("spaces") * space / catcodes_s )^0 + * spaces * ( P("nospaces") * space / catcodes_n )^0 + * spaces * ( P("global") * space * Cc(true) + Cc(false) ) + * spaces * ( P("unexpanded") * space * Cc(true) + Cc(false) ) + * spaces * ( P("expanded") * space * Cc(true) + Cc(false) ) + * spaces * ( C(option) * space + Cc(false) ) + * spaces * ( C((1-S(" #["))^1) ) + * spaces * Cs( ( P("[") * dargument * P("]") + dargument)^1 * sentinel^-1 * double^-1 + ( P("[") * sargument * P("]") + sargument)^1 * sentinel^-1 * single^-1 + sentinel^-1 * (double+single)^-1 @@ -160,24 +281,43 @@ local pattern = Cs( -- ^-1 local ctx_dostarttexdefinition = context.dostarttexdefinition local function texdefinition_one(str) - usespaces = nil - texpreamble = lpegmatch(pattern,str) - if usespaces == true then - setcatcode(32,10) -- space - setcatcode(13, 5) -- endofline - elseif usespaces == false then - setcatcode(32, 9) -- ignore - setcatcode(13, 9) -- ignore - else - -- this is default - -- setcatcode(32,10) -- space - -- setcatcode(13, 9) -- ignore - end + global, unexpanded, expanded, optional, csname, rest = lpegmatch(pattern,str) ctx_dostarttexdefinition() end local function texdefinition_two() - context(texpreamble) + if optional then + context ( + [[\unexpanded\expandafter]] .. + (global and [[\xdef]] or [[\edef]]) .. + [[\csname ]] .. + csname .. + [[\endcsname{\expandafter\noexpand\expandafter\do]] .. + optional .. + [[\csname _do_]] .. + csname .. + -- [[_\endcsname}\unexpanded\expandafter]] .. + [[_\endcsname}\expandafter]] .. + (global and [[\gdef]] or [[\edef]]) .. + [[\csname _do_]] .. + csname .. + [[_\endcsname ]] .. + rest + ) + else + context ( + [[\unexpanded\expandafter]] .. + ( global and ( + expanded and [[\xdef]] or [[\gdef]] + ) or ( + expanded and [[\edef]] or [[\def]] + ) ) .. + [[\csname ]] .. + csname .. + [[\endcsname ]] .. + rest + ) + end end implement { name = "texdefinition_one", actions = texdefinition_one, scope = "private", arguments = "string" } diff --git a/tex/context/base/mkiv/syst-aux.mkiv b/tex/context/base/mkiv/syst-aux.mkiv index 825d18636..eb5b3b90a 100644 --- a/tex/context/base/mkiv/syst-aux.mkiv +++ b/tex/context/base/mkiv/syst-aux.mkiv @@ -3040,7 +3040,7 @@ \endgroup} %D \macros -%D {writestring,writeline,writebanner, +%D {writestring,writeline, %D writestatus,statuswidth,normalwritestatus} %D %D Maybe one didn't notice, but we've already introduced a @@ -3063,11 +3063,8 @@ \ifdefined\writestring \else - \newtoks\everywritestring - - \def\writedirect {\immediate\write\statuswrite} - \def\writeline {\writedirect{}} - \unexpanded\def\writestring#1{\begingroup\the\everywritestring\writedirect{#1}\endgroup} + \unexpanded\def\writestring{\immediate\write\statuswrite} + \unexpanded\def\writeline {\writestring{}} \fi @@ -3100,15 +3097,14 @@ %D a macro accepting two arguments and a boolean (in fact a %D few macro's too). -\newif\ifdebuggerinfo - -\unexpanded\def\debuggerinfo#1#2% - {\ifdebuggerinfo - \writestatus{debugger}{#1:: #2}% - \fi} - -\ifdefined\writestatus \else \let\writestatus\normalwritestatus \fi -\ifdefined\writebanner \else \unexpanded\def\writebanner{\writestring} \fi +% \newif\ifdebuggerinfo +% +% \unexpanded\def\debuggerinfo#1#2% +% {\ifdebuggerinfo +% \writestatus{debugger}{#1:: #2}% +% \fi} +% +% \ifdefined\writestatus \else \let\writestatus\normalwritestatus \fi % % % % % % % % % % % % % % % % % % % % % % % % @@ -3190,7 +3186,7 @@ %D are needed: \unexpanded\def\newif#1% - {\scratchcounter\escapechar + {\privatescratchcounter\escapechar \escapechar\minusone \expandafter\expandafter\expandafter \redoglobal\expandafter\expandafter\expandafter @@ -3199,7 +3195,7 @@ \redoglobal\expandafter\expandafter\expandafter \edef\@if#1{false}{\let\noexpand#1\noexpand\iffalse}% \dodoglobal\@if#1{false}% - \escapechar\scratchcounter} + \escapechar\privatescratchcounter} %D Also new: @@ -3849,15 +3845,16 @@ \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname##1##2{#4}% \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel \csname\??recursestepwise + % we need the x in order to avoid the \relax that tex adds \ifnum#3>\zerocount - \ifnum#2<#1\else d\fi + \ifnum#2<#1x\else d\fi \else\ifnum#3<\zerocount - \ifnum#1<#2\else r\fi + \ifnum#1<#2x\else r\fi \fi\fi \expandafter\endcsname\normalexpanded{{\number#1}{\number#2}{\number#3}}} % \expandafter\endcsname\expandafter{\number#1\expandafter}\expandafter{\number#2\expandafter}\expandafter{\number#3}} -\letvalue{\??recursestepwise }\syst_helpers_stepwise_exit +\letvalue{\??recursestepwise x}\syst_helpers_stepwise_exit \letvalue{\??recursestepwise d}\syst_helpers_stepwise_recurse \letvalue{\??recursestepwise r}\syst_helpers_stepwise_reverse @@ -4200,9 +4197,9 @@ %D Watch the one level expansion of the second argument. \unexpanded\def\doifelsemeaning#1#2% - {\edef\m_syst_string_one{\meaning#1}% + {\edef\m_syst_string_one{\normalmeaning#1}% \def \m_syst_string_two{#2}% - \edef\m_syst_string_two{\meaning\m_syst_string_two}% + \edef\m_syst_string_two{\normalmeaning\m_syst_string_two}% \ifx\m_syst_string_one\m_syst_string_two \expandafter\firstoftwoarguments \else @@ -5141,6 +5138,25 @@ \expandafter\syst_helpers_split_string#1#2#2\empty\\} %D \macros +%D {splitatperiod, +%D {splitatcomma, +%D splitatasterisk, +%D splitatcolon, +%D splitatcolons} + +\unexpanded\def\splitatperiod #1{\normalexpanded{\syst_helpers_splitatperiod #1}..\relax} +\unexpanded\def\splitatcomma #1{\normalexpanded{\syst_helpers_splitatcomma #1},,\relax} % not at ", " +\unexpanded\def\splitatasterisk#1{\normalexpanded{\syst_helpers_splitatasterisk#1}**\relax} +\unexpanded\def\splitatcolon #1{\normalexpanded{\syst_helpers_splitatcolon #1}::\relax} +\unexpanded\def\splitatcolons #1{\normalexpanded{\syst_helpers_splitatcolons #1}::::\relax} + +\unexpanded\def\syst_helpers_splitatperiod #1.#2.#3\relax#4#5{\def#4{#1}\def#5{#2}} +\unexpanded\def\syst_helpers_splitatcomma #1,#2,#3\relax#4#5{\def#4{#1}\def#5{#2}} +\unexpanded\def\syst_helpers_splitatasterisk #1*#2*#3\relax#4#5{\def#4{#1}\def#5{#2}} +\unexpanded\def\syst_helpers_splitatcolon #1:#2:#3\relax#4#5{\def#4{#1}\def#5{#2}} +\unexpanded\def\syst_helpers_splitatcolons #1::#2::#3\relax#4#5{\edef#4{#1}\edef#5{#2}} + +%D \macros %D {removesubstring} %D %D A first application of the two routines defined above is: @@ -5526,7 +5542,7 @@ {\xdef\m_syst_helpers_push_macro{\csstring#1}% \c_syst_helpers_pop_count\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname \global\advance\lastnamedcs \minusone - \expandafter\let\expandafter#1\csname\the\c_syst_helpers_pop_count\m_syst_helpers_push_macro\endcsname} + \global\expandafter\let\expandafter#1\csname\the\c_syst_helpers_pop_count\m_syst_helpers_push_macro\endcsname} \unexpanded\def\localpopmacro#1% {\xdef\m_syst_helpers_push_macro{\csstring#1}% @@ -6237,23 +6253,23 @@ {\def\m_syst_string_three{#1}% \ifx\m_syst_string_two\m_syst_string_three \else \ifx\m_syst_string_one\m_syst_string_three - \advance\scratchcounter\plusone + \advance\privatescratchcounter\plusone \fi \expandafter\syst_helpers_count_token \fi} \unexpanded\def\counttoken#1\in#2\to#3% - {\scratchcounter\zerocount + {\privatescratchcounter\zerocount \def\m_syst_string_one{#1}% \def\m_syst_string_two{\end}% \syst_helpers_count_token#2\end - \dodoglobal#3\scratchcounter} + \dodoglobal#3\privatescratchcounter} \unexpanded\def\counttokens#1\to#2% - {\scratchcounter\zerocount - \def\syst_helpers_count_token##1{\advance\scratchcounter\plusone}% + {\privatescratchcounter\zerocount + \def\syst_helpers_count_token##1{\advance\privatescratchcounter\plusone}% \handletokens#1\with\syst_helpers_count_token - \dodoglobal#2\scratchcounter} + \dodoglobal#2\privatescratchcounter} %D \macros %D {splitofftokens} @@ -6264,10 +6280,10 @@ \unexpanded\def\splitofftokens#1\from#2\to#3% slow but hardly used {\ifnum#1>\zerocount - \scratchcounter#1\relax + \privatescratchcounter#1\relax \def\syst_helpers_split_off_tokens##1% - {\ifnum\scratchcounter>\zerocount - \advance\scratchcounter \minusone + {\ifnum\privatescratchcounter>\zerocount + \advance\privatescratchcounter \minusone \edef#3{#3##1}% \fi}% % \let#3\empty % #3 can be #2, so: @@ -6463,7 +6479,7 @@ {\afterassignment\gobblefourarguments#1=#2#3pt\relax\empty\empty\empty\empty} \unexpanded\def\freezedimensionwithunit#1#2% - {\setdimensionwithunit\scratchdimen#1{#2}\edef#1{\the\scratchdimen}} + {\setdimensionwithunit\privatescratchdimen#1{#2}\edef#1{\the\privatescratchdimen}} %D \macros %D {doifsometokselse, doifsometoks} @@ -6718,7 +6734,7 @@ %D This is a dirty one: we simply append a unit and discard it when needed. \def\doifelsedimension#1% - {\afterassignment\syst_helpers_if_dimension_else\scratchdimen#1pt\relax} + {\afterassignment\syst_helpers_if_dimension_else\privatescratchdimen#1pt\relax} \let\doifdimensionelse\doifelsedimension @@ -6864,10 +6880,10 @@ \syst_helpers_unspaced} \unexpanded\def\unspaceargument#1\to#2% - {\scratchcounter\catcode\spaceasciicode + {\privatescratchcounter\catcode\spaceasciicode \catcode\spaceasciicode\ignorecatcode \scantextokens{\edef#2{#1}}% - \catcode\spaceasciicode\scratchcounter} + \catcode\spaceasciicode\privatescratchcounter} \unexpanded\def\unspaceafter#1#2% {\unspaceargument#2\to\ascii @@ -6924,7 +6940,7 @@ \def\syst_helpers_if_non_zero_positive_else#1#2\end % #3#4% {\ifx#1\relax - \ifcase\scratchcounter + \ifcase\privatescratchcounter \endgroup \doubleexpandafter\secondoftwoarguments \else @@ -6937,7 +6953,7 @@ \fi} \def\doifelsenonzeropositive#1% - {\begingroup\afterassignment\syst_helpers_if_non_zero_positive_else\scratchcounter=0#1\relax\empty\end} + {\begingroup\afterassignment\syst_helpers_if_non_zero_positive_else\privatescratchcounter=0#1\relax\empty\end} \let\doifnonzeropositiveelse\doifelsenonzeropositive @@ -7005,7 +7021,7 @@ \unexpanded\def\retestfeature % timer support is new per 10/5/2005 {\bgroup \ifcase\interactionmode\let\wait\relax\fi - \writestatus\m!system{starting feature test}\wait + \writestatus\m!system{starting feature test (n=\number\c_syst_helpers_test_feature_m)}\wait \resettimer \c_syst_helpers_test_feature_n\zerocount \syst_helpers_test_feature_step diff --git a/tex/context/base/mkiv/syst-ini.mkiv b/tex/context/base/mkiv/syst-ini.mkiv index dc8300e7f..bbc856a5e 100644 --- a/tex/context/base/mkiv/syst-ini.mkiv +++ b/tex/context/base/mkiv/syst-ini.mkiv @@ -200,6 +200,16 @@ \countdef \normalpagebox = 127 \normalpagebox = 255 % hardcoded in pdftex/xetex +% Only to be used by developers in very special cases! + +% \def\lastallocatedcount {\the\c_syst_last_allocated_count} +% \def\lastallocateddimen {\the\c_syst_last_allocated_dimen} +% \def\lastallocatedskip {\the\c_syst_last_allocated_skip} +% \def\lastallocatedmuskip {\the\c_syst_last_allocated_muskip} +% \def\lastallocatedbox {\the\c_syst_last_allocated_dimen} +% \def\lastallocatedtoks {\the\c_syst_last_allocated_toks} +% \def\lastallocatedattribute{\the\c_syst_last_allocated_attribute} + % A few traditional allocations (these might go): \countdef \count@ = 255 % hm, used in \newif .. todo: replace it there @@ -310,14 +320,15 @@ %D scratchtoks} %D %D We now define a few scratch registers, so that successive loads at least have -%D some available. +%D some available. The private ones are used in cases where we don't want to +%D intrude on normal scratch ones. -\newcount \scratchcounter \newcount \globalscratchcounter -\newdimen \scratchdimen \newdimen \globalscratchdimen -\newskip \scratchskip \newskip \globalscratchskip -\newmuskip\scratchmuskip \newmuskip\globalscratchmuskip -\newtoks \scratchtoks \newtoks \globalscratchtoks -\newbox \scratchbox \newbox \globalscratchbox +\newcount \scratchcounter \newcount \globalscratchcounter \newcount \privatescratchcounter +\newdimen \scratchdimen \newdimen \globalscratchdimen \newdimen \privatescratchdimen +\newskip \scratchskip \newskip \globalscratchskip \newskip \privatescratchskip +\newmuskip\scratchmuskip \newmuskip\globalscratchmuskip \newmuskip\privatescratchmuskip +\newtoks \scratchtoks \newtoks \globalscratchtoks \newtoks \privatescratchtoks +\newbox \scratchbox \newbox \globalscratchbox \newbox \privatescratchbox \newcount\scratchcounterone \newcount\scratchcountertwo \newcount\scratchcounterthree \newdimen \scratchdimenone \newdimen \scratchdimentwo \newdimen \scratchdimenthree @@ -384,6 +395,7 @@ \newdimen \onepoint \onepoint = 1pt \newdimen \halfapoint \halfapoint = 0.5pt \newdimen \maxdimen \maxdimen = 16383.99999pt +\newcount \maxcount \maxcount = 2147483647 \newdimen \onebasepoint \onebasepoint = 1bp \newdimen \scaledpoint \scaledpoint = 1sp \newdimen \thousandpoint \thousandpoint = 1000pt @@ -1153,7 +1165,20 @@ %D For now: -\ifdefined\protrusionboundary \else \let\protrusionboundary\boundary \fi -\ifdefined\wordboundary \else \let\wordboundary \noboundary \fi +\ifdefined\protrusionboundary \else \let\protrusionboundary\boundary \fi +\ifdefined\wordboundary \else \let\wordboundary \noboundary \fi + +\ifdefined\mathrulesfam \else \newcount\mathrulesfam \fi +\ifdefined\mathrulesmode \else \newcount\mathrulesmode \fi +\ifdefined\mathsurroundmode \else \newcount\mathsurroundmode \fi +\ifdefined\mathitalicsmode \else \newcount\mathitalicsmode \fi + +\ifdefined\hyphenpenaltymode \else \newcount\hyphenpenaltymode \fi +\ifdefined\automatichyphenpenalty \else \newcount\automatichyphenpenalty \fi +\ifdefined\automatichyphenmode \else \newcount\automatichyphenmode \fi +\ifdefined\explicithyphenpenalty \else \newcount\explicithyphenpenalty \fi + +\ifdefined\explicitdiscretionary \else \let\explicitdiscretionary \- \fi +\ifdefined\automaticdiscretionary \else \def\automaticdiscretionary{\Uchar\exhyphenchar} \fi \protect \endinput diff --git a/tex/context/base/mkiv/syst-lua.lua b/tex/context/base/mkiv/syst-lua.lua index 422f57a00..ee3b8c327 100644 --- a/tex/context/base/mkiv/syst-lua.lua +++ b/tex/context/base/mkiv/syst-lua.lua @@ -10,92 +10,70 @@ local find, match = string.find, string.match local tonumber = tonumber local S, C, P, lpegmatch, lpegtsplitat = lpeg.S, lpeg.C, lpeg.P, lpeg.match, lpeg.tsplitat +commands = commands or { } +local commands = commands +local context = context +local implement = interfaces.implement -commands = commands or { } -local commands = commands - -local implement = interfaces.implement +local ctx_protected_cs = context.protected.cs -- more efficient +local ctx_firstoftwoarguments = ctx_protected_cs.firstoftwoarguments +local ctx_secondoftwoarguments = ctx_protected_cs.secondoftwoarguments +local ctx_firstofoneargument = ctx_protected_cs.firstofoneargument +local ctx_gobbleoneargument = ctx_protected_cs.gobbleoneargument local two_strings = interfaces.strings[2] -local context = context -local csprint = context.sprint - -local prtcatcodes = tex.prtcatcodes - -implement { -- will b eoverloaded later +implement { -- will be overloaded later name = "writestatus", arguments = two_strings, actions = logs.status, } -local ctx_firstoftwoarguments = context.firstoftwoarguments -- context.constructcsonly("firstoftwoarguments" ) -local ctx_secondoftwoarguments = context.secondoftwoarguments -- context.constructcsonly("secondoftwoarguments") -local ctx_firstofoneargument = context.firstofoneargument -- context.constructcsonly("firstofoneargument" ) -local ctx_gobbleoneargument = context.gobbleoneargument -- context.constructcsonly("gobbleoneargument" ) - --- contextsprint(prtcatcodes,[[\ui_fo]]) -- ctx_firstofonearguments --- contextsprint(prtcatcodes,[[\ui_go]]) -- ctx_gobbleonearguments --- contextsprint(prtcatcodes,[[\ui_ft]]) -- ctx_firstoftwoarguments --- contextsprint(prtcatcodes,[[\ui_st]]) -- ctx_secondoftwoarguments - function commands.doifelse(b) if b then ctx_firstoftwoarguments() --- csprint(prtcatcodes,[[\ui_ft]]) -- ctx_firstoftwoarguments else ctx_secondoftwoarguments() --- csprint(prtcatcodes,[[\ui_st]]) -- ctx_secondoftwoarguments end end function commands.doifelsesomething(b) if b and b ~= "" then ctx_firstoftwoarguments() --- csprint(prtcatcodes,[[\ui_ft]]) -- ctx_firstoftwoarguments else ctx_secondoftwoarguments() --- csprint(prtcatcodes,[[\ui_st]]) -- ctx_secondoftwoarguments end end function commands.doif(b) if b then ctx_firstofoneargument() --- context.__flushdirect(prtcatcodes,[[\ui_fo]]) -- ctx_firstofonearguments else ctx_gobbleoneargument() --- context.__flushdirect(prtcatcodes,[[\ui_go]]) -- ctx_gobbleonearguments end end function commands.doifsomething(b) if b and b ~= "" then ctx_firstofoneargument() --- context.__flushdirect(prtcatcodes,[[\ui_fo]]) -- ctx_firstofonearguments else ctx_gobbleoneargument() --- context.__flushdirect(prtcatcodes,[[\ui_go]]) -- ctx_gobbleonearguments end end function commands.doifnot(b) if b then ctx_gobbleoneargument() --- csprint(prtcatcodes,[[\ui_go]]) -- ctx_gobbleonearguments else ctx_firstofoneargument() --- csprint(prtcatcodes,[[\ui_fo]]) -- ctx_firstofonearguments end end function commands.doifnotthing(b) if b and b ~= "" then ctx_gobbleoneargument() --- csprint(prtcatcodes,[[\ui_go]]) -- ctx_gobbleonearguments else ctx_firstofoneargument() --- csprint(prtcatcodes,[[\ui_fo]]) -- ctx_firstofonearguments end end diff --git a/tex/context/base/mkiv/syst-mes.mkiv b/tex/context/base/mkiv/syst-mes.mkiv index 4cd36e24b..3b16d7f97 100644 --- a/tex/context/base/mkiv/syst-mes.mkiv +++ b/tex/context/base/mkiv/syst-mes.mkiv @@ -11,12 +11,8 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newtoks\everywritestring - -\def\writedirect {\immediate\write\statuswrite} -\def\writeline {\writedirect{}} -\def\writestring#1{\begingroup\the\everywritestring\writedirect{#1}\endgroup} -\let\writebanner \writestring +\def\writestring {\immediate\write\statuswrite} +\def\writeline {\writestring{}} \let\message \normalmessage \endinput diff --git a/tex/context/base/mkiv/tabl-frm.mkiv b/tex/context/base/mkiv/tabl-frm.mkiv new file mode 100644 index 000000000..639d6f06d --- /dev/null +++ b/tex/context/base/mkiv/tabl-frm.mkiv @@ -0,0 +1,209 @@ +%D \module +%D [ file=tabl-frm, +%D version=2017.04.11, +%D title=\CONTEXT\ Table Macros, +%D subtitle=Framed Tables, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D For Thomas Schmitz who needed 3000 pages long tables. + +\unprotect + +\writestatus{loading}{ConTeXt Table Macros / Framed Tables} + +\installcorenamespace{framedtable} +\installcorenamespace{framedtablerow} +\installcorenamespace{framedtablecolumn} + +\newcount\c_tabl_framed_c +\newcount\c_tabl_framed_r +\newdimen\d_tabl_framed_h +\newdimen\d_tabl_framed_d +\newdimen\b_tabl_framed + +\initializeboxstack\??framedtable + +\defineframed[\??framedtable] +\defineframed[\??framedtablerow][\??framedtable] +\defineframed[\??framedtablecolumn][\??framedtable] + +\setupframed + [\??framedtable] + [\c!distance=\zeropoint, + \c!before=, + \c!after=, + \c!inbetween=] + +\setupframed + [\??framedtablerow] + [\c!strut=\v!no, + \c!offset=\v!overlay] + +% \defineframedtable[foo] +% \defineframedtable[bar][foo] + +\unexpanded\def\defineframedtable + {\dodoubleempty\tabl_framed_define} + +\def\tabl_framed_define[#1][#2]% + {\ifsecondargument + \defineframed[\??framedtable#1][\??framedtable#2]% + \else\iffirstargument + \defineframed[\??framedtable#1][\??framedtable]% + \fi\fi} + +% \setupframedtable[foo][...] + +\unexpanded\def\setupframedtable + {\dodoubleempty\tabl_framed_setup} + +\def\tabl_framed_setup[#1][#2]% + {\ifsecondargument + \ifcsname\??framed:\??framedtable#1\endcsname \else + \defineframed[\??framedtable#1][\??framedtable]% + \fi + \setupframed[\??framedtable#1][#2]% + \else + \setupframed[\??framedtable][#1]% + \fi} + +% \setupframedtable[1][...] +% \setupframedtable[foo][1][...] + +\unexpanded\def\setupframedtablerow + {\dotripleempty\tabl_framed_setup_row} + +\def\tabl_framed_setup_row[#1][#2][#3]% + {\ifthirdargument + \ifcsname\??framed:\??framedtable#1\endcsname \else + \defineframed[\??framedtable#1][\??framedtable]% + \fi + \ifcsname\??framed:\??framedtablerow#1:#2\endcsname \else + \defineframed[\??framedtablerow#1:#2][\??framedtable#1]% + \fi + \setupframed[\??framedtablerow#1:#2][#3]% + \else\ifsecondargument + \ifcsname\??framed:\??framedtablerow:#1\endcsname \else + \defineframed[\??framedtablerow:#1][\??framedtable]% + \fi + \setupframed[\??framedtablerow:#1][#2]% + \fi\fi} + +\unexpanded\def\setupframedtablecolumn + {\dotripleempty\tabl_framed_setup_column} + +\def\tabl_framed_setup_column[#1][#2][#3]% + {\ifthirdargument + \ifcsname\??framed:\??framedtable#1\endcsname \else + \defineframed[\??framedtable#1][\??framedtable]% + \fi + \ifcsname\??framed:\??framedtablecolumn#1:#2\endcsname \else + \defineframed[\??framedtablecolumn#1:#2][\??framedtable#1]% + \fi + \setupframed[\??framedtablecolumn#1:#2][#3]% + \else\ifsecondargument + \ifcsname\??framed:\??framedtablecolumn:#1\endcsname \else + \defineframed[\??framedtablecolumn:#1][\??framedtable]% + \fi + \setupframed[\??framedtablecolumn:#1][#2]% + \fi\fi} + +\unexpanded\def\startframedtable + {\dodoubleempty\tabl_framed_start} + +\unexpanded\def\tabl_framed_start[#1][#2]% + {\begingroup + \forgetall + \doifelseassignment{#1}% + {\let\currentframedtable\empty + \setupframed[\??framedtable][#1]}% + {\edef\currentframedtable{#1}% + \setupframed[\??framedtable][#2]}% + \edef\currentframed{\??framedtable\currentframedtable}% + \c_tabl_framed_r\zerocount + \d_tabl_framed_d\framedparameter\c!distance + \framedparameter\c!before} + +\unexpanded\def\stopframedtable + {\framedparameter\c!after + \endgroup} + +\unexpanded\def\startframedrow + {\advance\c_tabl_framed_r\plusone + \c_tabl_framed_c\zerocount + \d_tabl_framed_h\zeropoint + \bgroup + \edef\currentframed{\number\c_tabl_framed_r}% + \edef\currentframed + {\??framedtablerow\currentframedtable + \ifcsname\??framedtablerow\currentframedtable:\currentframed\endcsname + :\currentframed + \else\ifcsname\??framedtablerow\currentframedtable:\v!each\endcsname + :\v!each + \fi\fi}% + \dosingleempty\pack_framed_start_framed_nop_indeed} + +\unexpanded\def\stopframedrow + {\dofastloopcs\c_tabl_framed_c\tabl_framed_flush_row + \stopframed + \nointerlineskip + \vskip\zeropoint\relax + \framedparameter\c!inbetween} + +\unexpanded\def\tabl_framed_flush_row + {\vpack to \d_tabl_framed_h{\flushbox\??framedtable{\number\fastloopindex}\vfill}% + \ifdim\d_tabl_framed_d=\zeropoint\else\kern\d_tabl_framed_d\fi} + +\unexpanded\def\startframedcell + {\advance\c_tabl_framed_c\plusone + \setbox\b_tabl_framed\hpack\bgroup + %\bgroup + \edef\currentframed{\number\c_tabl_framed_c}% + \edef\currentframed + {\??framedtablecolumn\currentframedtable + \ifcsname\??framedtablecolumn\currentframedtable:\currentframed\endcsname + :\currentframed + \else\ifcsname\??framedtablecolumn\currentframedtable:\v!each\endcsname + :\v!each + \fi\fi}% + \dosingleempty\pack_framed_start_framed_nop_indeed} + +\unexpanded\def\stopframedcell + {\stopframed + %\egroup + \ifdim\ht\b_tabl_framed>\d_tabl_framed_h + \d_tabl_framed_h\ht\b_tabl_framed + \fi + \savebox\??framedtable{\number\c_tabl_framed_c}{\box\b_tabl_framed}} + +\protect \endinput + +\starttext + +\setupframedtablecolumn [1] [width=3cm,background=color,backgroundcolor=red] +\setupframedtablecolumn [2] [width=4cm,background=color,backgroundcolor=green,align=normal] +% \setupframedtablerow [each] [background=color,backgroundcolor=blue,strut=no] +% \setupframedtablerow [each] [strut=no,offset=overlay] + +\startframedtable[inbetween=\kern-0.4pt,distance=-0.4pt] + +\testfeatureonce{10000}{ +% \testfeatureonce{10}{ + \startframedrow + \startframedcell%[backgroundcolor=yellow] + test + \stopframedcell + \startframedcell + test \par test + \stopframedcell + \stopframedrow +} +\stopframedtable + +\stoptext diff --git a/tex/context/base/mkiv/tabl-ltb.mkiv b/tex/context/base/mkiv/tabl-ltb.mkiv index b0e3f52e4..3147fa1cc 100644 --- a/tex/context/base/mkiv/tabl-ltb.mkiv +++ b/tex/context/base/mkiv/tabl-ltb.mkiv @@ -474,7 +474,8 @@ \ifconditional\c_tabl_lines_preroll \else \box\b_tabl_lines_cell % the columncounter is one ahead ! - \dorecurse\c_tabl_lines_step{\strut\hfil}% +% \dorecurse\c_tabl_lines_step{\strut\hfil}% +\strut \hskip\scratchskip \fi \fi} diff --git a/tex/context/base/mkiv/tabl-ntb.mkiv b/tex/context/base/mkiv/tabl-ntb.mkiv index 78e867546..276f85d31 100644 --- a/tex/context/base/mkiv/tabl-ntb.mkiv +++ b/tex/context/base/mkiv/tabl-ntb.mkiv @@ -107,16 +107,18 @@ {% \inhibitblank \dotagTABLEcell %\tabl_ntb_next_level + \font_styles_math_reset \usenaturaltablelocalstyleandcolor\c!style\c!color - \everypar\t_tabl_ntb_cell_start} + \everypar\t_tabl_ntb_cell_start + \font_styles_math_start} \unexpanded\def\tabl_ntb_cell_stop - {\ifhmode + {\font_styles_math_stop + \ifhmode \the\t_tabl_ntb_cell_stop \par % added 13/4/2006 \else % not sure yet:\naturaltablelocalparameter\c!right - \par \ifdim\prevdepth<\zeropoint % =-1000pt ? \vskip-\strutdp \else @@ -124,6 +126,24 @@ \fi \fi} +% maybe: +% +% \unexpanded\def\tabl_ntb_cell_stop +% {\ifhmode +% \the\t_tabl_ntb_cell_stop +% \par % added 13/4/2006 +% \else +% % not sure yet:\naturaltablelocalparameter\c!right +% \par +% \ifhmode +% % \removeunwantedspaces +% \else\ifdim\prevdepth<\zeropoint % =-1000pt ? +% \vskip-\strutdp +% \else +% \removebottomthings +% \fi\fi +% \fi} + \newcount\c_tabl_ntb_row \newcount\c_tabl_ntb_col \newcount\c_tabl_ntb_spn @@ -235,6 +255,7 @@ \installcorenamespace{naturaltablehei} \installcorenamespace{naturaltabledis} \installcorenamespace{naturaltableaut} +\installcorenamespace{naturaltablebck} %installcorenamespace{naturaltablefwd} % forcedwidth \installcorenamespace{naturaltabletxt} \installcorenamespace{naturaltablespn} @@ -259,7 +280,7 @@ \def\tabl_ntb_set_nob#1{\expandafter\let\csname\??naturaltablenob\m_tabl_tbl_level:\number#1\endcsname\plusone} \def\tabl_ntb_get_nob#1{\ifcsname\??naturaltablenob\m_tabl_tbl_level:\number#1\endcsname\plusone\else\zerocount\fi} -\def\tabl_ntb_set_tag#1#2{\expandafter\edef\csname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname} +%def\tabl_ntb_set_tag#1#2{\expandafter\edef\csname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname} \def\tabl_ntb_set_col#1#2{\expandafter\edef\csname\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2\endcsname} \def\tabl_ntb_set_row#1#2{\expandafter\edef\csname\??naturaltablerow\m_tabl_tbl_level:\number#1:\number#2\endcsname} @@ -267,17 +288,17 @@ \def\tabl_ntb_let_col#1#2{\expandafter\let\csname\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2\endcsname} \def\tabl_ntb_let_row#1#2{\expandafter\let\csname\??naturaltablerow\m_tabl_tbl_level:\number#1:\number#2\endcsname} -\def\tabl_ntb_set_wd#1#2{\expandafter\xdef\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! +%def\tabl_ntb_set_wd#1#2{\expandafter\xdef\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! \def\tabl_ntb_set_ht#1#2{\expandafter\xdef\csname\??naturaltableht\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! -\def\tabl_ntb_let_wd#1#2{\global\expandafter\let\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! +%def\tabl_ntb_let_wd#1#2{\global\expandafter\let\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! \def\tabl_ntb_let_ht#1#2{\global\expandafter\let\csname\??naturaltableht\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! \def\tabl_ntb_get_tag#1#2{\csname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname} \def\tabl_ntb_get_col#1#2{\csname\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2\endcsname} \def\tabl_ntb_get_row#1#2{\csname\??naturaltablerow\m_tabl_tbl_level:\number#1:\number#2\endcsname} -\def\tabl_ntb_get_wd#1#2{\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} +%def\tabl_ntb_get_wd#1#2{\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} \def\tabl_ntb_get_ht#1#2{\csname\??naturaltableht\m_tabl_tbl_level:\number#1:\number#2\endcsname} \def\tabl_ntb_set_wid#1{\expandafter\xdef\csname\??naturaltablewid\m_tabl_tbl_level:\number#1\endcsname} % {#2} global ! @@ -295,6 +316,10 @@ \def\tabl_ntb_get_dis#1{\ifcsname\??naturaltabledis\m_tabl_tbl_level:\number#1\endcsname\lastnamedcs\else\zeropoint\fi} \def\tabl_ntb_get_aut#1{\csname \??naturaltableaut\m_tabl_tbl_level:\number#1\endcsname} +\def\tabl_ntb_let_bck#1#2{\global\expandafter\chardef\csname\??naturaltablebck\m_tabl_tbl_level:\number#1:\number#2\endcsname} + +\def\tabl_ntb_get_bck#1#2{\csname\??naturaltablebck\m_tabl_tbl_level:\number#1:\number#2\endcsname} + \def\tabl_ntb_tag_pattern#1#2{\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2} \def\tabl_ntb_row_pattern#1#2{\??naturaltablerow\m_tabl_tbl_level:\number#1:\number#2} \def\tabl_ntb_col_pattern#1#2{\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2} @@ -1089,7 +1114,7 @@ \fi \fi \tabl_ntb_let_ht\c_tabl_ntb_current_row\c_tabl_ntb_current_col\zeropoint - \tabl_ntb_let_wd\c_tabl_ntb_current_row\c_tabl_ntb_current_col\zeropoint + %tabl_ntb_let_wd\c_tabl_ntb_current_row\c_tabl_ntb_current_col\zeropoint \ifcsname\tabl_ntb_col_pattern\c_tabl_ntb_current_row\c_tabl_ntb_current_col\endcsname \else \tabl_ntb_let_col\c_tabl_ntb_current_row\c_tabl_ntb_current_col\zerocount \fi @@ -1167,7 +1192,7 @@ \global\let\m_tabl_ntb_same_page \empty} \def\tabl_ntb_prelocate_error - {\writestatus\m!system{fatal error: use \string\prelocateTBLrows\space to increase table memory (now: \the\c_tabl_prelocated_rows)}} + {\writestatus\m!TABLE{fatal error: use \string\prelocateTBLrows\space to increase table memory (now: \the\c_tabl_prelocated_rows)}} % \prelocateTBLrows{1000} % may speed up large tables @@ -1288,7 +1313,8 @@ \dostoptagged} \unexpanded\def\tabl_ntb_span#1% - {\dorecurse{#1} + {\hskip\tabl_ntb_get_dis\c_tabl_ntb_col + \dorecurse{#1} {\hskip\tabl_ntb_get_wid\c_tabl_ntb_col\relax \global\advance\c_tabl_ntb_col\plusone}} @@ -1367,7 +1393,7 @@ \fi \setbox\scratchbox\hbox{\tabl_ntb_get_txt{#1}{#2}}% \tabl_ntb_set_ht{#1}{#2}{\the\ht\scratchbox}% - \tabl_ntb_set_wd{#1}{#2}{\the\wd\scratchbox}% + %tabl_ntb_set_wd{#1}{#2}{\the\wd\scratchbox}% \ifdim\ht\scratchbox>\tabl_ntb_get_hei{#1}\relax \tabl_ntb_set_hei{#1}{\the\ht\scratchbox}% \fi}% @@ -1459,6 +1485,20 @@ \let\tabl_ntb_preroll\relax +\def\tabl_ntb_table_get_max_width#1#2% + {#1\wd#2\relax} + +% first needs testing (in projects): +% +% \def\tabl_ntb_table_get_max_width#1#2% +% {#1\zeropoint +% \dorecurse\c_tabl_ntb_maximum_col +% {\advance#1\tabl_ntb_get_wid\recurselevel +% \advance#1\tabl_ntb_get_dis\recurselevel}% +% \ifdim#1<\wd#2\relax +% #1\wd#2\relax +% \fi} + \def\tabl_ntb_table_stop {\forgetall % new, here see narrower-004.tex %\setbox\scratchbox\hbox @@ -1472,7 +1512,7 @@ % new \c_tabl_ntb_current_col_one\recurselevel\relax \dorecurse\c_tabl_ntb_maximum_row - {\tabl_ntb_let_wd\recurselevel\c_tabl_ntb_current_col_one\zeropoint + {%tabl_ntb_let_wd\recurselevel\c_tabl_ntb_current_col_one\zeropoint \tabl_ntb_let_ht\recurselevel\c_tabl_ntb_current_col_one\zeropoint}% % till here \tabl_ntb_let_tal\recurselevel\zerocount @@ -1481,7 +1521,7 @@ \dorecurse\c_tabl_ntb_maximum_row {\tabl_ntb_let_hei\recurselevel\maxdimen}% \tabl_ntb_let_gal\zerocount -\tabl_ntb_preroll\relax + \tabl_ntb_preroll\relax \c_tabl_tbl_pass\plusone \let\tabl_ntb_pass\tabl_ntb_pass_one \let\tabl_ntb_cell_process\tabl_ntb_cell_process_a @@ -1493,6 +1533,9 @@ \setbox\scratchbox\vbox{\settrialtypesetting \tabl_ntb_flush_content}% \fi \tabl_ntb_let_dis\c_tabl_ntb_maximum_col\zeropoint + % + \tabl_ntb_table_get_max_width\scratchdimen\scratchbox + % \ifautoTBLspread % experimental, stretch non fixed cells to \hsize \tabl_ntb_check_widths_one % trial run @@ -1500,7 +1543,8 @@ \tabl_ntb_stretch_widths \let\tabl_ntb_cell_process\tabl_ntb_cell_process_b \setbox\scratchbox\vbox{\settrialtypesetting \tabl_ntb_flush_content}% - \else\ifdim\wd\scratchbox>\hsize + % \else\ifdim\wd\scratchbox>\hsize + \else\ifdim\scratchdimen>\hsize \ifautoTBLhsize \tabl_ntb_check_widths_one % trial run \tabl_ntb_check_widths_two % real run @@ -1514,7 +1558,8 @@ \writestatus\m!TABLE{missing\space\number\numexpr\c_tabl_ntb_maximum_col-\c_tabl_ntb_encountered_max\relax\space column(s), guessing widths}% \fi \edef\savedhsize{\the\hsize}% - \hsize\wd\scratchbox\relax % new per 17/04/2006 + % \hsize\wd\scratchbox\relax % new per 17/04/2006 + \hsize\scratchdimen\relax % new per 17/04/2006 \tabl_ntb_check_widths_one % trial run \tabl_ntb_check_widths_two % real run \hsize\savedhsize @@ -1573,9 +1618,10 @@ % \hbox{\registerparoptions\box\b_tabl_ntb_final}% (*) better here % better : \ifinsidefloat - % nothing, else we get a \hsized box + % no \dontleavehmode else too wide, otherwise we get a \hsized box \else - \registerparoptions % (*) better here + \registerparoptions % (*) better here (also does a \dontleavehmode) + \ifhmode\else\dontleavehmode\fi \fi \box\b_tabl_ntb_final \afterTABLEbox} @@ -1632,11 +1678,11 @@ \let\beforeTABLEbox \relax \let\afterTABLEbox \relax -\def\tabl_ntb_check_widths_one{\tabl_ntb_check_widths_indeed0} % 0 = trial run -\def\tabl_ntb_check_widths_two{\tabl_ntb_check_widths_indeed1} % 1 = real run +\def\tabl_ntb_check_widths_one{\tabl_ntb_check_widths_indeed\zerocount} % 0 = trial run +\def\tabl_ntb_check_widths_two{\tabl_ntb_check_widths_indeed\plusone } % 1 = real run \def\tabl_ntb_check_widths_indeed#1% - {\iftraceTABLE\tabl_ntb_show_widths{B#1}\fi + {\iftraceTABLE\tabl_ntb_show_widths B#1\fi \!!counta\zerocount \!!dimena\dimexpr \hsize @@ -1669,6 +1715,7 @@ \fi \fi \fi}% + \iftraceTABLE\tabl_ntb_show_widths M#1\fi \ifcase\!!counta \else \divide\!!dimena \!!counta \fi \dorecurse\c_tabl_ntb_maximum_col {\scratchdimen\tabl_ntb_get_wid\recurselevel\relax @@ -1681,7 +1728,7 @@ \tabl_ntb_set_wid\recurselevel{\the\!!dimena}% \fi \fi}% - \iftraceTABLE\tabl_ntb_show_widths{E#1}\fi} + \iftraceTABLE\tabl_ntb_show_widths E#1\fi} \def\tabl_ntb_check_heights_one_indeed {\!!countb\tabl_ntb_get_row\c_tabl_ntb_current_row_three\c_tabl_ntb_current_col_three\relax @@ -1754,13 +1801,15 @@ \def\tabl_ntb_check_heights_two {} -\def\tabl_ntb_show_widths#1% - {\vbox - {\forgetall - \tttf[#1]% - \dorecurse\c_tabl_ntb_maximum_col - {\scratchdimen\tabl_ntb_get_wid\recurselevel\relax - [\recurselevel:\the\scratchdimen]}}} +\def\tabl_ntb_show_widths#1#2% + {\begingroup + \scratchdimen\zeropoint + \dorecurse\c_tabl_ntb_maximum_col + {\advance\scratchdimen\tabl_ntb_get_wid\recurselevel\relax}% + \writestatus\m!TABLE{#1 \ifcase#2trial\else real\fi: hsize: \the\hsize, total: \the\scratchdimen}% + \dorecurse\c_tabl_ntb_maximum_col + {\writestatus\m!TABLE{\space\space\recurselevel: \the\dimexpr\tabl_ntb_get_wid\recurselevel}}% + \endgroup} % \def\tabl_ntb_char_align % {\doifelse{\naturaltablelocalparameter\c!aligncharacter}\v!yes @@ -1897,7 +1946,13 @@ \ifdim\scratchdimen>\tabl_ntb_get_dis{#2}\relax \tabl_ntb_set_dis{#2}{\the\scratchdimen}% \fi - \inheritednaturaltablelocalframed{\tabl_ntb_cell_start\tabl_ntb_char_align{#1}{#2}#4\tabl_ntb_cell_stop\tabl_ntb_cell_finalize}}% + \anch_backgrounds_text_level_start + \inheritednaturaltablelocalframed{\tabl_ntb_cell_start\tabl_ntb_char_align{#1}{#2}#4\tabl_ntb_cell_stop\tabl_ntb_cell_finalize}% + \anch_backgrounds_text_level_stop +\ifcase\c_anch_backgrounds_text_count\else + \tabl_ntb_let_bck{#1}{#2}\c_anch_backgrounds_text_state +\fi + }% \scratchdimen\tabl_ntb_get_wid\c_tabl_ntb_col\relax \ifdim\wd\scratchbox>\scratchdimen \ifsqueezeTBLspan @@ -1913,7 +1968,7 @@ \tabl_ntb_set_hei\scratchcounter{\the\ht\scratchbox}% auto set \fi \tabl_ntb_set_ht{#1}{#2}{\the\ht\scratchbox}% - \tabl_ntb_set_wd{#1}{#2}{\the\wd\scratchbox}% + %tabl_ntb_set_wd{#1}{#2}{\the\wd\scratchbox}% \ifautoTBLcheckwidth \ifdim\wd\scratchbox<.75\hsize % fuzzy guess \ifdim\ht\scratchbox>2\openlineheight % honor width since this @@ -1931,11 +1986,11 @@ \fi \fi \fi - \setbox2\emptyhbox - \wd2\wd\scratchbox - \ht2\ht\scratchbox - \dp2\dp\scratchbox - \box2 + \setbox\scratchboxone\emptyhbox + \wd\scratchboxone\wd\scratchbox + \ht\scratchboxone\ht\scratchbox + \dp\scratchboxone\dp\scratchbox + \box\scratchboxone \egroup} \unexpanded\def\tabl_ntb_cell_process_b_c#1#2#3[#4]#5% @@ -2000,40 +2055,98 @@ \else \setnaturaltablelocalparameter\c!height{\d_tabl_ntb_height}% \fi +\ifcase\c_anch_backgrounds_text_count\else + \edef\p_region{\naturaltablelocalparameter\c!region}% + \ifx\p_region\empty\ifnum\tabl_ntb_get_bck{#1}{#2}>\zerocount + \letnaturaltablelocalparameter\c!region\v!yes + \fi\fi +\fi \inheritednaturaltablelocalframed{\tabl_ntb_cell_start\tabl_ntb_char_align{#1}{#2}#4\tabl_ntb_cell_stop}}% \hskip\tabl_ntb_get_dis{#2}} -\setupTABLE - [\c!frameoffset=.5\linewidth, - \c!backgroundoffset=\v!frame, - % \c!framecolor=\s!black, - \c!width=\v!fit, - \c!height=\v!fit, - \c!autowidth=\v!yes, - \c!rulethickness=\linewidth, - \c!strut=\v!yes, - \c!autostrut=\v!no, - % - \c!color=, - \c!style=, - \c!headstyle=\v!bold, - \c!headcolor=, - \c!aligncharacter=\v!no, - \c!alignmentcharacter={,}, - \c!option=, % \v!stretch - \c!header=, - \c!spaceinbetween=, - \c!maxwidth=8\emwidth, - \c!textwidth=\v!local, % was \hsize - \c!split=\v!auto, - \c!splitoffset=\zeropoint, - \c!distance=\zeropoint, % individual column - \c!columndistance=\zeropoint, % each column (whole table) - \c!leftmargindistance=\zeropoint, % whole table - \c!rightmargindistance=\zeropoint,% whole table - \c!left=, - \c!right=, - \c!setups=] +\newtoks\everyresetTABLEyes +\newtoks\everyresetTABLEnop + +\appendtoks + \setupTABLE [% + % + % framed defaults + % + \c!width=\v!fit,% + \c!height=\v!fit,% + \c!lines=,% + \c!offset=.25\exheight,% + \c!empty=\v!no,% + \c!frame=\v!on,% + \c!topframe=,% + \c!bottomframe=,% + \c!leftframe=,% + \c!rightframe=,% + \c!radius=.5\bodyfontsize,% + \c!rulethickness=\linewidth,% + \c!corner=\v!rectangular,% + \c!depth=\zeropoint,% + \c!foregroundcolor=,% + \c!foregroundstyle=,% + \c!background=,% + \c!backgroundcolor=,% + \c!backgroundoffset=\v!frame,% + \c!framecolor=,% + \c!frameoffset=.5\linewidth,% + % \c!backgroundcorner=\framedparameter\c!corner,% + % \c!backgrounddepth=\framedparameter\c!depth,% + % \c!backgroundradius=\framedparameter\c!radius,% + % \c!framecorner=\framedparameter\c!corner,% + % \c!framedepth=\framedparameter\c!depth,% + % \c!frameradius=\framedparameter\c!radius,% + \c!component=,% + \c!region=,% + \c!align=,% + \c!bottom=\vss,% + \c!top=,% + \c!strut=\v!yes,% + \c!autostrut=\v!no,% + \c!location=\v!normal,% + \c!orientation=,% + \c!autowidth=\v!yes,% + \c!setups=,% + \c!loffset=\zeropoint,% + \c!roffset=\zeropoint,% + \c!toffset=\zeropoint,% + \c!boffset=\zeropoint,% + % + % table specific + % + \c!aligncharacter=\v!no,% + \c!alignmentcharacter={,},% + \c!color=,% + \c!columndistance=\zeropoint,% each column (whole table) + \c!distance=\zeropoint,% individual column + \c!headcolor=,% + \c!header=,% + \c!headstyle=\v!bold,% + \c!left=,% + \c!leftmargindistance=\zeropoint,% whole table + \c!maxwidth=8\emwidth,% + \c!option=,% \v!stretch + \c!right=,% + \c!rightmargindistance=\zeropoint,% whole table + \c!spaceinbetween=,% + \c!split=\v!auto,% + \c!splitoffset=\zeropoint,% + \c!style=,% + \c!textwidth=\v!local,% was \hsize + ]% +\to \everyresetTABLEyes + +\appendtoks + \setupTABLE [% + \c!width=\v!fit,% + \c!height=\v!fit% + ]% +\to \everyresetTABLEnop + +\the\everyresetTABLEyes % \bgroup % \setupTABLE[column][1][aligncharacter=yes, alignmentcharacter={,}] @@ -2054,29 +2167,9 @@ \def\tabl_ntb_parameters_reset % we can use setters instead {\ifnum\m_tabl_tbl_level>\plusone % in ieder geval \ifconditional\resetTABLEmode - % not ok yet - \setupTABLE - [\c!frameoffset=.5\linewidth, - \c!backgroundoffset=\v!frame, - % \c!framecolor=\s!black, - \c!width=\v!fit, - \c!height=\v!fit, - \c!autowidth=\v!yes, - % \c!rulethickness=\linewidth, - \c!strut=\v!no, - \c!strut=\v!yes, % needed for mathml, but ... maybe we need another resetTABLEmode - \c!autostrut=\v!no, - \c!color=, - \c!style=, - \c!headstyle=, - \c!headcolor=, - \c!aligncharacter=\v!no, - \c!alignmentcharacter={,}, - \c!maxwidth=8\emwidth]% + \the\everyresetTABLEyes \else - \setupTABLE - [\c!width=\v!fit, - \c!height=\v!fit]% + \the\everyresetTABLEnop \fi \fi} diff --git a/tex/context/base/mkiv/tabl-tab.mkiv b/tex/context/base/mkiv/tabl-tab.mkiv index e238447b9..76f7f76c3 100644 --- a/tex/context/base/mkiv/tabl-tab.mkiv +++ b/tex/context/base/mkiv/tabl-tab.mkiv @@ -981,7 +981,10 @@ \def\tabl_table_normal_full_rule {\starttablenoalign \!ttGetHalfRuleThickness + \scratchdistance\directtablesparameter\c!openup + \ifzeropt\scratchdistance\else\kern\scratchdistance\fi \hrule\s!height\scratchdimen\s!depth\scratchdimen + \ifzeropt\scratchdistance\else\kern\scratchdistance\fi \stoptablenoalign} \def\tabl_table_normal_short_rule % was: \!ttShortHrule @@ -2268,6 +2271,7 @@ \c!commands=, \c!background=, \c!backgroundcolor=, - \c!split=\v!auto] + \c!split=\v!auto, + \c!openup=\zeropoint] \protect \endinput diff --git a/tex/context/base/mkiv/tabl-tbl.mkiv b/tex/context/base/mkiv/tabl-tbl.mkiv index 4cd839bd6..b21771009 100644 --- a/tex/context/base/mkiv/tabl-tbl.mkiv +++ b/tex/context/base/mkiv/tabl-tbl.mkiv @@ -575,7 +575,7 @@ % future let but just pick up the key. % \installtabulatepreambleoption \s!unknown % -% {\writestatus{tabulate}{unknown preamble key [\meaning\next]}% +% {\writestatus{tabulate}{unknown preamble key [\normalmeaning\next]}% % \tabl_tabulate_set_preamble} % % \def\tabl_tabulate_set_preamble @@ -787,7 +787,7 @@ \global\d_tabl_tabulate_vrulethickness\d_tabl_tabulate_vrulethickness_default \rawprocesscommalist[#1]\tabl_tabulate_set_vrule_command \fi - \tabl_tabulate_set_preamble#2\relax\relax % permits i without n + \tabl_tabulate_set_preamble#2\relax\relax % permits i without n \ifcase\c_tabl_tabulate_modus\relax \tabl_tabulate_set_width_normal \or % fixed width @@ -1213,10 +1213,89 @@ % todo: spacing around tabulate when bodyfont is set -\unexpanded\def\tabl_tabulate_start_building - {\ifinsidefloat \else +% \let\tabl_tabulate_inside_before \relax +% \let\tabl_tabulate_inside_after \relax +% \let\tabl_tabulate_inside_inbetween\relax +% +% \def\tabl_tabulate_outside_before +% {\whitespace +% \tabulationparameter\c!before} +% +% \def\tabl_tabulate_outside_after +% {\tabulationparameter\c!after} + +% \showboxes +% +% \startcombination +% {\insidefloattrue \starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate} {} +% {\insidefloattrue \starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate} {} +% \stopcombination +% +% \startcombination +% {\vbox{\starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate}} {} +% {\vbox{\starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate}} {} +% \stopcombination +% +% \startcombination +% {\starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate} {} +% {\starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate} {} +% \stopcombination + +\let\tabl_tabulate_inside_after \relax +\let\tabl_tabulate_outside_after \relax +\let\tabl_tabulate_inside_inbetween \relax +\let\tabl_tabulate_outside_inbetween\relax + +\unexpanded\def\tabl_tabulate_inside_before + {\ifhmode\par\fi + \ifhmode + \ifinsidesplitfloat + \let\tabl_tabulate_inside_after\relax + \else + \vbox\bgroup + \let\tabl_tabulate_inside_after\egroup + \fi + \else + \let\tabl_tabulate_inside_after\relax + \fi} + +\unexpanded\def\tabl_tabulate_outside_before + {\ifhmode\par\fi + \ifhmode + \vbox\bgroup + \let\tabl_tabulate_outside_after \egroup + \let\tabl_tabulate_outside_inbetween\relax + \else\ifinner + \let\tabl_tabulate_outside_after \relax + \let\tabl_tabulate_outside_inbetween\relax + \else \whitespace \tabulationparameter\c!before + \relax + \let\tabl_tabulate_outside_after \tabl_tabulate_outside_after_indeed + \let\tabl_tabulate_outside_inbetween\tabl_tabulate_outside_inbetween_indeed + \fi\fi} + +\def\tabl_tabulate_outside_after_indeed + {\tabulationparameter\c!after}% + +\def\tabl_tabulate_outside_inbetween_indeed + {\doifempty{\tabulationparameter\c!after} + {\vskip\strutdp + \verticalstrut + \vskip-\struttotal}} + +\def\tabl_tabulate_inside_inbetween % needs checking + {\doifempty{\tabulationparameter\c!after} + {\vskip\strutdp + \verticalstrut + \vskip-\struttotal}} + +\unexpanded\def\tabl_tabulate_start_building + {\ifinsidefloat + \tabl_tabulate_inside_before + \else + \tabl_tabulate_outside_before \fi \bgroup % settings % @@ -1232,6 +1311,15 @@ \edef\p_rulethickness{\tabulationparameter\c!rulethickness}% \edef\p_bodyfont {\tabulationparameter\c!bodyfont} \edef\p_indenting {\tabulationparameter\c!indenting}% + \edef\p_keeptogether {\tabulationparameter\c!keeptogether}% + % + \ifx\p_keeptogether\v!no + \settrue \c_tabl_tabulate_tolerant_break + %\setfalse\c_tabl_tabulate_handlepbreak + \else + \setfalse\c_tabl_tabulate_tolerant_break + %\settrue \c_tabl_tabulate_handlepbreak + \fi % \settrue\c_tabl_tabulate_split \csname\??tabulatesplit\tabulationparameter\c!split\endcsname @@ -1958,11 +2046,10 @@ \tabl_tabulate_column_rule_separator_inject \tabl_tabulate_nobreak_inject \tabl_tabulate_hrule_inject - \ifinsidefloat\else - \doifempty{\tabulationparameter\c!after} - {\vskip\strutdp - \verticalstrut - \vskip-\struttotal}% + \ifinsidefloat + \tabl_tabulate_inside_inbetween + \else + \tabl_tabulate_outside_inbetween \fi \stoptabulatenoalign} @@ -2072,6 +2159,14 @@ \let\v_tabl_tabulate_align\!!zerocount +\def\tabl_tabulate_check_side_float % new per 29-07-2016 + {\ifdefined\page_sides_check_floats_indeed + \page_sides_check_floats_indeed + \ifdim\hangindent>\zeropoint + \advance\d_tabl_tabulate_indent\hangindent + \fi + \fi} + \def\tabl_tabulate_set_local_hsize {\setlocalhsize \hsize\localhsize} @@ -2159,23 +2254,30 @@ \ifinsidefloat \d_tabl_tabulate_indent\zeropoint \else + \tabl_tabulate_check_side_float \tabl_tabulate_set_local_hsize \fi \dontcomplain \forgetall % hm, interference with preceding \forgetparindent probably bug, to be solved \everypar\everytabulatepar - \setbox0\vbox % outside \if because of line counting + \setbox\scratchbox\vbox % outside \if because of line counting {\notesenabledfalse \d_tabl_tabulate_indent\zeropoint \settrialtypesetting % very important +\anch_backgrounds_text_level_start \expandafter\halign\expandafter{\the\t_tabl_tabulate_preamble\crcr\tabl_tabulate_insert_content\crcr}}% +\anch_backgrounds_text_level_stop +\ifcase\c_anch_backgrounds_text_state\else + \global\settrue\tablehaspositions +\fi \ifnum\c_tabl_tabulate_nofauto>\zerocount % so, even if the natural size is larger, in the final run, we force the calculated width - \d_tabl_tabulate_width\dimexpr\hsize-\wd0-\d_tabl_tabulate_width_p-\d_tabl_tabulate_width_w\relax + \d_tabl_tabulate_width\dimexpr\hsize-\wd\scratchbox-\d_tabl_tabulate_width_p-\d_tabl_tabulate_width_w\relax \ifnum\c_tabl_tabulate_nofauto>\zerocount \divide\d_tabl_tabulate_width \c_tabl_tabulate_nofauto\relax \fi \fi + \setbox\scratchbox\emptybox % free memory \ifconditional\c_tabl_tabulate_split \splittopskip\strutht \glet\tabl_tabulate_flush_collected_indeed\empty @@ -2232,8 +2334,10 @@ \tabl_split_box\b_tabl_tabulate \fi % - \ifinsidefloat \else - \tabulationparameter\c!after + \ifinsidefloat + \tabl_tabulate_inside_after + \else + \tabl_tabulate_outside_after \fi \egroup} % whole thing @@ -2491,4 +2595,34 @@ \definetabulate[tabulate] \setuptabulate[tabulate][\c!format=\v!none] % so no \v! here +%D The following helpers are just there because we also have them at the \LUA\ end: +%D +%D \startbuffer +%D \starttabulate[|l|c|r|] +%D \tabulaterow {a,b,c} +%D \tabulaterowbold{aa,bb,cc} +%D \tabulaterowtype{aaa,bbb,ccc} +%D \tabulaterowtyp {aaaa,bbbb,cccc} +%D \stoptabulate +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +\def\tabl_tabulate_compact_row#1#2% + {\NC\tabl_tabulate_compact_step#1#2,\end,} + +\def\tabl_tabulate_compact_step#1#2#3,% + {\ifx#2\end + \NR + \expandafter\gobbleoneargument + \else + #1{#2#3}\NC + \expandafter\tabl_tabulate_compact_step + \fi#1} + +\unexpanded\def\tabulaterow {\tabl_tabulate_compact_row\relax} +\unexpanded\def\tabulaterowbold{\tabl_tabulate_compact_row\bold} +\unexpanded\def\tabulaterowtype{\tabl_tabulate_compact_row\type} +\unexpanded\def\tabulaterowtyp {\tabl_tabulate_compact_row\typ} + \protect \endinput diff --git a/tex/context/base/mkiv/tabl-tsp.mkiv b/tex/context/base/mkiv/tabl-tsp.mkiv index e0c3b9b74..eadcda16c 100644 --- a/tex/context/base/mkiv/tabl-tsp.mkiv +++ b/tex/context/base/mkiv/tabl-tsp.mkiv @@ -372,13 +372,13 @@ \page_split_float_process{\tsplitbeforeresult\box\tsplitresult\tsplitafterresult}% \doifnotinsidesplitfloat\tsplitafter \endgraf + \global\settrue\usesamefloatnumber % new, prevent next increment \fi \ifinsidecolumns \goodbreak % was \doifnotinsidesplitfloat\goodbreak \else \page % was \doifnotinsidesplitfloat\page \fi - \global\settrue\usesamefloatnumber % new, prevent next increment \fi} %D The next one assumes that the split takes place elsewhere. This is diff --git a/tex/context/base/mkiv/tabl-xtb.lua b/tex/context/base/mkiv/tabl-xtb.lua index 87d5fa121..dade345fc 100644 --- a/tex/context/base/mkiv/tabl-xtb.lua +++ b/tex/context/base/mkiv/tabl-xtb.lua @@ -26,81 +26,84 @@ this mechamism will be improved so that it can replace its older cousin. -- todo: use linked list instead of r/c array -- todo: we can use the sum of previously forced widths for column spans -local tonumber, next = tonumber, next - -local commands = commands -local context = context -local tex = tex - -local implement = interfaces.implement - -local texgetcount = tex.getcount -local texsetcount = tex.setcount -local texgetdimen = tex.getdimen -local texsetdimen = tex.setdimen -local texget = tex.get - -local format = string.format -local concat = table.concat -local points = number.points - -local todimen = string.todimen - -local context_beginvbox = context.beginvbox -local context_endvbox = context.endvbox -local context_blank = context.blank -local context_nointerlineskip = context.nointerlineskip -local context_dummyxcell = context.dummyxcell - -local variables = interfaces.variables - -local setmetatableindex = table.setmetatableindex -local settings_to_hash = utilities.parsers.settings_to_hash - -local nuts = nodes.nuts -- here nuts gain hardly nothing -local tonut = nuts.tonut -local tonode = nuts.tonode - -local getnext = nuts.getnext -local getprev = nuts.getprev -local getlist = nuts.getlist -local getfield = nuts.getfield -local getbox = nuts.getbox - -local setfield = nuts.setfield -local setlink = nuts.setlink - -local copy_node_list = nuts.copy_list -local hpack_node_list = nuts.hpack -local flush_node_list = nuts.flush_list -local takebox = nuts.takebox - -local nodepool = nuts.pool - -local new_glue = nodepool.glue -local new_kern = nodepool.kern -local new_penalty = nodepool.penalty -local new_hlist = nodepool.hlist - -local v_stretch = variables.stretch -local v_normal = variables.normal -local v_width = variables.width -local v_height = variables.height -local v_repeat = variables["repeat"] -local v_max = variables.max -local v_fixed = variables.fixed -local v_auto = variables.auto -local v_before = variables.before -local v_after = variables.after -local v_both = variables.both -local v_samepage = variables.samepage -local v_tight = variables.tight - -local xtables = { } -typesetters.xtables = xtables - -local trace_xtable = false -local report_xtable = logs.reporter("xtable") +local tonumber, next, rawget = tonumber, next, rawget + +local commands = commands +local context = context +local ctxnode = context.nodes.flush + +local implement = interfaces.implement + +local tex = tex +local texgetcount = tex.getcount +local texsetcount = tex.setcount +local texgetdimen = tex.getdimen +local texsetdimen = tex.setdimen +local texget = tex.get + +local format = string.format +local concat = table.concat +local points = number.points + +local todimen = string.todimen + +local ctx_beginvbox = context.beginvbox +local ctx_endvbox = context.endvbox +local ctx_blank = context.blank +local ctx_nointerlineskip = context.nointerlineskip +local ctx_dummyxcell = context.dummyxcell + +local variables = interfaces.variables + +local setmetatableindex = table.setmetatableindex +local settings_to_hash = utilities.parsers.settings_to_hash + +local nuts = nodes.nuts -- here nuts gain hardly nothing +local tonut = nuts.tonut +local tonode = nuts.tonode + +local getnext = nuts.getnext +local getprev = nuts.getprev +local getlist = nuts.getlist +local getfield = nuts.getfield +local getbox = nuts.getbox +local getwhd = nuts.getwhd + +local setfield = nuts.setfield +local setlink = nuts.setlink +local setdir = nuts.setdir +local setshift = nuts.setshift + +local copy_node_list = nuts.copy_list +local hpack_node_list = nuts.hpack +local flush_node_list = nuts.flush_list +local takebox = nuts.takebox + +local nodepool = nuts.pool + +local new_glue = nodepool.glue +local new_kern = nodepool.kern +local new_hlist = nodepool.hlist + +local v_stretch = variables.stretch +local v_normal = variables.normal +local v_width = variables.width +local v_height = variables.height +local v_repeat = variables["repeat"] +local v_max = variables.max +local v_fixed = variables.fixed +----- v_auto = variables.auto +local v_before = variables.before +local v_after = variables.after +local v_both = variables.both +local v_samepage = variables.samepage +local v_tight = variables.tight + +local xtables = { } +typesetters.xtables = xtables + +local trace_xtable = false +local report_xtable = logs.reporter("xtable") trackers.register("xtable.construct", function(v) trace_xtable = v end) @@ -256,9 +259,7 @@ function xtables.set_reflow_width() -- drc.list = true -- we don't need to keep the content around as we're in trial mode (no: copy_node_list(tb)) -- - local width = getfield(tb,"width") - local height = getfield(tb,"height") - local depth = getfield(tb,"depth") + local width, height, depth = getwhd(tb) -- local widths = data.widths local heights = data.heights @@ -428,9 +429,7 @@ function xtables.set_reflow_height() local tb = getbox("b_tabl_x") local drc = row[c] -- - local width = getfield(tb,"width") - local height = getfield(tb,"height") - local depth = getfield(tb,"depth") + local width, height, depth = getwhd(tb) -- if drc.ny < 2 then if data.fixedrows[r] == 0 then -- and drc.dimensionstate < 2 @@ -520,6 +519,7 @@ function xtables.reflow_width() local nofrows = data.nofrows local nofcolumns = data.nofcolumns local rows = data.rows +-- inspect(rows) for r=1,nofrows do local row = rows[r] for c=1,nofcolumns do @@ -551,6 +551,7 @@ function xtables.reflow_width() showwidths("stage 1",widths,autowidths) end local noffrozen = 0 +-- here we can also check spans -- inspect(data.fixedcspans) if options[v_max] then for c=1,nofcolumns do @@ -819,11 +820,10 @@ function xtables.construct() end local list = drc.list if list then - setfield(list,"shift",getfield(list,"height") + getfield(list,"depth")) + local w, h, d = getwhd(list) + setshift(list,h+d) -- list = hpack_node_list(list) -- is somehow needed - -- setfield(list,"width",0) - -- setfield(list,"height",0) - -- setfield(list,"depth",0) + -- setwhd(list,0,0,0) -- faster: local h = new_hlist(list) list = h @@ -872,7 +872,7 @@ function xtables.construct() -- we have a direction issue here but hpack_node_list(list,0,"exactly","TLT") cannot be used -- due to the fact that we need the width local hbox = hpack_node_list(list) - setfield(hbox,"dir","TLT") + setdir(hbox,"TLT") result[nofr] = { hbox, size, @@ -921,29 +921,29 @@ local function inject(row,copy,package) row[1] = copy_node_list(list) end if package then - context_beginvbox() - context(tonode(list)) - context(tonode(new_kern(row[2]))) - context_endvbox() - context_nointerlineskip() -- figure out a better way + ctx_beginvbox() + ctxnode(tonode(list)) + ctxnode(tonode(new_kern(row[2]))) + ctx_endvbox() + ctx_nointerlineskip() -- figure out a better way if row[4] then -- nothing as we have a span elseif row[5] then if row[3] then - context_blank { v_samepage, row[3] .. "sp" } + ctx_blank { v_samepage, row[3] .. "sp" } else - context_blank { v_samepage } + ctx_blank { v_samepage } end elseif row[3] then - context_blank { row[3] .. "sp" } -- why blank ? + ctx_blank { row[3] .. "sp" } -- why blank ? else - context(tonode(new_glue(0))) + ctxnode(tonode(new_glue(0))) end else - context(tonode(list)) - context(tonode(new_kern(row[2]))) + ctxnode(tonode(list)) + ctxnode(tonode(new_kern(row[2]))) if row[3] then - context(tonode(new_glue(row[3]))) + ctxnode(tonode(new_glue(row[3]))) end end end @@ -1000,7 +1000,7 @@ function xtables.flush(directives) -- todo split by size / no inbetween then .. local repeatheader = settings.header == v_repeat local repeatfooter = settings.footer == v_repeat if height and height > 0 then - context_beginvbox() + ctx_beginvbox() local bodystart = data.bodystart or 1 local bodystop = data.bodystop or #body if bodystart > 0 and bodystart <= bodystop then @@ -1016,7 +1016,7 @@ function xtables.flush(directives) -- todo split by size / no inbetween then .. inject(head[i],repeatheader) end if rowdistance > 0 then - context(tonode(new_glue(rowdistance))) + ctxnode(tonode(new_glue(rowdistance))) end if not repeatheader then results[head_mode] = { } @@ -1029,7 +1029,7 @@ function xtables.flush(directives) -- todo split by size / no inbetween then .. inject(more[i],true) end if rowdistance > 0 then - context(tonode(new_glue(rowdistance))) + ctxnode(tonode(new_glue(rowdistance))) end end elseif headsize > 0 and repeatheader then -- following chunk gets head @@ -1039,7 +1039,7 @@ function xtables.flush(directives) -- todo split by size / no inbetween then .. inject(head[i],true) end if rowdistance > 0 then - context(tonode(new_glue(rowdistance))) + ctxnode(tonode(new_glue(rowdistance))) end end else -- following chunk gets nothing @@ -1066,7 +1066,7 @@ function xtables.flush(directives) -- todo split by size / no inbetween then .. -- all is flushed and footer fits if footsize > 0 then if rowdistance > 0 then - context(tonode(new_glue(rowdistance))) + ctxnode(tonode(new_glue(rowdistance))) end for i=1,#foot do inject(foot[i]) @@ -1080,7 +1080,7 @@ function xtables.flush(directives) -- todo split by size / no inbetween then .. -- todo: try to flush a few more lines if repeatfooter and footsize > 0 then if rowdistance > 0 then - context(tonode(new_glue(rowdistance))) + ctxnode(tonode(new_glue(rowdistance))) end for i=1,#foot do inject(foot[i],true) @@ -1106,7 +1106,7 @@ function xtables.flush(directives) -- todo split by size / no inbetween then .. end data.bodystart = bodystart data.bodystop = bodystop - context_endvbox() + ctx_endvbox() else if method == variables.split then -- maybe also a non float mode with header/footer repeat although @@ -1115,35 +1115,35 @@ function xtables.flush(directives) -- todo split by size / no inbetween then .. inject(head[i],false,true) end if #head > 0 and rowdistance > 0 then - context_blank { rowdistance .. "sp" } + ctx_blank { rowdistance .. "sp" } end for i=1,#body do inject(body[i],false,true) end if #foot > 0 and rowdistance > 0 then - context_blank { rowdistance .. "sp" } + ctx_blank { rowdistance .. "sp" } end for i=1,#foot do inject(foot[i],false,true) end else -- normal - context_beginvbox() + ctx_beginvbox() for i=1,#head do inject(head[i]) end if #head > 0 and rowdistance > 0 then - context(tonode(new_glue(rowdistance))) + ctxnode(tonode(new_glue(rowdistance))) end for i=1,#body do inject(body[i]) end if #foot > 0 and rowdistance > 0 then - context(tonode(new_glue(rowdistance))) + ctxnode(tonode(new_glue(rowdistance))) end for i=1,#foot do inject(foot[i]) end - context_endvbox() + ctx_endvbox() end results[head_mode] = { } results[body_mode] = { } @@ -1166,10 +1166,8 @@ function xtables.cleanup() -- local cell = row[i] -- local list = cell.list -- if list then - -- cell.width = getfield(list,"width") - -- cell.height = getfield(list,"height") - -- cell.depth = getfield(list,"depth") - -- cell.list = true + -- cell.width, cell.height, cell.depth = getwhd(list) + -- cell.list = true -- end -- end -- end @@ -1188,11 +1186,19 @@ function xtables.next_row(specification) end function xtables.finish_row() - local n = data.nofcolumns - data.currentcolumn + local c = data.currentcolumn + local r = data.currentrow + local d = data.rows[r][c] + local n = data.nofcolumns - c + if d then + local nx = d.nx + if nx > 0 then + n = n - nx + 1 + end + end if n > 0 then - -- message for i=1,n do - context_dummyxcell() + ctx_dummyxcell() end end end @@ -1253,19 +1259,20 @@ implement { name = "x_table_c", actions = function() con do local context = context + local ctxcore = context.core - local startxtable = context.startxtable - local stopxtable = context.stopxtable + local startxtable = ctxcore.startxtable + local stopxtable = ctxcore.stopxtable local startcollecting = context.startcollecting local stopcollecting = context.stopcollecting - function context.startxtable(...) + function ctxcore.startxtable(...) startcollecting() startxtable(...) end - function context.stopxtable() + function ctxcore.stopxtable() stopxtable() stopcollecting() end diff --git a/tex/context/base/mkiv/tabl-xtb.mkvi b/tex/context/base/mkiv/tabl-xtb.mkvi index 851b6e80f..f7d682631 100644 --- a/tex/context/base/mkiv/tabl-xtb.mkvi +++ b/tex/context/base/mkiv/tabl-xtb.mkvi @@ -245,6 +245,8 @@ \d_tabl_x_textwidth\p_textwidth \fi} +\newtoks\everypreparextable + \unexpanded\def\tabl_x_prepare#settings% assumes \iffirstargument to be set {\advance\c_tabl_x_nesting\plusone \dostarttaggedchained\t!table\empty\??xtable @@ -252,6 +254,7 @@ \tabl_x_set_checked{#settings}% \fi \tabl_x_check_textwidth + \the\everypreparextable }% else whitespace mess \def\tabl_x_get_buffer @@ -807,4 +810,26 @@ {\tabl_x_stop_row \endgroup} +%D A bonus, not advertised but some like it this way: + +\unexpanded\def\tabl_x_nc + {\startxrow + \let\NC\tabl_x_nc_next + \let\NR\tabl_x_nr + \startxcell} + +\unexpanded\def\tabl_x_nc_next + {\stopxcell + \startxcell} + +\unexpanded\def\tabl_x_nr + {\stopxcell + \stopxrow + \let\NC\tabl_x_nc} + +\appendtoks + \let\NC\tabl_x_nc + \let\NR\tabl_x_nr +\to \everypreparextable + \protect \endinput diff --git a/tex/context/base/mkiv/task-ini.lua b/tex/context/base/mkiv/task-ini.lua index 696a3b4a9..d0c00f5c8 100644 --- a/tex/context/base/mkiv/task-ini.lua +++ b/tex/context/base/mkiv/task-ini.lua @@ -49,13 +49,16 @@ appendaction("processors", "words", "typesetters.firstlines.handler") appendaction("processors", "fonts", "builders.paragraphs.solutions.splitters.split") -- experimental appendaction("processors", "fonts", "nodes.handlers.characters") -- maybe todo -appendaction("processors", "fonts", "nodes.injections.handler") -- maybe todo +appendaction("processors", "fonts", "nodes.injections.handler") +appendaction("processors", "fonts", "typesetters.fontkerns.handler") appendaction("processors", "fonts", "nodes.handlers.protectglyphs", nil, "nohead") -- maybe todo appendaction("processors", "fonts", "builders.kernel.ligaturing") -- always on (could be selective: if only node mode) appendaction("processors", "fonts", "builders.kernel.kerning") -- always on (could be selective: if only node mode) appendaction("processors", "fonts", "nodes.handlers.stripping") -- disabled (might move) ------------("processors", "fonts", "typesetters.italics.handler") -- disabled (after otf/kern handling) +appendaction("processors", "fonts", "nodes.handlers.flatten") +appendaction("processors", "lists", "typesetters.rubies.check") -- disabled (maybe someplace else) appendaction("processors", "lists", "typesetters.characteralign.handler") -- disabled (we need to to this after otf appliance) appendaction("processors", "lists", "typesetters.spacings.handler") -- disabled appendaction("processors", "lists", "typesetters.kerns.handler") -- disabled @@ -63,8 +66,9 @@ appendaction("processors", "lists", "typesetters.digits.handler") appendaction("processors", "lists", "typesetters.italics.handler") -- disabled (after otf/kern handling) appendaction("processors", "lists", "languages.visualizediscretionaries") -- disabled --- appendaction("processors", "lists", "typesetters.initials.handler") -- disabled +appendaction ("processors", "after", "typesetters.marksuspects") +appendaction("shipouts", "normalizers", "typesetters.showsuspects") appendaction("shipouts", "normalizers", "typesetters.margins.finalhandler") -- disabled ------------("shipouts", "normalizers", "nodes.handlers.cleanuppage") -- disabled appendaction("shipouts", "normalizers", "builders.paragraphs.expansion.trace") -- disabled @@ -78,6 +82,7 @@ appendaction("shipouts", "normalizers", "nodes.handlers.accessibility") appendaction("shipouts", "normalizers", "nodes.handlers.backgrounds") -- disabled appendaction("shipouts", "normalizers", "nodes.handlers.alignbackgrounds") -- disabled ------------("shipouts", "normalizers", "nodes.handlers.export") -- disabled +appendaction("shipouts", "normalizers", "typesetters.rubies.attach") -- disabled appendaction("shipouts", "finishers", "nodes.visualizers.handler") -- disabled appendaction("shipouts", "finishers", "attributes.colors.handler") -- disabled @@ -105,11 +110,13 @@ appendaction("math", "normalizers", "noads.handlers.resize", nil, "no appendaction("math", "normalizers", "noads.handlers.alternates",nil, "nohead") -- always on appendaction("math", "normalizers", "noads.handlers.tags", nil, "nohead") -- disabled appendaction("math", "normalizers", "noads.handlers.italics", nil, "nohead") -- disabled +appendaction("math", "normalizers", "noads.handlers.kernpairs", nil, "nohead") -- disabled appendaction("math", "normalizers", "noads.handlers.classes", nil, "nohead") -- disabled appendaction("math", "builders", "builders.kernel.mlist_to_hlist") -- always on -------------("math", "builders", "noads.handlers.italics", nil, "nohead") -- disabled +------------("math", "builders", "noads.handlers.italics", nil, "nohead") -- disabled appendaction("math", "builders", "typesetters.directions.processmath") -- disabled (has to happen pretty late) +appendaction("math", "builders", "noads.handlers.makeup", nil, "nohead") -- disabled (has to happen last) appendaction("finalizers", "lists", "typesetters.paragraphs.normalize") -- moved here appendaction("finalizers", "lists", "typesetters.margins.localhandler") -- disabled @@ -117,8 +124,14 @@ appendaction("finalizers", "lists", "builders.paragraphs.keeptogether") ------------("finalizers", "lists", "nodes.handlers.graphicvadjust") -- todo appendaction("finalizers", "fonts", "builders.paragraphs.solutions.splitters.optimize") -- experimental appendaction("finalizers", "lists", "builders.paragraphs.tag") + +-- the next can also be in contributers normalizers (when we remove the loop in the handler) + appendaction("finalizers", "lists", "nodes.linefillers.handler") +appendaction("contributers", "normalizers", "nodes.handlers.flattenline") +appendaction("contributers", "normalizers", "nodes.handlers.textbackgrounds") + -- still experimental appendaction("mvlbuilders", "normalizers", "typesetters.margins.globalhandler") -- disabled @@ -166,7 +179,12 @@ disableaction("processors", "typesetters.italics.handler") disableaction("processors", "languages.visualizediscretionaries") disableaction("processors", "nodes.handlers.stripping") disableaction("processors", "builders.paragraphs.solutions.splitters.split") +disableaction("processors", "typesetters.rubies.check") +disableaction("processors", "typesetters.fontkerns.handler") +disableaction("processors", "nodes.handlers.flatten") +disableaction("processors", "typesetters.marksuspects") +disableaction("shipouts", "typesetters.showsuspects") disableaction("shipouts", "typesetters.margins.finalhandler") disableaction("shipouts", "builders.paragraphs.expansion.trace") disableaction("shipouts", "typesetters.alignments.handler") @@ -186,6 +204,7 @@ disableaction("shipouts", "nodes.handlers.alignbackgrounds") disableaction("shipouts", "nodes.references.handler") disableaction("shipouts", "nodes.destinations.handler") -------------("shipouts", "nodes.handlers.export") +disableaction("shipouts", "typesetters.rubies.attach") disableaction("finalizers", "typesetters.margins.localhandler") disableaction("finalizers", "builders.paragraphs.keeptogether") @@ -194,12 +213,17 @@ disableaction("finalizers", "builders.paragraphs.solutions.splitters.optimize") disableaction("finalizers", "builders.paragraphs.tag") disableaction("finalizers", "nodes.linefillers.handler") +disableaction("contributers","nodes.handlers.flattenline") +disableaction("contributers","nodes.handlers.textbackgrounds") + disableaction("math", "noads.handlers.showtree") disableaction("math", "noads.handlers.tags") disableaction("math", "noads.handlers.italics") +disableaction("math", "noads.handlers.kernpairs") disableaction("math", "noads.handlers.domains") disableaction("math", "noads.handlers.classes") disableaction("math", "noads.handlers.autofences") +disableaction("math", "noads.handlers.makeup") disableaction("math", "typesetters.directions.processmath") disableaction("mvlbuilders", "typesetters.margins.globalhandler") diff --git a/tex/context/base/mkiv/toks-ini.lua b/tex/context/base/mkiv/toks-ini.lua index 132605d38..0ce7b4836 100644 --- a/tex/context/base/mkiv/toks-ini.lua +++ b/tex/context/base/mkiv/toks-ini.lua @@ -68,7 +68,23 @@ local scan_csname = token.scan_csname local get_next = token.get_next +if not token.get_macro then + local scantoks = tex.scantoks + local gettoks = tex.gettoks + function token.get_meaning(name) + scantoks("t_get_macro",tex.ctxcatcodes,"\\"..name) + return gettoks("t_get_macro") + end + function token.get_macro(name) + scantoks("t_get_macro",tex.ctxcatcodes,"\\"..name) + local s = gettoks("t_get_macro") + return match(s,"^.-%->(.*)$") or s + end +end + local set_macro = token.set_macro +local get_macro = token.get_macro +local get_meaning = token.get_meaning local get_cmdname = token.get_cmdname local create_token = token.create @@ -238,14 +254,16 @@ tokens.scanners = { -- these expand } tokens.getters = { -- these don't expand - token = get_next, - count = tex.getcount, - dimen = tex.getdimen, - skip = tex.getglue, - glue = tex.getglue, - skip = tex.getmuglue, - glue = tex.getmuglue, - box = tex.getbox, + meaning = get_meaning, + macro = get_macro, + token = get_next, + count = tex.getcount, + dimen = tex.getdimen, + skip = tex.getglue, + glue = tex.getglue, + skip = tex.getmuglue, + glue = tex.getmuglue, + box = tex.getbox, } tokens.setters = { diff --git a/tex/context/base/mkiv/toks-ini.mkiv b/tex/context/base/mkiv/toks-ini.mkiv index 03ec99742..aaa735207 100644 --- a/tex/context/base/mkiv/toks-ini.mkiv +++ b/tex/context/base/mkiv/toks-ini.mkiv @@ -13,13 +13,13 @@ \writestatus{loading}{ConTeXt Token Support / Initialization} +\unprotect + +\newtoks\t_get_macro % will go away + \registerctxluafile{toks-ini}{1.001} \registerctxluafile{toks-scn}{1.001} \registerctxluafile{cldf-scn}{1.001} \registerctxluafile{cldf-stp}{1.001} -\unprotect - -% nothing yet - \protect \endinput diff --git a/tex/context/base/mkiv/toks-scn.lua b/tex/context/base/mkiv/toks-scn.lua index 5c8dee8f3..3c41eedd8 100644 --- a/tex/context/base/mkiv/toks-scn.lua +++ b/tex/context/base/mkiv/toks-scn.lua @@ -153,8 +153,25 @@ tokens.converters = { toglue = "todimen", } +-- We could just pickup a keyword but then we really need to make sure +-- that no number follows it when that is the assignment and adding +-- an optional = defeats the gain in speed. Currently we have sources +-- with no spaces (\startcontextdefinitioncode ...) so it fails there. +-- +-- Another drawback is that we then need to use { } instead of ending +-- with \relax (as we can do now) but that is no big deal. It's just +-- that I then need to check the TeX end. More pain than gain and a bit +-- risky too. + local f_if = formatters[ " if scankeyword('%s') then data['%s'] = scan%s()"] local f_elseif = formatters[" elseif scankeyword('%s') then data['%s'] = scan%s()"] + +----- f_if = formatters[" local key = scanword() if key == '' then break elseif key == '%s' then data['%s'] = scan%s()"] +----- f_elseif = formatters[" elseif key == '%s' then data['%s'] = scan%s()"] + +----- f_if_x = formatters[ " if not data['%s'] and scankeyword('%s') then data['%s'] = scan%s()"] +----- f_elseif_x = formatters[" elseif not data['%s'] and scankeyword('%s') then data['%s'] = scan%s()"] + local f_local = formatters["local scan%s = scanners.%s"] local f_scan = formatters["scan%s()"] local f_shortcut = formatters["local %s = scanners.converters.%s"] @@ -163,6 +180,11 @@ local f_if_c = formatters[ " if scankeyword('%s') then data['%s'] = %s(s local f_elseif_c = formatters[" elseif scankeyword('%s') then data['%s'] = %s(scan%s())"] local f_scan_c = formatters["%s(scan%s())"] +-- see above +-- +----- f_if_c = formatters[" local key = scanword() if key == '' then break elseif key == '%s' then data['%s'] = %s(scan%s())"] +----- f_elseif_c = formatters[" elseif k == '%s' then data['%s'] = %s(scan%s())"] + local f_any = formatters[" else local key = scanword() if key then data[key] = scan%s() else break end end"] local f_any_c = formatters[" else local key = scanword() if key then data[key] = %s(scan%s()) else break end end"] local s_done = " else break end" @@ -269,6 +291,7 @@ function tokens.compile(specification) else m = m + 1 r[m] = (m > 1 and f_elseif or f_if )(t1,t1,t2) + -- r[m] = (m > 1 and f_elseif_x or f_if_x)(t1,t1,t1,t2) end end end @@ -291,8 +314,9 @@ function tokens.compile(specification) end tokens._action = a for i=1,#a do - code = f_action_f(i,code) - f[#f+1] = f_action_s(i,i) + code = f_action_f(i,code) + n = n + 1 + f[n] = f_action_s(i,i) end code = f_simple(f,code) else @@ -308,8 +332,9 @@ function tokens.compile(specification) if a then tokens._action = a for i=1,#a do - code = f_action_f(i,code) - f[#f+1] = f_action_s(i,i) + code = f_action_f(i,code) + n = n + 1 + f[n] = f_action_s(i,i) end end code = f_table(f,ti,code) @@ -317,8 +342,9 @@ function tokens.compile(specification) code = f_scan(ti) tokens._action = a for i=1,#a do - code = f_action_f(i,code) - f[#f+1] = f_action_s(i,i) + code = f_action_f(i,code) + n = n + 1 + f[n] = f_action_s(i,i) end code = f_simple(f,code) else @@ -364,8 +390,9 @@ function tokens.compile(specification) if a then tokens._action = a for i=1,#a do - code = f_action_f(i,code) - f[#f+1] = f_action_s(i,i) + code = f_action_f(i,code) + n = n + 1 + f[n] = f_action_s(i,i) end end code = f_sequence(c,f,p,code) diff --git a/tex/context/base/mkiv/toks-tra.lua b/tex/context/base/mkiv/toks-tra.lua index a1408b0b8..3a5bc1306 100644 --- a/tex/context/base/mkiv/toks-tra.lua +++ b/tex/context/base/mkiv/toks-tra.lua @@ -5,6 +5,7 @@ if not modules then modules = { } end modules ['toks-ini'] = { license = "see context related readme files" } +-- this will become a module local utfbyte, utfchar, utfvalues = utf.byte, utf.char, utf.values local format, gsub = string.format, string.gsub diff --git a/tex/context/base/mkiv/toks-tra.mkiv b/tex/context/base/mkiv/toks-tra.mkiv index a3e27eaf8..6186402a7 100644 --- a/tex/context/base/mkiv/toks-tra.mkiv +++ b/tex/context/base/mkiv/toks-tra.mkiv @@ -22,10 +22,13 @@ \unexpanded\def\starttokens [#1]{\ctxcommand{collecttokens("#1","stoptokens")}} \let\stoptokens \relax - \def\flushtokens [#1]{\ctxcommand{flushtokens("#1")}} - \def\showtokens [#1]{\ctxcommand{showtokens("#1")}} - \def\testtokens [#1]{\ctxcommand{testtokens("#1")}} - \def\registertoken #1{\ctxcommand{registertoken("#1")}} +\unexpanded\def\flushtokens [#1]{\ctxcommand{flushtokens("#1")}} +\unexpanded\def\showtokens [#1]{\ctxcommand{showtokens("#1")}} +\unexpanded\def\testtokens [#1]{\ctxcommand{testtokens("#1")}} +\unexpanded\def\registertoken #1{\ctxcommand{registertoken("#1")}} +\let\toks_show\showtokens % we also support the primitive + +\unexpanded\def\showtokens{\doifelsenextoptional\toks_show\normalshowtokens} \protect \endinput diff --git a/tex/context/base/mkiv/trac-deb.lua b/tex/context/base/mkiv/trac-deb.lua index 792ad9b56..03df86825 100644 --- a/tex/context/base/mkiv/trac-deb.lua +++ b/tex/context/base/mkiv/trac-deb.lua @@ -185,6 +185,7 @@ local function processerror(offset) local lasttexerror = status.lasterrorstring or "?" local lastluaerror = status.lastluaerrorstring or lasttexerror local luaerrorline = match(lastluaerror,[[lua%]?:.-(%d+)]]) or (lastluaerror and find(lastluaerror,"?:0:",1,true) and 0) + local lastmpserror = match(lasttexerror,[[^.-mp%serror:%s*(.*)$]]) resetmessages() lastluaerror = gsub(lastluaerror,"%[\\directlua%]","[ctxlua]") tracers.printerror { @@ -192,6 +193,7 @@ local function processerror(offset) linenumber = linenumber, offset = tonumber(offset) or 10, lasttexerror = lasttexerror, + lastmpserror = lastmpserror, lastluaerror = lastluaerror, luaerrorline = luaerrorline, lastcontext = lastcontext, @@ -204,9 +206,11 @@ function tracers.printerror(specification) local filename = specification.filename local linenumber = specification.linenumber local lasttexerror = specification.lasttexerror + local lastmpserror = specification.lastmpserror local lastluaerror = specification.lastluaerror local lastcontext = specification.lasterrorcontext local luaerrorline = specification.luaerrorline + local errortype = specification.errortype local offset = specification.offset local report = errorreporter(luaerrorline) if not filename then @@ -217,7 +221,8 @@ function tracers.printerror(specification) report_nl() if luaerrorline then report("lua error on line %s in file %s:\n\n%s",linenumber,filename,lastluaerror) - -- report("error on line %s in file %s:\n\n%s",linenumber,filename,lasttexerror) + elseif lastmpserror then + report("mp error on line %s in file %s:\n\n%s",linenumber,filename,lastmpserror) else report("tex error on line %s in file %s: %s",linenumber,filename,lasttexerror) if lastcontext then @@ -321,18 +326,37 @@ end directives.register("system.showerror", lmx.overloaderror) -local debugger = utilities.debugger - -local function trace_calls(n) - debugger.enable() - luatex.registerstopactions(function() - debugger.disable() - debugger.savestats(tex.jobname .. "-luacalls.log",tonumber(n)) - end) - trace_calls = function() end -end +-- local debugger = utilities.debugger +-- +-- local function trace_calls(n) +-- debugger.enable() +-- luatex.registerstopactions(function() +-- debugger.disable() +-- debugger.savestats(tex.jobname .. "-luacalls.log",tonumber(n)) +-- end) +-- trace_calls = function() end +-- end +-- +-- directives.register("system.tracecalls", function(n) +-- trace_calls(n) +-- end) -- indirect is needed for nilling + +local editor = [[scite "-open:%filename%" -goto:%linenumber%]] + +directives.register("system.editor",function(v) + editor = v +end) -directives.register("system.tracecalls", function(n) trace_calls(n) end) -- indirect is needed for nilling +callback.register("call_edit",function(filename,linenumber) + if editor then + editor = gsub(editor,"%%s",filename) + editor = gsub(editor,"%%d",linenumber) + editor = gsub(editor,"%%filename%%",filename) + editor = gsub(editor,"%%linenumber%%",linenumber) + logs.report("system","starting editor: %s",editor) + os.execute(editor) + end +end) implement { name = "showtrackers", actions = trackers.show } implement { name = "enabletrackers", actions = trackers.enable, arguments = "string" } @@ -350,3 +374,17 @@ implement { name = "disableexperiments", actions = experiments.disable, argument implement { name = "showdebuginfo", actions = lmx.showdebuginfo } implement { name = "overloaderror", actions = lmx.overloaderror } implement { name = "showlogcategories", actions = logs.show } + +local debugger = utilities.debugger + +directives.register("system.profile",function(n) + luatex.registerstopactions(function() + debugger.disable() + debugger.savestats("luatex-profile.log",tonumber(n) or 0) + report_nl() + logs.report("system","profiler stopped, log saved in %a","luatex-profile.log") + report_nl() + end) + logs.report("system","profiler started") + debugger.enable() +end) diff --git a/tex/context/base/mkiv/trac-inf.lua b/tex/context/base/mkiv/trac-inf.lua index 401fd01e7..f66485015 100644 --- a/tex/context/base/mkiv/trac-inf.lua +++ b/tex/context/base/mkiv/trac-inf.lua @@ -42,11 +42,51 @@ local function resettiming(instance) timers[instance or "notimer"] = { timing = 0, loadtime = 0 } end +local ticks = clock +local seconds = function(n) return n or 0 end + +-- if FFISUPPORTED and ffi and os.type == "windows" then +-- +-- local okay, kernel = pcall(ffi.load,"kernel32") +-- +-- if kernel then +-- +-- local tonumber = ffi.number or tonumber +-- +-- ffi.cdef[[ +-- int QueryPerformanceFrequency(int64_t *lpFrequency); +-- int QueryPerformanceCounter(int64_t *lpPerformanceCount); +-- ]] +-- +-- local target = ffi.new("__int64[1]") +-- +-- ticks = function() +-- if kernel.QueryPerformanceCounter(target) == 1 then +-- return tonumber(target[0]) +-- else +-- return 0 +-- end +-- end +-- +-- local target = ffi.new("__int64[1]") +-- +-- seconds = function(ticks) +-- if kernel.QueryPerformanceFrequency(target) == 1 then +-- return ticks / tonumber(target[0]) +-- else +-- return 0 +-- end +-- end +-- +-- end +-- +-- end + local function starttiming(instance) local timer = timers[instance or "notimer"] local it = timer.timing or 0 if it == 0 then - timer.starttime = clock() + timer.starttime = ticks() if not timer.loadtime then timer.loadtime = 0 end @@ -61,12 +101,13 @@ local function stoptiming(instance) timer.timing = it - 1 else local starttime = timer.starttime - if starttime then - local stoptime = clock() - local loadtime = stoptime - starttime - timer.stoptime = stoptime - timer.loadtime = timer.loadtime + loadtime - timer.timing = 0 + if starttime and starttime > 0 then + local stoptime = ticks() + local loadtime = stoptime - starttime + timer.stoptime = stoptime + timer.loadtime = timer.loadtime + loadtime + timer.timing = 0 + timer.starttime = 0 return loadtime end end @@ -78,7 +119,7 @@ local function elapsed(instance) return instance or 0 else local timer = timers[instance or "notimer"] - return timer and timer.loadtime or 0 + return timer and seconds(timer.loadtime) or 0 end end @@ -136,10 +177,13 @@ function statistics.show() local total, indirect = status.callbacks or 0, status.indirect_callbacks or 0 return format("%s direct, %s indirect, %s total", total-indirect, indirect, total) end) - if jit then - local jitstatus = { jit.status() } - if jitstatus[1] then - register("luajit options", concat(jitstatus," ",2)) + if TEXENGINE == "luajittex" and JITSUPPORTED then + local jitstatus = jit.status + if jitstatus then + local jitstatus = { jitstatus() } + if jitstatus[1] then + register("luajit options", concat(jitstatus," ",2)) + end end end -- so far @@ -183,6 +227,7 @@ end function statistics.runtime() stoptiming(statistics) + -- stoptiming(statistics) -- somehow we can start the timer twice, but where return statistics.formatruntime(elapsedtime(statistics)) end diff --git a/tex/context/base/mkiv/trac-jus.lua b/tex/context/base/mkiv/trac-jus.lua index ad1a098e2..6d00bf19e 100644 --- a/tex/context/base/mkiv/trac-jus.lua +++ b/tex/context/base/mkiv/trac-jus.lua @@ -6,49 +6,51 @@ if not modules then modules = { } end modules ['trac-jus'] = { license = "see context related readme files" } -local checkers = typesetters.checkers or { } -typesetters.checkers = checkers +local checkers = typesetters.checkers or { } +typesetters.checkers = checkers ----- report_justification = logs.reporter("visualize","justification") -local a_alignstate = attributes.private("alignstate") -local a_justification = attributes.private("justification") +local a_alignstate = attributes.private("alignstate") +local a_justification = attributes.private("justification") -local nuts = nodes.nuts -local tonut = nuts.tonut +local nuts = nodes.nuts +local tonut = nuts.tonut -local getfield = nuts.getfield -local setfield = nuts.setfield -local getlist = nuts.getlist -local getattr = nuts.getattr -local setattr = nuts.setattr -local setlist = nuts.setlist +local getfield = nuts.getfield +local setfield = nuts.setfield +local getlist = nuts.getlist +local getattr = nuts.getattr +local setattr = nuts.setattr +local setlist = nuts.setlist +local setlink = nuts.setlink +local getwidth = nuts.getwidth +local findtail = nuts.tail -local traverse_id = nuts.traverse_id -local get_list_dimensions = nuts.dimensions -local linked_nodes = nuts.linked -local copy_node = nuts.copy +local traverse_id = nuts.traverse_id +local list_dimensions = nuts.dimensions +local copy_list = nuts.copy_list -local tracedrule = nodes.tracers.pool.nuts.rule +local tracedrule = nodes.tracers.pool.nuts.rule -local nodepool = nuts.pool +local nodepool = nuts.pool -local new_rule = nodepool.rule -local new_hlist = nodepool.hlist -local new_glue = nodepool.glue -local new_kern = nodepool.kern +local new_hlist = nodepool.hlist +local new_kern = nodepool.kern -local hlist_code = nodes.nodecodes.hlist +local hlist_code = nodes.nodecodes.hlist -local texsetattribute = tex.setattribute -local unsetvalue = attributes.unsetvalue +local texsetattribute = tex.setattribute +local unsetvalue = attributes.unsetvalue -local min_threshold = 0 -local max_threshold = 0 +local enableaction = nodes.tasks.enableaction + +local min_threshold = 0 +local max_threshold = 0 local function set(n) - nodes.tasks.enableaction("mvlbuilders", "typesetters.checkers.handler") - nodes.tasks.enableaction("vboxbuilders","typesetters.checkers.handler") + enableaction("mvlbuilders", "typesetters.checkers.handler") + enableaction("vboxbuilders","typesetters.checkers.handler") texsetattribute(a_justification,n or 1) function typesetters.checkers.set(n) texsetattribute(a_justification,n or 1) @@ -79,32 +81,38 @@ function checkers.handler(head) for current in traverse_id(hlist_code,tonut(head)) do if getattr(current,a_justification) == 1 then setattr(current,a_justification,0) -- kind of reset - local width = getfield(current,"width") + local width = getwidth(current) if width > 0 then local list = getlist(current) if list then - local naturalwidth, naturalheight, naturaldepth = get_list_dimensions(list) + local naturalwidth, naturalheight, naturaldepth = list_dimensions(list) local delta = naturalwidth - width if naturalwidth == 0 or delta == 0 then -- special box elseif delta >= max_threshold then - local rule = tracedrule(delta,naturalheight,naturaldepth,getfield(list,"glue_set") == 1 and "trace:dr" or "trace:db") - setlist(current,linked_nodes(list,new_hlist(rule))) + local rule = new_hlist(tracedrule(delta,naturalheight,naturaldepth,getfield(list,"glue_set") == 1 and "trace:dr" or "trace:db")) + setlink(findtail(list),rule) + setlist(current,list) elseif delta <= min_threshold then local alignstate = getattr(list,a_alignstate) if alignstate == 1 then - local rule = tracedrule(-delta,naturalheight,naturaldepth,"trace:dc") - setlist(current,linked_nodes(new_hlist(rule),list)) + local rule = new_hlist(tracedrule(-delta,naturalheight,naturaldepth,"trace:dc")) + setlink(rule,list) + setlist(current,rule) elseif alignstate == 2 then - local lrule = tracedrule(-delta/2,naturalheight,naturaldepth,"trace:dy") - local rrule = copy_node(lrule) - setlist(current,linked_nodes(new_hlist(lrule),list,new_kern(delta/2),new_hlist(rrule))) + local lrule = new_hlist(tracedrule(-delta/2,naturalheight,naturaldepth,"trace:dy")) + local rrule = copy_list(lrule) + setlink(lrule,list) + setlink(findtail(list),new_kern(delta/2),rrule) + setlist(current,lrule) elseif alignstate == 3 then - local rule = tracedrule(-delta,naturalheight,naturaldepth,"trace:dm") - setlist(current,linked_nodes(list,new_kern(delta),new_hlist(rule))) + local rule = new_hlist(tracedrule(-delta,naturalheight,naturaldepth,"trace:dm")) + setlink(findtail(list),new_kern(delta),rule) + setlist(current,list) else - local rule = tracedrule(-delta,naturalheight,naturaldepth,"trace:dg") - setlist(current,linked_nodes(list,new_kern(delta),new_hlist(rule))) + local rule = new_hlist(tracedrule(-delta,naturalheight,naturaldepth,"trace:dg")) + setlink(findtail(list),new_kern(delta),rule) + setlist(current,list) end end end diff --git a/tex/context/base/mkiv/trac-log.lua b/tex/context/base/mkiv/trac-log.lua index 86557ef09..b6bb123cf 100644 --- a/tex/context/base/mkiv/trac-log.lua +++ b/tex/context/base/mkiv/trac-log.lua @@ -114,6 +114,16 @@ if tex and (tex.jobname or tex.formatname) then texio.setescape(0) -- or (false) end + if arg then + -- we're don't have environment.arguments yet + for k, v in next, arg do -- k can be negative ! + if v == "--ansi" or v == "--c:ansi" then + variant = "ansi" + break + end + end + end + local function useluawrites() -- quick hack, awaiting speedup in engine (8 -> 6.4 sec for --make with console2) @@ -793,7 +803,7 @@ end -- we don't have show_open and show_close callbacks yet -local report_files = logs.reporter("files") +----- report_files = logs.reporter("files") local nesting = 0 local verbose = false local hasscheme = url.hasscheme diff --git a/tex/context/base/mkiv/trac-par.lua b/tex/context/base/mkiv/trac-par.lua index fc3be5b6c..56291f8c8 100644 --- a/tex/context/base/mkiv/trac-par.lua +++ b/tex/context/base/mkiv/trac-par.lua @@ -21,16 +21,18 @@ local getnext = nuts.getnext local getlist = nuts.getlist local getfont = nuts.getfont local getchar = nuts.getchar +local getwidth = nuts.getwidth local nodecodes = nodes.nodecodes local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist local glyph_code = nodecodes.glyph -local kern_code = nodecodes.kern local setnodecolor = nodes.tracers.colors.set local parameters = fonts.hashes.parameters local basepoints = number.basepoints +local setaction = nodes.tasks.setaction + -- definecolor[hz:positive] [r=0.6] -- definecolor[hz:negative] [g=0.6] -- definecolor[hz:zero] [b=0.6] @@ -99,7 +101,7 @@ local function colorize(n) if trace_verbose then length = length + 1 list[length] = utfchar(getchar(n)) - width = width + getfield(n,"width") -- no kerning yet + width = width + getwidth(n) -- no kerning yet end end end @@ -127,17 +129,8 @@ function builders.paragraphs.expansion.trace(head) return head end -local tasks = nodes.tasks - --- tasks.prependaction("shipouts","normalizers","builders.paragraphs.expansion.trace") --- tasks.disableaction("shipouts","builders.paragraphs.expansion.trace") - local function set(v) - if v then - tasks.enableaction("shipouts","builders.paragraphs.expansion.trace") - else - tasks.disableaction("shipouts","builders.paragraphs.expansion.trace") - end + setaction("shipouts","builders.paragraphs.expansion.trace",v) end trackers.register("builders.paragraphs.expansion.verbose",set) diff --git a/tex/context/base/mkiv/trac-set.lua b/tex/context/base/mkiv/trac-set.lua index 9e2bf8758..d0047650f 100644 --- a/tex/context/base/mkiv/trac-set.lua +++ b/tex/context/base/mkiv/trac-set.lua @@ -213,7 +213,6 @@ function setters.list(t) -- pattern end function setters.show(t) - local category = t.name local list = setters.list(t) t.report() for k=1,#list do diff --git a/tex/context/base/mkiv/trac-tex.lua b/tex/context/base/mkiv/trac-tex.lua index 86f3b539f..66cdc2c91 100644 --- a/tex/context/base/mkiv/trac-tex.lua +++ b/tex/context/base/mkiv/trac-tex.lua @@ -6,29 +6,36 @@ if not modules then modules = { } end modules ['trac-tex'] = { license = "see context related readme files" } --- moved from trac-deb.lua - -local next = next - local texhashtokens = tex.hashtokens -local trackers = trackers -local token = token -local saved = { } +local trackers = trackers +local token = token +local saved = { } +local create = token.create +local undefined = create("undefined").command function trackers.savehash() saved = texhashtokens() + if type(saved[1]) == "table" then + -- LUATEXVERSION < 1.002 + saved = table.tohash(saved) + end + return saved end function trackers.dumphashtofile(filename,delta) local list = { } - local hash = tex.hashtokens() + local hash = texhashtokens() local create = token.create - for name, token in next, hash do + if type(hash[1]) == "table" then + -- LUATEXVERSION < 1.002 + hash = table.sortedkeys(hash) + end + for i=1,#hash do + local name = hash[i] if not delta or not saved[name] then - if token[2] ~= 0 then -- still old interface - local token = create(name) - -- inspect(token) + local token = create(name) + if token.command ~= undefined then local category = token.cmdname local dk = list[category] if not dk then @@ -59,34 +66,11 @@ function trackers.dumphashtofile(filename,delta) table.save(filename or tex.jobname .. "-hash.log",list) end --- -- old token code --- --- function trackers.dumphashtofile(filename,delta) --- local list = { } --- local hash = texhashtokens() --- local getname = token.command_name --- for name, token in next, hash do --- if not delta or not saved[name] then --- -- token: cmd, chr, csid -- combination cmd,chr determines name --- local category = getname(token) --- local dk = list[category] --- if not dk then --- -- a bit funny names but this sorts better (easier to study) --- dk = { names = { }, found = 0, code = token[1] } --- list[category] = dk --- end --- dk.names[name] = { token[2], token[3] } --- dk.found = dk.found + 1 --- end --- end --- table.save(filename or tex.jobname .. "-hash.log",list) --- end - local delta = nil local function dump_hash(wanteddelta) if delta == nil then - saved = saved or texhashtokens() -- no need for trackers.dump_hash + saved = saved or trackers.savehash() luatex.registerstopactions(1,function() dump_hash(nil,wanteddelta) end) -- at front end delta = wanteddelta @@ -95,8 +79,6 @@ end directives.register("system.dumphash", function() dump_hash(false) end) directives.register("system.dumpdelta", function() dump_hash(true ) end) -local report_dump = logs.reporter("resolvers","dump") - local function saveusedfilesintrees(format) local data = { jobname = environment.jobname or "?", diff --git a/tex/context/base/mkiv/trac-vis.lua b/tex/context/base/mkiv/trac-vis.lua index 061cef8ba..5d98bc24f 100644 --- a/tex/context/base/mkiv/trac-vis.lua +++ b/tex/context/base/mkiv/trac-vis.lua @@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['trac-vis'] = { local string, number, table = string, number, table local node, nodes, attributes, fonts, tex = node, nodes, attributes, fonts, tex local type = type -local format = string.format +local gmatch = string.gmatch local formatters = string.formatters -- This module started out in the early days of mkiv and luatex with @@ -76,6 +76,8 @@ local setlist = nuts.setlist local setleader = nuts.setleader local setsubtype = nuts.setsubtype local setattr = nuts.setattr +local setwidth = nuts.setwidth +local setshift = nuts.setshift local getfield = nuts.getfield local getid = nuts.getid @@ -90,18 +92,22 @@ local getnext = nuts.getnext local getprev = nuts.getprev local getboth = nuts.getboth local getdisc = nuts.getdisc +local getwhd = nuts.getwhd +local getkern = nuts.getkern +local getpenalty = nuts.getpenalty +local getdir = nuts.getdir +local getwidth = nuts.getwidth +local getshift = nuts.getshift local hpack_nodes = nuts.hpack local vpack_nodes = nuts.vpack -local copy_node = nuts.copy local copy_list = nuts.copy_list -local free_node = nuts.free -local free_node_list = nuts.flush_list +local flush_node_list = nuts.flush_list local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after local traverse_nodes = nuts.traverse -local linked_nodes = nuts.linked - +local apply_to_nodes = nuts.apply +local find_tail = nuts.tail local effectiveglue = nuts.effective_glue local hpack_string = nuts.typesetters.tohpack @@ -123,7 +129,6 @@ local nodepool = nuts.pool local new_rule = nodepool.rule local new_kern = nodepool.kern local new_glue = nodepool.glue -local new_penalty = nodepool.penalty local new_hlist = nodepool.hlist local new_vlist = nodepool.vlist @@ -147,6 +152,8 @@ local bit = number.bit local setbit = number.setbit local clearbit = number.clearbit +local enableaction = nodes.tasks.enableaction + local trace_hbox local trace_vbox local trace_vtop @@ -159,32 +166,35 @@ local trace_whatsit local trace_user local trace_math local trace_italic +local trace_discretionary local report_visualize = logs.reporter("visualize") local modes = { - hbox = 1, - vbox = 2, - vtop = 4, - kern = 8, - glue = 16, - penalty = 32, - fontkern = 64, - strut = 128, - whatsit = 256, - glyph = 512, - simple = 1024, - simplehbox = 1024 + 1, - simplevbox = 1024 + 2, - simplevtop = 1024 + 4, - user = 2048, - math = 4096, - italic = 8192, - origin = 16384, + hbox = 1, + vbox = 2, + vtop = 4, + kern = 8, + glue = 16, + -- skip = 16, + penalty = 32, + fontkern = 64, + strut = 128, + whatsit = 256, + glyph = 512, + simple = 1024, + simplehbox = 1024 + 1, + simplevbox = 1024 + 2, + simplevtop = 1024 + 4, + user = 2048, + math = 4096, + italic = 8192, + origin = 16384, + discretionary = 32768, } local usedfont, exheight, emwidth -local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_whatsit, l_glyph, l_user, l_math, l_italic, l_origin +local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_whatsit, l_glyph, l_user, l_math, l_italic, l_origin, l_discretionary local enabled = false local layers = { } @@ -219,30 +229,31 @@ local function enable() } layers[mode] = attributes.viewerlayers.register(tag,true) end - l_hbox = layers.hbox - l_vbox = layers.vbox - l_vtop = layers.vtop - l_glue = layers.glue - l_kern = layers.kern - l_penalty = layers.penalty - l_fontkern = layers.fontkern - l_strut = layers.strut - l_whatsit = layers.whatsit - l_glyph = layers.glyph - l_user = layers.user - l_math = layers.math - l_italic = layers.italic - l_origin = layers.origin - nodes.tasks.enableaction("shipouts","nodes.visualizers.handler") + l_hbox = layers.hbox + l_vbox = layers.vbox + l_vtop = layers.vtop + l_glue = layers.glue + l_kern = layers.kern + l_penalty = layers.penalty + l_fontkern = layers.fontkern + l_strut = layers.strut + l_whatsit = layers.whatsit + l_glyph = layers.glyph + l_user = layers.user + l_math = layers.math + l_italic = layers.italic + l_origin = layers.origin + l_discretionary = layers.discretionary + enableaction("shipouts","nodes.visualizers.handler") report_visualize("enabled") enabled = true tex.setcount("global","c_syst_visualizers_state",1) -- so that we can optimize at the tex end end -local function setvisual(n,a,what) -- this will become more efficient when we have the bit lib linked in +local function setvisual(n,a,what,list) -- this will become more efficient when we have the bit lib linked in if not n or n == "reset" then return unsetvalue - elseif n == "makeup" then + elseif n == true or n == "makeup" then if not a or a == 0 or a == unsetvalue then a = preset_makeup else @@ -263,22 +274,15 @@ local function setvisual(n,a,what) -- this will become more efficient when we ha a = setbit(a,preset_all) end else - local m = modes[n] - if not m then - -- go on - elseif a == unsetvalue then - if what == false then - return unsetvalue - else - -- a = setbit(0,m) + for s in gmatch(n,"[a-z]+") do + local m = modes[s] + if not m then + -- go on + elseif not a or a == 0 or a == unsetvalue then a = m + else + a = setbit(a,m) end - elseif what == false then - a = clearbit(a,m) - elseif not a or a == 0 then - a = m - else - a = setbit(a,m) end end if not a or a == 0 or a == unsetvalue then @@ -293,6 +297,20 @@ function nuts.setvisual(n,mode) setattr(n,a_visual,setvisual(mode,getattr(n,a_visual),true)) end +function nuts.setvisuals(n,mode) + setattr(n,a_visual,setvisual(mode,getattr(n,a_visual),true,true)) +end + +function nuts.applyvisuals(n,mode) + local a = unsetvalue + if mode == true then + a = texgetattribute (a_visual) + elseif mode then + a = setvisual(mode) + end + apply_to_nodes(n,function(n) setattr(n,a_visual,a) end) +end + function nuts.copyvisual(n,m) setattr(n,a_visual,getattr(m,a_visual)) end @@ -325,35 +343,37 @@ trackers .register("visualizers.makeup", function(v) set("makeup",v) end) trackers .register("visualizers.boxes", function(v) set("boxes", v) end) directives.register("visualizers.fraction", function(v) fraction = (v and tonumber(v)) or (v == "more" and 5) or 10 end) -local c_positive = "trace:b" -local c_negative = "trace:r" -local c_zero = "trace:g" -local c_text = "trace:s" -local c_space = "trace:y" -local c_skip_a = "trace:c" -local c_skip_b = "trace:m" -local c_glyph = "trace:o" -local c_ligature = "trace:s" -local c_white = "trace:w" -local c_math = "trace:r" -local c_origin = "trace:o" - -local c_positive_d = "trace:db" -local c_negative_d = "trace:dr" -local c_zero_d = "trace:dg" -local c_text_d = "trace:ds" -local c_space_d = "trace:dy" -local c_skip_a_d = "trace:dc" -local c_skip_b_d = "trace:dm" -local c_glyph_d = "trace:do" -local c_ligature_d = "trace:ds" -local c_white_d = "trace:dw" -local c_math_d = "trace:dr" -local c_origin_d = "trace:do" +local c_positive = "trace:b" +local c_negative = "trace:r" +local c_zero = "trace:g" +local c_text = "trace:s" +local c_space = "trace:y" +local c_skip_a = "trace:c" +local c_skip_b = "trace:m" +local c_glyph = "trace:o" +local c_ligature = "trace:s" +local c_white = "trace:w" +local c_math = "trace:r" +local c_origin = "trace:o" +local c_discretionary = "trace:o" + +local c_positive_d = "trace:db" +local c_negative_d = "trace:dr" +local c_zero_d = "trace:dg" +local c_text_d = "trace:ds" +local c_space_d = "trace:dy" +local c_skip_a_d = "trace:dc" +local c_skip_b_d = "trace:dm" +local c_glyph_d = "trace:do" +local c_ligature_d = "trace:ds" +local c_white_d = "trace:dw" +local c_math_d = "trace:dr" +local c_origin_d = "trace:do" +local c_discretionary_d = "trace:do" local function sometext(str,layer,color,textcolor,lap) -- we can just paste verbatim together .. no typesteting needed local text = hpack_string(str,usedfont) - local size = getfield(text,"width") + local size = getwidth(text) local rule = new_rule(size,2*exheight,exheight/2) local kern = new_kern(-size) if color then @@ -362,12 +382,14 @@ local function sometext(str,layer,color,textcolor,lap) -- we can just paste verb if textcolor then setlistcolor(getlist(text),textcolor) end - local info = linked_nodes(rule,kern,text) + local info = setlink(rule,kern,text) setlisttransparency(info,c_zero) - info = new_hlist(info) - local width = getfield(info,"width") + info = hpack_nodes(info) + local width = getwidth(info) if lap then - info = new_hlist(linked_nodes(new_kern(-width),info)) + info = new_hlist(setlink(new_kern(-width),info)) + else + info = new_hlist(info) end if layer then setattr(info,a_layer,layer) @@ -375,472 +397,537 @@ local function sometext(str,layer,color,textcolor,lap) -- we can just paste verb return info, width end -local f_cache = { } +local caches = table.setmetatableindex("table") -local function fontkern(head,current) - local kern = getfield(current,"kern") + getfield(current,"expansion_factor") - local info = f_cache[kern] - if info then - -- print("hit fontkern") - else - local text = hpack_string(formatters[" %0.3f"](kern*pt_factor),usedfont) - local rule = new_rule(emwidth/fraction,6*exheight,2*exheight) - local list = getlist(text) - if kern > 0 then - setlistcolor(list,c_positive_d) - elseif kern < 0 then - setlistcolor(list,c_negative_d) +local fontkern do + + local f_cache = caches["fontkern"] + + fontkern = function(head,current) + local width = getkern(current) + local extra = getfield(current,"expansion_factor") + local kern = width + extra + local info = f_cache[kern] + -- report_visualize("fontkern: %p ex %p",width,extra) + if info then + -- print("hit fontkern") else - setlistcolor(list,c_zero_d) + local text = hpack_string(formatters[" %0.3f"](kern*pt_factor),usedfont) + local rule = new_rule(emwidth/fraction,6*exheight,2*exheight) + local list = getlist(text) + if kern > 0 then + setlistcolor(list,c_positive_d) + elseif kern < 0 then + setlistcolor(list,c_negative_d) + else + setlistcolor(list,c_zero_d) + end + setlisttransparency(list,c_text_d) + setcolor(rule,c_text_d) + settransparency(rule,c_text_d) + setshift(text,-5 * exheight) + info = new_hlist(setlink(rule,text)) + setattr(info,a_layer,l_fontkern) + f_cache[kern] = info end - setlisttransparency(list,c_text_d) - settransparency(rule,c_text_d) - setfield(text,"shift",-5 * exheight) - info = new_hlist(linked_nodes(rule,text)) - setattr(info,a_layer,l_fontkern) - f_cache[kern] = info + head = insert_node_before(head,current,copy_list(info)) + return head, current end - head = insert_node_before(head,current,copy_list(info)) - return head, current -end -local w_cache = { } -local tags = { - open = "FIC", - write = "FIW", - close = "FIC", - special = "SPE", - latelua = "LUA", - savepos = "POS", - userdefined = "USR", - -- backend stuff - pdfliteral = "PDF", - pdfrefobj = "PDF", - pdfannot = "PDF", - pdfstartlink = "PDF", - pdfendlink = "PDF", - pdfdest = "PDF", - pdfthread = "PDF", - pdfstartthread = "PDF", - pdfendthread = "PDF", - pdfthreaddata = "PDF", - pdflinkdata = "PDF", - pdfcolorstack = "PDF", - pdfsetmatrix = "PDF", - pdfsave = "PDF", - pdfrestore = "PDF", -} - -local function whatsit(head,current) - local what = getsubtype(current) - local info = w_cache[what] - if info then - -- print("hit whatsit") - else - local tag = whatsitcodes[what] - -- maybe different text colors per tag - info = sometext(formatters["W:%s"](tag and tags[tag] or what),usedfont,nil,c_white) - setattr(info,a_layer,l_whatsit) - w_cache[what] = info - end - head, current = insert_node_after(head,current,copy_list(info)) - return head, current end -local u_cache = { } +local whatsit do + + local w_cache = caches["whatsit"] + + local tags = { + open = "FIC", + write = "FIW", + close = "FIC", + special = "SPE", + latelua = "LUA", + savepos = "POS", + userdefined = "USR", + -- backend stuff + pdfliteral = "PDF", + pdfrefobj = "PDF", + pdfannot = "PDF", + pdfstartlink = "PDF", + pdfendlink = "PDF", + pdfdest = "PDF", + pdfthread = "PDF", + pdfstartthread = "PDF", + pdfendthread = "PDF", + pdfthreaddata = "PDF", + pdflinkdata = "PDF", + pdfcolorstack = "PDF", + pdfsetmatrix = "PDF", + pdfsave = "PDF", + pdfrestore = "PDF", + } -local function user(head,current) - local what = getsubtype(current) - local info = u_cache[what] - if info then - -- print("hit user") - else - info = sometext(formatters["U:%s"](what),usedfont) - setattr(info,a_layer,l_user) - u_cache[what] = info + whatsit = function(head,current) + local what = getsubtype(current) + local info = w_cache[what] + if info then + -- print("hit whatsit") + else + local tag = whatsitcodes[what] + -- maybe different text colors per tag + info = sometext(formatters["W:%s"](tag and tags[tag] or what),usedfont,nil,c_white) + setattr(info,a_layer,l_whatsit) + w_cache[what] = info + end + head, current = insert_node_after(head,current,copy_list(info)) + return head, current end - head, current = insert_node_after(head,current,copy_list(info)) - return head, current + end -local m_cache = { } -local tags = { - beginmath = "B", - endmath = "E", -} +local user do -local function math(head,current) - local what = getsubtype(current) - local info = m_cache[what] - if info then - -- print("hit math") - else - local tag = mathcodes[what] - info = sometext(formatters["M:%s"](tag and tags[tag] or what),usedfont,nil,c_math_d) - setattr(info,a_layer,l_math) - m_cache[what] = info + local u_cache = caches["user"] + + user = function(head,current) + local what = getsubtype(current) + local info = u_cache[what] + if info then + -- print("hit user") + else + info = sometext(formatters["U:%s"](what),usedfont) + setattr(info,a_layer,l_user) + u_cache[what] = info + end + head, current = insert_node_after(head,current,copy_list(info)) + return head, current end - head, current = insert_node_after(head,current,copy_list(info)) - return head, current + end -local b_cache = { } +local math do -local o_cache = table.setmetatableindex(function(t,size) - local rule = new_rule(2*size,size,size) - origin = hpack_nodes(rule) - setcolor(rule,c_origin_d) - settransparency(rule,c_origin_d) - setattr(rule,a_layer,l_origin) - t[size] = origin - return origin -end) + local m_cache = { + beginmath = caches["bmath"], + endmath = caches["emath"], + } -local function ruledbox(head,current,vertical,layer,what,simple,previous,trace_origin,parent) - local wd = getfield(current,"width") - if wd ~= 0 then - local ht = getfield(current,"height") - local dp = getfield(current,"depth") - local shift = getfield(current,"shift") - local next = getnext(current) - local prev = previous - -- local prev = getprev(current) -- prev can be wrong in math mode < 0.78.3 - setboth(current) - local linewidth = emwidth/fraction - local size = 2*linewidth - local baseline, baseskip - if dp ~= 0 and ht ~= 0 then - if wd > 20*linewidth then - baseline = b_cache.baseline - if not baseline then - -- due to an optimized leader color/transparency we need to set the glue node in order - -- to trigger this mechanism - local leader = linked_nodes(new_glue(size),new_rule(3*size,linewidth,0),new_glue(size)) - leader = hpack_nodes(leader) - baseline = new_glue(0) - setleader(baseline,leader) - setsubtype(baseline,cleaders_code) - setfield(baseline,"stretch",65536) - setfield(baseline,"stretch_order",2) - setlisttransparency(baseline,c_text) - b_cache.baseline = baseline - end - baseline = copy_list(baseline) - baseline = hpack_nodes(baseline,wd-size) - -- or new_hlist, set head and also: - -- baseline.width = wd - -- baseline.glue_set = wd/65536 - -- baseline.glue_order = 2 - -- baseline.glue_sign = 1 - baseskip = new_kern(-wd+linewidth) + local tags = { + beginmath = "B", + endmath = "E", + } + + math = function(head,current) + local what = getsubtype(current) + local tag = mathcodes[what] + local skip = getkern(current) + getwidth(current) -- surround + local info = m_cache[tag][skip] + if info then + -- print("hit math") + else + local text, width = sometext(formatters["M:%s"](tag and tags[tag] or what),usedfont,nil,c_math_d) + local rule = new_rule(skip,-655360/fraction,2*655360/fraction) + setcolor(rule,c_math_d) + settransparency(rule,c_math_d) + setattr(rule,a_layer,l_math) + if tag == "beginmath" then + info = new_hlist(setlink(new_glue(-skip),rule,new_glue(-width),text)) else - baseline = new_rule(wd-size,linewidth,0) - baseskip = new_kern(-wd+size) + info = new_hlist(setlink(new_glue(-skip),rule,new_glue(-skip),text)) end + setattr(info,a_layer,l_math) + m_cache[tag][skip] = info end - local this - if not simple then - this = b_cache[what] - if not this then - local text = hpack_string(what,usedfont) - this = linked_nodes(new_kern(-getfield(text,"width")),text) - setlisttransparency(this,c_text) - this = new_hlist(this) - b_cache[what] = this + head, current = insert_node_after(head,current,copy_list(info)) + return head, current + end + +end + +local ruledbox do + + local b_cache = caches["box"] + local o_cache = caches["origin"] + + table.setmetatableindex(o_cache,function(t,size) + local rule = new_rule(2*size,size,size) + local origin = hpack_nodes(rule) + setcolor(rule,c_origin_d) + settransparency(rule,c_origin_d) + setattr(rule,a_layer,l_origin) + t[size] = origin + return origin + end) + + ruledbox = function(head,current,vertical,layer,what,simple,previous,trace_origin,parent) + local wd, ht, dp = getwhd(current) + if wd ~= 0 then + local shift = getshift(current) + local dir = getdir(current) + -- if dir == "LTL" or dir == "RRT" then + -- wd, ht, dp = ht + dp, wd, 0 + -- end + local next = getnext(current) + local prev = previous + -- local prev = getprev(current) -- prev can be wrong in math mode < 0.78.3 + setboth(current) + local linewidth = emwidth/fraction + local size = 2*linewidth + local baseline, baseskip + if dp ~= 0 and ht ~= 0 then + if wd > 20*linewidth then + local targetsize = wd - size + baseline = b_cache[targetsize] + if not baseline then + -- due to an optimized leader color/transparency we need to set the glue node in order + -- to trigger this mechanism + local leader = setlink(new_glue(size),new_rule(3*size,linewidth,0),new_glue(size)) + leader = hpack_nodes(leader) + baseline = new_glue(0,65536,0,2,0) + setleader(baseline,leader) + setsubtype(baseline,cleaders_code) + setlisttransparency(baseline,c_text) + baseline = hpack_nodes(baseline,targetsize) + b_cache[targetsize] = baseline + end + baseline = copy_list(baseline) + baseskip = new_kern(-wd+linewidth) + else + baseline = new_rule(wd-size,linewidth,0) + baseskip = new_kern(-wd+size) + end end - end - -- we need to trigger the right mode (else sometimes no whatits) - local info = linked_nodes( - this and copy_list(this) or nil, - new_rule(linewidth,ht,dp), - new_rule(wd-size,-dp+linewidth,dp), - new_rule(linewidth,ht,dp), - new_kern(-wd+linewidth), - new_rule(wd-size,ht,-ht+linewidth) - ) - if baseskip then - info = linked_nodes(info,baseskip,baseline) -- could be in previous linked - end - setlisttransparency(info,c_text) - info = new_hlist(info) - -- - setattr(info,a_layer,layer) - if vertical then - if shift == 0 then - info = linked_nodes(current,info) - elseif trace_origin then - local size = 2*size - local origin = o_cache[size] - origin = copy_list(origin) - if getid(parent) == vlist_code then - setfield(origin,"shift",-shift) - info = linked_nodes(current,new_kern(-size),origin,new_kern(-size),info) + local this + if not simple then + this = b_cache[what] + if not this then + local text = hpack_string(what,usedfont) + this = setlink(new_kern(-getwidth(text)),text) + setlisttransparency(this,c_text) + this = new_hlist(this) + b_cache[what] = this + end + end + -- we need to trigger the right mode (else sometimes no whatits) + local info = setlink( + this and copy_list(this) or nil, + new_rule(linewidth,ht,dp), + new_rule(wd-size,-dp+linewidth,dp), + new_rule(linewidth,ht,dp), + new_kern(-wd+linewidth), + new_rule(wd-size,ht,-ht+linewidth), + baseskip, + baseskip and baseline or nil + ) + setlisttransparency(info,c_text) + info = new_hlist(info) + -- + setattr(info,a_layer,layer) + if vertical then + if shift == 0 then + info = setlink(current,dp ~= 0 and new_kern(-dp) or nil,info) + elseif trace_origin then + local size = 2*size + local origin = o_cache[size] + origin = copy_list(origin) + if getid(parent) == vlist_code then + setshift(origin,-shift) + info = setlink(current,new_kern(-size),origin,new_kern(-size-dp),info) + else + -- todo .. i need an example + info = setlink(current,dp ~= 0 and new_kern(-dp) or nil,info) + end + setshift(current,0) else - -- todo .. i need an example - info = linked_nodes(current,info) + info = setlink(current,new_dp ~= 0 and new_kern(-dp) or nil,info) + setshift(current,0) end - setfield(current,"shift",0) + info = new_vlist(info,wd,ht,dp,shift) else - info = linked_nodes(current,info) - setfield(current,"shift",0) + if shift == 0 then + info = setlink(current,new_kern(-wd),info) + elseif trace_origin then + local size = 2*size + local origin = o_cache[size] + origin = copy_list(origin) + if getid(parent) == vlist_code then + info = setlink(current,new_kern(-wd-size-shift),origin,new_kern(-size+shift),info) + else + setshift(origin,-shift) + info = setlink(current,new_kern(-wd-size),origin,new_kern(-size),info) + end + setshift(current,0) + else + info = setlink(current,new_kern(-wd),info) + setshift(current,0) + end + info = new_hlist(info,wd,ht,dp,shift) end - info = new_vlist(info,wd,ht,dp,shift) - else - if shift == 0 then - info = linked_nodes(current,new_kern(-wd),info) - elseif trace_origin then - local size = 2*size - local origin = o_cache[size] - origin = copy_list(origin) - if getid(parent) == vlist_code then - info = linked_nodes(current,new_kern(-wd-size-shift),origin,new_kern(-size+shift),info) + if next then + setlink(info,next) + end + if prev then + if getid(prev) == gluespec_code then + report_visualize("ignoring invalid prev") + -- weird, how can this happen, an inline glue-spec, probably math else - setfield(origin,"shift",-shift) - info = linked_nodes(current,new_kern(-wd-size),origin,new_kern(-size),info) + setlink(prev,info) end - setfield(current,"shift",0) + end + if head == current then + return info, info else - info = linked_nodes(current,new_kern(-wd),info) - setfield(current,"shift",0) + return head, info end - info = new_hlist(info,wd,ht,dp,shift) + else + return head, current end + end --- how about dir, so maybe just copy the node --- --- local l = getlist(current) --- setlist(current,nil) --- local c = copy_node(current) --- setlist(current,l) --- setlist(c,info) --- info = c - - if next then - setlink(info,next) - end - if prev then - if getid(prev) == gluespec_code then - report_visualize("ignoring invalid prev") - -- weird, how can this happen, an inline glue-spec, probably math +end + +local ruledglyph do + + ruledglyph = function(head,current,previous) -- wrong for vertical glyphs + local wd = getwidth(current) + -- local wd = chardata[getfont(current)][getchar(current)].width + if wd ~= 0 then + local wd, ht, dp = getwhd(current) + -- local dir = getdir(current) + -- if dir == "LTL" or dir = "RTT" then + -- wd, ht, dp = ht + dp, wd, 0 + -- end + local next = getnext(current) + local prev = previous + setboth(current) + local linewidth = emwidth/(2*fraction) + local baseline + -- if dp ~= 0 and ht ~= 0 then + if (dp >= 0 and ht >= 0) or (dp <= 0 and ht <= 0) then + baseline = new_rule(wd-2*linewidth,linewidth,0) + end + local doublelinewidth = 2*linewidth + -- could be a pdf rule (or a user rule now) + local info = setlink( + new_rule(linewidth,ht,dp), + new_rule(wd-doublelinewidth,-dp+linewidth,dp), + new_rule(linewidth,ht,dp), + new_kern(-wd+linewidth), + new_rule(wd-doublelinewidth,ht,-ht+linewidth), + new_kern(-wd+doublelinewidth), + baseline + ) + local char = chardata[getfont(current)][getchar(current)] + if char and type(char.unicode) == "table" then -- hackery test + setlistcolor(info,c_ligature) + setlisttransparency(info,c_ligature_d) else + setlistcolor(info,c_glyph) + setlisttransparency(info,c_glyph_d) + end + info = new_hlist(info) + setattr(info,a_layer,l_glyph) + local info = setlink(current,new_kern(-wd),info) + info = hpack_nodes(info) + setwidth(info,wd) + if next then + setlink(info,next) + end + if prev then setlink(prev,info) end - end - if head == current then - return info, info + if head == current then + return info, info + else + return head, info + end else - return head, info + return head, current end - else - return head, current end + end -local bpfactor = number.dimenfactors.bp - --- callback.register("process_rule",function(n,h,v) --- local p = string.formatters["0 0 %0.6F %0.6F re f"](h*bpfactor,v*bpfactor) --- pdf.print("direct",p) --- end) - -local function ruledglyph(head,current,previous) - local wd = getfield(current,"width") - -- local wd = chardata[getfont(current)][getchar(current)].width - if wd ~= 0 then - local ht = getfield(current,"height") - local dp = getfield(current,"depth") - local next = getnext(current) - local prev = previous - setboth(current) - local linewidth = emwidth/(2*fraction) - local baseline - -- if dp ~= 0 and ht ~= 0 then - if (dp >= 0 and ht >= 0) or (dp <= 0 and ht <= 0) then - baseline = new_rule(wd-2*linewidth,linewidth,0) - end - local doublelinewidth = 2*linewidth - -- could be a pdf rule (or a user rule now) - local info = linked_nodes( - new_rule(linewidth,ht,dp), - new_rule(wd-doublelinewidth,-dp+linewidth,dp), - new_rule(linewidth,ht,dp), - new_kern(-wd+linewidth), - new_rule(wd-doublelinewidth,ht,-ht+linewidth), - new_kern(-wd+doublelinewidth), - baseline - ) - local char = chardata[getfont(current)][getchar(current)] - if char and type(char.unicode) == "table" then -- hackery test - setlistcolor(info,c_ligature) - setlisttransparency(info,c_ligature_d) +local ruledglue do + + local g_cache_v = caches["vglue"] + local g_cache_h = caches["hglue"] + + local tags = { + -- userskip = "US", + lineskip = "LS", + baselineskip = "BS", + parskip = "PS", + abovedisplayskip = "DA", + belowdisplayskip = "DB", + abovedisplayshortskip = "SA", + belowdisplayshortskip = "SB", + leftskip = "LS", + rightskip = "RS", + topskip = "TS", + splittopskip = "ST", + tabskip = "AS", + spaceskip = "SS", + xspaceskip = "XS", + parfillskip = "PF", + thinmuskip = "MS", + medmuskip = "MM", + thickmuskip = "ML", + leaders = "NL", + cleaders = "CL", + xleaders = "XL", + gleaders = "GL", + -- true = "VS", + -- false = "HS", + } + + -- we sometimes pass previous as we can have issues in math (not watertight for all) + + ruledglue = function(head,current,vertical,parent) + local subtype = getsubtype(current) + local width = effectiveglue(current,parent) + local amount = formatters["%s:%0.3f"](tags[subtype] or (vertical and "VS") or "HS",width*pt_factor) + local info = (vertical and g_cache_v or g_cache_h)[amount] + if info then + -- print("glue hit") else - setlistcolor(info,c_glyph) - setlisttransparency(info,c_glyph_d) - end - info = new_hlist(info) - setattr(info,a_layer,l_glyph) - local info = linked_nodes(current,new_kern(-wd),info) - info = hpack_nodes(info) - setfield(info,"width",wd) - if next then - setlink(info,next) - end - if prev then - setlink(prev,info) + if subtype == space_code or subtype == xspace_code then -- not yet all space + info = sometext(amount,l_glue,c_space) + elseif subtype == leftskip_code or subtype == rightskip_code then + info = sometext(amount,l_glue,c_skip_a) + elseif subtype == userskip_code then + if width > 0 then + info = sometext(amount,l_glue,c_positive) + elseif width < 0 then + info = sometext(amount,l_glue,c_negative) + else + info = sometext(amount,l_glue,c_zero) + end + else + info = sometext(amount,l_glue,c_skip_b) + end + (vertical and g_cache_v or g_cache_h)[amount] = info end - if head == current then - return info, info - else - return head, info + info = copy_list(info) + if vertical then + info = vpack_nodes(info) end - else - return head, current + head, current = insert_node_before(head,current,info) + return head, getnext(current) end + end -local g_cache_v = { } -local g_cache_h = { } - -local tags = { - -- userskip = "US", - lineskip = "LS", - baselineskip = "BS", - parskip = "PS", - abovedisplayskip = "DA", - belowdisplayskip = "DB", - abovedisplayshortskip = "SA", - belowdisplayshortskip = "SB", - leftskip = "LS", - rightskip = "RS", - topskip = "TS", - splittopskip = "ST", - tabskip = "AS", - spaceskip = "SS", - xspaceskip = "XS", - parfillskip = "PF", - thinmuskip = "MS", - medmuskip = "MM", - thickmuskip = "ML", - leaders = "NL", - cleaders = "CL", - xleaders = "XL", - gleaders = "GL", - -- true = "VS", - -- false = "HS", -} +local ruledkern do --- we sometimes pass previous as we can have issues in math (not watertight for all) + local k_cache_v = caches["vkern"] + local k_cache_h = caches["hkern"] -local function ruledglue(head,current,vertical,parent) - local subtype = getsubtype(current) - local width = effectiveglue(current,parent) - local amount = formatters["%s:%0.3f"](tags[subtype] or (vertical and "VS") or "HS",width*pt_factor) - local info = (vertical and g_cache_v or g_cache_h)[amount] - if info then - -- print("glue hit") - else - if subtype == space_code or subtype == xspace_code then -- not yet all space - info = sometext(amount,l_glue,c_space) - elseif subtype == leftskip_code or subtype == rightskip_code then - info = sometext(amount,l_glue,c_skip_a) - elseif subtype == userskip_code then - if width > 0 then - info = sometext(amount,l_glue,c_positive) - elseif width < 0 then - info = sometext(amount,l_glue,c_negative) + ruledkern = function(head,current,vertical) + local kern = getkern(current) + local info = (vertical and k_cache_v or k_cache_h)[kern] + if info then + -- print("kern hit") + else + local amount = formatters["%s:%0.3f"](vertical and "VK" or "HK",kern*pt_factor) + if kern > 0 then + info = sometext(amount,l_kern,c_positive) + elseif kern < 0 then + info = sometext(amount,l_kern,c_negative) else - info = sometext(amount,l_glue,c_zero) + info = sometext(amount,l_kern,c_zero) end - else - info = sometext(amount,l_glue,c_skip_b) + (vertical and k_cache_v or k_cache_h)[kern] = info end - (vertical and g_cache_v or g_cache_h)[amount] = info - end - info = copy_list(info) - if vertical then - info = vpack_nodes(info) + info = copy_list(info) + if vertical then + info = vpack_nodes(info) + end + head, current = insert_node_before(head,current,info) + return head, getnext(current) end - head, current = insert_node_before(head,current,info) - return head, getnext(current) + end -local k_cache_v = { } -local k_cache_h = { } +local ruleditalic do -local function ruledkern(head,current,vertical) - local kern = getfield(current,"kern") - local info = (vertical and k_cache_v or k_cache_h)[kern] - if info then - -- print("kern hit") - else - local amount = formatters["%s:%0.3f"](vertical and "VK" or "HK",kern*pt_factor) - if kern > 0 then - info = sometext(amount,l_kern,c_positive) - elseif kern < 0 then - info = sometext(amount,l_kern,c_negative) + local i_cache = caches["itatalic"] + + ruleditalic = function(head,current) + local kern = getkern(current) + local info = i_cache[kern] + if info then + -- print("kern hit") else - info = sometext(amount,l_kern,c_zero) + local amount = formatters["%s:%0.3f"]("IC",kern*pt_factor) + if kern > 0 then + info = sometext(amount,l_kern,c_positive) + elseif kern < 0 then + info = sometext(amount,l_kern,c_negative) + else + info = sometext(amount,l_kern,c_zero) + end + i_cache[kern] = info end - (vertical and k_cache_v or k_cache_h)[kern] = info - end - info = copy_list(info) - if vertical then - info = vpack_nodes(info) + info = copy_list(info) + head, current = insert_node_before(head,current,info) + return head, getnext(current) end - head, current = insert_node_before(head,current,info) - return head, getnext(current) -end -local i_cache = { } +end -local function ruleditalic(head,current) - local kern = getfield(current,"kern") - local info = i_cache[kern] - if info then - -- print("kern hit") - else - local amount = formatters["%s:%0.3f"]("IC",kern*pt_factor) - if kern > 0 then - info = sometext(amount,l_kern,c_positive) - elseif kern < 0 then - info = sometext(amount,l_kern,c_negative) - else - info = sometext(amount,l_kern,c_zero) +local ruleddiscretionary do + + local d_cache = caches["discretionary"] + + ruleddiscretionary = function(head,current) + local d = d_cache[true] + if not the_discretionary then + local rule = new_rule(4*emwidth/fraction,4*exheight,exheight) + local kern = new_kern(-2*emwidth/fraction) + setlink(kern,rule) + setcolor(rule,c_discretionary_d) + settransparency(rule,c_discretionary_d) + setattr(rule,a_layer,l_discretionary) + d = new_hlist(kern) + d_cache[true] = d end - i_cache[kern] = info + insert_node_after(head,current,copy_list(d)) + return head, current end - info = copy_list(info) - head, current = insert_node_before(head,current,info) - return head, getnext(current) + end -local p_cache_v = { } -local p_cache_h = { } +local ruledpenalty do -local function ruledpenalty(head,current,vertical) - local penalty = getfield(current,"penalty") - local info = (vertical and p_cache_v or p_cache_h)[penalty] - if info then - -- print("penalty hit") - else - local amount = formatters["%s:%s"](vertical and "VP" or "HP",penalty) - if penalty > 0 then - info = sometext(amount,l_penalty,c_positive) - elseif penalty < 0 then - info = sometext(amount,l_penalty,c_negative) + local p_cache_v = caches["vpenalty"] + local p_cache_h = caches["hpenalty"] + + ruledpenalty = function(head,current,vertical) + local penalty = getpenalty(current) + local info = (vertical and p_cache_v or p_cache_h)[penalty] + if info then + -- print("penalty hit") else - info = sometext(amount,l_penalty,c_zero) + local amount = formatters["%s:%s"](vertical and "VP" or "HP",penalty) + if penalty > 0 then + info = sometext(amount,l_penalty,c_positive) + elseif penalty < 0 then + info = sometext(amount,l_penalty,c_negative) + else + info = sometext(amount,l_penalty,c_zero) + end + (vertical and p_cache_v or p_cache_h)[penalty] = info end - (vertical and p_cache_v or p_cache_h)[penalty] = info - end - info = copy_list(info) - if vertical then - info = vpack_nodes(info) - elseif raisepenalties then - setfield(info,"shift",-65536*4) + info = copy_list(info) + if vertical then + info = vpack_nodes(info) + elseif raisepenalties then + setshift(info,-65536*4) + end + head, current = insert_node_before(head,current,info) + return head, getnext(current) end - head, current = insert_node_before(head,current,info) - return head, getnext(current) + end local function visualize(head,vertical,forced,parent) @@ -869,37 +956,39 @@ local function visualize(head,vertical,forced,parent) if a ~= attr then prev_trace_fontkern = trace_fontkern if a == unsetvalue then - trace_hbox = false - trace_vbox = false - trace_vtop = false - trace_kern = false - trace_glue = false - trace_penalty = false - trace_fontkern = false - trace_strut = false - trace_whatsit = false - trace_glyph = false - trace_simple = false - trace_user = false - trace_math = false - trace_italic = false - trace_origin = false + trace_hbox = false + trace_vbox = false + trace_vtop = false + trace_kern = false + trace_glue = false + trace_penalty = false + trace_fontkern = false + trace_strut = false + trace_whatsit = false + trace_glyph = false + trace_simple = false + trace_user = false + trace_math = false + trace_italic = false + trace_origin = false + trace_discretionary = false else -- dead slow: - trace_hbox = hasbit(a, 1) - trace_vbox = hasbit(a, 2) - trace_vtop = hasbit(a, 4) - trace_kern = hasbit(a, 8) - trace_glue = hasbit(a, 16) - trace_penalty = hasbit(a, 32) - trace_fontkern = hasbit(a, 64) - trace_strut = hasbit(a, 128) - trace_whatsit = hasbit(a, 256) - trace_glyph = hasbit(a, 512) - trace_simple = hasbit(a, 1024) - trace_user = hasbit(a, 2048) - trace_math = hasbit(a, 4096) - trace_italic = hasbit(a, 8192) - trace_origin = hasbit(a,16384) + trace_hbox = hasbit(a, 1) + trace_vbox = hasbit(a, 2) + trace_vtop = hasbit(a, 4) + trace_kern = hasbit(a, 8) + trace_glue = hasbit(a, 16) + trace_penalty = hasbit(a, 32) + trace_fontkern = hasbit(a, 64) + trace_strut = hasbit(a, 128) + trace_whatsit = hasbit(a, 256) + trace_glyph = hasbit(a, 512) + trace_simple = hasbit(a, 1024) + trace_user = hasbit(a, 2048) + trace_math = hasbit(a, 4096) + trace_italic = hasbit(a, 8192) + trace_origin = hasbit(a,16384) + trace_discretionary = hasbit(a,32768) end attr = a end @@ -910,6 +999,9 @@ local function visualize(head,vertical,forced,parent) head, current = ruledglyph(head,current,previous) end elseif id == disc_code then + if trace_discretionary then + head, current = ruleddiscretionary(head,current) + end local pre, post, replace = getdisc(current) if pre then pre = visualize(pre,false,a,parent) @@ -985,46 +1077,21 @@ end do - local function freed(cache) - local n = 0 - for k, v in next, cache do - free_node_list(v) - n = n + 1 + local function cleanup() + for tag, cache in next, caches do + for k, v in next, cache do + flush_node_list(v) + end end - if n == 0 then - return 0, cache - else - return n, { } + cleanup = function() + report_visualize("error, duplicate cleanup") end end - local function cleanup() - local hf, nw, nb, ng_v, ng_h, np_v, np_h, nk_v, nk_h - nf, f_cache = freed(f_cache) - nw, w_cache = freed(w_cache) - nb, b_cache = freed(b_cache) - no, o_cache = freed(o_cache) - ng_v, g_cache_v = freed(g_cache_v) - ng_h, g_cache_h = freed(g_cache_h) - np_v, p_cache_v = freed(p_cache_v) - np_h, p_cache_h = freed(p_cache_h) - nk_v, k_cache_v = freed(k_cache_v) - nk_h, k_cache_h = freed(k_cache_h) - -- report_visualize("cache cleanup: %s fontkerns, %s skips, %s penalties, %s kerns, %s whatsits, %s boxes, %s origins", - -- nf,ng_v+ng_h,np_v+np_h,nk_v+nk_h,nw,nb,no) - end - local function handler(head) if usedfont then starttiming(visualizers) - -- local l = texgetattribute(a_layer) - -- local v = texgetattribute(a_visual) - -- texsetattribute(a_layer,unsetvalue) - -- texsetattribute(a_visual,unsetvalue) head = visualize(tonut(head),true) - -- texsetattribute(a_layer,l) - -- texsetattribute(a_visual,v) - -- -- cleanup() stoptiming(visualizers) return tonode(head), true else @@ -1091,7 +1158,7 @@ end statistics.register("visualization time",function() if enabled then -- cleanup() -- in case we don't don't do it each time - return format("%s seconds",statistics.elapsedtime(visualizers)) + return formatters["%s seconds"](statistics.elapsedtime(visualizers)) end end) @@ -1099,9 +1166,38 @@ end) local implement = interfaces.implement -implement { name = "setvisual", arguments = "string", actions = visualizers.setvisual } -implement { name = "getvisual", arguments = "string", actions = { setvisual, context } } -implement { name = "setvisuallayer", arguments = "string", actions = visualizers.setlayer } -implement { name = "markvisualfonts", arguments = "integer", actions = visualizers.markfonts } -implement { name = "setvisualfont", arguments = "integer", actions = visualizers.setfont } +implement { + name = "setvisual", + arguments = "string", + actions = visualizers.setvisual +} + +implement { + name = "setvisuals", + arguments = "string", + actions = visualizers.setvisual +} + +implement { + name = "getvisual", + arguments = "string", + actions = { setvisual, context } +} + + implement { + name = "setvisuallayer", + arguments = "string", + actions = visualizers.setlayer +} + +implement { + name = "markvisualfonts", + arguments = "integer", + actions = visualizers.markfonts +} +implement { + name = "setvisualfont", + arguments = "integer", + actions = visualizers.setfont +} diff --git a/tex/context/base/mkiv/trac-vis.mkiv b/tex/context/base/mkiv/trac-vis.mkiv index a503981f5..894408222 100644 --- a/tex/context/base/mkiv/trac-vis.mkiv +++ b/tex/context/base/mkiv/trac-vis.mkiv @@ -39,7 +39,7 @@ \newconstant\c_syst_visualizers_state \newtoks \t_syst_visualizers_optimize -\definesystemattribute[visual][public,global] % global ? +% \definesystemattribute[visual][public,global] % already defined % no, but can become an option: % diff --git a/tex/context/base/mkiv/trac-xml.lua b/tex/context/base/mkiv/trac-xml.lua index cd8b8c0a5..7906d76a8 100644 --- a/tex/context/base/mkiv/trac-xml.lua +++ b/tex/context/base/mkiv/trac-xml.lua @@ -169,6 +169,7 @@ function reporters.export(t,methods,filename) if filename then local fullname = file.replacesuffix(filename,method) t.report("saving export in %a",fullname) + dir.mkdirs(file.pathpart(fullname)) io.savedata(fullname,result) else reporters.lines(t,result) diff --git a/tex/context/base/mkiv/type-set.mkiv b/tex/context/base/mkiv/type-set.mkiv index e2d7071d4..1ef137d39 100644 --- a/tex/context/base/mkiv/type-set.mkiv +++ b/tex/context/base/mkiv/type-set.mkiv @@ -121,4 +121,12 @@ \definefilesynonym [type-imp-mathdesigngaramond.mkiv] [type-imp-mathdesign.mkiv] \definefilesynonym [type-imp-mathdesignutopia.mkiv] [type-imp-mathdesign.mkiv] +\definefilesynonym [type-imp-cows.mkiv] [type-imp-koeielettersot.mkiv] +\definefilesynonym [type-imp-sheep.mkiv] [type-imp-koeielettersot.mkiv] +\definefilesynonym [type-imp-coloredcows.mkiv] [type-imp-koeielettersot.mkiv] +\definefilesynonym [type-imp-coloredsheep.mkiv] [type-imp-koeielettersot.mkiv] +\definefilesynonym [type-imp-koeieletters.mkiv] [type-imp-koeielettersot.mkiv] + +\definefilesynonym [type-imp-stixtwo.mkiv] [type-imp-stix.mkiv] + \protect \endinput diff --git a/tex/context/base/mkiv/typo-bld.lua b/tex/context/base/mkiv/typo-bld.lua index ce6a65baf..153218eef 100644 --- a/tex/context/base/mkiv/typo-bld.lua +++ b/tex/context/base/mkiv/typo-bld.lua @@ -37,6 +37,7 @@ local texnest = tex.nest local texlists = tex.lists local nodes = nodes +local nodeidstostring = nodes.idstostring local nodepool = nodes.pool local new_baselineskip = nodepool.baselineskip local new_lineskip = nodepool.lineskip @@ -46,6 +47,8 @@ local hpack_node = nodes.hpack local starttiming = statistics.starttiming local stoptiming = statistics.stoptiming +local registercallback = callbacks.register + storage.register("builders/paragraphs/constructors/names", names, "builders.paragraphs.constructors.names") storage.register("builders/paragraphs/constructors/numbers", numbers, "builders.paragraphs.constructors.numbers") @@ -172,7 +175,7 @@ end function constructors.enable () enabled = true end function constructors.disable() enabled = false end -callbacks.register('linebreak_filter', processor, "breaking paragraps into lines") +registercallback('linebreak_filter', processor, "breaking paragraps into lines") statistics.register("linebreak processing time", function() return statistics.elapsedseconds(parbuilders) @@ -183,8 +186,6 @@ end) nodes.builders = nodes.builder or { } local builders = nodes.builders -local normalize = typesetters.paragraphs.normalize - local vboxactions = nodes.tasks.actions("vboxbuilders") function builders.vpack_filter(head,groupcode,size,packtype,maxdepth,direction) @@ -227,9 +228,8 @@ end -- check why box is called before after_linebreak .. maybe make categories and -- call 'm less - -- this will be split into contribute_filter for these 4 so at some point --- thecheck can go away +-- the check can go away function builders.buildpage_filter(groupcode) -- the next check saves 1% runtime on 1000 tufte pages @@ -257,9 +257,9 @@ function builders.buildpage_filter(groupcode) end end -callbacks.register('vpack_filter', builders.vpack_filter, "vertical spacing etc") -callbacks.register('buildpage_filter', builders.buildpage_filter, "vertical spacing etc (mvl)") ----------.register('contribute_filter', builders.contribute_filter, "adding content to lists") +registercallback('vpack_filter', builders.vpack_filter, "vertical spacing etc") +registercallback('buildpage_filter', builders.buildpage_filter, "vertical spacing etc (mvl)") +----------------('contribute_filter', builders.contribute_filter, "adding content to lists") statistics.register("v-node processing time", function() return statistics.elapsedseconds(builders) @@ -298,7 +298,7 @@ local function vpack_quality(how,n,detail,first,last) end trackers.register("builders.vpack.quality",function(v) - callback.register("vpack_quality",v and report_vpack_quality or nil) + registercallback("vpack_quality",v and report_vpack_quality or nil,"check vpack quality") end) local report, show = false, false @@ -349,37 +349,40 @@ end trackers.register("builders.hpack.quality",function(v) report = v - callback.register("hpack_quality",(report or show) and hpack_quality or nil) + registercallback("hpack_quality",(report or show) and hpack_quality or nil,"check hpack quality") end) trackers.register("builders.hpack.overflow",function(v) show = v - callback.register("hpack_quality",(report or show) and hpack_quality or nil) + registercallback("hpack_quality",(report or show) and hpack_quality or nil,"check hpack quality") end) -- local ignoredepth = - 65536000 -- --- callback.register("append_to_vlist_filter", function(box,location,prevdepth,mirrored) --- if prevdepth > ignoredepth then --- local b = tex.baselineskip --- local d = b.width - prevdepth --- local g = nil --- if mirrored then --- d = d - box.depth +-- registercallback( +-- "append_to_vlist_filter", +-- function(box,location,prevdepth,mirrored), +-- if prevdepth > ignoredepth then +-- local b = tex.baselineskip +-- local d = b.width - prevdepth +-- local g = nil +-- if mirrored then +-- d = d - box.depth +-- else +-- d = d - box.height +-- end +-- if d < tex.lineskiplimit then +-- g = nodes.pool.glue() +-- g.spec = tex.lineskip +-- else +-- g = nodes.pool.baselineskip(d) +-- end +-- g.next = box +-- box.prev = g +-- return g, mirrored and box.height or box.depth -- else --- d = d - box.height +-- return box, mirrored and box.height or box.depth -- end --- if d < tex.lineskiplimit then --- g = nodes.pool.glue() --- g.spec = tex.lineskip --- else --- g = nodes.pool.baselineskip(d) --- end --- g.next = box --- box.prev = g --- return g, mirrored and box.height or box.depth --- else --- return box, mirrored and box.height or box.depth --- end --- end) --- +-- end, +-- "experimental prevdepth checking" +-- ) diff --git a/tex/context/base/mkiv/typo-brk.lua b/tex/context/base/mkiv/typo-brk.lua index 106bb4954..84eff0654 100644 --- a/tex/context/base/mkiv/typo-brk.lua +++ b/tex/context/base/mkiv/typo-brk.lua @@ -32,11 +32,15 @@ local getsubtype = nuts.getsubtype local getfont = nuts.getfont local getid = nuts.getid local getfield = nuts.getfield -local getattr = nuts.getattr +----- getattr = nuts.getattr +local getattrlist = nuts.getattrlist +local takeattr = nuts.takeattr +local getlang = nuts.getlang local isglyph = nuts.isglyph local setfield = nuts.setfield local setattr = nuts.setattr +local setattrlist = nuts.setattrlist local setlink = nuts.setlink local setchar = nuts.setchar local setdisc = nuts.setdisc @@ -45,9 +49,9 @@ local setprev = nuts.setprev local setboth = nuts.setboth local setsubtype = nuts.setsubtype -local copy_node = nuts.copy -local copy_nodelist = nuts.copy_list -local free_node = nuts.free +local copy_node = nuts.copy_node +local copy_node_list = nuts.copy_list +local flush_node = nuts.flush_node local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after local remove_node = nuts.remove @@ -59,7 +63,7 @@ local texsetattribute = tex.setattribute local unsetvalue = attributes.unsetvalue local nodepool = nuts.pool -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction local v_reset = interfaces.variables.reset local v_yes = interfaces.variables.yes @@ -79,7 +83,7 @@ local kern_code = nodecodes.kern local math_code = nodecodes.math local fontkern_code = kerncodes.fontkern -local userkern_code = kerncodes.userkern +----- userkern_code = kerncodes.userkern local italickern_code = kerncodes.italiccorrection local typesetters = typesetters @@ -109,19 +113,21 @@ end -- todo: use boundaries -local function withattribute(n,a) - setfield(n,"attr",a) - return n -end - local function insert_break(head,start,stop,before,after,kern) - local a = getfield(start,"attr") if not kern then - insert_node_before(head,start,withattribute(new_penalty(before),a)) - insert_node_before(head,start,withattribute(new_glue(0),a)) + local p = new_penalty(before) + local g = new_glue() + setattrlist(p,start) + setattrlist(g,start) + insert_node_before(head,start,p) + insert_node_before(head,start,g) end - insert_node_after(head,stop,withattribute(new_glue(0),a)) - insert_node_after(head,stop,withattribute(new_penalty(after),a)) + local p = new_penalty(after) + local g = new_glue() + setattrlist(p,start) + setattrlist(g,start) + insert_node_after(head,stop,g) + insert_node_after(head,stop,p) end methods[1] = function(head,start,stop,settings,kern) @@ -142,21 +148,15 @@ methods[6] = function(head,start,stop,settings,kern) local l = new_wordboundary() local d = new_disc() local r = new_wordboundary() - local a = getfield(start,"attr") - -- setfield(l,"attr",a) - setfield(d,"attr",a) -- otherwise basemode is forces and we crash - -- setfield(r,"attr",a) - setlink(p,l) - setlink(l,d) - setlink(d,r) - setlink(r,n) + setattrlist(d,start) -- otherwise basemode is forced and we crash + setlink(p,l,d,r,n) if start == stop then setboth(start) setdisc(d,start,nil,copy_node(start)) else setprev(start) setnext(stop) - setdisc(d,start,nil,copy_nodelist(start)) + setdisc(d,start,nil,copy_node_list(start)) end stop = r end @@ -167,17 +167,14 @@ end methods[2] = function(head,start) -- ( => (- local p, n = getboth(start) if p and n then - local tmp - head, start, tmp = remove_node(head,start) - head, start = insert_node_before(head,start,new_disc()) - -- setfield(start,"attr",copy_nodelist(getfield(tmp,"attr"))) -- just a copy will do - setfield(start,"attr",getfield(tmp,"attr")) - setfield(start,"replace",tmp) - local tmp = copy_node(tmp) - local hyphen = copy_node(tmp) - setchar(hyphen,languages.prehyphenchar(getfield(tmp,"lang"))) - setlink(tmp,hyphen) - setfield(start,"post",tmp) + local replace + head, start, replace = remove_node(head,start) + local post = copy_node(replace) + local hyphen = copy_node(post) + setchar(hyphen,languages.prehyphenchar(getlang(post))) + setlink(post,hyphen) + head, start = insert_node_before(head,start,new_disc(nil,post,replace)) + setattrlist(start,replace) insert_break(head,start,start,10000,10000) end return head, start @@ -186,17 +183,14 @@ end methods[3] = function(head,start) -- ) => -) local p, n = getboth(start) if p and n then - local tmp - head, start, tmp = remove_node(head,start) - head, start = insert_node_before(head,start,new_disc()) - -- setfield(start,"attr",copy_nodelist(getfield(tmp,"attr"))) -- just a copy will do - setfield(start,"attr",getfield(tmp,"attr")) - setfield(start,"replace",tmp) - local tmp = copy_node(tmp) - local hyphen = copy_node(tmp) - setchar(hyphen,languages.prehyphenchar(getfield(tmp,"lang"))) - setlink(hyphen,tmp) - setfield(start,"pre",hyphen) + local replace + head, start, replace = remove_node(head,start) + local pre = copy_node(replace) + local hyphen = copy_node(pre) + setchar(hyphen,languages.prehyphenchar(getlang(pre))) + setlink(hyphen,pre) + head, start = insert_node_before(head,start,new_disc(hyphen,nil,replace)) -- so not pre ! + setattrlist(start,tmp) insert_break(head,start,start,10000,10000) end return head, start @@ -208,8 +202,7 @@ methods[4] = function(head,start) -- - => - - - local tmp head, start, tmp = remove_node(head,start) head, start = insert_node_before(head,start,new_disc()) - -- setfield(start,"attr",copy_nodelist(getfield(tmp,"attr"))) -- just a copy will do - setfield(start,"attr",getfield(tmp,"attr")) + setattrlist(start,tmp) setdisc(start,copy_node(tmp),copy_node(tmp),tmp) insert_break(head,start,start,10000,10000) end @@ -221,11 +214,11 @@ methods[5] = function(head,start,stop,settings) -- x => p q r if p and n then local tmp head, start, tmp = remove_node(head,start) - head, start = insert_node_before(head,start,new_disc()) - local attr = getfield(tmp,"attr") - local font = getfont(tmp) - local left = settings.left - local right = settings.right + head, start = insert_node_before(head,start,new_disc()) + local attr = getattrlist(tmp) + local font = getfont(tmp) + local left = settings.left + local right = settings.right local middle = settings.middle if left then left = tonodes(tostring(left),font,attr) @@ -237,9 +230,8 @@ methods[5] = function(head,start,stop,settings) -- x => p q r middle = tonodes(tostring(middle),font,attr) end setdisc(start,left,right,middle) - -- setfield(start,"attr",copy_nodelist(attr)) -- todo: critical only -- just a copy will do - setfield(start,"attr",attr) -- todo: critical only -- just a copy will do - free_node(tmp) + setattrlist(start,attr) + flush_node(tmp) insert_break(head,start,start,10000,10000) end return head, start @@ -258,7 +250,8 @@ function breakpoints.handler(head) while current do local char, id = isglyph(current) if char then - local a = getattr(current,a_breakpoints) + -- local a = getattr(current,a_breakpoints) + local a = takeattr(current,a_breakpoints) if a and a > 0 then if a ~= attr then local data = mapping[a] @@ -272,9 +265,10 @@ function breakpoints.handler(head) if map then local cmap = map[char] if cmap then + -- setattr(current,a_breakpoints,unsetvalue) -- should not be needed -- for now we collect but when found ok we can move the handler here -- although it saves nothing in terms of performance - local lang = getfield(current,"lang") + local lang = getlang(current) local smap = lang and lang >= 0 and lang < 0x7FFF and (cmap[numbers[lang]] or cmap[""]) if smap then local skip = smap.skip @@ -301,7 +295,6 @@ function breakpoints.handler(head) else current = getnext(current) end - setattr(start,a_breakpoints,unsetvalue) -- should not be needed else current = getnext(current) end @@ -332,7 +325,7 @@ function breakpoints.handler(head) local stop = data[2] local cmap = data[3] local smap = data[4] --- local lang = getfield(start,"lang") +-- local lang = getlang(start) -- -- we do a sanity check for language -- local smap = lang and lang >= 0 and lang < 0x7FFF and (cmap[numbers[lang]] or cmap[""]) -- if smap then @@ -454,7 +447,7 @@ function breakpoints.set(n) if trace_breakpoints then report_breakpoints("enabling breakpoints handler") end - tasks.enableaction("processors","typesetters.breakpoints.handler") + enableaction("processors","typesetters.breakpoints.handler") end n = n.number end @@ -462,10 +455,6 @@ function breakpoints.set(n) texsetattribute(a_breakpoints,n) end --- function breakpoints.enable() --- tasks.enableaction("processors","typesetters.breakpoints.handler") --- end - -- interface implement { diff --git a/tex/context/base/mkiv/typo-cap.lua b/tex/context/base/mkiv/typo-cap.lua index 62b90b8ab..6bf4669df 100644 --- a/tex/context/base/mkiv/typo-cap.lua +++ b/tex/context/base/mkiv/typo-cap.lua @@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['typo-cap'] = { local next, type = next, type local format, insert = string.format, table.insert -local div, randomnumber = math.div, math.random +local div, getrandom = math.div, utilities.randomizer.get local trace_casing = false trackers .register("typesetters.casing", function(v) trace_casing = v end) local check_kerns = true directives.register("typesetters.casing.checkkerns", function(v) check_kerns = v end) @@ -25,7 +25,8 @@ local getfield = nuts.getfield local getnext = nuts.getnext local getprev = nuts.getprev local getid = nuts.getid -local getattr = nuts.getattr +----- getattr = nuts.getattr +local takeattr = nuts.takeattr local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getchar = nuts.getchar @@ -34,12 +35,13 @@ local getdisc = nuts.getdisc local setfield = nuts.setfield local setattr = nuts.setattr local setchar = nuts.setchar +local setfont = nuts.setfont local copy_node = nuts.copy local end_of_math = nuts.end_of_math -local traverse_nodes = nuts.traverse local traverse_id = nuts.traverse_id local insert_after = nuts.insert_after +local find_attribute = nuts.find_attribute local nodecodes = nodes.nodecodes local skipcodes = nodes.skipcodes @@ -52,7 +54,7 @@ local math_code = nodecodes.math local kerning_code = kerncodes.kerning -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction local newkern = nuts.pool.kern @@ -63,7 +65,6 @@ local fontchar = fonthashes.characters local variables = interfaces.variables local v_reset = variables.reset -local chardata = characters.data local texsetattribute = tex.setattribute local unsetvalue = attributes.unsetvalue @@ -216,7 +217,7 @@ end -- elseif dc == char then -- local lfa = lastfont[n] -- if lfa then --- setfield(first,"font",lfa) +-- setfont(first,lfa) -- return start, true, true -- else -- return start, false, true @@ -239,7 +240,7 @@ local function mixed(start,attr,lastfont,n,count,where,first) elseif dc == char then local lfa = lastfont[n] if lfa then - setfield(used,"font",lfa) + setfont(used,lfa) return start, true, true else return start, false, true @@ -276,7 +277,7 @@ local function Capital(start,attr,lastfont,n,count,where,first,once) -- 3 if lfa then local dc = uccodes[getchar(used)] if dc then - setfield(used,"font",lfa) + setfont(used,lfa) end end end @@ -295,7 +296,7 @@ local function none(start,attr,lastfont,n,count,where,first) return start, false, true end -local function random(start,attr,lastfont,n,count,where,first) +local function randomized(start,attr,lastfont,n,count,where,first) local used = first or start local char = getchar(used) local font = getfont(used) @@ -304,7 +305,7 @@ local function random(start,attr,lastfont,n,count,where,first) local kind = categories[char] if kind == "lu" then while true do - local n = randomnumber(0x41,0x5A) + local n = getrandom("capital lu",0x41,0x5A) if tfm[n] then -- this also intercepts tables setchar(used,n) return start, true @@ -312,7 +313,7 @@ local function random(start,attr,lastfont,n,count,where,first) end elseif kind == "ll" then while true do - local n = randomnumber(0x61,0x7A) + local n = getrandom("capital ll",0x61,0x7A) if tfm[n] then -- this also intercepts tables setchar(used,n) return start, true @@ -329,7 +330,7 @@ register(variables.Words, Words) -- 4 register(variables.capital,capital) -- 5 register(variables.Capital,Capital) -- 6 register(variables.none, none) -- 7 (dummy) -register(variables.random, random) -- 8 +register(variables.random, randomized) -- 8 register(variables.mixed, mixed) -- 9 register(variables.camel, camel) -- 10 @@ -337,17 +338,18 @@ register(variables.cap, variables.capital) -- clone register(variables.Cap, variables.Capital) -- clone function cases.handler(head) -- not real fast but also not used on much data + local start = tonut(head) local lastfont = { } local lastattr = nil local done = false - local start = tonut(head) local count = 0 local previd = nil local prev = nil while start do -- while because start can jump ahead local id = getid(start) if id == glyph_code then - local attr = getattr(start,a_cases) + -- local attr = getattr(start,a_cases) + local attr = takeattr(start,a_cases) if attr and attr > 0 and not blocked[attr] then if attr ~= lastattr then lastattr = attr @@ -355,7 +357,7 @@ function cases.handler(head) -- not real fast but also not used on much data else count = count + 1 end - setattr(start,a_cases,unsetvalue) + -- setattr(start,a_cases,unsetvalue) -- not needed local n, id, m = get(attr) if lastfont[n] == nil then lastfont[n] = id @@ -374,13 +376,14 @@ function cases.handler(head) -- not real fast but also not used on much data end end elseif id == disc_code then - local attr = getattr(start,a_cases) + -- local attr = getattr(start,a_cases) + local attr = takeattr(start,a_cases) if attr and attr > 0 and not blocked[attr] then if attr ~= lastattr then lastattr = attr count = 0 end - setattr(start,a_cases,unsetvalue) + -- setattr(start,a_cases,unsetvalue) -- not needed local n, id, m = get(attr) if lastfont[n] == nil then lastfont[n] = id @@ -392,6 +395,7 @@ function cases.handler(head) -- not real fast but also not used on much data local cnt = count for g in traverse_id(glyph_code,replace) do cnt = cnt + 1 + takeattr(g,a_cases) -- setattr(g,a_cases,unsetvalue) local _, _, quit = action(start,attr,lastfont,n,cnt,"replace",g) if quit then break end @@ -401,6 +405,7 @@ function cases.handler(head) -- not real fast but also not used on much data local cnt = count for g in traverse_id(glyph_code,pre) do cnt = cnt + 1 + takeattr(g,a_cases) -- setattr(g,a_cases,unsetvalue) local _, _, quit = action(start,attr,lastfont,n,cnt,"pre",g) if quit then break end @@ -410,6 +415,7 @@ function cases.handler(head) -- not real fast but also not used on much data local cnt = count for g in traverse_id(glyph_code,post) do cnt = cnt + 1 + takeattr(g,a_cases) -- setattr(g,a_cases,unsetvalue) local _, _, quit = action(start,attr,lastfont,n,cnt,"post",g) if quit then break end @@ -422,7 +428,7 @@ function cases.handler(head) -- not real fast but also not used on much data start = end_of_math(start) count = 0 elseif prev_id == kern_code and getsubtype(prev) == kerning_code then - -- still inside a word ...nomally kerns are added later + -- still inside a word ...normally kerns are added later else count = 0 end @@ -435,6 +441,120 @@ function cases.handler(head) -- not real fast but also not used on much data return head, done end +-- function cases.handler(head) -- not real fast but also not used on much data +-- local attr, start = find_attribute(tonut(head),a_cases) +-- if not start then +-- return head, false +-- end +-- local lastfont = { } +-- local lastattr = nil +-- local done = false +-- local count = 0 +-- local previd = nil +-- local prev = nil +-- while start do +-- while start do -- while because start can jump ahead +-- local id = getid(start) +-- if id == glyph_code then +-- -- local attr = getattr(start,a_cases) +-- local attr = takeattr(start,a_cases) +-- if attr and attr > 0 and not blocked[attr] then +-- if attr ~= lastattr then +-- lastattr = attr +-- count = 1 +-- else +-- count = count + 1 +-- end +-- -- setattr(start,a_cases,unsetvalue) -- not needed +-- local n, id, m = get(attr) +-- if lastfont[n] == nil then +-- lastfont[n] = id +-- end +-- local action = actions[n] -- map back to low number +-- if action then +-- start, ok = action(start,attr,lastfont,n,count) +-- if ok then +-- done = true +-- end +-- if trace_casing then +-- report_casing("case trigger %a, instance %a, fontid %a, result %a",n,m,id,ok) +-- end +-- elseif trace_casing then +-- report_casing("unknown case trigger %a",n) +-- end +-- end +-- elseif id == disc_code then +-- -- local attr = getattr(start,a_cases) +-- local attr = takeattr(start,a_cases) +-- if attr and attr > 0 and not blocked[attr] then +-- if attr ~= lastattr then +-- lastattr = attr +-- count = 0 +-- end +-- -- setattr(start,a_cases,unsetvalue) -- not needed +-- local n, id, m = get(attr) +-- if lastfont[n] == nil then +-- lastfont[n] = id +-- end +-- local action = actions[n] -- map back to low number +-- if action then +-- local pre, post, replace = getdisc(start) +-- if replace then +-- local cnt = count +-- for g in traverse_id(glyph_code,replace) do +-- cnt = cnt + 1 +-- takeattr(g,a_cases) +-- -- setattr(g,a_cases,unsetvalue) +-- local _, _, quit = action(start,attr,lastfont,n,cnt,"replace",g) +-- if quit then break end +-- end +-- end +-- if pre then +-- local cnt = count +-- for g in traverse_id(glyph_code,pre) do +-- cnt = cnt + 1 +-- takeattr(g,a_cases) +-- -- setattr(g,a_cases,unsetvalue) +-- local _, _, quit = action(start,attr,lastfont,n,cnt,"pre",g) +-- if quit then break end +-- end +-- end +-- if post then +-- local cnt = count +-- for g in traverse_id(glyph_code,post) do +-- cnt = cnt + 1 +-- takeattr(g,a_cases) +-- -- setattr(g,a_cases,unsetvalue) +-- local _, _, quit = action(start,attr,lastfont,n,cnt,"post",g) +-- if quit then break end +-- end +-- end +-- end +-- count = count + 1 +-- end +-- elseif id == math_code then +-- start = end_of_math(start) +-- count = 0 +-- elseif prev_id == kern_code and getsubtype(prev) == kerning_code then +-- -- still inside a word ...normally kerns are added later +-- else +-- count = 0 +-- start = getnext(start) +-- break +-- end +-- if start then +-- prev = start +-- previd = id +-- start = getnext(start) +-- end +-- end +-- if start then +-- attr, start = find_attribute(start,a_cases) +-- end +-- end +-- return head, done +-- end + -- function cases.handler(head) -- let's assume head doesn't change ... no reason -- local done = false -- local lastfont = { } @@ -463,7 +583,7 @@ function cases.set(n,id) n = registered[n] or tonumber(n) if n then if not enabled then - tasks.enableaction("processors","typesetters.cases.handler") + enableaction("processors","typesetters.cases.handler") if trace_casing then report_casing("enabling case handler") end diff --git a/tex/context/base/mkiv/typo-cap.mkiv b/tex/context/base/mkiv/typo-cap.mkiv index 114532e4e..96f3e28d6 100644 --- a/tex/context/base/mkiv/typo-cap.mkiv +++ b/tex/context/base/mkiv/typo-cap.mkiv @@ -20,7 +20,7 @@ \registerctxluafile{typo-cap}{1.001} -\definesystemattribute[case][public] +% \definesystemattribute[case][public] % already predefined %D \macros %D {setupcapitals} diff --git a/tex/context/base/mkiv/typo-chr.lua b/tex/context/base/mkiv/typo-chr.lua index 041a73e1b..f6bcfde56 100644 --- a/tex/context/base/mkiv/typo-chr.lua +++ b/tex/context/base/mkiv/typo-chr.lua @@ -90,11 +90,10 @@ local insert, remove = table.insert, table.remove local nodecodes = nodes.nodecodes local glyph_code = nodecodes.glyph -local whatsit_code = nodecodes.whatsit local localpar_code = nodecodes.localpar local texnest = tex.nest -local free_node = node.free +local flush_node = node.flush_node local flush_list = node.flush_list local settexattribute = tex.setattribute @@ -135,7 +134,7 @@ local actions = { remove = function(specification) local n = pickup() if n then - free_node(n) + flush_node(n) end end, push = function(specification) diff --git a/tex/context/base/mkiv/typo-cln.lua b/tex/context/base/mkiv/typo-cln.lua index bc11f944c..53452f838 100644 --- a/tex/context/base/mkiv/typo-cln.lua +++ b/tex/context/base/mkiv/typo-cln.lua @@ -24,7 +24,8 @@ local cleaners = typesetters.cleaners local variables = interfaces.variables local nodecodes = nodes.nodecodes -local tasks = nodes.tasks + +local enableaction = nodes.tasks.enableaction local texsetattribute = tex.setattribute @@ -91,7 +92,7 @@ function cleaners.set(n) texsetattribute(a_cleaner,unsetvalue) else if not enabled then - tasks.enableaction("processors","typesetters.cleaners.handler") + enableaction("processors","typesetters.cleaners.handler") if trace_cleaners then report_cleaners("enabling cleaners") end diff --git a/tex/context/base/mkiv/typo-del.mkiv b/tex/context/base/mkiv/typo-del.mkiv index eb51a06e1..84fe2c469 100644 --- a/tex/context/base/mkiv/typo-del.mkiv +++ b/tex/context/base/mkiv/typo-del.mkiv @@ -267,10 +267,67 @@ \def\c_typo_delimited_nesting{\csname\??delimitedtextlevel\currentparentdelimitedtext\endcsname} -\def\typo_delimited_push#1% - {\globalpushmacro\currentdelimitedtext - \def\currentdelimitedtext{#1}% - \setlanguageparameter\delimitedtextparameter +% the \setlanguageparameter macro sets but we are ungrouped .. only used here +% +% \currentusedlanguage +% \usedlanguageparameter + +%D The optional argument can be a language, a narrower spec, or a outer:inner language +%D specification. +%D +%D \starttabulate +%D \NC [en] \NC {\tttf en} \quotation[en] {{\tttf <en=\currentlanguage>} something french} \NC \NR +%D \NC [fr] \NC {\tttf en} \quotation[fr] {{\tttf <fr=\currentlanguage>} something french} \NC \NR +%D \NC [fr:] \NC {\tttf fr} \quotation[fr:] {{\tttf <en=\currentlanguage>} something french} \NC \NR +%D \NC [:fr] \NC {\tttf en} \quotation[:fr] {{\tttf <fr=\currentlanguage>} something french} \NC \NR +%D \NC [fr:fr] \NC {\tttf fr} \quotation[fr:fr]{{\tttf <fr=\currentlanguage>} something french} \NC \NR +%D \NC [en:fr] \NC {\tttf en} \quotation[en:fr]{{\tttf <fr=\currentlanguage>} something french} \NC \NR +%D \NC [fr:en] \NC {\tttf fr} \quotation[fr:en]{{\tttf <en=\currentlanguage>} something french} \NC \NR +%D \stoptabulate + +\let\currentdelimitedlanguage\empty + +\def\typo_delimited_set_language_nop + {\setusedlanguage{\delimitedtextparameter\c!language}} + +\def\typo_delimited_set_language_yes + {\doiflanguageelse\m_delimited_argument + \typo_delimited_set_language_yes_a + {\doifelseinstring:\m_delimited_argument + \typo_delimited_set_language_yes_b + \typo_delimited_set_language_nop}} + +\def\typo_delimited_set_language_yes_b + {\splitatcolon\m_delimited_argument\outerdelimitedlanguage\innerdelimitedlanguage + \ifx\outerdelimitedlanguage\empty + \typo_delimited_set_language_nop + \else + \doiflanguageelse\outerdelimitedlanguage + {\setusedlanguage\outerdelimitedlanguage}% + \typo_delimited_set_language_nop + \fi + \ifx\innerdelimitedlanguage\empty + \else + \doiflanguageelse\innerdelimitedlanguage + {\let\currentdelimitedlanguage\innerdelimitedlanguage}% + \donothing + \fi + \let\m_delimited_argument\empty} + +\def\typo_delimited_set_language_yes_a + {\let\currentdelimitedlanguage\m_delimited_argument + \let\m_delimited_argument\empty} + +\def\typo_delimited_push#1#2% + {\globalpushmacro\currentdelimitedtext % can we combine these two + \globalpushmacro\currentdelimitedlanguage % the language used for hyphenation + \edef\currentdelimitedtext{#1}% + \edef\m_delimited_argument{#2}% + \ifx\m_delimited_argument\empty + \typo_delimited_set_language_nop + \else + \typo_delimited_set_language_yes + \fi \let\currentparentdelimitedtext\currentdelimitedtext \global\advance\c_typo_delimited_nesting\plusone \edef\delimitedtextlevel{\number\c_typo_delimited_nesting}% @@ -279,6 +336,7 @@ \def\typo_delimited_pop {\global\advance\c_typo_delimited_nesting\minusone + \globalpopmacro\currentdelimitedlanguage \globalpopmacro\currentdelimitedtext} \installcorenamespace{delimitedtext} @@ -308,6 +366,7 @@ \c!right=, %\c!level=0, \c!method=, + %\c!language=\v!local, \c!repeat=\v!no] \def\typo_delimited_repeat_ideed @@ -317,9 +376,12 @@ \let\typo_delimited_repeat\relax -\unexpanded\def\startdelimitedtext[#1]% +\unexpanded\def\startdelimitedtext + {\dodoubleempty\typo_delimited_text_start} + +\unexpanded\def\typo_delimited_text_start[#1][#2]% {\begingroup - \typo_delimited_push{#1}% + \typo_delimited_push{#1}{#2}% \dostarttaggedchained\t!delimitedblock\currentdelimitedtext\??delimitedtext \edef\p_delimited_method{\delimitedtextparameter\c!method}% \ifx\p_delimited_method\s!font @@ -355,12 +417,40 @@ \fi\fi} \def\typo_delimitedtexts_finish_font - {\removeunwantedspaces + {\removeunwantedspaces % again ? \dostarttagged\t!delimitedsymbol\empty \dotagsetdelimitedsymbol\s!right \delimitedtextparameter\c!right \dostoptagged} +\def\typo_delimited_show_language_indeed#1#2% + {\begingroup + \infofont + \setbox\scratchbox\hpack{\lower\strutht\hbox to \zeropoint{\darkred#1\currentlanguage:\currentdelimitedlanguage#2}}% + \vsmashbox\scratchbox + \box\scratchbox + \endgroup} + +\let\typo_delimited_show_language\gobbletwoarguments + +\installtextracker{delimited.language} + {\let\typo_delimited_show_language\typo_delimited_show_language_indeed} + {\let\typo_delimited_show_language\gobbletwoarguments} + +\def\typo_delimited_start_content + {\dostarttagged\t!delimitedcontent\empty + \begingroup + \douselanguageparameter\currentdelimitedlanguage + \typo_delimited_show_language<\hss + \ignorespaces} + +\def\typo_delimited_stop_content + {\removeunwantedspaces + \removelastskip % redundant + \typo_delimited_show_language\hss<% + \endgroup + \dostoptagged} + \def\typo_delimited_start_par {\dosingleempty\typo_delimited_start_par_indeed} @@ -373,14 +463,19 @@ \blank[\p_delimited_spacebefore]% \fi \delimitedtextparameter\c!before - \edef\m_typo_delimited_narrower{#1}% - \ifx\m_typo_delimited_narrower\empty + \iffirstargument + \edef\m_delimited_argument{#1}% + \fi + \ifx\m_delimited_argument\empty + \let\m_delimited_argument\m_delimited_argument + \fi + \ifx\m_delimited_argument\empty \endgraf \doadaptleftskip {\delimitedtextparameter\c!leftmargin}% \doadaptrightskip{\delimitedtextparameter\c!rightmargin}% \let\typo_delimited_stop_par_indeed\endgraf \else % backward compatible direct directive - \startnarrower[#1]% + \startnarrower[\m_delimited_argument]% \let\typo_delimited_stop_par_indeed\stopnarrower \fi % so far @@ -400,13 +495,10 @@ \setnextleftdelimitedtextmark \setnextrightdelimitedtextmark % - \ignorespaces - \dostarttagged\t!delimitedcontent\empty} + \typo_delimited_start_content} \def\typo_delimited_stop_par - {\removeunwantedspaces - \removelastskip - \dostoptagged + {\typo_delimited_stop_content \rightdelimitedtextmark \carryoverpar\endgroup % new per 2013-01-21 ... please left floats \popmacro\checkindentation @@ -424,12 +516,10 @@ \begingroup \usedelimitedtextstyleandcolor\c!style\c!color \typo_delimited_handle_left\c!left - \ignorespaces - \dostarttagged\t!delimitedcontent\empty} + \typo_delimited_start_content} \def\typo_delimited_stop_txt - {\removeunwantedspaces - \dostoptagged + {\typo_delimited_stop_content \typo_delimited_handle_right\c!right \endgroup} @@ -439,9 +529,12 @@ \typo_delimited_pop \endgroup} -\unexpanded\def\delimitedtext[#1]% +\unexpanded\def\delimitedtext + {\dodoubleempty\typo_delimited_text} + +\unexpanded\def\typo_delimited_text[#1][#2]% {\dontleavehmode % following ones can be omited - \typo_delimited_push{#1}% + \typo_delimited_push{#1}{#2}% \edef\p_delimited_method{\delimitedtextparameter\c!method}% \ifx\p_delimited_method\s!font \expandafter\typo_delimited_fontdriven @@ -569,7 +662,7 @@ % \stoptext \def\typo_delimited_handle_middle#1% - {\dostoptagged + {\typo_delimited_stop_content \begingroup \usedelimitedtextstyleandcolor\c!symstyle\c!symcolor \setbox\scratchbox\hbox{\delimitedtextparameter#1}% @@ -591,7 +684,7 @@ \kern\d_typo_delimited_signal % +- \prewordbreak \fi \endgroup - \dostarttagged\t!delimitedcontent\empty} + \typo_delimited_start_content} \def\typo_delimited_handle_left#1% {\begingroup @@ -652,10 +745,10 @@ {\dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext % block? \usedelimitedtextstyleandcolor\c!style\c!color \typo_delimited_handle_left\c!left - \dostarttagged\t!delimitedcontent\empty} - {\dostoptagged + \typo_delimited_start_content} + {\typo_delimited_stop_content \typo_delimited_handle_right\c!right - \removelastskip + \removelastskip % hm \dostoptagged \typo_delimited_pop}} @@ -667,52 +760,56 @@ \expandafter\typo_delimited_quoted \fi} -\def\typo_delimited_quoted_b - {\dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext +\def\typo_delimited_quoted + {\dontleavehmode + \begingroup + \dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext \typo_delimited_handle_left\c!left \usedelimitedtextstyleandcolor\c!style\c!color - \dostarttagged\t!delimitedcontent\empty} + \typo_delimited_start_content + \bgroup + \aftergroup\typo_delimited_quoted_e + \let\next=} \def\typo_delimited_quoted_e - {\dostoptagged + {\typo_delimited_stop_content \typo_delimited_handle_right\c!right \removelastskip % ? \dostoptagged - \typo_delimited_pop} + \typo_delimited_pop + \endgroup} -\def\typo_delimited_attributed_b - {\dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext +\def\typo_delimited_attributed + {\dontleavehmode + \begingroup + \dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext \usedelimitedtextstyleandcolor\c!style\c!color - \dostarttagged\t!delimitedcontent\empty - \ignorespaces} + \typo_delimited_start_content + \typo_delimited_attributed_e + \let\next=} \def\typo_delimited_attributed_e - {\dostoptagged + {\typo_delimited_stop_content \dostoptagged - \typo_delimited_pop} + \typo_delimited_pop + \endgroup} -\def\typo_delimited_fontdriven_b - {\dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext +\def\typo_delimited_fontdriven + {\dontleavehmode + \begingroup + \dostarttaggedchained\t!delimited\currentdelimitedtext\??delimitedtext \usedlanguageparameter{\c!left\currentparentdelimitedtext}% was: \currentdelimitedtext \usedelimitedtextstyleandcolor\c!style\c!color - \dostarttagged\t!delimitedcontent\empty} + \typo_delimited_start_content + \aftergroup\typo_delimited_fontdriven_e + \let\next=} \def\typo_delimited_fontdriven_e - {\dostoptagged + {\typo_delimited_stop_content \usedlanguageparameter{\c!right\currentparentdelimitedtext}% was: \currentdelimitedtext \dostoptagged - \typo_delimited_pop} - -% We now assume proper argument usage (so no longer grouped -% command). - -% \def\typo_delimited_quoted {\groupedcommand \typo_delimited_quoted_b \typo_delimited_quoted_e } -% \def\typo_delimited_attributed{\groupedcommand \typo_delimited_attributed_b\typo_delimited_attributed_e} -% \def\typo_delimited_fontdriven{\simplegroupedcommand\typo_delimited_fontdriven_b\typo_delimited_fontdriven_e} - -\def\typo_delimited_quoted {\bgroup\typo_delimited_quoted_b \aftergroup\typo_delimited_quoted_e \let\next=} -\def\typo_delimited_attributed{\bgroup\typo_delimited_attributed_b\aftergroup\typo_delimited_attributed_e\let\next=} -\def\typo_delimited_fontdriven{\bgroup\typo_delimited_fontdriven_b\aftergroup\typo_delimited_fontdriven_e\let\next=} + \typo_delimited_pop + \endgroup} % testcase for nesting: % diff --git a/tex/context/base/mkiv/typo-dha.lua b/tex/context/base/mkiv/typo-dha.lua index 25e92bd28..a32f72e46 100644 --- a/tex/context/base/mkiv/typo-dha.lua +++ b/tex/context/base/mkiv/typo-dha.lua @@ -48,7 +48,6 @@ local report_directions = logs.reporter("typesetting","text directions") local nuts = nodes.nuts local tonut = nuts.tonut local tonode = nuts.tonode -local nutstring = nuts.tostring local getnext = nuts.getnext local getprev = nuts.getprev @@ -59,6 +58,7 @@ local getlist = nuts.getlist local getfield = nuts.getfield local getattr = nuts.getattr local getprop = nuts.getprop +local getdir = nuts.getdir local isglyph = nuts.isglyph -- or ischar local setfield = nuts.setfield @@ -77,11 +77,8 @@ local skipcodes = nodes.skipcodes local glyph_code = nodecodes.glyph local math_code = nodecodes.math -local penalty_code = nodecodes.penalty local kern_code = nodecodes.kern local glue_code = nodecodes.glue -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist local dir_code = nodecodes.dir local localpar_code = nodecodes.localpar @@ -94,7 +91,6 @@ local formatters = string.formatters local insert = table.insert local fonthashes = fonts.hashes -local fontdata = fonthashes.identifiers local fontchar = fonthashes.characters local chardirections = characters.directions @@ -317,7 +313,7 @@ local function process(start) elseif id == kern_code then setprop(current,"direction",'k') elseif id == dir_code then - local dir = getfield(current,"dir") + local dir = getdir(current) if dir == "+TRT" then autodir = -1 elseif dir == "+TLT" then @@ -334,7 +330,7 @@ local function process(start) textdir = autodir setprop(current,"direction",true) elseif id == localpar_code then - local dir = getfield(current,"dir") + local dir = getdir(current) if dir == 'TRT' then autodir = -1 elseif dir == 'TLT' then diff --git a/tex/context/base/mkiv/typo-dig.lua b/tex/context/base/mkiv/typo-dig.lua index 09c2f64ee..3d60131c7 100644 --- a/tex/context/base/mkiv/typo-dig.lua +++ b/tex/context/base/mkiv/typo-dig.lua @@ -28,13 +28,13 @@ local getprev = nuts.getprev local getfont = nuts.getfont local getchar = nuts.getchar local getid = nuts.getid +local getwidth = nuts.getwidth local getfield = nuts.getfield -local getattr = nuts.getattr +local takeattr = nuts.takeattr local setlink = nuts.setlink local setnext = nuts.setnext local setprev = nuts.setprev -local setattr = nuts.setattr local hpack_node = nuts.hpack local traverse_id = nuts.traverse_id @@ -48,14 +48,12 @@ local nodecodes = nodes.nodecodes local glyph_code = nodecodes.glyph local nodepool = nuts.pool -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction local new_glue = nodepool.glue local fonthashes = fonts.hashes -local fontdata = fonthashes.identifiers local chardata = fonthashes.characters -local quaddata = fonthashes.quads local v_reset = interfaces.variables.reset @@ -106,7 +104,7 @@ actions[1] = function(head,start,attr) local char = getchar(start) local unic = chardata[font][char].unicode or char if charbase[unic].category == "nd" then -- ignore unic tables - local oldwidth = getfield(start,"width") + local oldwidth = getwidth(start) local newwidth = getdigitwidth(font) if newwidth ~= oldwidth then if trace_digits then @@ -125,9 +123,8 @@ function digits.handler(head) local done, current, ok = false, head, false while current do if getid(current) == glyph_code then - local attr = getattr(current,a_digits) + local attr = takeattr(current,a_digits) if attr and attr > 0 then - setattr(current,a_digits,unsetvalue) local action = actions[attr%100] -- map back to low number if action then head, current, ok = action(head,current,attr) @@ -153,7 +150,7 @@ function digits.set(n) -- number or 'reset' n = tonumber(n) if n then if not enabled then - tasks.enableaction("processors","typesetters.digits.handler") + enableaction("processors","typesetters.digits.handler") if trace_digits then report_digits("enabling digit handler") end diff --git a/tex/context/base/mkiv/typo-dir.lua b/tex/context/base/mkiv/typo-dir.lua index 482b7114d..5ecf77a1f 100644 --- a/tex/context/base/mkiv/typo-dir.lua +++ b/tex/context/base/mkiv/typo-dir.lua @@ -28,7 +28,6 @@ if not modules then modules = { } end modules ['typo-dir'] = { local next, type = next, type local format, insert, sub, find, match = string.format, table.insert, string.sub, string.find, string.match -local utfchar = utf.char local formatters = string.formatters local nodes, node = nodes, node @@ -38,14 +37,14 @@ local trace_mathdirections = false trackers.register("typesetters.directions.m local trace_directions = false trackers.register("typesetters.directions", function(v) trace_textdirections = v trace_mathdirections = v end) local report_textdirections = logs.reporter("typesetting","text directions") -local report_mathdirections = logs.reporter("typesetting","math directions") +----- report_mathdirections = logs.reporter("typesetting","math directions") local hasbit = number.hasbit local texsetattribute = tex.setattribute local unsetvalue = attributes.unsetvalue -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction local tracers = nodes.tracers local setcolor = tracers.colors.set local resetcolor = tracers.colors.reset @@ -181,16 +180,12 @@ statistics.register("text directions", function() end end) --- function directions.enable() --- tasks.enableaction("processors","directions.handler") --- end - function directions.set(n) -- todo: names and numbers if not enabled then if trace_textdirections then report_textdirections("enabling directions handler") end - tasks.enableaction("processors","typesetters.directions.handler") + enableaction("processors","typesetters.directions.handler") enabled = true end if not n or n == 0 then diff --git a/tex/context/base/mkiv/typo-drp.lua b/tex/context/base/mkiv/typo-drp.lua index bddcc008e..e27ad75f3 100644 --- a/tex/context/base/mkiv/typo-drp.lua +++ b/tex/context/base/mkiv/typo-drp.lua @@ -22,7 +22,10 @@ local initials = typesetters.paragraphs or { } typesetters.initials = initials or { } local nodes = nodes + local tasks = nodes.tasks +local enableaction = tasks.enableaction +local disableaction = tasks.disableaction local nuts = nodes.nuts local tonut = nuts.tonut @@ -35,13 +38,18 @@ local getid = nuts.getid local getsubtype = nuts.getsubtype local getfield = nuts.getfield local getattr = nuts.getattr +local getwhd = nuts.getwhd local setfield = nuts.setfield local setattr = nuts.setattr local setlink = nuts.setlink local setprev = nuts.setprev local setnext = nuts.setnext +local setfont = nuts.setfont local setchar = nuts.setchar +local setwhd = nuts.setwhd +local setkern = nuts.setkern +local setoffsets = nuts.setoffsets local hpack_nodes = nuts.hpack @@ -55,7 +63,6 @@ local insert_after = nuts.insert_after local remove_node = nuts.remove local traverse_id = nuts.traverse_id local traverse = nuts.traverse -local free_node = nuts.free local variables = interfaces.variables local v_default = variables.default @@ -65,6 +72,7 @@ local v_first = variables.first local v_last = variables.last local texget = tex.get +local texset = tex.set local texsetattribute = tex.setattribute local unsetvalue = attributes.unsetvalue @@ -80,7 +88,7 @@ initials.actions = actions local a_initial = attributes.private("initial") local a_color = attributes.private('color') local a_transparency = attributes.private('transparency') -local a_colorspace = attributes.private('colormodel') +local a_colormodel = attributes.private('colormodel') local category = characters.category @@ -89,7 +97,7 @@ local settings = nil function initials.set(specification) settings = specification or { } settings.enabled = true - tasks.enableaction("processors","typesetters.initials.handler") + enableaction("processors","typesetters.initials.handler") if trace_initials then report_initials("enabling initials") end @@ -156,8 +164,8 @@ actions[v_default] = function(head,setting) local distance = setting.distance or 0 local voffset = setting.voffset or 0 local hoffset = setting.hoffset or 0 - local parindent = tex.parindent - local baseline = texget("baselineskip").width + local parindent = texget("parindent") + local baseline = texget("baselineskip",false) local lines = tonumber(setting.n) or 0 local dynamic = setting.dynamic local font = setting.font @@ -248,11 +256,11 @@ actions[v_default] = function(head,setting) while true do local id = getid(current) if id == kern_code then - setfield(current,"kern",0) + setkern(current,0) elseif id == glyph_code then local next = getnext(current) if font then - setfield(current,"font",font) + setfont(current,font) end if dynamic > 0 then setattr(current,0,dynamic) @@ -264,11 +272,11 @@ actions[v_default] = function(head,setting) -- nodes.handlers.characters(g) -- nodes.handlers.protectglyphs(g) -- setchar(current,g.char) --- nodes.free(g) +-- nodes.flush_node(g) -- can be a helper if ca and ca > 0 then - setattr(current,a_colorspace,ma == 0 and 1 or ma) + setattr(current,a_colormodel,ma == 0 and 1 or ma) setattr(current,a_color,ca) end if ta and ta > 0 then @@ -291,12 +299,8 @@ actions[v_default] = function(head,setting) setprev(first) setnext(last) local dropper = hpack_nodes(first) - local width = getfield(dropper,"width") - local height = getfield(dropper,"height") - local depth = getfield(dropper,"depth") - setfield(dropper,"width",0) - setfield(dropper,"height",0) - setfield(dropper,"depth",0) + local width, height, depth = getwhd(dropper) + setwhd(dropper,0,0,0) -- setlink(prev,dropper) setlink(dropper,next) @@ -318,8 +322,7 @@ actions[v_default] = function(head,setting) -- local hoffset = width + hoffset + distance + (indent and parindent or 0) for current in traverse_id(glyph_code,first) do - setfield(current,"xoffset",- hoffset ) - setfield(current,"yoffset",- voffset) -- no longer - height here + setoffsets(current,-hoffset,-voffset) -- no longer - height here if current == last then break end @@ -340,8 +343,8 @@ actions[v_default] = function(head,setting) if trace_initials then report_initials("setting hangafter to %i and hangindent to %p",hangafter,hangindent) end - tex.hangafter = hangafter - tex.hangindent = hangindent + texset("hangafter",hangafter) + texset("hangindent",hangindent) end if indent then insert_after(first,first,new_kern(-parindent)) @@ -368,7 +371,7 @@ function initials.handler(head) end if attr then -- here as we can process nested boxes first so we need to keep state - tasks.disableaction("processors","typesetters.initials.handler") + disableaction("processors","typesetters.initials.handler") -- texsetattribute(attribute,unsetvalue) local alternative = settings.alternative or v_default local action = actions[alternative] or actions[v_default] diff --git a/tex/context/base/mkiv/typo-dua.lua b/tex/context/base/mkiv/typo-dua.lua index f697ac562..c2f3c2763 100644 --- a/tex/context/base/mkiv/typo-dua.lua +++ b/tex/context/base/mkiv/typo-dua.lua @@ -69,7 +69,6 @@ local mirrordata = characters.mirrors local nuts = nodes.nuts local tonut = nuts.tonut local tonode = nuts.tonode -local nutstring = nuts.tostring local getnext = nuts.getnext local getid = nuts.getid @@ -78,10 +77,13 @@ local getlist = nuts.getlist local getchar = nuts.getchar local getfield = nuts.getfield local getprop = nuts.getprop +local getdir = nuts.getdir local setfield = nuts.setfield local setprop = nuts.setprop local setchar = nuts.setchar +local setdir = nuts.setdir +----- setattrlist = nuts.setattrlist local remove_node = nuts.remove local insert_node_after = nuts.insert_after @@ -154,7 +156,7 @@ local function show_list(list,size,what) result[i] = formatters["%-3s:%s %s (%i)"](direction,joiner,nodecodes[first],skip or 0) end elseif character >= 0x202A and character <= 0x202C then - result[i] = formatters["%-3s:%s %U"](direction,joiner,character) + result[i] = formatters["%-3s:%s %U"](direction,joiner,character) else result[i] = formatters["%-3s:%s %c %U"](direction,joiner,character,character) end @@ -233,7 +235,7 @@ local function build_list(head) -- todo: store node pointer ... saves loop list[size] = { char = 0x0020, direction = "ws", original = "ws", level = 0 } current = getnext(current) elseif id == dir_code then - local dir = getfield(current,"dir") + local dir = getdir(current) if dir == "+TLT" then list[size] = { char = 0x202A, direction = "lre", original = "lre", level = 0 } elseif dir == "+TRT" then @@ -325,7 +327,7 @@ end local function get_baselevel(head,list,size) -- todo: skip if first is object (or pass head and test for localpar) local id = getid(head) if id == localpar_code then - if getfield(head,"dir") == "TRT" then + if getdir(head) == "TRT" then return 1, "TRT", true else return 0, "TLT", true @@ -748,13 +750,13 @@ local function apply_to_list(list,size,head,pardir) setcolor(current,direction,false,mirror) end elseif id == hlist_code or id == vlist_code then - setfield(current,"dir",pardir) -- is this really needed? + setdir(current,pardir) -- is this really needed? elseif id == glue_code then if enddir and getsubtype(current) == parfillskip_code then -- insert the last enddir before \parfillskip glue local d = new_textdir(enddir) setprop(d,"directions",true) - -- setfield(d,"attr",getfield(current,"attr")) + -- setattrlist(d,current) head = insert_node_before(head,current,d) enddir = false done = true @@ -764,7 +766,7 @@ local function apply_to_list(list,size,head,pardir) -- localpar should always be the 1st node local d = new_textdir(begindir) setprop(d,"directions",true) - -- setfield(d,"attr",getfield(current,"attr")) + -- setattrlist(d,current) head, current = insert_node_after(head,current,d) begindir = nil done = true @@ -773,7 +775,7 @@ local function apply_to_list(list,size,head,pardir) if begindir then local d = new_textdir(begindir) setprop(d,"directions",true) - -- setfield(d,"attr",getfield(current,"attr")) + -- setattrlist(d,current) head = insert_node_before(head,current,d) done = true end @@ -787,7 +789,7 @@ local function apply_to_list(list,size,head,pardir) if enddir then local d = new_textdir(enddir) setprop(d,"directions",true) - -- setfield(d,"attr",getfield(current,"attr")) + -- setattrlist(d,current) head, current = insert_node_after(head,current,d) done = true end @@ -822,7 +824,7 @@ local function process(head) report_directions("after : %s",show_list(list,size,"direction")) report_directions("result : %s",show_done(list,size)) end - head, done = apply_to_list(list,size,head,pardir) + local head, done = apply_to_list(list,size,head,pardir) return tonode(head), done end diff --git a/tex/context/base/mkiv/typo-dub.lua b/tex/context/base/mkiv/typo-dub.lua index 7ac339799..eea743c6d 100644 --- a/tex/context/base/mkiv/typo-dub.lua +++ b/tex/context/base/mkiv/typo-dub.lua @@ -57,7 +57,6 @@ local textclassdata = characters.textclasses local nuts = nodes.nuts local tonut = nuts.tonut local tonode = nuts.tonode -local nutstring = nuts.tostring local getnext = nuts.getnext local getid = nuts.getid @@ -67,10 +66,13 @@ local getchar = nuts.getchar local getattr = nuts.getattr local getfield = nuts.getfield local getprop = nuts.getprop +local getdir = nuts.getdir local setfield = nuts.setfield local setprop = nuts.setprop local setchar = nuts.setchar +local setdir = nuts.setdir +local setattrlist = nuts.setattrlist local remove_node = nuts.remove local insert_node_after = nuts.insert_after @@ -98,12 +100,6 @@ local setcolor = directions.setcolor local getfences = directions.getfences local a_directions = attributes.private('directions') -local a_textbidi = attributes.private('textbidi') ------ a_state = attributes.private('state') - ------ s_isol = fonts.analyzers.states.isol - ------ current[a_state] = s_isol -- maybe better have a special bidi attr value -> override (9) -> todo local remove_controls = true directives.register("typesetters.directions.removecontrols",function(v) remove_controls = v end) ----- analyze_fences = true directives.register("typesetters.directions.analyzefences", function(v) analyze_fences = v end) @@ -288,7 +284,7 @@ local function build_list(head) -- todo: store node pointer ... saves loop list[size] = { char = 0x0020, direction = "ws", original = "ws", level = 0 } current = getnext(current) elseif id == dir_code then - local dir = getfield(current,"dir") + local dir = getdir(current) if dir == "+TLT" then list[size] = { char = 0x202A, direction = "lre", original = "lre", level = 0 } elseif dir == "+TRT" then @@ -403,7 +399,7 @@ end local function get_baselevel(head,list,size) -- todo: skip if first is object (or pass head and test for localpar) local id = getid(head) if id == localpar_code then - if getfield(head,"dir") == "TRT" then + if getdir(head) == "TRT" then return 1, "TRT", true else return 0, "TLT", true @@ -901,13 +897,13 @@ local function apply_to_list(list,size,head,pardir) setcolor(current,direction,false,mirror) end elseif id == hlist_code or id == vlist_code then - setfield(current,"dir",pardir) -- is this really needed? + setdir(current,pardir) -- is this really needed? elseif id == glue_code then if enddir and getsubtype(current) == parfillskip_code then -- insert the last enddir before \parfillskip glue local d = new_textdir(enddir) setprop(d,"directions",true) - -- setfield(d,"attr",getfield(current,"attr")) + -- setattrlist(d,current) head = insert_node_before(head,current,d) enddir = false done = true @@ -917,17 +913,16 @@ local function apply_to_list(list,size,head,pardir) -- localpar should always be the 1st node local d = new_textdir(begindir) setprop(d,"directions",true) - -- setfield(d,"attr",getfield(current,"attr")) + -- setattrlist(d,current) head, current = insert_node_after(head,current,d) begindir = nil done = true end - else end if begindir then local d = new_textdir(begindir) setprop(d,"directions",true) - -- setfield(d,"attr",getfield(current,"attr")) + -- setattrlist(d,current) head = insert_node_before(head,current,d) done = true end @@ -941,7 +936,7 @@ local function apply_to_list(list,size,head,pardir) if enddir then local d = new_textdir(enddir) setprop(d,"directions",true) - -- setfield(d,"attr",getfield(current,"attr")) + -- setattrlist(d,current) head, current = insert_node_after(head,current,d) done = true end @@ -983,7 +978,7 @@ local function process(head) report_directions("after : %s",show_list(list,size,"direction")) report_directions("result : %s",show_done(list,size)) end - head, done = apply_to_list(list,size,head,pardir) + local head, done = apply_to_list(list,size,head,pardir) return tonode(head), done end diff --git a/tex/context/base/mkiv/typo-duc.lua b/tex/context/base/mkiv/typo-duc.lua index fce40932f..7fd49e54e 100644 --- a/tex/context/base/mkiv/typo-duc.lua +++ b/tex/context/base/mkiv/typo-duc.lua @@ -58,7 +58,6 @@ local textclassdata = characters.textclasses local nuts = nodes.nuts local tonut = nuts.tonut local tonode = nuts.tonode -local nutstring = nuts.tostring local getnext = nuts.getnext local getid = nuts.getid @@ -68,10 +67,13 @@ local getlist = nuts.getlist local getattr = nuts.getattr local getfield = nuts.getfield local getprop = nuts.getprop +local getdir = nuts.getdir local setfield = nuts.setfield local setprop = nuts.setprop local setchar = nuts.setchar +local setdir = nuts.setdir +local setattrlist = nuts.setattrlist local properties = nodes.properties @@ -101,12 +103,6 @@ local setcolor = directions.setcolor local getfences = directions.getfences local a_directions = attributes.private('directions') -local a_textbidi = attributes.private('textbidi') ------ a_state = attributes.private('state') - ------ s_isol = fonts.analyzers.states.isol - ------ current[a_state] = s_isol -- maybe better have a special bidi attr value -> override (9) -> todo local remove_controls = true directives.register("typesetters.directions.removecontrols",function(v) remove_controls = v end) ----- analyze_fences = true directives.register("typesetters.directions.analyzefences", function(v) analyze_fences = v end) @@ -295,7 +291,7 @@ local function build_list(head) -- todo: store node pointer ... saves loop setmetatable(t,mt_space) current = getnext(current) elseif id == dir_code then - local dir = getfield(current,"dir") + local dir = getdir(current) if dir == "+TLT" then t = { } setmetatable(t,mt_lre) @@ -419,7 +415,7 @@ end local function get_baselevel(head,list,size) -- todo: skip if first is object (or pass head and test for localpar) local id = getid(head) if id == localpar_code then - if getfield(head,"dir") == "TRT" then + if getdir(head) == "TRT" then return 1, "TRT", true else return 0, "TLT", true @@ -937,13 +933,13 @@ local function apply_to_list(list,size,head,pardir) setcolor(current,direction,false,mirror) end elseif id == hlist_code or id == vlist_code then - setfield(current,"dir",pardir) -- is this really needed? + setdir(current,pardir) -- is this really needed? elseif id == glue_code then if enddir and getsubtype(current) == parfillskip_code then -- insert the last enddir before \parfillskip glue local d = new_textdir(enddir) local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end - -- setfield(d,"attr",getfield(current,"attr")) + -- setattrlist(d,current) head = insert_node_before(head,current,d) enddir = false done = true @@ -953,7 +949,7 @@ local function apply_to_list(list,size,head,pardir) -- localpar should always be the 1st node local d = new_textdir(begindir) local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end - -- setfield(d,"attr",getfield(current,"attr")) + -- setattrlist(d,current) head, current = insert_node_after(head,current,d) begindir = nil done = true @@ -962,7 +958,7 @@ local function apply_to_list(list,size,head,pardir) if begindir then local d = new_textdir(begindir) local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end - -- setfield(d,"attr",getfield(current,"attr")) + -- setattrlist(d,current) head = insert_node_before(head,current,d) done = true end @@ -976,7 +972,7 @@ local function apply_to_list(list,size,head,pardir) if enddir then local d = new_textdir(enddir) local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end - -- setfield(d,"attr",getfield(current,"attr")) + -- setattrlist(d,current) head, current = insert_node_after(head,current,d) done = true end diff --git a/tex/context/base/mkiv/typo-fkr.lua b/tex/context/base/mkiv/typo-fkr.lua new file mode 100644 index 000000000..a1135d0f3 --- /dev/null +++ b/tex/context/base/mkiv/typo-fkr.lua @@ -0,0 +1,129 @@ +if not modules then modules = { } end modules ['typo-fkr'] = { + version = 1.001, + comment = "companion to typo-fkr.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local nuts = nodes.nuts +local tonut = nuts.tonut +local getid = nuts.getid +local getnext = nuts.getnext +local getchar = nuts.getchar +local getfont = nuts.getfont +local getattr = nuts.getattr + +local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph + +local fontdata = fonts.hashes.identifiers +local getkernpair = fonts.handlers.otf.getkern + +local insert_before = nuts.insert_before +local new_kern = nuts.pool.fontkern + +local enableaction = nodes.tasks.enableaction + +local a_extrakern = attributes.private("extrafontkern") + +-- 0=none 1=min 2=max 3=mixed + +typesetters.fontkerns = { } + +function typesetters.fontkerns.handler(head) + local kepthead = head + local head = tonut(head) + local current = head + local lastfont = nil + local lastchar = nil + local lastdata = nil + local done = false + while current do + local id = getid(current) + if id == glyph_code then + local a = getattr(current,a_extrakern) + if a then + local char = getchar(current) + local font = getfont(current) + if font ~= lastfont then + if a > 0 and lastchar then + if not lastdata then + lastdata = fontdata[lastfont] + end + local kern = nil + local data = fontdata[font] + local kern1 = getkernpair(lastdata,lastchar,char) + local kern2 = getkernpair(data,lastchar,char) + if a == 1 then + kern = kern1 > kern2 and kern2 or kern1 -- min + elseif a == 2 then + kern = kern1 > kern2 and kern1 or kern2 -- max + else -- 3 + kern = (kern1 + kern2)/2 -- mixed + end + if kern ~= 0 then + head, current = insert_before(head,current,new_kern(kern)) + done = true + end + lastdata = data + else + lastdata = nil + end + elseif lastchar then + if not lastdata then + lastdata = fontdata[lastfont] + end + local kern = getkernpair(lastdata,lastchar,char) + if kern ~= 0 then + head, current = insert_before(head,current,new_kern(kern)) + done = true + end + end + lastchar = char + lastfont = font + elseif lastfont then + lastfont = nil + lastchar = nil + lastdata = nil + end + elseif lastfont then + lastfont = nil + lastchar = nil + lastdata = nil + end + current = getnext(current) + end + return kepthead, done +end + +if context then + + local variables = interfaces.variables + local unsetvalue = attributes.unsetvalue + local enabled = false + local setattribute = tex.setattribute + + local values = { + [variables.none ] = 0, + [variables.min ] = 1, + [variables.max ] = 2, + [variables.mixed] = 3, + [variables.reset] = unsetvalue, + } + + local function setextrafontkerns(str) + if not enabled then + enableaction("processors","typesetters.fontkerns.handler") + enabled = true + end + setattribute(a_extrakern,values[str] or unsetvalue) + end + + interfaces.implement { + name = "setextrafontkerns", + arguments = "string", + actions = setextrafontkerns, + } + +end diff --git a/tex/context/base/mkiv/typo-fkr.mkiv b/tex/context/base/mkiv/typo-fkr.mkiv new file mode 100644 index 000000000..684d831bc --- /dev/null +++ b/tex/context/base/mkiv/typo-fkr.mkiv @@ -0,0 +1,38 @@ +%D \module +%D [ file=typo-fkr, +%D version=2016.10.10, +%D title=\CONTEXT\ Typesetting Macros, +%D subtitle=Additional Font Kerning, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Typesetting Macros / Additional Font Kerning} + +\registerctxluafile{typo-fkr}{1.001} + +\definesystemattribute[extrafontkern][public] + +\unprotect + +% none : not across fonts (but still within) +% min : min value across fonts +% max : max value across fonts +% mixed : mean value across fonts +% reset : disable + +\unexpanded\def\setextrafontkerns[#1]% + {\clf_setextrafontkerns{#1}} + +\unexpanded\def\resetextrafontkerns + {\attribute\extrafontkernattribute\attributeunsetvalue} + +\appendtoks + \resetextrafontkerns +\to \everyresettypesetting + +\protect diff --git a/tex/context/base/mkiv/typo-fln.lua b/tex/context/base/mkiv/typo-fln.lua index 1e1a2c44a..cef77cea1 100644 --- a/tex/context/base/mkiv/typo-fln.lua +++ b/tex/context/base/mkiv/typo-fln.lua @@ -21,7 +21,10 @@ typesetters.firstlines = typesetters.firstlines or { } local firstlines = typesetters.firstlines local nodes = nodes + local tasks = nodes.tasks +local enableaction = tasks.enableaction +local disableaction = tasks.disableaction local context = context local implement = interfaces.implement @@ -31,6 +34,9 @@ local tonut = nuts.tonut local tonode = nuts.tonode local getnext = nuts.getnext +local getprev = nuts.getprev +local getboth = nuts.getboth +local setboth = nuts.setboth local getid = nuts.getid local getfield = nuts.getfield local setfield = nuts.setfield @@ -39,6 +45,10 @@ local setlist = nuts.setlist local getattr = nuts.getattr local setattr = nuts.setattr local getbox = nuts.getbox +local getdisc = nuts.getdisc +local setdisc = nuts.setdisc +local setlink = nuts.setlink +local setfont = nuts.setfont local nodecodes = nodes.nodecodes local glyph_code = nodecodes.glyph @@ -46,13 +56,12 @@ local disc_code = nodecodes.disc local kern_code = nodecodes.kern local traverse_id = nuts.traverse_id -local free_node_list = nuts.flush_list -local free_node = nuts.flush_node +local flush_node_list = nuts.flush_list +local flush_node = nuts.flush_node local copy_node_list = nuts.copy_list local insert_node_after = nuts.insert_after -local insert_node_before = nuts.insert_before -local hpack_node_list = nuts.hpack local remove_node = nuts.remove +local list_dimensions = nuts.dimensions local nodepool = nuts.pool local newpenalty = nodepool.penalty @@ -65,7 +74,7 @@ firstlines.actions = actions local a_firstline = attributes.private('firstline') local a_color = attributes.private('color') local a_transparency = attributes.private('transparency') -local a_colorspace = attributes.private('colormodel') +local a_colormodel = attributes.private('colormodel') local texsetattribute = tex.setattribute local unsetvalue = attributes.unsetvalue @@ -82,7 +91,7 @@ local settings = nil function firstlines.set(specification) settings = specification or { } - tasks.enableaction("processors","typesetters.firstlines.handler") + enableaction("processors","typesetters.firstlines.handler") if trace_firstlines then report_firstlines("enabling firstlines") end @@ -120,12 +129,31 @@ actions[v_line] = function(head,setting) local n = 0 local temp = copy_node_list(head) local linebreaks = { } - for g in traverse_id(glyph_code,temp) do - if dynamic > 0 then - setattr(g,0,dynamic) + + local function set(head) + for g in traverse_id(glyph_code,head) do + if dynamic > 0 then + setattr(g,0,dynamic) + end + setfont(g,font) + end + end + + set(temp) + + for g in traverse_id(disc_code,temp) do + local pre, post, replace = getdisc(g) + if pre then + set(pre) + end + if post then + set(post) + end + if replace then + set(replace) end - setfield(g,"font",font) end + local start = temp local list = temp local prev = temp @@ -137,25 +165,37 @@ actions[v_line] = function(head,setting) if i <= - hangafter then hsize = hsize - hangindent end + + local function try(extra) + local width = list_dimensions(list,start) + if extra then + width = width + list_dimensions(extra) + end + if width > hsize then + list = prev + return true + else + linebreaks[i] = n + prev = start + nofchars = n + end + end + while start do local id = getid(start) if id == glyph_code then n = n + 1 elseif id == disc_code then -- this could be an option + n = n + 1 + if try(getfield(start,"pre")) then + break + end elseif id == kern_code then -- todo: fontkern -- this could be an option elseif n > 0 then - local pack = hpack_node_list(copy_node_list(list,start)) - if getfield(pack,"width") > hsize then - free_node_list(pack) - list = prev + if try() then break - else - linebreaks[i] = n - prev = start - free_node_list(pack) - nofchars = n end end start = getnext(start) @@ -166,23 +206,69 @@ actions[v_line] = function(head,setting) end local start = head local n = 0 + + local function update(start) + if dynamic > 0 then + setattr(start,0,dynamic) + end + setfont(start,font) + if ca and ca > 0 then + setattr(start,a_colormodel,ma == 0 and 1 or ma) + setattr(start,a_color,ca) + end + if ta and ta > 0 then + setattr(start,a_transparency,ta) + end + end + for i=1,noflines do local linebreak = linebreaks[i] while start and n < nofchars do local id = getid(start) - if id == glyph_code then -- or id == disc_code then - if dynamic > 0 then - setattr(start,0,dynamic) - end - setfield(start,"font",font) - if ca and ca > 0 then - setattr(start,a_colorspace,ma == 0 and 1 or ma) - setattr(start,a_color,ca) - end - if ta and ta > 0 then - setattr(start,a_transparency,ta) - end + if id == glyph_code then n = n + 1 + update(start) + elseif id == disc_code then + n = n + 1 + local disc = start + local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true) + if linebreak == n then + local p, n = getboth(start) + if pre then + for current in traverse_id(glyph_code,pre) do + update(current) + end + setlink(pretail,n) + setlink(p,pre) + start = pretail + pre = nil + else + setlink(p,n) + start = p + end + if post then + local p, n = getboth(start) + setlink(posttail,n) + setlink(start,post) + post = nil + end + else + local p, n = getboth(start) + if replace then + for current in traverse_id(glyph_code,replace) do + update(current) + end + setlink(replacetail,n) + setlink(p,replace) + start = replacetail + replace = nil + else + setlink(p,n) + start = p + end + end + setdisc(disc,pre,post,replace) + flush_node(disc) end if linebreak == n then if trace_firstlines then @@ -196,7 +282,7 @@ actions[v_line] = function(head,setting) start = getnext(start) end end - free_node_list(temp) + flush_node_list(temp) return head, true end @@ -220,7 +306,7 @@ actions[v_word] = function(head,setting) ok = true end if ca and ca > 0 then - setattr(start,a_colorspace,ma == 0 and 1 or ma) + setattr(start,a_colormodel,ma == 0 and 1 or ma) setattr(start,a_color,ca) end if ta and ta > 0 then @@ -229,7 +315,7 @@ actions[v_word] = function(head,setting) if dynamic > 0 then setattr(start,0,dynamic) end - setfield(start,"font",font) + setfont(start,font) elseif id == disc_code then -- continue elseif id == kern_code then -- todo: fontkern @@ -263,7 +349,7 @@ function firstlines.handler(head) end if attr then -- here as we can process nested boxes first so we need to keep state - tasks.disableaction("processors","typesetters.firstlines.handler") + disableaction("processors","typesetters.firstlines.handler") -- texsetattribute(attribute,unsetvalue) local alternative = settings.alternative or v_default local action = actions[alternative] or actions[v_default] diff --git a/tex/context/base/mkiv/typo-itc.lua b/tex/context/base/mkiv/typo-itc.lua index ea8103aad..312832d5b 100644 --- a/tex/context/base/mkiv/typo-itc.lua +++ b/tex/context/base/mkiv/typo-itc.lua @@ -6,9 +6,9 @@ if not modules then modules = { } end modules ['typo-itc'] = { license = "see context related readme files" } -local utfchar = utf.char local trace_italics = false trackers.register("typesetters.italics", function(v) trace_italics = v end) + local report_italics = logs.reporter("nodes","italics") local threshold = 0.5 trackers.register("typesetters.threshold", function(v) threshold = v == true and 0.5 or tonumber(v) end) @@ -23,7 +23,7 @@ local glue_code = nodecodes.glue local disc_code = nodecodes.disc local math_code = nodecodes.math -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction local nuts = nodes.nuts local nodepool = nuts.pool @@ -40,14 +40,18 @@ local getchar = nuts.getchar local getdisc = nuts.getdisc local getattr = nuts.getattr local setattr = nuts.setattr +local getattrlist = nuts.getattrlist +local setattrlist = nuts.setattrlist local setfield = nuts.setfield local setdisc = nuts.setdisc local isglyph = nuts.isglyph +local setkern = nuts.setkern +local getkern = nuts.getkern +local getheight = nuts.getheight local insert_node_after = nuts.insert_after local delete_node = nuts.delete local end_of_math = nuts.end_of_math -local find_tail = nuts.tail local texgetattribute = tex.getattribute local texsetattribute = tex.setattribute @@ -63,6 +67,7 @@ local fonthashes = fonts.hashes local fontdata = fonthashes.identifiers local italicsdata = fonthashes.italics local exheights = fonthashes.exheights +local chardata = fonthashes.characters local is_punctuation = characters.is_punctuation @@ -117,14 +122,14 @@ end -- todo: clear attribute local function okay(data,current,font,prevchar,previtalic,char,what) - if not data then + if data then if trace_italics then report_italics("ignoring %p between %s italic %C and italic %C",previtalic,what,prevchar,char) end return false end if threshold then - local ht = getfield(current,"height") + local ht = getheight(current) local ex = exheights[font] local th = threshold * ex if ht <= th then @@ -149,9 +154,9 @@ end local function correction_kern(kern,n) local k = new_correction_kern(kern) if n then - local a = getfield(n,"attr") + local a = getattrlist(n) if a then -- maybe not - setfield(k,"attr",a) -- can be a marked content (border case) + setattrlist(k,a) -- can be a marked content (border case) end end return k @@ -160,9 +165,9 @@ end local function correction_glue(glue,n) local g = new_correction_glue(glue) if n then - local a = getfield(n,"attr") + local a = getattrlist(n) if a then -- maybe not - setfield(g,"attr",a) -- can be a marked content (border case) + setattrlist(g,a) -- can be a marked content (border case) end end return g @@ -195,12 +200,37 @@ local function domath(head,current, done) else a = a + 100 end - if getfield(next,"height") < 1.25*ex then - if trace_italics then - report_italics("removing italic between math %C and punctuation %C",getchar(glyph),char) + local i = getkern(kern) + local f = getfont(glyph) + local c = getchar(glyph) + if getheight(next) < 1.25*exheights[f] then + if i == 0 then + if trace_italics then + report_italics("%s italic %p between math %C and punctuation %C","ignoring",i,c,char) + end + else + if trace_italics then + report_italics("%s italic between math %C and punctuation %C","removing",i,c,char) + end + setkern(kern,0) -- or maybe a small value or half the ic + done = true + end + elseif i == 0 then + local d = chardata[f][c] + local i = d.italic + if i == 0 then + if trace_italics then + report_italics("%s italic %p between math %C and punctuation %C","ignoring",i,c,char) + end + else + setkern(kern,i) + if trace_italics then + report_italics("%s italic %p between math %C and punctuation %C","setting",i,c,char) + end + done = true end - setfield(kern,"kern",0) -- or maybe a small value or half the ic - done = true + elseif trace_italics then + report_italics("%s italic %p between math %C and punctuation %C","keeping",k,c,char) end end end @@ -253,7 +283,7 @@ local function texthandler(head) local previnserted = nil local pre = nil - local pretail = nil + local pretail = nil local post = nil local posttail = nil @@ -568,7 +598,7 @@ function italics.handler(head) end enabletext = function() - tasks.enableaction("processors","typesetters.italics.handler") + enableaction("processors","typesetters.italics.handler") if trace_italics then report_italics("enabling text/text italics") end @@ -577,7 +607,7 @@ enabletext = function() end enablemath = function() - tasks.enableaction("processors","typesetters.italics.handler") + enableaction("processors","typesetters.italics.handler") if trace_italics then report_italics("enabling math/text italics") end diff --git a/tex/context/base/mkiv/typo-krn.lua b/tex/context/base/mkiv/typo-krn.lua index 7607fc5f5..24a91d6b6 100644 --- a/tex/context/base/mkiv/typo-krn.lua +++ b/tex/context/base/mkiv/typo-krn.lua @@ -10,12 +10,12 @@ if not modules then modules = { } end modules ['typo-krn'] = { -- components: better split on tounicode local next, type, tonumber = next, type, tonumber -local utfchar = utf.char local nodes = nodes local fonts = fonts -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction + local nuts = nodes.nuts local nodepool = nuts.pool @@ -25,27 +25,31 @@ local tonut = nuts.tonut -- check what is used local find_node_tail = nuts.tail -local free_node = nuts.free +local flush_node = nuts.flush_node local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after local end_of_math = nuts.end_of_math +local use_components = nuts.use_components local getfield = nuts.getfield local getnext = nuts.getnext local getprev = nuts.getprev -local getboth = nuts.getboth local getid = nuts.getid local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getchar = nuts.getchar local getdisc = nuts.getdisc +local getglue = nuts.getglue +local getkern = nuts.getkern local isglyph = nuts.isglyph local setfield = nuts.setfield local getattr = nuts.getattr -local setattr = nuts.setattr +local takeattr = nuts.takeattr local setlink = nuts.setlink -local setsubtype = nuts.setsubtype +local setdisc = nuts.setdisc +local setglue = nuts.setglue +local setkern = nuts.setkern local texsetattribute = tex.setattribute local unsetvalue = attributes.unsetvalue @@ -82,7 +86,6 @@ local spaceskip_code = skipcodes.spaceskip local xspaceskip_code = skipcodes.xspaceskip local fonthashes = fonts.hashes -local fontdata = fonthashes.identifiers local chardata = fonthashes.characters local quaddata = fonthashes.quads local markdata = fonthashes.marks @@ -104,11 +107,8 @@ typesetters.kerns = typesetters.kerns or { } local kerns = typesetters.kerns local report = logs.reporter("kerns") -local trace_ligatures = false trackers.register("typesetters.kerns.ligatures",function(v) trace_ligatures = v end) - --- use_advance is just an experiment: it makes copying glyphs (instead of new_glyph) dangerous - -local use_advance = false directives.register("typesetters.kerns.advance", function(v) use_advance = v end) +local trace_ligatures = false trackers.register("typesetters.kerns.ligatures", function(v) trace_ligatures = v end) +local trace_ligatures_d = false trackers.register("typesetters.kerns.ligatures.detail",function(v) trace_ligatures_d = v end) kerns.mapping = kerns.mapping or { } kerns.factors = kerns.factors or { } @@ -146,18 +146,24 @@ function kerns.keepligature(n) -- might become default local c = getchar(n) local d = fontdescriptions[f][c].name if a > 0 and contextsetups[a].keepligatures == v_auto then - report("font %!font:name!, glyph %a, slot %X -> ligature %s, by %s feature %a",f,d,c,"kept","dynamic","keepligatures") + if trace_ligatures_d then + report("font %!font:name!, glyph %a, slot %X -> ligature %s, by %s feature %a",f,d,c,"kept","dynamic","keepligatures") + end setcolor(n,"darkred") return true end local k = fontfeatures[f].keepligatures if k == v_auto then - report("font %!font:name!, glyph %a, slot %X -> ligature %s, by %s feature %a",f,d,c,"kept","static","keepligatures") + if trace_ligatures_d then + report("font %!font:name!, glyph %a, slot %X -> ligature %s, by %s feature %a",f,d,c,"kept","static","keepligatures") + end setcolor(n,"darkgreen") return true end if not k then - report("font %!font:name!, glyph %a, slot %X -> ligature %s, by %s feature %a",f,d,c,"split","static","keepligatures") + if trace_ligatures_d then + report("font %!font:name!, glyph %a, slot %X -> ligature %s, by %s feature %a",f,d,c,"split","static","keepligatures") + end resetcolor(n) return false end @@ -227,8 +233,7 @@ local function inject_begin(boundary,prev,keeptogether,krn,ok) -- prev is a glyp end if inject then -- not yet ok, as injected kerns can be overlays (from node-inj.lua) - setsubtype(boundary,userkern_code) - setfield(boundary,"kern",getfield(boundary,"kern") + quaddata[getfont(prev)]*krn) + setkern(boundary,getkern(boundary) + quaddata[getfont(prev)]*krn,userkern_code) return boundary, true end end @@ -264,8 +269,7 @@ local function inject_end(boundary,next,keeptogether,krn,ok) end if inject then -- not yet ok, as injected kerns can be overlays (from node-inj.lua) - setsubtype(tail,userkern_code) - setfield(tail,"kern",getfield(tail,"kern") + quaddata[getfont(next)]*krn) + setkern(tail,getkern(tail) + quaddata[getfont(next)]*krn,userkern_code) return boundary, true end end @@ -279,7 +283,7 @@ local function inject_end(boundary,next,keeptogether,krn,ok) local data = chardata[font][nextchar] local kerns = data and data.kerns local kern = (kerns and kerns[char] or 0) + quaddata[font]*krn - insert_node_after(boundary,tail,new_kern(kern)) + setlink(tail,new_kern(kern)) return boundary, true end end @@ -315,8 +319,7 @@ local function process_list(head,keeptogether,krn,font,okay) end if inject then -- not yet ok, as injected kerns can be overlays (from node-inj.lua) - setsubtype(prev,userkern_code) - setfield(prev,"kern",getfield(prev,"kern") + kern) + setkern(prev,getkern(prev) + kern,userkern_code) okay = true end end @@ -378,9 +381,8 @@ function kerns.handler(head) -- fontkerns don't get the attribute but they always sit between glyphs so -- are always valid bound .. disc nodes also somtimes don't get them local id = getid(start) - local attr = getattr(start,a_kerns) + local attr = takeattr(start,a_kerns) if attr and attr > 0 then - setattr(start,a_kerns,0) -- unsetvalue) local krn = mapping[attr] if krn == v_max then krn = .25 @@ -390,31 +392,13 @@ function kerns.handler(head) end if not krn or krn == 0 then bound = false - elseif id == glyph_code then -- we could use the subtype ligature - local c = getfield(start,"components") - if not c then - -- fine - elseif keepligature and keepligature(start) then + elseif id == glyph_code then + if keepligature and keepligature(start) then -- keep 'm - c = nil else - while c do - local s = start - local t = find_node_tail(c) - local p, n = getboth(s) - if p then - setlink(p,c) - else - head = c - end - if n then - setlink(t,n) - end - start = c - setfield(s,"components",nil) - free_node(s) - c = getfield(start,"components") - end + -- we could use the subtype ligature but that's also a call + -- todo: check tounicode and use that information to split + head, start = use_components(head,start) end local char = getchar(start) local font = getfont(start) @@ -433,8 +417,7 @@ function kerns.handler(head) end if inject then -- not yet ok, as injected kerns can be overlays (from node-inj.lua) - setsubtype(prev,userkern_code) - setfield(prev,"kern",getfield(prev,"kern") + quaddata[font]*krn) + setkern(prev,getkern(prev) + quaddata[font]*krn,userkern_code) done = true end end @@ -446,11 +429,7 @@ function kerns.handler(head) local data = chardata[font][prevchar] local kerns = data and data.kerns local kern = (kerns and kerns[char] or 0) + quaddata[font]*krn - if not fillup and use_advance then - setfield(prev,"xadvance",getfield(prev,"xadvance") + kern) - else - insert_node_before(head,start,kern_injector(fillup,kern)) - end + insert_node_before(head,start,kern_injector(fillup,kern)) done = true end else @@ -480,12 +459,7 @@ function kerns.handler(head) languages.expand(start,pglyph and prev) end local pre, post, replace = getdisc(start) - -- we really need to reasign the fields as luatex keeps track of - -- the tail in a temp preceding head .. kind of messy so we might - -- want to come up with a better solution some day like a real - -- pretail etc fields in a disc node - -- - -- maybe i'll merge the now split functions + local indeed = false if pre then local okay = false if not prev then @@ -497,8 +471,7 @@ function kerns.handler(head) end pre, okay = process_list(pre,keeptogether,krn,false,okay) if okay then - setfield(start,"pre",pre) - done = true + indeed = true end end if post then @@ -512,8 +485,7 @@ function kerns.handler(head) end post, okay = process_list(post,keeptogether,krn,false,okay) if okay then - setfield(start,"post",post) - done = true + indeed = true end end if replace then @@ -534,11 +506,14 @@ function kerns.handler(head) end replace, okay = process_list(replace,keeptogether,krn,false,okay) if okay then - setfield(start,"replace",replace) - done = true + indeed = true end elseif prevfont then - setfield(start,"replace",new_kern(quaddata[prevfont]*krn)) + replace = new_kern(quaddata[prevfont]*krn) + indeed = true + end + if indeed then + setdisc(start,pre,post,replace) done = true end bound = false @@ -549,21 +524,18 @@ function kerns.handler(head) elseif id == glue_code then local subtype = getsubtype(start) if subtype == userskip_code or subtype == xspaceskip_code or subtype == spaceskip_code then - local w = getfield(start,"width") - if w > 0 then - local width = w + gluefactor * w * krn - local stretch = getfield(start,"stretch") * width / w - local shrink = getfield(start,"shrink") * width / w + local width, stretch, shrink, stretch_order, shrink_order = getglue(start) + if width > 0 then + local w = width + gluefactor * width * krn + stretch = stretch * w / width + shrink = shrink * w / width if fillup then stretch = 2 * stretch shrink = 2 * shrink - setfield(start,"stretch_order",1) - -- shrink_order ? + stretch_order = 1 + -- shrink_order = 1 ? end - setfield(start,"width",width) - setfield(start,"stretch",stretch) - setfield(start,"shrink", shrink) - -- + setglue(start,w,stretch,shrink,stretch_order,shrink_order) done = true end end @@ -612,7 +584,7 @@ function kerns.set(factor) end if factor == v_max or factor ~= 0 then if not enabled then - tasks.enableaction("processors","typesetters.kerns.handler") + enableaction("processors","typesetters.kerns.handler") enabled = true end local a = factors[factor] diff --git a/tex/context/base/mkiv/typo-lin.lua b/tex/context/base/mkiv/typo-lin.lua index a74a635f6..d702bcb8c 100644 --- a/tex/context/base/mkiv/typo-lin.lua +++ b/tex/context/base/mkiv/typo-lin.lua @@ -65,7 +65,7 @@ local hlist_code = nodecodes.hlist local glue_code = nodecodes.glue local kern_code = nodecodes.kern local line_code = listcodes.line -local localpar_code = nodecodes.localpar +----- localpar_code = nodecodes.localpar local leftskip_code = gluecodes.leftskip local rightskip_code = gluecodes.rightskip local parfillskip_code = gluecodes.parfillskip @@ -77,6 +77,7 @@ local traverse_id = nuts.traverse_id local insert_before = nuts.insert_before local insert_after = nuts.insert_after local find_tail = nuts.tail +local rehpack = nuts.rehpack ----- remove_node = nuts.remove local getsubtype = nuts.getsubtype @@ -88,6 +89,14 @@ local getprev = nuts.getprev local getboth = nuts.getboth local getfield = nuts.getfield local setfield = nuts.setfield +local setlink = nuts.setlink +local setkern = nuts.setkern +local getkern = nuts.getkern +local getdir = nuts.getdir +local getshift = nuts.getshift +local setshift = nuts.setshift +local getwidth = nuts.getwidth +local setwidth = nuts.setwidth local setprop = nuts.setprop local getprop = nuts.rawprop -- getprop @@ -95,16 +104,15 @@ local getprop = nuts.rawprop -- getprop local effectiveglue = nuts.effective_glue local nodepool = nuts.pool -local new_glue = nodepool.glue local new_kern = nodepool.kern local new_leftskip = nodepool.leftskip local new_rightskip = nodepool.rightskip local new_hlist = nodepool.hlist -local new_vlist = nodepool.vlist local new_rule = nodepool.rule -local new_latelua = nodepool.latelua +local new_glue = nodepool.glue local texgetcount = tex.getcount +local texgetglue = tex.getglue local setmetatableindex = table.setmetatableindex local formatters = string.formatters @@ -135,8 +143,8 @@ local function finalize(prop,key) -- delayed calculations local line = prop.line local hsize = prop.hsize local width = prop.width - local shift = getfield(line,"shift") -- dangerous as it can be vertical as well - local reverse = getfield(line,"dir") == "TRT" or false + local shift = getshift(line) -- dangerous as it can be vertical as well + local reverse = getdir(line) == "TRT" or false local pack = new_hlist() local head = getlist(line) local delta = 0 @@ -168,7 +176,7 @@ local function normalize(line,islocal) -- assumes prestine lines, nothing pre/ap local head = oldhead local leftskip = nil local rightskip = nil - local width = getfield(line,"width") + local width = getwidth(line) local hsize = islocal and width or tex.hsize local lskip = 0 local rskip = 0 @@ -179,7 +187,7 @@ local function normalize(line,islocal) -- assumes prestine lines, nothing pre/ap local subtype = getsubtype(head) if subtype == leftskip_code then leftskip = head - lskip = getfield(head,"width") or 0 + lskip = getwidth(head) or 0 end current = getnext(head) id = getid(current) @@ -194,7 +202,7 @@ local function normalize(line,islocal) -- assumes prestine lines, nothing pre/ap if id == glue_code then if getsubtype(current) == rightskip_code then rightskip = tail - rskip = getfield(current,"width") or 0 + rskip = getwidth(current) or 0 current = getprev(tail) id = getid(current) end @@ -241,9 +249,47 @@ function paragraphs.normalize(head,islocal) -- can be an option, maybe we need a proper state in lua itself ... is this check still needed? return head, false end + -- this can become a separate handler but it makes sense to integrate it here + local l_width, l_stretch, l_shrink = texgetglue("parfillleftskip") + if l_width ~= 0 or l_stretch ~= 0 or l_shrink ~= 0 then + local last = nil -- a nut + local done = false + for line in traverse_id(hlist_code,tonut(head)) do + if getsubtype(line) == line_code and not getprop(line,"line") then + if done then + last = line + else + done = true + end + end + end + if last then -- only if we have more than one line + local head = getlist(last) + local current = head + if current then + if getid(current) == glue_code and getsubtype(current,leftskip_code) then + current = getnext(current) + end + if current then + head, current = insert_before(head,current,new_glue(l_width,l_stretch,l_shrink)) + if head == current then + setlist(last,head) + end + -- can be a 'rehpack(h )' + rehpack(last) + end + end + end + end + -- normalizer for line in traverse_id(hlist_code,tonut(head)) do if getsubtype(line) == line_code and not getprop(line,"line") then normalize(line) + if done then + last = line + else + done = true + end end end return head, true @@ -317,12 +363,14 @@ local function addanchortoline(n,anchor) local anchor = tonut(anchor) local where = line.where if trace_anchors then - local rule1 = new_rule(65536/2,4*65536,4*65536) - local rule2 = new_rule(8*65536,65536/4,65536/4) - local kern1 = new_kern(-65536/4) - local kern2 = new_kern(-65536/4-4*65536) - anchor = new_hlist(nuts.link { anchor, kern1, rule1, kern2, rule2 }) - setfield(anchor,"width",0) + anchor = new_hlist(setlink( + anchor, + new_kern(-65536/4), + new_rule(65536/2,4*65536,4*65536), + new_kern(-65536/4-4*65536), + new_rule(8*65536,65536/4,65536/4) + )) + setwidth(anchor,0) end if where.tail then local head = where.head @@ -355,15 +403,15 @@ function paragraphs.moveinline(n,blob,dx,dy) if dx ~= 0 then local prev, next = getboth(blob) if prev and getid(prev) == kern_code then - setfield(prev,"kern",getfield(prev,"kern") + dx) + setkern(prev,getkern(prev) + dx) end if next and getid(next) == kern_code then - setfield(next,"kern",getfield(next,"kern") - dx) + setkern(next,getkern(next) - dx) end end if dy ~= 0 then if getid(blob) == hlist_code then - setfield(blob,"shift",getfield(blob,"shift") + dy) + setshift(blob,getshift(blob) + dy) end end else @@ -372,13 +420,6 @@ function paragraphs.moveinline(n,blob,dx,dy) end end --- local f_anchor = formatters["_plib_.set('md:h',%i,{x=true,c=true})"] --- local s_anchor = 'md:h' --- --- local function setanchor(h_anchor) --- return new_latelua(f_anchor(h_anchor)) --- end - local lateluafunction = nodepool.lateluafunction local setposition = job.positions.set local t_anchor = { x = true, c = true } diff --git a/tex/context/base/mkiv/typo-mar.lua b/tex/context/base/mkiv/typo-mar.lua index 727846678..a5d607cd7 100644 --- a/tex/context/base/mkiv/typo-mar.lua +++ b/tex/context/base/mkiv/typo-mar.lua @@ -9,70 +9,8 @@ if not modules then modules = { } end modules ['typo-mar'] = { -- todo: -- -- * autoleft/right depending on available space (or distance to margin) --- * stack across paragraphs, but that is messy and one should reconsider --- using margin data then as also vertical spacing kicks in -- * floating margin data, with close-to-call anchoring --- -- experiment (does not work, too much interference) --- --- local pdfprint = pdf.print --- local format = string.format --- --- anchors = anchors or { } --- --- local whatever = { } --- local factor = (7200/7227)/65536 --- --- function anchors.set(tag) --- whatever[tag] = { pdf.h, pdf.v } --- end --- --- function anchors.reset(tag) --- whatever[tag] = nil --- end --- --- function anchors.startmove(tag,how) -- save/restore nodes but they don't support moves --- local w = whatever[tag] --- if not w then --- -- error --- elseif how == "horizontal" or how == "h" then --- pdfprint("page",format(" q 1 0 0 1 %f 0 cm ", (w[1] - pdf.h) * factor)) --- elseif how == "vertical" or how == "v" then --- pdfprint("page",format(" q 1 0 0 1 0 %f cm ", (w[2] - pdf.v) * factor)) --- else --- pdfprint("page",format(" q 1 0 0 1 %f %f cm ", (w[1] - pdf.h) * factor, (w[2] - pdf.v) * factor)) --- end --- end --- --- function anchors.stopmove(tag) --- local w = whatever[tag] --- if not w then --- -- error --- else --- pdfprint("page"," Q ") --- end --- end --- --- local latelua = nodes.pool.latelua --- --- function anchors.node_set(tag) --- return latelua(formatters["anchors.set(%q)"](tag)) --- end --- --- function anchors.node_reset(tag) --- return latelua(formatters["anchors.reset(%q)"](tag)) --- end --- --- function anchors.node_start_move(tag,how) --- return latelua(formatters["anchors.startmove(%q,%q)](tag,how)) --- end --- --- function anchors.node_stop_move(tag) --- return latelua(formatters["anchors.stopmove(%q)"](tag)) --- end - --- so far - local format, validstring = string.format, string.valid local insert, remove, sortedkeys, fastcopy = table.insert, table.remove, table.sortedkeys, table.fastcopy local setmetatable, next = setmetatable, next @@ -104,8 +42,6 @@ local v_local = variables["local"] local v_global = variables["global"] local v_left = variables.left local v_right = variables.right -local v_flushleft = variables.flushleft -local v_flushright = variables.flushright local v_inner = variables.inner local v_outer = variables.outer local v_margin = variables.margin @@ -117,9 +53,7 @@ local v_continue = variables.continue local v_first = variables.first local v_text = variables.text local v_paragraph = variables.paragraph -local v_column = variables.column local v_line = variables.line -local v_hanging = variables.hanging local nuts = nodes.nuts local nodepool = nuts.pool @@ -127,13 +61,9 @@ local nodepool = nuts.pool local tonode = nuts.tonode local tonut = nuts.tonut -local copy_node_list = nuts.copy_list local hpack_nodes = nuts.hpack local traverse_id = nuts.traverse_id -local free_node_list = nuts.flush_list -local insert_node_after = nuts.insert_after -local insert_node_before = nuts.insert_before -local linked_nodes = nuts.linked +local flush_node_list = nuts.flush_list local getfield = nuts.getfield local setfield = nuts.setfield @@ -143,9 +73,18 @@ local getid = nuts.getid local getattr = nuts.getattr local setattr = nuts.setattr local getsubtype = nuts.getsubtype -local getbox = nuts.getbox local getlist = nuts.getlist +local getwhd = nuts.getwhd local setlist = nuts.setlist +local setlink = nuts.setlink +local getshift = nuts.getshift +local setshift = nuts.setshift +local getwidth = nuts.getwidth +local setwidth = nuts.setwidth +local getheight = nuts.getheight + +local getbox = nuts.getbox +local takebox = nuts.takebox local setprop = nuts.setprop local getprop = nuts.getprop @@ -157,25 +96,18 @@ local whatsitcodes = nodes.whatsitcodes local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist -local glue_code = nodecodes.glue -local kern_code = nodecodes.kern -local penalty_code = nodecodes.penalty local whatsit_code = nodecodes.whatsit -local line_code = listcodes.line -local cell_code = listcodes.cell -local alignment_code = listcodes.alignment local userdefined_code = whatsitcodes.userdefined local nodepool = nuts.pool -local new_kern = nodepool.kern local new_usernumber = nodepool.usernumber -local new_latelua = nodepool.latelua +local new_hlist = nodepool.hlist local lateluafunction = nodepool.lateluafunction -local texgetcount = tex.getcount local texgetdimen = tex.getdimen +local texgetcount = tex.getcount local texget = tex.get local isleftpage = layouts.status.isleftpage @@ -186,7 +118,6 @@ local addtoline = paragraphs.addtoline local moveinline = paragraphs.moveinline local calculatedelta = paragraphs.calculatedelta ------ a_specialcontent = attributes.private("specialcontent") local a_linenumber = attributes.private('linenumber') local inline_mark = nodepool.userids["margins.inline"] @@ -207,6 +138,7 @@ local nofsaved = 0 local nofstored = 0 local nofinlined = 0 local nofdelayed = 0 +local nofinjected = 0 local h_anchors = 0 local v_anchors = 0 @@ -269,8 +201,7 @@ end function margins.save(t) setmetatable(t,defaults) - local content = getbox(t.number) - -- setattr(content,a_specialcontent,1) + local content = takebox(t.number) setprop(content,"specialcontent","margindata") local location = t.location local category = t.category @@ -316,12 +247,13 @@ function margins.save(t) showstore(store,"before",location) end if name and name ~= "" then + -- this can be used to overload if inlinestore then -- todo: inline store has to be done differently (not sparse) local t = sortedkeys(store) for j=#t,1,-1 do local i = t[j] local si = store[i] if si.name == name then local s = remove(store,i) - free_node_list(s.box) + flush_node_list(s.box) end end else @@ -329,7 +261,7 @@ function margins.save(t) local si = store[i] if si.name == name then local s = remove(store,i) - free_node_list(s.box) + flush_node_list(s.box) end end end @@ -341,16 +273,17 @@ function margins.save(t) local leftmargindistance = texgetdimen("naturalleftmargindistance") local rightmargindistance = texgetdimen("naturalrightmargindistance") local strutbox = getbox("strutbox") + local _, strutht, strutdp = getwhd(strutbox) -- better make a new table and make t entry in t - t.box = copy_node_list(content) + t.box = content t.n = nofsaved -- used later (we will clean up this natural mess later) -- nice is to make a special status table mechanism - t.strutdepth = getfield(strutbox,"depth") - t.strutheight = getfield(strutbox,"height") - -- beware: can be different from the applied one - t.leftskip = getfield(texget("leftskip"),"width") -- we're not in forgetall - t.rightskip = getfield(texget("rightskip"),"width") -- we're not in forgetall + t.strutheight = strutht + t.strutdepth = strutdp + -- beware: can be different from the applied one (we're not in forgetall) + t.leftskip = texget("leftskip",false) + t.rightskip = texget("rightskip",false) -- t.leftmargindistance = leftmargindistance -- todo:layoutstatus table t.rightmargindistance = rightmargindistance @@ -387,19 +320,6 @@ end -- When the prototype inner/outer code that was part of this proved to be -- okay it was moved elsewhere. --- local f_anchor = formatters["_plib_.set('md:h',%i,{x=true,c=true})"] --- local s_anchor = 'md:h' --- --- local function setanchor(h_anchor) --- return new_latelua(f_anchor(h_anchor)) --- end - --- local t_anchor = { x = true, c = true } --- --- local function setanchor(h_anchor) --- return lateluafunction(function() setposition("md:h",h_anchor,t_anchor) end) --- end - local function realign(current,candidate) local location = candidate.location local margin = candidate.margin @@ -417,7 +337,7 @@ local function realign(current,candidate) local atleft = true local hmove = 0 local delta = 0 - local leftpage = isleftpage(false,true) + local leftpage = isleftpage() local leftdelta = 0 local rightdelta = 0 local leftdistance = distance @@ -451,6 +371,8 @@ local function realign(current,candidate) if not leftpage then atleft = false end + else + -- v_left end local islocal = scope == v_local @@ -502,20 +424,23 @@ end -- table gets saved when the v_continue case is active. We use a special variant -- of position tracking, after all we only need the page number and vertical position. -local stacked = { } -- left/right keys depending on location +local validstacknames = { + [v_left ] = v_left , + [v_right] = v_right, + [v_inner] = v_inner, + [v_outer] = v_outer, +} + local cache = { } -local anchors = { } - -local function resetstacked(location) - if location then - local s = { } - stacked[location] = s - anchors[location] = false - return s - else - stacked = { } - anchors = { } - return stacked +local stacked = { [v_yes] = { }, [v_continue] = { } } +local anchors = { [v_yes] = { }, [v_continue] = { } } + +local function resetstacked(all) + stacked[v_yes] = { } + anchors[v_yes] = { } + if all then + stacked[v_continue] = { } + anchors[v_continue] = { } end end @@ -523,103 +448,65 @@ end local function sa(tag) -- maybe l/r keys ipv left/right keys local p = cache[tag] - if trace_marginstack then - report_margindata("updating anchor %a",tag) + if p then + if trace_marginstack then + report_margindata("updating anchor %a",tag) + end + p.p = true + p.y = true + setposition('md:v',tag,p) + cache[tag] = nil -- do this later, per page a cleanup end - p.p = true - p.y = true --- p.a = tag - setposition('md:v',tag,p) - cache[tag] = nil end local function setanchor(v_anchor) -- freezes the global here return lateluafunction(function() sa(v_anchor) end) end +local function aa(tag,n) -- maybe l/r keys ipv left/right keys + local p = jobpositions.gettobesaved('md:v',tag) + if p then + if trace_marginstack then + report_margindata("updating injected %a",tag) + end + local pages = p.pages + if not pages then + pages = { } + p.pages = pages + end + pages[n] = texgetcount("realpageno") + elseif trace_marginstack then + report_margindata("not updating injected %a",tag) + end +end + +local function addtoanchor(v_anchor,n) -- freezes the global here + return lateluafunction(function() aa(v_anchor,n) end) +end + local function markovershoot(current) -- todo: alleen als offset > line v_anchors = v_anchors + 1 cache[v_anchors] = fastcopy(stacked) --- cache[v_anchors] = stacked -- so we adapt the previous too local anchor = setanchor(v_anchors) - -- local list = hpack_nodes(linked_nodes(anchor,getlist(current))) -- not ok, we need to retain width - local list = hpack_nodes(linked_nodes(anchor,getlist(current)),getfield(current,"width"),"exactly")-- - -- why not: - -- local list = linked_nodes(anchor,getlist(current)) + -- local list = hpack_nodes(setlink(anchor,getlist(current))) -- not ok, we need to retain width + -- local list = setlink(anchor,getlist(current)) -- why not this ... better play safe + local list = hpack_nodes(setlink(anchor,getlist(current)),getwidth(current),"exactly")-- if trace_marginstack then report_margindata("marking anchor %a",v_anchors) end setlist(current,list) end --- local function getovershoot(location) --- local p = getposition("md:v",v_anchors) --- local c = getposition("md:v",v_anchors+1) --- if p and c and p.p and p.p == c.p then --- local distance = p.y - c.y --- local offset = p[location] or 0 --- local overshoot = offset - distance --- if trace_marginstack then --- report_margindata("location %a, anchor %a, distance %p, offset %p, overshoot %p",location,v_anchors,distance,offset,overshoot) --- end --- if overshoot > 0 then --- return overshoot, offset, distance --- else --- return 0, offset, distance --- end --- elseif trace_marginstack then --- report_margindata("location %a, anchor %a, nothing to correct",location,v_anchors) --- end --- return 0, 0, 0 --- end - -local function getovershoot(location) - local c = getposition("md:v",v_anchors+1) - if c then - local p = false - local cp = c.p - for i=v_anchors,1,-1 do - local pi = getposition("md:v",i) - if pi.p == cp then - p = pi - else - break - end - end - if p then - local distance = p.y - c.y - local offset = p[location] or 0 - local overshoot = offset - distance - if trace_marginstack then - report_margindata("location %a, anchor %a, distance %p, offset %p, overshoot %p",location,v_anchors,distance,offset,overshoot) - end - if overshoot > 0 then - return overshoot, offset, distance - else - return 0, offset, distance - end - end - end - if trace_marginstack then - report_margindata("location %a, anchor %a, nothing to correct",location,v_anchors) - end - return 0, 0, 0 -end - -local function getanchor(location,anchor) - return getposition("md:v",anchor) -end - local function inject(parent,head,candidate) local box = candidate.box if not box then return head, nil, false -- we can have empty texts end - local width = getfield(box,"width") - local height = getfield(box,"height") - local depth = getfield(box,"depth") - local shift = getfield(box,"shift") + local width, height, depth + = getwhd(box) + local shift = getshift(box) local stack = candidate.stack + local stackname = candidate.stackname local location = candidate.location local method = candidate.method local voffset = candidate.voffset @@ -629,8 +516,18 @@ local function inject(parent,head,candidate) local strutdepth = candidate.strutdepth local inline = candidate.inline local psubtype = getsubtype(parent) - local offset = stacked[location] + -- This stackname is experimental and therefore undocumented and basically + -- unsupported. It was introduced when we needed to support overlapping + -- of different anchors. + if not stackname or stackname == "" then + stackname = location + else + stackname = validstacknames[stackname] or location + end + local isstacked = stack == v_continue or stack == v_yes + local offset = isstacked and stacked[stack][stackname] local firstonstack = offset == false or offset == nil + nofinjected = nofinjected + 1 nofdelayed = nofdelayed + 1 -- yet untested baseline = tonumber(baseline) @@ -647,63 +544,81 @@ local function inject(parent,head,candidate) baseline = false -- strutheight -- actually a hack end end - candidate.width = width - candidate.hsize = getfield(parent,"width") -- we can also pass textwidth - candidate.psubtype = psubtype + candidate.width = width + candidate.hsize = getwidth(parent) -- we can also pass textwidth + candidate.psubtype = psubtype + candidate.stackname = stackname if trace_margindata then report_margindata("processing, index %s, height %p, depth %p, parent %a, method %a",candidate.n,height,depth,listcodes[psubtype],method) end - -- The next section handles the inline notes that are checked for overlap which - -- is somewhat tricky as that mechanism is mostly for paragraph boundnotes. - local stackedinline = inline and (stack == v_yes or stack == v_continue) - if stackedinline then + -- Overlap detection is somewhat complex because we have display and inline + -- notes mixed as well as inner and outer positioning. We do need to + -- handle it in the stream because we also keep lines together so we keep + -- track of page numbers of notes. + + if isstacked then firstonstack = true - if anchors[location] then - local a1 = getanchor(location,anchors[location]) - local a2 = getanchor(location,v_anchors+1) - if a1 and a2 then - local distance = a1.y - a2.y - if distance > offset then - -- report_margindata("location %s, no overlap, case 1",location) - elseif offset > 0 then - offset = offset - distance - firstonstack = false - -- report_margindata("location %s, overlap %a",location,offset) - -- else - -- report_margindata("location %s, no overlap, case 2",location) + local anchor = getposition("md:v") + if anchor and (location == v_inner or location == v_outer) then + local pages = anchor.pages + if pages then + local page = pages[nofinjected] + if page then + if isleftpage(page) then + stackname = location == v_inner and v_right or v_left + else + stackname = location == v_inner and v_left or v_right + end + candidate.stackname = stackname + offset = stack and stack ~= "" and stacked[stack][stackname] end - -- else - -- report_margindata("location %s, no overlap, case 3",location) end - -- else - -- report_margindata("location %s, no overlap, case 4",location) end - anchors[location] = v_anchors + 1 - end - -- end of special section - if firstonstack then - offset = 0 - else - -- offset = offset + height - end - if stack == v_yes then + local current = v_anchors + 1 + local previous = anchors[stack][stackname] + if trace_margindata then + report_margindata("anchor %i, offset so far %p",current,offset or 0) + end + local ap = anchor and anchor[previous] + local ac = anchor and anchor[current] + if not previous then + elseif previous == current then + firstonstack = false + elseif ap and ac and ap.p == ac.p then + local distance = ap.y - ac.y + if trace_margindata then + report_margindata("distance %p",distance) + end + if offset > distance then + -- we already overflow + offset = offset - distance + firstonstack = false + else + offset = 0 + end + else + -- what to do + end + anchors[v_yes] [stackname] = current + anchors[v_continue][stackname] = current + if firstonstack then + offset = 0 + end offset = offset + candidate.dy -- always shift = shift + offset - elseif stack == v_continue then - offset = offset + candidate.dy -- always + else if firstonstack then - offset = offset + getovershoot(location) + offset = 0 end - shift = shift + offset + offset = offset + candidate.dy -- always + shift = shift + offset end - -- -- -- -- Maybe we also need to patch offset when we apply methods, but how ... -- This needs a bit of playing as it depends on the stack setting of the -- following which we don't know yet ... so, consider stacking partially -- experimental. - -- -- -- if method == v_top then - local delta = height - getfield(parent,"height") + local delta = height - getheight(parent) if trace_margindata then report_margindata("top aligned by %p",delta) end @@ -711,8 +626,9 @@ local function inject(parent,head,candidate) shift = shift + voffset + delta end elseif method == v_line then - if getfield(parent,"depth") == 0 then - local delta = height - getfield(parent,"height") + local _, ph, pd = getwhd(parent) + if pd == 0 then + local delta = height - ph if trace_margindata then report_margindata("top aligned by %p (no depth)",delta) end @@ -756,14 +672,20 @@ local function inject(parent,head,candidate) shift = shift + delta offset = offset + delta end - setfield(box,"shift",shift) - setfield(box,"width",0) + setshift(box,shift) + setwidth(box,0) -- not needed when wrapped + -- + if isstacked then + setlink(box,addtoanchor(v_anchor,nofinjected)) + box = new_hlist(box) + -- set height / depth ? + end -- candidate.hook, candidate.node = addtoline(parent,box) -- setprop(box,"margindata",candidate) if trace_margindata then - report_margindata("injected, location %a, shift %p",location,shift) + report_margindata("injected, location %a, stack %a, shift %p",location,stackname,shift) end -- we need to add line etc to offset as well offset = offset + depth @@ -772,16 +694,17 @@ local function inject(parent,head,candidate) depth = offset, slack = candidate.bottomspace, -- todo: 'depth' => strutdepth lineheight = candidate.lineheight, -- only for tracing - stacked = stackedinline, + stacked = inline and isstacked, } offset = offset + height -- we need a restart ... when there is no overlap at all - stacked[location] = offset + stacked[v_yes] [stackname] = offset + stacked[v_continue][stackname] = offset -- todo: if no real depth then zero if trace_margindata then report_margindata("status, offset %s",offset) end - return getlist(parent), room, stackedinline or (stack == v_continue) + return getlist(parent), room, inline and isstacked or (stack == v_continue) end local function flushinline(parent,head) @@ -863,7 +786,7 @@ local function flushed(scope,parent) -- current is hlist if done then local a = getattr(head,a_linenumber) -- hack .. we need a more decent critical attribute inheritance mechanism if false then - local l = hpack_nodes(head,getfield(parent,"width"),"exactly") + local l = hpack_nodes(head,getwidth(parent),"exactly") setlist(parent,l) if a then setattr(l,a_linenumber,a) @@ -875,7 +798,6 @@ local function flushed(scope,parent) -- current is hlist setattr(parent,a_linenumber,a) end end - -- resetstacked() end return done, continue end @@ -915,9 +837,7 @@ local function handler(scope,head,group) report_margindata("flushing stage one, nothing done, %s left",nofstored) end end - -- if done then - resetstacked() -- why doesn't done work ok here? - -- end +resetstacked() return tonode(head), done else return head, false @@ -926,6 +846,9 @@ end local trialtypesetting = context.trialtypesetting +-- maybe change this to an action applied to the to be shipped out box (that is +-- the mvl list in there so that we don't need to traverse global + function margins.localhandler(head,group) -- sometimes group is "" which is weird if trialtypesetting() then @@ -986,7 +909,6 @@ local function finalhandler(head) local id = getid(current) if id == hlist_code then -- only lines? local a = getprop(current,"margindata") --- if not a or a == 0 then if not a then finalhandler(getlist(current)) elseif realigned(current,a) then @@ -1013,9 +935,12 @@ function margins.finalhandler(head) end head = tonut(head) local head, done = finalhandler(head) +-- resetstacked(true) +resetstacked(nofdelayed==0) head = tonode(head) return head, done else + resetstacked() return head, false end end @@ -1023,14 +948,6 @@ end -- Somehow the vbox builder (in combinations) gets pretty confused and decides to -- go horizontal. So this needs more testing. -prependaction("finalizers", "lists", "typesetters.margins.localhandler") -prependaction("mvlbuilders", "normalizers", "typesetters.margins.globalhandler") -prependaction("shipouts", "normalizers", "typesetters.margins.finalhandler") - -disableaction("finalizers", "typesetters.margins.localhandler") -disableaction("mvlbuilders", "typesetters.margins.globalhandler") -disableaction("shipouts", "typesetters.margins.finalhandler") - enablelocal = function() enableaction("finalizers", "typesetters.margins.localhandler") enableaction("shipouts", "typesetters.margins.finalhandler") @@ -1077,6 +994,7 @@ interfaces.implement { { "align" }, { "option" }, { "line", "integer" }, + { "stackname" }, { "stack" }, } } diff --git a/tex/context/base/mkiv/typo-mar.mkiv b/tex/context/base/mkiv/typo-mar.mkiv index 90ccd46e2..462cc633e 100644 --- a/tex/context/base/mkiv/typo-mar.mkiv +++ b/tex/context/base/mkiv/typo-mar.mkiv @@ -122,6 +122,7 @@ \c!scope=\v!global, \c!width=, % \c!stack=, + % \c!stackname=, % \c!option=, % \v!paragraph (follow shape) \c!line=0, \c!anchor=\v!text, @@ -131,8 +132,8 @@ \c!hoffset=\zeropoint, \c!voffset=\zeropoint] -\setupmarginframed % so, align should be set with the data command - [\c!strut=\v!yes, +\setupmarginframed % so, align should be set with the data command + [\c!strut=\v!yes, % so by default we scale the strut to the font ! \c!offset=\v!overlay, \c!fr!analyze=\v!yes, \c!frame=\v!off, @@ -195,6 +196,8 @@ % todo: naturalhbox +% when name is set we overload + \let\margindatahbox\naturalhbox % \hbox \unexpanded\def\typo_margins_data_yes_indeed[#dataparameters][#textparameters]#content% @@ -301,6 +304,7 @@ % \fi align {\margindataparameter\c!align}% line \numexpr\margindataparameter\c!line\relax + stackname {\margindataparameter\c!stackname}% stack {\margindataparameter\c!stack}% \relax \else @@ -435,4 +439,46 @@ % \let\dostophanchoring \dostopanchoring % \let\dostopvanchoring \dostopanchoring +%D Here because in strc-ren we are too early: + +% % \definemargindata +% % [margintext:chapter] +% % [margintext:section] +% % +% % \defineheadalternative +% % [margintext:chapter] +% % [margintext] +% % [margintext=margintext:chapter] +% % +% % \setuphead +% % [chapter] +% % [alternative=margintext:chapter] +% +% \setuphead +% [chapter] +% [alternative=margintext] + +\definemargindata + [\v!margintext:\v!section] + [\v!left] + [\c!margin=\v!margin, + \c!width=\leftmarginwidth, + \c!align=\v!flushright] + +\defineheadalternative + [\v!margintext] + [\c!alternative=\v!somewhere, + \c!margintext=\v!margintext:\v!section, + \c!renderingsetup=\??headrenderings:\v!margintext] + +\startsetups[\??headrenderings:\v!margintext] + \executeifdefined{\headalternativeparameter\c!margintext}\margintext { + \ifconditional\headshownumber + \headnumbercontent + \hskip\headnumberdistance + \fi + \headtextcontent + } +\stopsetups + \protect \endinput diff --git a/tex/context/base/mkiv/typo-pag.lua b/tex/context/base/mkiv/typo-pag.lua index 355becff6..d6f71c8cc 100644 --- a/tex/context/base/mkiv/typo-pag.lua +++ b/tex/context/base/mkiv/typo-pag.lua @@ -34,7 +34,13 @@ local getnext = nuts.getnext local getprev = nuts.getprev local getid = nuts.getid local getattr = nuts.getattr +local takeattr = nuts.takeattr local setattr = nuts.setattr +local getwhd = nuts.getwhd +local getkern = nuts.getkern +local setpenalty = nuts.setpenalty +local getwidth = nuts.getwidth +local getdepth = nuts.getdepth local insert_node_after = nuts.insert_after local new_penalty = nuts.pool.penalty @@ -42,6 +48,8 @@ local new_penalty = nuts.pool.penalty local trace_keeptogether = false local report_keeptogether = logs.reporter("parbuilders","keeptogether") +local enableaction = nodes.tasks.enableaction + local cache = { } local last = 0 local enabled = false @@ -56,7 +64,7 @@ function parbuilders.registertogether(line,specification) -- might change return end if not enabled then - nodes.tasks.enableaction("finalizers","builders.paragraphs.keeptogether") + enableaction("finalizers","builders.paragraphs.keeptogether") end local a = getattr(line,a_keeptogether) local c = a and cache[a] @@ -109,7 +117,7 @@ local function keeptogether(start,a) if a then local current = getnext(start) local previous = start - local total = getfield(previous,"depth") + local total = getdepth(previous) local slack = specification.slack local threshold = specification.depth - slack if trace_keeptogether then @@ -118,13 +126,14 @@ local function keeptogether(start,a) while current do local id = getid(current) if id == vlist_code or id == hlist_code then - total = total + getfield(current,"height") + getfield(current,"depth") + local wd, ht, dp = getwhd(current) + total = total + ht + dp if trace_keeptogether then report_keeptogether("%s, index %s, total %p, threshold %p","list",a,total,threshold) end if total <= threshold then if getid(previous) == penalty_code then - setfield(previous,"penalty",10000) + setpenalty(previous,10000) else insert_node_after(head,previous,new_penalty(10000)) end @@ -133,13 +142,13 @@ local function keeptogether(start,a) end elseif id == glue_code then -- hm, breakpoint, maybe turn this into kern - total = total + getfield(current,"width") + total = total + getwidth(current) if trace_keeptogether then report_keeptogether("%s, index %s, total %p, threshold %p","glue",a,total,threshold) end if total <= threshold then if getid(previous) == penalty_code then - setfield(previous,"penalty",10000) + setpenalty(previous,10000) else insert_node_after(head,previous,new_penalty(10000)) end @@ -147,13 +156,13 @@ local function keeptogether(start,a) break end elseif id == kern_code then - total = total + getfield(current,"kern") + total = total + getkern(current) if trace_keeptogether then report_keeptogether("%s, index %s, total %s, threshold %s","kern",a,total,threshold) end if total <= threshold then if getid(previous) == penalty_code then - setfield(previous,"penalty",10000) + setpenalty(previous,10000) else insert_node_after(head,previous,new_penalty(10000)) end @@ -163,9 +172,9 @@ local function keeptogether(start,a) elseif id == penalty_code then if total <= threshold then if getid(previous) == penalty_code then - setfield(previous,"penalty",10000) + setpenalty(previous,10000) end - setfield(current,"penalty",10000) + setpenalty(current,10000) else break end @@ -184,10 +193,9 @@ function parbuilders.keeptogether(head) local current = tonut(head) while current do if getid(current) == hlist_code then - local a = getattr(current,a_keeptogether) + local a = takeattr(current,a_keeptogether) if a and a > 0 then keeptogether(current,a) - setattr(current,a_keeptogether,unsetvalue) cache[a] = nil done = true end diff --git a/tex/context/base/mkiv/typo-rep.lua b/tex/context/base/mkiv/typo-rep.lua index a8925a2ce..5266aa103 100644 --- a/tex/context/base/mkiv/typo-rep.lua +++ b/tex/context/base/mkiv/typo-rep.lua @@ -18,7 +18,7 @@ local trace_stripping = false trackers.register("nodes.stripping", function(v) local report_stripping = logs.reporter("fonts","stripping") local nodes = nodes -local tasks = nodes.tasks +local enableaction = nodes.tasks.enableaction local nuts = nodes.nuts local tonut = nuts.tonut @@ -35,11 +35,9 @@ local replace_node = nuts.replace local copy_node = nuts.copy local nodecodes = nodes.nodecodes -local glyph_code = nodecodes.glyph local chardata = characters.data local collected = false -local fontdata = fonts.hashes.identifiers local a_stripping = attributes.private("stripping") local texsetattribute = tex.setattribute @@ -121,7 +119,7 @@ function stripping.set(n) -- number or 'reset' if n then if not enabled then if initialize then initialize() end - tasks.enableaction("processors","nodes.handlers.stripping") + enableaction("processors","nodes.handlers.stripping") enabled = true end else @@ -131,11 +129,6 @@ function stripping.set(n) -- number or 'reset' texsetattribute(a_stripping,n) end --- why not in task-ini? - -tasks.appendaction("processors","fonts","nodes.handlers.stripping",nil,"nodes.handlers.characters") -tasks.disableaction("processors","nodes.handlers.stripping") - -- interface interfaces.implement { diff --git a/tex/context/base/mkiv/typo-rub.lua b/tex/context/base/mkiv/typo-rub.lua new file mode 100644 index 000000000..9621a6218 --- /dev/null +++ b/tex/context/base/mkiv/typo-rub.lua @@ -0,0 +1,419 @@ +if not modules then modules = { } end modules ['typo-rub'] = { + version = 1.001, + comment = "companion to typo-rub.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo: recycle slots better +-- todo: hoffset +-- todo: auto-increase line height +-- todo: only hpack when start <> stop + +-- A typical bit of afternoon hackery ... with some breaks for watching +-- Ghost-Note on youtube (Robert Searight and Nate Werth) ... which expands +-- my to-be-had cd/dvd list again. + +local lpegmatch = lpeg.match +local utfcharacters = utf.characters +local setmetatableindex = table.setmetatableindex + +local variables = interfaces.variables +local implement = interfaces.implement + +local texsetattribute = tex.setattribute + +local v_flushleft = variables.flushleft +local v_middle = variables.middle +local v_flushright = variables.flushright +local v_yes = variables.yes +local v_no = variables.no +local v_auto = variables.auto + +local nuts = nodes.nuts + +local tonut = nodes.tonut +local tonode = nodes.tonode +local getid = nuts.getid +local getsubtype = nuts.getsubtype +local getattr = nuts.getattr +local setattr = nuts.setattr +local getfield = nuts.getfield +local setfield = nuts.setfield +local getnext = nuts.getnext +local setnext = nuts.setnext +local getprev = nuts.getprev +local setprev = nuts.setprev +local setlink = nuts.setlink +local getlist = nuts.getlist +local setlist = nuts.setlist +local setshift = nuts.setshift +local getwidth = nuts.getwidth +local setwidth = nuts.setwidth + +local hpack = nuts.hpack +local insert_after = nuts.insert_after +local takebox = nuts.takebox +local traverse_id = nuts.traverse_id + +local nodecodes = nodes.nodecodes +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc +local kern_code = nodecodes.kern +local glue_code = nodecodes.glue +local penalty_code = nodecodes.penalty +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local whatsit_code = nodecodes.whatsit +local localpar_code = nodecodes.localpar + +local whatsitcodes = nodes.whatsitcodes +----- late_luacode = whatsitcodes.latelua + +local kerncodes = nodes.kerncodes +local font_code = kerncodes.font + +local nodepool = nuts.pool +local new_kern = nodepool.kern + +local setprop = nuts.setprop +local getprop = nuts.getprop + +local enableaction = nodes.tasks.enableaction + +local nofrubies = 0 +local rubylist = { } + +local a_ruby = attributes.private("ruby") + +local rubies = { } +typesetters.rubies = rubies + +local trace_rubies = false trackers.register("typesetters.rubies",function(v) trace_rubies = v end) +local report_rubies = logs.reporter("rubies") + +do + + local shared = nil + local splitter = lpeg.tsplitat("|") + + local function enable() + enableaction("processors","typesetters.rubies.check") + enableaction("shipouts", "typesetters.rubies.attach") + enable = false + end + + local ctx_setruby = context.core.setruby + + local function ruby(settings) + local base = settings.base + local comment = settings.comment + shared = settings + local c = lpegmatch(splitter,comment) + if #c == 1 then + ctx_setruby(base,comment) + if trace_rubies then + report_rubies("- %s -> %s",base,comment) + end + else + local i = 0 + for b in utfcharacters(base) do + i = i + 1 + local r = c[i] + if r then + ctx_setruby(b,r) + if trace_rubies then + report_rubies("%i: %s -> %s",i,b,r) + end + else + ctx_setruby(b,"") + if trace_rubies then + report_rubies("%i: %s",i,b) + end + end + end + end + if enable then + enable() + end + end + + local function startruby(settings) + shared = settings + if enable then + enable() + end + end + + implement { + name = "ruby", + actions = ruby, + arguments = { + { + { "align" }, + { "stretch" }, + { "hoffset", "dimension" }, + { "voffset", "dimension" }, + { "comment" }, + { "base" }, + } + }, + } + + implement { + name = "startruby", + actions = startruby, + arguments = { + { + { "align" }, + { "stretch" }, + { "hoffset", "dimension" }, + { "voffset", "dimension" }, + } + }, + } + + local function setruby(n,m) + nofrubies = nofrubies + 1 + local r = takebox(n) + rubylist[nofrubies] = setmetatableindex({ + text = r, + width = getwidth(r), + basewidth = 0, + start = false, + stop = false, + }, shared) + texsetattribute(a_ruby,nofrubies) + end + + implement { + name = "setruby", + actions = setruby, + arguments = "integer", + } + +end + +function rubies.check(head) + local head = tonut(head) + local current = head + local start = nil + local stop = nil + local found = nil + + local function flush(where) + local r = rubylist[found] + if r then + local prev = getprev(start) + local next = getnext(stop) + setprev(start) + setnext(stop) + local h = hpack(start) + if prev == head then + head = h + else + setlink(prev,h) + end + setlink(h,next) + local bwidth = getwidth(h) + local rwidth = r.width + r.basewidth = bwidth + r.start = start + r.stop = stop + setprop(h,"ruby",found) + if rwidth > bwidth then + -- ruby is wider + setwidth(h,rwidth) + end + end + end + + while current do + local nx = getnext(current) + local id = getid(current) + if id == glyph_code then + local a = getattr(current,a_ruby) + if not a then + if found then + flush("flush 1") + found = nil + end + elseif a == found then + stop = current + else + if found then + flush("flush 2") + end + found = a + start = current + stop = current + end + elseif id == kern_code and getsubtype(current,font_code) then + -- go on + elseif found and id == disc_code then + -- go on (todo: look into disc) + elseif found then + flush("flush 4") + found = nil + end + current = nx + end + if found then + flush("flush 5") + end + return tonode(head), true +end + +local attach + +local function whatever(current) + local a = getprop(current,"ruby") + if a then + local ruby = rubylist[a] + local align = ruby.align or v_middle + local stretch = ruby.stretch or v_no + local hoffset = ruby.hoffset or 0 + local voffset = ruby.voffset or 0 + local start = ruby.start + local stop = ruby.stop + local text = ruby.text + local rwidth = ruby.width + local bwidth = ruby.basewidth + local delta = rwidth - bwidth + setwidth(text,0) + if voffset ~= 0 then + setshift(text,voffset) + end + -- center them + if delta > 0 then + -- ruby is wider + if stretch == v_yes then + setlink(text,start) + while start and start ~= stop do + local s = nodepool.stretch() + local n = getnext(start) + setlink(start,s,n) + start = n + end + text = hpack(text,rwidth,"exactly") + else + local left = new_kern(delta/2) + local right = new_kern(delta/2) +-- setlink(left,start) +-- setlink(stop,right) +-- setlink(text,left) + setlink(text,left,start) + setlink(stop,right) + end + setlist(current,text) + elseif delta < 0 then + -- ruby is narrower + if align == v_auto then + local l = true + local c = getprev(current) + while c do + local id = getid(c) + if id == glue_code or id == penalty_code or id == kern_code or (id == whatsit_code and getsubtype(current,localpar_code)) then + -- go on + elseif id == hlist_code and getwidth(c) == 0 then + -- go on + elseif id == whatsit_code or id == localpar_code then + -- go on + else + l = false + break + end + c = getprev(c) + end + local r = true + local c = getnext(current) + while c do + local id = getid(c) + if id == glue_code or id == penalty_code or id == kern_code then + -- go on + elseif id == hlist_code and getwidth(c) == 0 then + -- go on + else + r = false + break + end + c = getnext(c) + end + if l and not r then + align = v_flushleft + elseif r and not l then + align = v_flushright + else + align = v_middle + end + end + if align == v_flushleft then + setlink(text,start) + setlist(current,text) + elseif align == v_flushright then + local left = new_kern(-delta) + local right = new_kern(delta) +-- setlink(left,text) +-- setlink(text,right) +-- setlink(right,start) + setlink(left,text,right,start) + setlist(current,left) + else + local left = new_kern(-delta/2) + local right = new_kern(delta/2) +-- setlink(left,text) +-- setlink(text,right) +-- setlink(right,start) + setlink(left,text,right,start) + setlist(current,left) + end + else + setlink(text,start) + setlist(current,text) + end + setprop(current,"ruby",false) + rubylist[a] = nil + else + local list = getlist(current) + if list then + attach(list) + end + end +end + +attach = function(head) + for current in traverse_id(hlist_code,head) do + whatever(current) + end + for current in traverse_id(vlist_code,head) do + whatever(current) + end + return head, true +end + +function rubies.attach(head) + local h, d = attach(tonut(head)) + return tonode(h), d +end + +-- for now there is no need to be compact + +-- local data = { } +-- rubies.data = data +-- +-- function rubies.define(settings) +-- data[#data+1] = settings +-- return #data +-- end +-- +-- implement { +-- name = "defineruby", +-- actions = { rubies.define, context }, +-- arguments = { +-- { +-- { "align" }, +-- { "stretch" }, +-- } +-- } +-- } diff --git a/tex/context/base/mkiv/typo-rub.mkiv b/tex/context/base/mkiv/typo-rub.mkiv new file mode 100644 index 000000000..7b996089b --- /dev/null +++ b/tex/context/base/mkiv/typo-rub.mkiv @@ -0,0 +1,170 @@ +%D \module +%D [ file=typo-rub, +%D version=2016.10.10, +%D title=\CONTEXT\ Typesetting Macros, +%D subtitle=Rubies, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Experimental and unfinished. + +% todo: distance + +\writestatus{loading}{ConTeXt Typesetting Macros / Rubies} + +\unprotect + +\registerctxluafile{typo-rub}{1.001} + +\definesystemattribute[ruby][public] + +\installcorenamespace {ruby} +\installcorenamespace {rubyanalyze} +\installcorenamespace {rubyplacement} + +\installcommandhandler \??ruby {ruby} \??ruby + +% \appendtoks +% \clf_defineruby +% align {\rubyparameter\c!align} +% stretch {\rubyparameter\c!stretch} +% hoffset \rubyparameter\c!hoffset +% voffset \rubyparameter\c!voffset +% \relax +% \to \everydefineruby + +\unexpanded\def\ruby + {\dosingleempty\typo_ruby_yes} + +\unexpanded\def\typo_ruby_yes[#1]#2#3% + {\dontleavehmode + \begingroup + \let\typo_ruby_yes\typo_ruby_nop % no nesting + \edef\currentruby{#1}% + \edef\p_location{\rubyparameter\c!location}% + \let|\relax + \ifcsname\??rubyanalyze\p_location\endcsname + \expandafter\lastnamedcs\else\expandafter\typo_ruby_analyze + \fi{#2}{#3}% + \endgroup} + +\unexpanded\def\typo_ruby_nop[#1]#2#3% + {#2} + +\def\typo_ruby_analyze#1#2% + {\clf_ruby + base {#1}% + comment {#2} + \relax} + +\setvalue{\??rubyanalyze\v!top}#1#2% + {\clf_ruby + align {\rubyparameter\c!align}% + stretch {\rubyparameter\c!stretch}% + hoffset \rubyparameter\c!hoffset + voffset \rubyparameter\c!voffset + base {#1}% + comment {#2} + \relax} + +\setvalue{\??rubyplacement\v!top}#1#2% + {\setbox\scratchbox\hbox\bgroup + \userubystyleandcolor\c!style\c!color + #2% + \egroup + \clf_setruby \scratchbox + \relax + #1} + +\setvalue{\??rubyplacement\v!right}#1#2% + {#1% + \edef\p_distance{\rubyparameter\c!distance}% + \ifx\p_distance\empty\else\ifx\p_distance\v!none\else\hskip\p_distance\fi\fi + \begingroup + \userubystyleandcolor\c!style\c!color + \rubyparameter\c!left#2\rubyparameter\c!right + \endgroup} + +\setvalue{\??rubyplacement\v!left}#1#2% + {\begingroup + \userubystyleandcolor\c!style\c!color + \rubyparameter\c!left#2\rubyparameter\c!right + \endgroup + \edef\p_distance{\rubyparameter\c!distance}% + \ifx\p_distance\empty\else\ifx\p_distance\v!none\else\hskip\p_distance\fi\fi + #1} + +\unexpanded\def\setruby#1#2% + {\begingroup + \ifcsname\??rubyplacement\p_location\endcsname + \lastnamedcs{#1}{#2}% + \else + #1% + \fi + \endgroup} + +\unexpanded\def\startruby + {\dosingleempty\typo_ruby_start_yes} + +\unexpanded\def\typo_ruby_start_yes[#1]% + {\dontleavehmode + \begingroup + \let\typo_ruby_start_yes\begingroup + \edef\currentruby{#1}% + \clf_startruby + align {\rubyparameter\c!align}% + stretch {\rubyparameter\c!stretch}% + hoffset \rubyparameter\c!hoffset + voffset \rubyparameter\c!voffset + \relax} + +\unexpanded\def\stopruby + {\endgroup} + +\setupruby + [\c!style=\txx, + \c!location=\v!top, + \c!left=(, + \c!right=), + \c!distance=\zeropoint, % \v!none means no skip at all so no break either + \c!hoffset=\zeropoint, + \c!voffset=-2\exheight] + +\protect \endinput + +% \usemodule[art-01]\setupbodyfont[dejavu,12pt] +% +% \defineruby[auto] [align=auto,color=darkred] +% \defineruby[left] [align=flushleft,color=darkred] +% \defineruby[right] [align=flushright,color=darkred] +% \defineruby[spread][stretch=yes] +% +% \showframe \showglyphs \showfontkerns \setupinterlinespace[22pt] +% +% \starttext +% +% \startbuffer +% \dorecurse{20}{\ruby{XYZ}{a|bc|d} }\par +% \dorecurse{20}{\ruby{PQR}{p|q|r} }\par +% \dorecurse{20}{\ruby{XYZ}{1|22|333} }\par +% \dorecurse{20}{\ruby{XYZ}{111|222|333} }\par +% \dorecurse{20}{\ruby{XYZ}{foobar} }\par +% \dorecurse{20}{\ruby{XYZ}{fooledbar} }\par +% \dorecurse{20}{\ruby[spread]{XYZ}{fooledbar} }\par +% \dorecurse{20}{\ruby{extremely}{wide} }\par +% \dorecurse{20}{\ruby{wide}{extremely} }\par +% stopbuffer +% +% \testfeatureonce{1}{\start \setupinterlinespace[16pt] \setupruby[location=none] \getbuffer \stop \page} +% \testfeatureonce{1}{\start \setupinterlinespace[16pt] \setupruby[location=right] \getbuffer \stop \page} +% \testfeatureonce{1}{\start \setupinterlinespace[28pt] \setupruby[align=auto,color=darkred] \getbuffer \stop \page} +% \testfeatureonce{1}{\start \setupinterlinespace[28pt] \setupruby[align=flushleft,color=darkgreen] \getbuffer \stop \page} +% \testfeatureonce{1}{\start \setupinterlinespace[28pt] \setupruby[align=flushright,color=darkblue] \getbuffer \stop \page} +% \testfeatureonce{1}{\start \setupinterlinespace[28pt] \setupruby[align=middle,color=darkyellow] \getbuffer \stop \page} +% +% \stoptext diff --git a/tex/context/base/mkiv/typo-scr.mkiv b/tex/context/base/mkiv/typo-scr.mkiv index 6249c390a..7b8d62dfb 100644 --- a/tex/context/base/mkiv/typo-scr.mkiv +++ b/tex/context/base/mkiv/typo-scr.mkiv @@ -53,7 +53,7 @@ \begingroup \edef\currentlow{#1}% \kern\lowparameter\c!distance\relax - \setbox\scratchbox\hbox\bgroup + \setbox\scratchbox\runninghbox\bgroup \lower\lowparameter\c!down\hbox\bgroup \ifx\fontsize\empty \ifmmode @@ -79,7 +79,7 @@ \begingroup \edef\currenthigh{#1}% \kern\highparameter\c!distance\relax - \setbox\scratchbox\hbox\bgroup + \setbox\scratchbox\runninghbox\bgroup \raise\highparameter\c!up\hbox\bgroup \ifx\fontsize\empty \ifmmode @@ -136,7 +136,7 @@ \unexpanded\def\typo_scripts_lowhigh#1% #2 {\dontleavehmode - \hbox\bgroup + \runninghbox\bgroup \edef\currentlowhigh{#1}% \dosingleempty} % #2 @@ -228,7 +228,8 @@ \to \everydefinelowmidhigh \unexpanded\def\typo_scripts_lowmidhigh#1#2#3#4% - {\dontleavehmode \hbox \bgroup + {\dontleavehmode + \runninghbox\bgroup \edef\currentlowmidhigh{#1}% \dostarttagged\t!subsup\currentlowmidhigh \uselowmidhighstyleandcolor\c!style\c!color diff --git a/tex/context/base/mkiv/typo-spa.lua b/tex/context/base/mkiv/typo-spa.lua index f00e3ae6b..bda139719 100644 --- a/tex/context/base/mkiv/typo-spa.lua +++ b/tex/context/base/mkiv/typo-spa.lua @@ -7,7 +7,6 @@ if not modules then modules = { } end modules ['typo-spa'] = { } local next, type = next, type -local utfchar = utf.char local trace_spacing = false trackers.register("typesetters.spacing", function(v) trace_spacing = v end) @@ -15,10 +14,7 @@ local report_spacing = logs.reporter("typesetting","spacing") local nodes, fonts, node = nodes, fonts, node -local tasks = nodes.tasks - local fonthashes = fonts.hashes -local fontdata = fonthashes.identifiers local quaddata = fonthashes.quads local texsetattribute = tex.setattribute @@ -33,8 +29,7 @@ local tonode = nuts.tonode local getnext = nuts.getnext local getprev = nuts.getprev local getfont = nuts.getfont -local getattr = nuts.getattr -local setattr = nuts.setattr +local takeattr = nuts.takeattr local isglyph = nuts.isglyph local insert_node_before = nuts.insert_before @@ -47,12 +42,13 @@ local new_penalty = nodepool.penalty local new_glue = nodepool.glue local nodecodes = nodes.nodecodes -local glyph_code = nodecodes.glyph local math_code = nodecodes.math local somespace = nodes.somespace local somepenalty = nodes.somepenalty +local enableaction = nodes.tasks.enableaction + typesetters = typesetters or { } local typesetters = typesetters @@ -85,12 +81,11 @@ function spacings.handler(head) while start do local char, id = isglyph(start) if char then - local attr = getattr(start,a_spacings) + local attr = takeattr(start,a_spacings) if attr and attr > 0 then local data = mapping[attr] if data then local map = data.characters[char] - setattr(start,a_spacings,unsetvalue) -- needed? if map then local left = map.left local right = map.right @@ -213,7 +208,7 @@ function spacings.set(name) local data = numbers[name] if data then if not enabled then - tasks.enableaction("processors","typesetters.spacings.handler") + enableaction("processors","typesetters.spacings.handler") enabled = true end n = data.number or unsetvalue diff --git a/tex/context/base/mkiv/typo-sus.lua b/tex/context/base/mkiv/typo-sus.lua index ce1933330..f728993f6 100644 --- a/tex/context/base/mkiv/typo-sus.lua +++ b/tex/context/base/mkiv/typo-sus.lua @@ -48,9 +48,12 @@ local getfield = nuts.getfield local getattr = nuts.getattr local getfont = nuts.getfont local getlist = nuts.getlist +local getkern = nuts.getkern +local getpenalty = nuts.getpenalty +local getwidth = nuts.getwidth +local getwhd = nuts.getwhd local isglyph = nuts.isglyph -local setfield = nuts.setfield local setattr = nuts.setattr local setlist = nuts.setlist @@ -72,22 +75,21 @@ local a_suspect = attributes.private('suspect') local texsetattribute = tex.setattribute local enabled = false +local enableaction = nodes.tasks.enableaction + local threshold = 65536 / 4 local function special(n) if n then local id = getid(n) if id == kern_code then - local kern = getfield(n,"kern") - return kern < threshold + return getkern(n) < threshold elseif id == penalty_code then return true elseif id == glue_code then - local width = getfield(n,"width") - return width < threshold + return getwidth(n) < threshold elseif id == hlist_code then - local width = getfield(n,"width") - return width < threshold + return getwidth(n) < threshold end else return false @@ -118,23 +120,23 @@ local function mark(head,current,id,color) if id == glue_code then -- the glue can have stretch and/or shrink so the rule can overlap with the -- following glyph .. no big deal as that one then sits on top of the rule - local width = getfield(current,"width") + local width = getwidth(current) local rule = new_rule(width) local kern = new_kern(-width) head = insert_before(head,current,rule) head = insert_before(head,current,kern) setcolor(rule,color) -- elseif id == kern_code then - -- local width = getfield(current,"kern") + -- local width = getkern(current) -- local rule = new_rule(width) -- local kern = new_kern(-width) -- head = insert_before(head,current,rule) -- head = insert_before(head,current,kern) -- setcolor(rule,color) else - local width = getfield(current,"width") + local width, height, depth = getwhd(current) local extra = fonts.hashes.xheights[getfont(current)] / 2 - local rule = new_rule(width,getfield(current,"height")+extra,getfield(current,"depth")+extra) + local rule = new_rule(width,height+extra,depth+extra) local hlist = new_hlist(rule) head = insert_before(head,current,hlist) setcolor(rule,color) @@ -232,7 +234,7 @@ function typesetters.marksuspects(head) local prev = getprev(current) local prid = prev and getid(prev) local done = false - if prid == penalty_code and getfield(prev,"penalty") == 10000 then + if prid == penalty_code and getpenalty(prev) == 10000 then done = 8 -- orange else done = 5 -- darkmagenta @@ -292,19 +294,13 @@ function typesetters.showsuspects(head) end end -nodes.tasks.appendaction ("processors","after", "typesetters.marksuspects") -nodes.tasks.prependaction("shipouts", "normalizers","typesetters.showsuspects") - -nodes.tasks.disableaction("processors","typesetters.marksuspects") -nodes.tasks.disableaction("shipouts", "typesetters.showsuspects") - -- or maybe a directive trackers.register("typesetters.suspects",function(v) texsetattribute(a_suspecting,v and 1 or unsetvalue) if v and not enabled then - nodes.tasks.enableaction("processors","typesetters.marksuspects") - nodes.tasks.enableaction("shipouts", "typesetters.showsuspects") + enableaction("processors","typesetters.marksuspects") + enableaction("shipouts", "typesetters.showsuspects") enabled = true end end) diff --git a/tex/context/base/mkiv/typo-tal.lua b/tex/context/base/mkiv/typo-tal.lua index 21c6794c4..67380f24b 100644 --- a/tex/context/base/mkiv/typo-tal.lua +++ b/tex/context/base/mkiv/typo-tal.lua @@ -41,18 +41,16 @@ local getprev = nuts.getprev local getid = nuts.getid local getfont = nuts.getfont local getchar = nuts.getchar -local getfield = nuts.getfield local getattr = nuts.getattr local isglyph = nuts.isglyph -local setfield = nuts.setfield local setattr = nuts.setattr local setchar = nuts.setchar local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after local traverse_list_by_id = nuts.traverse_id -local dimensions_of_list = nuts.dimensions +local list_dimensions = nuts.dimensions local first_glyph = nuts.first_glyph local setglue = nuts.setglue @@ -64,6 +62,8 @@ local tracers = nodes.tracers local setcolor = tracers.colors.set local tracedrule = tracers.pool.nuts.rule +local enableaction = nodes.tasks.enableaction + local characteralign = { } typesetters.characteralign = characteralign @@ -102,7 +102,7 @@ local validsigns = { local function setcharacteralign(column,separator) if not enabled then - nodes.tasks.enableaction("processors","typesetters.characteralign.handler") + enableaction("processors","typesetters.characteralign.handler") enabled = true end if not datasets then @@ -381,8 +381,8 @@ function characteralign.handler(originalhead,where) end else entry = { - before = b_start and dimensions_of_list(b_start,getnext(b_stop)) or 0, - after = a_start and dimensions_of_list(a_start,getnext(a_stop)) or 0, + before = b_start and list_dimensions(b_start,getnext(b_stop)) or 0, + after = a_start and list_dimensions(a_start,getnext(a_stop)) or 0, } list[row] = entry end diff --git a/tex/context/base/mkiv/typo-wrp.lua b/tex/context/base/mkiv/typo-wrp.lua index 394e15090..07e34cd6c 100644 --- a/tex/context/base/mkiv/typo-wrp.lua +++ b/tex/context/base/mkiv/typo-wrp.lua @@ -23,9 +23,11 @@ local find_node_tail = nuts.tail local getprev = nuts.getprev local getid = nuts.getid local getsubtype = nuts.getsubtype -local getfield = nuts.getfield +local getpenalty = nuts.getpenalty local remove = nuts.remove +local enableaction = nodes.tasks.enableaction + local wrappers = { } typesetters.wrappers = wrappers @@ -39,9 +41,9 @@ local report = logs.reporter("paragraphs","wrappers") local function remove_dangling_crlf(head,tail) if tail and getid(tail) == glue_code and getsubtype(tail) == parfill_skip_code then tail = getprev(tail) - if tail and getid(tail) == penalty_code and getsubtype(tail) == user_penalty_code and getfield(tail,"penalty") == 10000 then + if tail and getid(tail) == penalty_code and getsubtype(tail) == user_penalty_code and getpenalty(tail) == 10000 then tail = getprev(tail) - if tail and getid(tail) == penalty_code and getsubtype(tail) == user_penalty_code and getfield(tail,"penalty") == -10000 then + if tail and getid(tail) == penalty_code and getsubtype(tail) == user_penalty_code and getpenalty(tail) == -10000 then if tail == head then -- can't happen else @@ -71,6 +73,6 @@ interfaces.implement { name = "enablecrlf", onlyonce = true, actions = function() - nodes.tasks.enableaction("processors","typesetters.wrappers.handler") + enableaction("processors","typesetters.wrappers.handler") end } diff --git a/tex/context/base/mkiv/util-deb.lua b/tex/context/base/mkiv/util-deb.lua index ee732b3b5..57e015386 100644 --- a/tex/context/base/mkiv/util-deb.lua +++ b/tex/context/base/mkiv/util-deb.lua @@ -12,87 +12,255 @@ if not modules then modules = { } end modules ['util-deb'] = { local debug = require "debug" -local getinfo = debug.getinfo -local type, next, tostring = type, next, tostring -local format, find = string.format, string.find -local is_boolean = string.is_boolean +local getinfo, sethook = debug.getinfo, debug.sethook +local type, next, tostring, tonumber = type, next, tostring, tonumber +local format, find, sub, gsub = string.format, string.find, string.sub, string.gsub +local insert, remove, sort = table.insert, table.remove, table.sort +local setmetatableindex = table.setmetatableindex utilities = utilities or { } local debugger = utilities.debugger or { } utilities.debugger = debugger -local counters = { } +local report = logs.reporter("debugger") + +local ticks = os.gettimeofday or os.clock +local seconds = function(n) return n or 0 end +local overhead = 0 +local dummycalls = 10*1000 +local nesting = 0 local names = { } -local report = logs.reporter("debugger") +local initialize = false --- one +if not (FFISUPPORTED and ffi) then -local function hook() - local f = getinfo(2) -- "nS" - if f then - local n = "unknown" - if f.what == "C" then - n = f.name or '<anonymous>' - if not names[n] then - names[n] = format("%42s",n) + -- we have no precise timer + +elseif os.type == "windows" then + + initialize = function() + local kernel = ffilib("kernel32","system") -- no checking + if kernel then + local tonumber = ffi.number or tonumber + ffi.cdef[[ + int QueryPerformanceFrequency(int64_t *lpFrequency); + int QueryPerformanceCounter(int64_t *lpPerformanceCount); + ]] + local target = ffi.new("__int64[1]") + ticks = function() + if kernel.QueryPerformanceCounter(target) == 1 then + return tonumber(target[0]) + else + return 0 + end end - else - -- source short_src linedefined what name namewhat nups func - n = f.name or f.namewhat or f.what - if not n or n == "" then - n = "?" + local target = ffi.new("__int64[1]") + seconds = function(ticks) + if kernel.QueryPerformanceFrequency(target) == 1 then + return ticks / tonumber(target[0]) + else + return 0 + end + end + end + initialize = false + end + +elseif os.type == "unix" then + + -- for the values: echo '#include <time.h>' > foo.h; gcc -dM -E foo.h + + initialize = function() + local C = ffi.C + local tonumber = ffi.number or tonumber + ffi.cdef [[ + /* what a mess */ + typedef int clk_id_t; + typedef enum { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID } clk_id; + typedef struct timespec { long sec; long nsec; } ctx_timespec; + int clock_gettime(clk_id_t timerid, struct timespec *t); + ]] + local target = ffi.new("ctx_timespec[?]",1) + local clock = C.CLOCK_PROCESS_CPUTIME_ID + ticks = function () + C.clock_gettime(clock,target) + return tonumber(target[0].sec*1000000000 + target[0].nsec) + end + seconds = function(ticks) + return ticks/1000000000 + end + initialize = false + end + +end + +setmetatableindex(names,function(t,name) + local v = setmetatableindex(function(t,source) + local v = setmetatableindex(function(t,line) + local v = { total = 0, count = 0 } + t[line] = v + return v + end) + t[source] = v + return v + end) + t[name] = v + return v +end) + +local function hook(where) + local f = getinfo(2,"nSl") + if f then + local source = f.short_src + if not source then + return + end + local line = f.linedefined or 0 + local name = f.name + if not name then + local what = f.what + if what == "C" then + name = "<anonymous>" + else + name = f.namewhat or what or "<unknown>" end - if not names[n] then - names[n] = format("%42s : % 5i : %s",n,f.linedefined or 0,f.short_src or "unknown source") + end + local data = names[name][source][line] + if where == "call" then + data.count = data.count + 1 + insert(data,ticks()) + elseif where == "return" then + local t = remove(data) + if t then + data.total = data.total + ticks() - t end end - counters[n] = (counters[n] or 0) + 1 end end -function debugger.showstats(printer,threshold) -- hm, something has changed, rubish now - printer = printer or report - threshold = threshold or 0 - local total, grandtotal, functions = 0, 0, 0 - local dataset = { } - for name, count in next, counters do - dataset[#dataset+1] = { name, count } +function debugger.showstats(printer,threshold) + local printer = printer or report + local calls = 0 + local functions = 0 + local dataset = { } + local length = 0 + local wholetime = 0 + local threshold = threshold or 0 + for name, sources in next, names do + for source, lines in next, sources do + for line, data in next, lines do + local count = data.count + if count > threshold then + if #name > length then + length = #name + end + local total = data.total + local real = total + if real > 0 then + real = total - (count * overhead / dummycalls) + if real < 0 then + real = 0 + end + wholetime = wholetime + real + end + if line < 0 then + line = 0 + end + -- if name = "a" then + -- -- weird name + -- end + dataset[#dataset+1] = { real, total, count, name, source, line } + end + end + end end - table.sort(dataset,function(a,b) return a[2] == b[2] and b[1] > a[1] or a[2] > b[2] end) - for i=1,#dataset do - local d = dataset[i] - local name = d[1] - local count = d[2] - if count > threshold and not find(name,"for generator") then -- move up - printer(format("%8i %s\n", count, names[name])) - total = total + count + sort(dataset,function(a,b) + if a[1] == b[1] then + if a[2] == b[2] then + if a[3] == b[3] then + if a[4] == b[4] then + if a[5] == b[5] then + return a[6] < b[6] + else + return a[5] < b[5] + end + else + return a[4] < b[4] + end + else + return b[3] < a[3] + end + else + return b[2] < a[2] + end + else + return b[1] < a[1] end - grandtotal = grandtotal + count + end) + if length > 50 then + length = 50 + end + local fmt = string.formatters["%4.9k %4.9k %3.3k %8i %-" .. length .. "s %4i %s"] + for i=1,#dataset do + local data = dataset[i] + local real = data[1] + local total = data[2] + local count = data[3] + local name = data[4] + local source = data[5] + local line = data[6] + local percent = real / wholetime + calls = calls + count functions = functions + 1 + name = gsub(name,"%s+"," ") + if #name > length then + name = sub(name,1,length) + end + printer(fmt(seconds(total),seconds(real),percent,count,name,line,source)) end - printer("\n") - printer(format("functions : % 10i\n", functions)) - printer(format("total : % 10i\n", total)) - printer(format("grand total: % 10i\n", grandtotal)) - printer(format("threshold : % 10i\n", threshold)) + printer("") + printer(format("functions : %i", functions)) + printer(format("calls : %i", calls)) + printer(format("overhead : %f", seconds(overhead/1000))) + + -- table.save("luatex-profile.lua",names) end function debugger.savestats(filename,threshold) local f = io.open(filename,'w') if f then - debugger.showstats(function(str) f:write(str) end,threshold) + debugger.showstats(function(str) f:write(str,"\n") end,threshold) f:close() end end function debugger.enable() - debug.sethook(hook,"c") + if nesting == 0 then + running = true + if initialize then + initialize() + end + sethook(hook,"cr") + local function dummy() end + local t = ticks() + for i=1,dummycalls do + dummy() + end + overhead = ticks() - t + end + if nesting > 0 then + nesting = nesting + 1 + end end function debugger.disable() - debug.sethook() - -- counters[debug.getinfo(2,"f").func] = nil + if nesting > 0 then + nesting = nesting - 1 + end + if nesting == 0 then + sethook() + end end -- debugger.enable() diff --git a/tex/context/base/mkiv/util-env.lua b/tex/context/base/mkiv/util-env.lua index b72226900..0b832e72e 100644 --- a/tex/context/base/mkiv/util-env.lua +++ b/tex/context/base/mkiv/util-env.lua @@ -15,14 +15,58 @@ local concat, insert, remove = table.concat, table.insert, table.remove environment = environment or { } local environment = environment --- precautions +-- locales are a useless feature in and even dangerous for luatex -os.setlocale(nil,nil) -- useless feature and even dangerous in luatex +os.setlocale(nil,nil) -- setlocale("all","C") function os.setlocale() -- no way you can mess with it end +-- do +-- +-- local setlocale = os.setlocale +-- +-- function os.resetlocale() +-- setlocale(nil,nil) +-- end +-- +-- function os.pushlocale(l,...) +-- insert(stack, { +-- collate = setlocale(nil,"collate"), +-- ctype = setlocale(nil,"ctype"), +-- monetary = setlocale(nil,"monetary"), +-- numeric = setlocale(nil,"numeric"), +-- time = setlocale(nil,"time"), +-- }) +-- if l then +-- setlocale(l,...) +-- else +-- setlocale(status.lc_collate ,"collate"), +-- setlocale(status.lc_ctype ,"ctype"), +-- setlocale(status.lc_monetary,"monetary"), +-- setlocale(status.lc_numeric ,"numeric"), +-- setlocale(status.lc_time ,"time"), +-- end +-- end +-- +-- function os.poplocale(...) +-- local l = remove(stack) +-- if l then +-- setlocale(unpack(l)) +-- else +-- resetlocale() +-- end +-- end +-- +-- function os.setlocale() +-- -- no way you can mess with it, use push/pop +-- end +-- +-- setlocale(nil,nil) -- setlocale("all","C") +-- +-- end + -- dirty tricks (we will replace the texlua call by luatex --luaonly) local validengines = allocate { diff --git a/tex/context/base/mkiv/util-fil.lua b/tex/context/base/mkiv/util-fil.lua index 28c92c7c3..01bcd571e 100644 --- a/tex/context/base/mkiv/util-fil.lua +++ b/tex/context/base/mkiv/util-fil.lua @@ -6,8 +6,10 @@ if not modules then modules = { } end modules ['util-fil'] = { license = "see context related readme files" } -local byte = string.byte -local extract = bit32.extract +local byte = string.byte +local char = string.char +local extract = bit32 and bit32.extract +local floor = math.floor -- Here are a few helpers (the starting point were old ones I used for parsing -- flac files). In Lua 5.3 we can probably do this better. Some code will move @@ -36,6 +38,8 @@ function files.size(f) return f:seek("end") end +files.getsize = files.size + function files.setposition(f,n) if zerobased[f] then f:seek("set",n) @@ -79,6 +83,12 @@ function files.readbytes(f,n) return byte(f:read(n),1,n) end +function files.readbytetable(f,n) + -- return { byte(f:read(n),1,n) } + local s = f:read(n or 1) + return { byte(s,1,#s) } -- best use the real length +end + function files.readchar(f) return f:read(1) end @@ -89,29 +99,43 @@ end function files.readinteger1(f) -- one byte local n = byte(f:read(1)) - if n >= 0x80 then - return n - 0xFF - 1 + if n >= 0x80 then + return n - 0x100 else return n end end -files.readcardinal1 = files.readbyte -- one byte -files.readcardinal = files.readcardinal1 -files.readinteger = files.readinteger1 +files.readcardinal1 = files.readbyte -- one byte +files.readcardinal = files.readcardinal1 +files.readinteger = files.readinteger1 +files.readsignedbyte = files.readinteger1 function files.readcardinal2(f) local a, b = byte(f:read(2),1,2) return 0x100 * a + b end +function files.readcardinal2le(f) + local b, a = byte(f:read(2),1,2) + return 0x100 * a + b +end + function files.readinteger2(f) local a, b = byte(f:read(2),1,2) - local n = 0x100 * a + b - if n >= 0x8000 then - return n - 0xFFFF - 1 + if a >= 0x80 then + return 0x100 * a + b - 0x10000 else - return n + return 0x100 * a + b + end +end + +function files.readinteger2le(f) + local b, a = byte(f:read(2),1,2) + if a >= 0x80 then + return 0x100 * a + b - 0x10000 + else + return 0x100 * a + b end end @@ -120,44 +144,115 @@ function files.readcardinal3(f) return 0x10000 * a + 0x100 * b + c end +function files.readcardinal3le(f) + local c, b, a = byte(f:read(3),1,3) + return 0x10000 * a + 0x100 * b + c +end + +function files.readinteger3(f) + local a, b, c = byte(f:read(3),1,3) + if a >= 0x80 then + return 0x10000 * a + 0x100 * b + c - 0x1000000 + else + return 0x10000 * a + 0x100 * b + c + end +end + +function files.readinteger3le(f) + local c, b, a = byte(f:read(3),1,3) + if a >= 0x80 then + return 0x10000 * a + 0x100 * b + c - 0x1000000 + else + return 0x10000 * a + 0x100 * b + c + end +end + function files.readcardinal4(f) local a, b, c, d = byte(f:read(4),1,4) return 0x1000000 * a + 0x10000 * b + 0x100 * c + d end +function files.readcardinal4le(f) + local d, c, b, a = byte(f:read(4),1,4) + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d +end + function files.readinteger4(f) local a, b, c, d = byte(f:read(4),1,4) - local n = 0x1000000 * a + 0x10000 * b + 0x100 * c + d - if n >= 0x8000000 then - return n - 0xFFFFFFFF - 1 + if a >= 0x80 then + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000 else - return n + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d end end -function files.readfixed4(f) - local a, b, c, d = byte(f:read(4),1,4) - local n = 0x100 * a + b - if n >= 0x8000 then - return n - 0xFFFF - 1 + (0x100 * c + d)/0xFFFF +function files.readinteger4le(f) + local d, c, b, a = byte(f:read(4),1,4) + if a >= 0x80 then + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000 else - return n + (0x100 * c + d)/0xFFFF + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d end end -function files.read2dot14(f) +-- function files.readfixed2(f) +-- local a, b = byte(f:read(2),1,2) +-- if a >= 0x80 then +-- return (0x100 * a + b - 0x10000)/256.0 +-- else +-- return (0x100 * a + b)/256.0 +-- end +-- end + +function files.readfixed2(f) local a, b = byte(f:read(2),1,2) - local n = 0x100 * a + b - local m = extract(n,0,30) - if n > 0x7FFF then - n = extract(n,30,2) - return m/0x4000 - 4 + if a >= 0x80 then + return (a - 0x100) + b/0x100 else - n = extract(n,30,2) - return n + m/0x4000 + return (a ) + b/0x100 end end +-- (real) (n>>16) + ((n&0xffff)/65536.0)) + +-- function files.readfixed4(f) +-- local a, b, c, d = byte(f:read(4),1,4) +-- if a >= 0x80 then +-- return (0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000)/65536.0 +-- else +-- return (0x1000000 * a + 0x10000 * b + 0x100 * c + d)/65536.0 +-- end +-- end + +function files.readfixed4(f) + local a, b, c, d = byte(f:read(4),1,4) + if a >= 0x80 then + return (0x100 * a + b - 0x10000) + (0x100 * c + d)/0x10000 + else + return (0x100 * a + b ) + (0x100 * c + d)/0x10000 + end +end + +if extract then + + local extract = bit32.extract + local band = bit32.band + + -- (real) ((n<<16)>>(16+14)) + ((n&0x3fff)/16384.0)) + + function files.read2dot14(f) + local a, b = byte(f:read(2),1,2) + if a >= 0x80 then + local n = -(0x100 * a + b) + return - (extract(n,14,2) + (band(n,0x3FFF) / 16384.0)) + else + local n = 0x100 * a + b + return (extract(n,14,2) + (band(n,0x3FFF) / 16384.0)) + end + end + +end + function files.skipshort(f,n) f:read(2*(n or 1)) end @@ -165,3 +260,68 @@ end function files.skiplong(f,n) f:read(4*(n or 1)) end + +-- writers (kind of slow) + +function files.writecardinal2(f,n) + local a = char(n % 256) + n = floor(n/256) + local b = char(n % 256) + f:write(b,a) +end + +function files.writecardinal4(f,n) + local a = char(n % 256) + n = floor(n/256) + local b = char(n % 256) + n = floor(n/256) + local c = char(n % 256) + n = floor(n/256) + local d = char(n % 256) + f:write(d,c,b,a) +end + +function files.writestring(f,s) + f:write(char(byte(s,1,#s))) +end + +function files.writebyte(f,b) + f:write(char(b)) +end + +if fio and fio.readcardinal1 then + + files.readcardinal1 = fio.readcardinal1 + files.readcardinal2 = fio.readcardinal2 + files.readcardinal3 = fio.readcardinal3 + files.readcardinal4 = fio.readcardinal4 + files.readinteger1 = fio.readinteger1 + files.readinteger2 = fio.readinteger2 + files.readinteger3 = fio.readinteger3 + files.readinteger4 = fio.readinteger4 + -- files.readfixed2 = fio.readfixed2 -- needs recent luatex + -- files.readfixed4 = fio.readfixed4 -- needs recent luatex + files.read2dot14 = fio.read2dot14 + files.setposition = fio.setposition + files.getposition = fio.getposition + + files.readbyte = files.readcardinal1 + files.readsignedbyte = files.readinteger1 + files.readcardinal = files.readcardinal1 + files.readinteger = files.readinteger1 + + local skipposition = fio.skipposition + files.skipposition = skipposition + + files.readbytes = fio.readbytes + files.readbytetable = fio.readbytetable + + function files.skipshort(f,n) + skipposition(f,2*(n or 1)) + end + + function files.skiplong(f,n) + skipposition(f,4*(n or 1)) + end + +end diff --git a/tex/context/base/mkiv/util-jsn.lua b/tex/context/base/mkiv/util-jsn.lua index bbe25d89d..e835c07d6 100644 --- a/tex/context/base/mkiv/util-jsn.lua +++ b/tex/context/base/mkiv/util-jsn.lua @@ -64,18 +64,19 @@ local jnumber = (1-whitespace-rparent-rbrace-comma)^1 / tonumber local key = jstring local jsonconverter = { "value", - object = lbrace * Cf(Ct("") * V("pair") * (comma * V("pair"))^0,rawset) * rbrace, - pair = Cg(optionalws * key * optionalws * colon * V("value")), - array = Ct(lparent * V("value") * (comma * V("value"))^0 * rparent), - value = optionalws * (jstring + V("object") + V("array") + jtrue + jfalse + jnull + jnumber + #rparent) * optionalws, + hash = lbrace * Cf(Ct("") * (V("pair") * (comma * V("pair"))^0 + optionalws),rawset) * rbrace, + pair = Cg(optionalws * key * optionalws * colon * V("value")), + array = Ct(lparent * (V("value") * (comma * V("value"))^0 + optionalws) * rparent), +-- value = optionalws * (jstring + V("hash") + V("array") + jtrue + jfalse + jnull + jnumber + #rparent) * optionalws, + value = optionalws * (jstring + V("hash") + V("array") + jtrue + jfalse + jnull + jnumber) * optionalws, } -- local jsonconverter = { "value", --- object = lbrace * Cf(Ct("") * V("pair") * (comma * V("pair"))^0,rawset) * rbrace, --- pair = Cg(optionalws * V("string") * optionalws * colon * V("value")), --- array = Ct(lparent * V("value") * (comma * V("value"))^0 * rparent), --- string = jstring, --- value = optionalws * (V("string") + V("object") + V("array") + jtrue + jfalse + jnull + jnumber) * optionalws, +-- hash = lbrace * Cf(Ct("") * (V("pair") * (comma * V("pair"))^0 + optionalws),rawset) * rbrace, +-- pair = Cg(optionalws * V("string") * optionalws * colon * V("value")), +-- array = Ct(lparent * (V("value") * (comma * V("value"))^0 + optionalws) * rparent), +-- string = jstring, +-- value = optionalws * (V("string") + V("hash") + V("array") + jtrue + jfalse + jnull + jnumber) * optionalws, -- } -- lpeg.print(jsonconverter) -- size 181 @@ -156,3 +157,5 @@ end -- inspect(tmp) -- inspect(json.tostring(true)) + +return json diff --git a/tex/context/base/mkiv/util-lib-imp-gm.lua b/tex/context/base/mkiv/util-lib-imp-gm.lua index 4c5254721..d1ffde879 100644 --- a/tex/context/base/mkiv/util-lib-imp-gm.lua +++ b/tex/context/base/mkiv/util-lib-imp-gm.lua @@ -9,9 +9,9 @@ if not modules then modules = { } end modules ['util-lib-imp-gm'] = { local graphicmagick = utilities.graphicmagick or { } utilities.graphicmagick = graphicmagick -local report_gm = logs.reporter("swiglib gm") +local report_gm = logs.reporter("swiglib graphicsmagick") -local gm = swiglib("gmwand.core") +local gm = swiglib("graphicsmagick.core") if gm then report_gm("library loaded") diff --git a/tex/context/base/mkiv/util-lib-imp-gs.lua b/tex/context/base/mkiv/util-lib-imp-gs.lua index 8fd2dd458..0eceda7aa 100644 --- a/tex/context/base/mkiv/util-lib-imp-gs.lua +++ b/tex/context/base/mkiv/util-lib-imp-gs.lua @@ -12,9 +12,9 @@ local formatters = string.formatters local ghostscript = utilities.ghostscript or { } utilities.ghostscript = ghostscript -local report_gs = logs.reporter("swiglib gs") +local report_gs = logs.reporter("swiglib ghostscript") -local gs = swiglib("gs.core") +local gs = swiglib("ghostscript.core") local helpers = swiglib("helpers.core") if gs then diff --git a/tex/context/base/mkiv/util-lib.lua b/tex/context/base/mkiv/util-lib.lua index 2601b2e57..e7b6e4875 100644 --- a/tex/context/base/mkiv/util-lib.lua +++ b/tex/context/base/mkiv/util-lib.lua @@ -6,9 +6,6 @@ if not modules then modules = { } end modules ['util-lib'] = { license = "see context related readme files", } --- This is experimental code for Hans and Luigi. Don't depend on it! There --- will be a plain variant. - --[[ The problem with library bindings is manyfold. They are of course platform @@ -73,47 +70,59 @@ and then without. ]]-- --- seems to be clua in recent texlive - -local gsub, find = string.gsub, string.find -local pathpart, nameonly, joinfile = file.pathpart, file.nameonly, file.join -local findfile, findfiles = resolvers and resolvers.findfile, resolvers and resolvers.findfiles - -local loaded = package.loaded +local type = type +local next = next +local pcall = pcall +local gsub = string.gsub +local find = string.find +local sort = table.sort +local pathpart = file.pathpart +local nameonly = file.nameonly +local joinfile = file.join +local removesuffix = file.removesuffix +local findfile = resolvers.findfile +local findfiles = resolvers.findfiles +local expandpaths = resolvers.expandedpathlistfromvariable +local qualifiedpath = file.is_qualified_path +local isfile = lfs.isfile -local report_swiglib = logs.reporter("swiglib") -local trace_swiglib = false trackers.register("resolvers.swiglib", function(v) trace_swiglib = v end) +local done = false -- We can check if there are more that one component, and if not, we can -- append 'core'. -local done = false - -local function requireswiglib(required,version) - local trace_swiglib = trace_swiglib or package.helpers.trace - local library = loaded[required] - if library == nil then - if trace_swiglib then - report_swiglib("requiring library %a with version %a",required,version or "any") +local function locate(required,version,trace,report,action) + if type(required) ~= "string" then + report("provide a proper library name") + return + end + if trace then + report("requiring library %a with version %a",required,version or "any") + end + local found_library = nil + local required_full = gsub(required,"%.","/") -- package.helpers.lualibfile + local required_path = pathpart(required_full) + local required_base = nameonly(required_full) + if qualifiedpath(required) then + if isfile(required) then + found_library = required end + else -- initialize a few variables - local required_full = gsub(required,"%.","/") -- package.helpers.lualibfile - local required_path = pathpart(required_full) - local required_base = nameonly(required_full) local required_name = required_base .. "." .. os.libsuffix local version = type(version) == "string" and version ~= "" and version or false local engine = environment.ownmain or false -- - if trace_swiglib and not done then - local list = resolvers.expandedpathlistfromvariable("lib") -- fresh, no reuse + if trace and not done then + local list = expandpaths("lib") -- fresh, no reuse for i=1,#list do - report_swiglib("tds path %i: %s",i,list[i]) + report("tds path %i: %s",i,list[i]) end end -- helpers local function found(locate,asked_library,how,...) - if trace_swiglib then - report_swiglib("checking %s: %a",how,asked_library) + if trace then + report("checking %s: %a",how,asked_library) end return locate(asked_library,...) end @@ -121,15 +130,15 @@ local function requireswiglib(required,version) local found = nil if version then local asked_library = joinfile(required_path,version,required_name) - if trace_swiglib then - report_swiglib("checking %s: %a","with version",asked_library) + if trace then + report("checking %s: %a","with version",asked_library) end found = locate(asked_library,...) end if not found or found == "" then local asked_library = joinfile(required_path,required_name) - if trace_swiglib then - report_swiglib("checking %s: %a","with version",asked_library) + if trace then + report("checking %s: %a","with version",asked_library) end found = locate(asked_library,...) end @@ -140,32 +149,32 @@ local function requireswiglib(required,version) -- match anyway. local function attempt(checkpattern) -- check cnf spec using name and version - if trace_swiglib then - report_swiglib("checking tds lib paths strictly") + if trace then + report("checking tds lib paths strictly") end local found = findfile and check(findfile,"lib") if found and (not checkpattern or find(found,checkpattern)) then return found end -- check cnf spec using wildcard - if trace_swiglib then - report_swiglib("checking tds lib paths with wildcard") + if trace then + report("checking tds lib paths with wildcard") end local asked_library = joinfile(required_path,".*",required_name) - if trace_swiglib then - report_swiglib("checking %s: %a","latest version",asked_library) + if trace then + report("checking %s: %a","latest version",asked_library) end local list = findfiles(asked_library,"lib",true) if list and #list > 0 then - table.sort(list) + sort(list) local found = list[#list] if found and (not checkpattern or find(found,checkpattern)) then return found end end -- Check lib paths using name and version. - if trace_swiglib then - report_swiglib("checking lib paths") + if trace then + report("checking lib paths") end package.extralibpath(environment.ownpath) local paths = package.libpaths() @@ -177,59 +186,87 @@ local function requireswiglib(required,version) end return false end - local found_library = nil if engine then - if trace_swiglib then - report_swiglib("attemp 1, engine %a",engine) + if trace then + report("attemp 1, engine %a",engine) end found_library = attempt("/"..engine.."/") if not found_library then - if trace_swiglib then - report_swiglib("attemp 2, no engine",asked_library) + if trace then + report("attemp 2, no engine",asked_library) end found_library = attempt() end else found_library = attempt() end - -- load and initialize when found - if not found_library then - if trace_swiglib then - report_swiglib("not found: %a",required) - end - library = false - else - local path = pathpart(found_library) - local base = nameonly(found_library) - dir.push(path) - if trace_swiglib then - report_swiglib("found: %a",found_library) - end - local message = nil - local opener = "luaopen_" .. required_base - library, message = package.loadlib(found_library,opener) - local libtype = type(library) - if libtype == "function" then - library = library() - else - report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library") - library = false - end - dir.pop() - end - -- cache result - if not library then - report_swiglib("unknown: %a",required) - elseif trace_swiglib then - report_swiglib("stored: %a",required) + end + -- load and initialize when found + if not found_library then + if trace then + report("not found: %a",required) end - loaded[required] = library + library = false else - report_swiglib("reused: %a",required) + if trace then + report("found: %a",found_library) + end + local message, result = action(found_library,required_base) + if result then + library = result + else + library = false + report("load error: message %a, library %a",tostring(message),found_library or "no library") + end + end + if not library then + report("unknown: %a",required) + elseif trace then + report("stored: %a",required) end return library end +do + + local report_swiglib = logs.reporter("swiglib") + local trace_swiglib = false + local savedrequire = require + local loadedlibs = { } + local loadlib = package.loadlib + + local pushdir = dir.push + local popdir = dir.pop + + trackers.register("resolvers.swiglib", function(v) trace_swiglib = v end) + + function requireswiglib(required,version) + local library = loadedlibs[library] + if library == nil then + local trace_swiglib = trace_swiglib or package.helpers.trace + library = locate(required,version,trace_swiglib,report_swiglib,function(name,base) + pushdir(pathpart(name)) + local opener = "luaopen_" .. base + if trace_swiglib then + report_swiglib("opening: %a with %a",name,opener) + end + local library, message = loadlib(name,opener) + local libtype = type(library) + if libtype == "function" then + library = library() + message = true + else + report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library") + library = false + end + popdir() + return message, library + end) + loadedlibs[required] = library or false + end + return library + end + --[[ For convenience we make the require loader function swiglib aware. Alternatively @@ -237,15 +274,13 @@ we could put the specific loader in the global namespace. ]]-- -local savedrequire = require - -function require(name,version) - if find(name,"^swiglib%.") then - return requireswiglib(name,version) - else - return savedrequire(name) + function require(name,version) + if find(name,"^swiglib%.") then + return requireswiglib(name,version) + else + return savedrequire(name) + end end -end --[[ @@ -255,43 +290,93 @@ recommended loader. ]]-- -local swiglibs = { } -local initializer = "core" + local swiglibs = { } + local initializer = "core" -function swiglib(name,version) - local library = swiglibs[name] - if not library then - statistics.starttiming(swiglibs) - if trace_swiglib then - report_swiglib("loading %a",name) + function swiglib(name,version) + local library = swiglibs[name] + if not library then + statistics.starttiming(swiglibs) + if trace_swiglib then + report_swiglib("loading %a",name) + end + if not find(name,"%." .. initializer .. "$") then + fullname = "swiglib." .. name .. "." .. initializer + else + fullname = "swiglib." .. name + end + library = requireswiglib(fullname,version) + swiglibs[name] = library + statistics.stoptiming(swiglibs) + end + return library + end + + statistics.register("used swiglibs", function() + if next(swiglibs) then + return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs)) end - if not find(name,"%." .. initializer .. "$") then - fullname = "swiglib." .. name .. "." .. initializer + end) + +end + +if FFISUPPORTED and ffi and ffi.load then + +--[[ + +We use the same lookup logic for ffi loading. + +]]-- + + local report_ffilib = logs.reporter("ffilib") + local trace_ffilib = false + local savedffiload = ffi.load + + trackers.register("resolvers.ffilib", function(v) trace_ffilib = v end) + + local function locateindeed(name) + local message, library = pcall(savedffiload,removesuffix(name)) + if type(library) == "userdata" then + return library else - fullname = "swiglib." .. name + return false end - library = requireswiglib(fullname,version) - swiglibs[name] = library - statistics.stoptiming(swiglibs) end - return library -end -statistics.register("used swiglibs", function() - if next(swiglibs) then - return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs)) + function ffilib(required,version) + if version == "system" then + return locateindeed(name) + else + return locate(required,version,trace_ffilib,report_ffilib,locateindeed) + end + end + + function ffi.load(name) + local library = ffilib(name) + if type(library) == "userdata" then + return library + else + report_ffilib("trying to load %a using normal loader",name) + return savedffiload(name) + end end -end) + +end --[[ -So, we now have: +-- So, we now have: -local gm = require("swiglib.gmwand.core") -local gm = swiglib("gmwand.core") +trackers.enable("resolvers.ffilib") +trackers.enable("resolvers.swiglib") + +local gm = require("swiglib.graphicsmagick.core") +local gm = swiglib("graphicsmagick.core") local sq = swiglib("mysql.core") local sq = swiglib("mysql.core","5.6") -Watch out, the last one is less explicit and lacks the swiglib prefix. +ffilib("libmysql","5.6.14") + +-- Watch out, the last one is less explicit and lacks the swiglib prefix. ]]-- diff --git a/tex/context/base/mkiv/util-lua.lua b/tex/context/base/mkiv/util-lua.lua index e1dcdc94d..b3346006c 100644 --- a/tex/context/base/mkiv/util-lua.lua +++ b/tex/context/base/mkiv/util-lua.lua @@ -158,3 +158,21 @@ end -- luautilities.registerdatatype(lpeg.P("!"),"lpeg") -- -- print(luautilities.datatype(lpeg.P("oeps"))) + +-- These finalizers will only be invoked when we have a proper lua_close +-- call (which is not happening in luatex tex node yes) or finish with an +-- os.exit(n,true). + +local finalizers = { } + +setmetatable(finalizers, { + __gc = function(t) + for i=1,#t do + pcall(t[i]) -- let's not crash + end + end +} ) + +function luautilities.registerfinalizer(f) + finalizers[#finalizers+1] = f +end diff --git a/tex/context/base/mkiv/util-prs.lua b/tex/context/base/mkiv/util-prs.lua index 02729dd0e..650a7ead6 100644 --- a/tex/context/base/mkiv/util-prs.lua +++ b/tex/context/base/mkiv/util-prs.lua @@ -83,10 +83,6 @@ local pattern_b = spaces * comma^0 * spaces * (key * ((spaces * equal * spaces * -- "a=1, b=2, c=3, d={a{b,c}d}, e=12345, f=xx{a{b,c}d}xx, g={}" : outer {} removes, leading spaces ignored --- todo: rewrite to fold etc --- --- parse = lpeg.Cf(lpeg.Carg(1) * lpeg.Cg(key * equal * value) * separator^0,rawset)^0 -- lpeg.match(parse,"...",1,hash) - local hash = { } local function set(key,value) @@ -197,6 +193,23 @@ function parsers.settings_to_array(str,strict) end end +function parsers.settings_to_numbers(str) + if not str or str == "" then + return { } + end + if type(str) == "table" then + -- fall through + elseif find(str,",",1,true) then + str = lpegmatch(pattern,str) + else + return { tonumber(str) } + end + for i=1,#str do + str[i] = tonumber(str[i]) + end + return str +end + local value = P(lbrace * C((nobrace + nestedbraces)^0) * rbrace) + C((nestedbraces + nestedbrackets + nestedparents + (1-comma))^0) local pattern = spaces * Ct(value*(separator*value)^0) diff --git a/tex/context/base/mkiv/util-sac.lua b/tex/context/base/mkiv/util-sac.lua index 8a12e7cf0..b509d9a9b 100644 --- a/tex/context/base/mkiv/util-sac.lua +++ b/tex/context/base/mkiv/util-sac.lua @@ -10,7 +10,7 @@ if not modules then modules = { } end modules ['util-sac'] = { -- with bytes) local byte, sub = string.byte, string.sub -local extract = bit32.extract +local extract = bit32 and bit32.extract utilities = utilities or { } local streams = { } @@ -82,6 +82,13 @@ function streams.readbytes(f,n) return byte(f[1],i,j-1) end +function streams.readbytetable(f,n) + local i = f[2] + local j = i + n + f[2] = j + return { byte(f[1],i,j-1) } +end + function streams.skipbytes(f,n) f[2] = f[2] + n end @@ -104,7 +111,7 @@ function streams.readinteger1(f) -- one byte f[2] = i + 1 local n = byte(f[1],i) if n >= 0x80 then - return n - 0xFF - 1 + return n - 0x100 else return n end @@ -122,16 +129,35 @@ function streams.readcardinal2(f) return 0x100 * a + b end +function streams.readcardinal2LE(f) + local i = f[2] + local j = i + 1 + f[2] = j + 1 + local b, a = byte(f[1],i,j) + return 0x100 * a + b +end + function streams.readinteger2(f) local i = f[2] local j = i + 1 f[2] = j + 1 local a, b = byte(f[1],i,j) - local n = 0x100 * a + b - if n >= 0x8000 then - return n - 0xFFFF - 1 + if a >= 0x80 then + return 0x100 * a + b - 0x10000 else - return n + return 0x100 * a + b + end +end + +function streams.readinteger2le(f) + local i = f[2] + local j = i + 1 + f[2] = j + 1 + local b, a = byte(f[1],i,j) + if a >= 0x80 then + return 0x100 * a + b - 0x10000 + else + return 0x100 * a + b end end @@ -143,6 +169,38 @@ function streams.readcardinal3(f) return 0x10000 * a + 0x100 * b + c end +function streams.readcardinal3le(f) + local i = f[2] + local j = i + 2 + f[2] = j + 1 + local c, b, a = byte(f[1],i,j) + return 0x10000 * a + 0x100 * b + c +end + +function streams.readinteger3(f) + local i = f[2] + local j = i + 3 + f[2] = j + 1 + local a, b, c = byte(f[1],i,j) + if a >= 0x80 then + return 0x10000 * a + 0x100 * b + c - 0x1000000 + else + return 0x10000 * a + 0x100 * b + c + end +end + +function streams.readinteger3le(f) + local i = f[2] + local j = i + 3 + f[2] = j + 1 + local c, b, a = byte(f[1],i,j) + if a >= 0x80 then + return 0x10000 * a + 0x100 * b + c - 0x1000000 + else + return 0x10000 * a + 0x100 * b + c + end +end + function streams.readcardinal4(f) local i = f[2] local j = i + 3 @@ -156,11 +214,22 @@ function streams.readinteger4(f) local j = i + 3 f[2] = j + 1 local a, b, c, d = byte(f[1],i,j) - local n = 0x1000000 * a + 0x10000 * b + 0x100 * c + d - if n >= 0x8000000 then - return n - 0xFFFFFFFF - 1 + if a >= 0x80 then + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000 else - return n + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d + end +end + +function streams.readinteger4le(f) + local i = f[2] + local j = i + 3 + f[2] = j + 1 + local d, c, b, a = byte(f[1],i,j) + if a >= 0x80 then + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000 + else + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d end end @@ -169,30 +238,46 @@ function streams.readfixed4(f) local j = i + 3 f[2] = j + 1 local a, b, c, d = byte(f[1],i,j) - local n = 0x100 * a + b - if n >= 0x8000 then - return n - 0xFFFF - 1 + (0x100 * c + d)/0xFFFF + if a >= 0x80 then + return (0x100 * a + b - 0x10000) + (0x100 * c + d)/0x10000 else - return n + (0x100 * c + d)/0xFFFF + return (0x100 * a + b ) + (0x100 * c + d)/0x10000 end end -function streams.read2dot14(f) +function streams.readfixed2(f) local i = f[2] local j = i + 1 f[2] = j + 1 local a, b = byte(f[1],i,j) - local n = 0x100 * a + b - local m = extract(n,0,30) - if n > 0x7FFF then - n = extract(n,30,2) - return m/0x4000 - 4 + if a >= 0x80 then + return (a - 0x100) + b/0x100 else - n = extract(n,30,2) - return n + m/0x4000 + return (a ) + b/0x100 end end +if extract then + + local extract = bit32.extract + local band = bit32.band + + function streams.read2dot14(f) + local i = f[2] + local j = i + 1 + f[2] = j + 1 + local a, b = byte(f[1],i,j) + if a >= 0x80 then + local n = -(0x100 * a + b) + return - (extract(n,14,2) + (band(n,0x3FFF) / 16384.0)) + else + local n = 0x100 * a + b + return (extract(n,14,2) + (band(n,0x3FFF) / 16384.0)) + end + end + +end + function streams.skipshort(f,n) f[2] = f[2] + 2*(n or 1) end @@ -200,3 +285,104 @@ end function streams.skiplong(f,n) f[2] = f[2] + 4*(n or 1) end + +if sio and sio.readcardinal2 then + + local readcardinal1 = sio.readcardinal1 + local readcardinal2 = sio.readcardinal2 + local readcardinal3 = sio.readcardinal3 + local readcardinal4 = sio.readcardinal4 + local readinteger1 = sio.readinteger1 + local readinteger2 = sio.readinteger2 + local readinteger3 = sio.readinteger3 + local readinteger4 = sio.readinteger4 + local readfixed2 = sio.readfixed2 + local readfixed4 = sio.readfixed4 + local read2dot14 = sio.read2dot14 + local readbytes = sio.readbytes + local readbytetable = sio.readbytetable + + function streams.readcardinal1(f) + local i = f[2] + f[2] = i + 1 + return readcardinal1(f[1],i) + end + function streams.readcardinal2(f) + local i = f[2] + f[2] = i + 2 + return readcardinal2(f[1],i) + end + function streams.readcardinal3(f) + local i = f[2] + f[2] = i + 3 + return readcardinal3(f[1],i) + end + function streams.readcardinal4(f) + local i = f[2] + f[2] = i + 4 + return readcardinal4(f[1],i) + end + function streams.readinteger1(f) + local i = f[2] + f[2] = i + 1 + return readinteger1(f[1],i) + end + function streams.readinteger2(f) + local i = f[2] + f[2] = i + 2 + return readinteger2(f[1],i) + end + function streams.readinteger3(f) + local i = f[2] + f[2] = i + 3 + return readinteger3(f[1],i) + end + function streams.readinteger4(f) + local i = f[2] + f[2] = i + 4 + return readinteger4(f[1],i) + end + -- function streams.readfixed2(f) -- needs recent luatex + -- local i = f[2] + -- f[2] = i + 2 + -- return readfixed2(f[1],i) + -- end + -- function streams.readfixed4(f) -- needs recent luatex + -- local i = f[2] + -- f[2] = i + 4 + -- return readfixed4(f[1],i) + -- end + function streams.read2dot4(f) + local i = f[2] + f[2] = i + 2 + return read2dot4(f[1],i) + end + function streams.readbytes(f,n) + local i = f[2] + local s = f[3] + local p = i + n + if p > s then + f[2] = s + 1 + else + f[2] = p + end + return readbytes(f[1],i,n) + end + function streams.readbytetable(f,n) + local i = f[2] + local s = f[3] + local p = i + n + if p > s then + f[2] = s + 1 + else + f[2] = p + end + return readbytetable(f[1],i,n) + end + + streams.readbyte = streams.readcardinal1 + streams.readsignedbyte = streams.readinteger1 + streams.readcardinal = streams.readcardinal1 + streams.readinteger = streams.readinteger1 + +end diff --git a/tex/context/base/mkiv/util-sbx.lua b/tex/context/base/mkiv/util-sbx.lua index 260e8b3b5..66a650875 100644 --- a/tex/context/base/mkiv/util-sbx.lua +++ b/tex/context/base/mkiv/util-sbx.lua @@ -23,19 +23,23 @@ local platform = os.type local P, S, C = lpeg.P, lpeg.S, lpeg.C local gsub = string.gsub local lower = string.lower +local find = string.find +local concat = string.concat local unquoted = string.unquoted local optionalquoted = string.optionalquoted +local basename = file.basename local sandbox = sandbox local validroots = { } local validrunners = { } -local validbinaries = { } +local validbinaries = true -- all permitted +local validlibraries = true -- all permitted local validators = { } -local p_validroot = nil local finalized = nil -local norunners = false local trace = false -local p_split = lpeg.tsplitat(" ") -- more spaces? + +local p_validroot = nil +local p_split = lpeg.firstofsplit(" ") local report = logs.reporter("sandbox") @@ -43,69 +47,87 @@ trackers.register("sandbox",function(v) trace = v end) -- often too late anyway sandbox.setreporter(report) -sandbox.finalizer(function() - finalized = true -end) +sandbox.finalizer { + category = "files", + action = function() + finalized = true + end +} local function registerroot(root,what) -- what == read|write if finalized then report("roots are already finalized") else - root = collapsepath(expandname(root)) - if platform == "windows" then - root = lower(root) -- we assume ascii names + if type(root) == "table" then + root, what = root[1], root[2] + end + if type(root) == "string" and root ~= "" then + root = collapsepath(expandname(root)) + -- if platform == "windows" then + -- root = lower(root) -- we assume ascii names + -- end + if what == "r" or what == "ro" or what == "readable" then + what = "read" + elseif what == "w" or what == "wo" or what == "writable" then + what = "write" + end + -- true: read & write | false: read + validroots[root] = what == "write" or false end - -- true: read & write | false: read - validroots[root] = what == "write" or false end end -sandbox.finalizer(function() -- initializers can set the path - if p_validroot then - report("roots are already initialized") - else - sandbox.registerroot(".","write") -- always ok - -- also register texmf as read - for name in sortedhash(validroots) do - if p_validroot then - p_validroot = P(name) + p_validroot - else - p_validroot = P(name) +sandbox.finalizer { + category = "files", + action = function() -- initializers can set the path + if p_validroot then + report("roots are already initialized") + else + sandbox.registerroot(".","write") -- always ok + -- also register texmf as read + for name in sortedhash(validroots) do + if p_validroot then + p_validroot = P(name) + p_validroot + else + p_validroot = P(name) + end end + p_validroot = p_validroot / validroots end - p_validroot = p_validroot / validroots end -end) +} -local function registerrunner(specification) +local function registerbinary(name) if finalized then - report("runners are already finalized") - else - local name = specification.name - if not name then - report("no runner name specified") + report("binaries are already finalized") + elseif type(name) == "string" and name ~= "" then + if not validbinaries then return end - local program = specification.program - if type(program) == "string" then - -- common for all platforms - elseif type(program) == "table" then - program = program[platform] - end - if type(program) ~= "string" or program == "" then - report("invalid runner %a specified for platform %a",name,platform) - return + if validbinaries == true then + validbinaries = { [name] = true } + else + validbinaries[name] = true end - specification.program = program - validrunners[name] = specification + elseif name == true then + validbinaries = { } end end -local function registerbinary(name) +local function registerlibrary(name) if finalized then - report("binaries are already finalized") + report("libraries are already finalized") elseif type(name) == "string" and name ~= "" then - validbinaries[name] = true + if not validlibraries then + return + end + if validlibraries == true then + validlibraries = { [name] = true } + else + validlibraries[name] = true + end + elseif name == true then + validlibraries = { } end end @@ -134,9 +156,9 @@ end local function validfilename(name,what) if p_validroot and type(name) == "string" and lpegmatch(p_path,name) then local asked = collapsepath(expandname(name)) - if platform == "windows" then - asked = lower(asked) -- we assume ascii names - end + -- if platform == "windows" then + -- asked = lower(asked) -- we assume ascii names + -- end local okay = lpegmatch(p_validroot,asked) if okay == true then -- read and write access @@ -163,39 +185,53 @@ local function validfilename(name,what) end return name end - else - if filenamelogger then - filenamelogger(name,"*",name,false) - end + elseif filenamelogger then + filenamelogger(name,"*",name,false) end else return name end end -local function readable(name) - if platform == "windows" then - name = lower(name) -- we assume ascii names - end +local function readable(name,finalized) +-- if platform == "windows" then -- yes or no +-- name = lower(name) -- we assume ascii names +-- end + return validfilename(name,"r") +end + +local function normalizedreadable(name,finalized) +-- if platform == "windows" then -- yes or no +-- name = lower(name) -- we assume ascii names +-- end local valid = validfilename(name,"r") if valid then return normalized(valid) end end -local function writeable(name) - if platform == "windows" then - name = lower(name) -- we assume ascii names - end +local function writeable(name,finalized) +-- if platform == "windows" then +-- name = lower(name) -- we assume ascii names +-- end + return validfilename(name,"w") +end + +local function normalizedwriteable(name,finalized) +-- if platform == "windows" then +-- name = lower(name) -- we assume ascii names +-- end local valid = validfilename(name,"w") if valid then return normalized(valid) end end -validators.readable = readable -validators.writeable = writeable -validators.filename = readable +validators.readable = readable +validators.writeable = normalizedwriteable +validators.normalizedreadable = normalizedreadable +validators.normalizedwriteable = writeable +validators.filename = readable table.setmetatableindex(validators,function(t,k) if k then @@ -204,23 +240,39 @@ table.setmetatableindex(validators,function(t,k) return readable end) -function validators.string(s) - return s -- can be used to prevent filename checking +function validators.string(s,finalized) + -- can be used to prevent filename checking (todo: only when registered) + if finalized and suspicious(s) then + return "" + else + return s + end end --- end of validators +function validators.cache(s) + if finalized then + return basename(s) + else + return s + end +end + +function validators.url(s) + if finalized and find("^file:") then + return "" + else + return s + end +end -sandbox.registerroot = registerroot -sandbox.registerrunner = registerrunner -sandbox.registerbinary = registerbinary -sandbox.validfilename = validfilename +-- end of validators local function filehandlerone(action,one,...) local checkedone = validfilename(one) if checkedone then return action(one,...) else --- report("file %a is unreachable",one) + -- report("file %a is unreachable",one) end end @@ -231,10 +283,10 @@ local function filehandlertwo(action,one,two,...) if checkedtwo then return action(one,two,...) else --- report("file %a is unreachable",two) + -- report("file %a is unreachable",two) end else --- report("file %a is unreachable",one) + -- report("file %a is unreachable",one) end end @@ -254,101 +306,289 @@ end -- runners can be strings or tables -- -- os.execute : string --- os.exec : table with program in [0|1] --- os.spawn : table with program in [0|1] +-- os.exec : string or table with program in [0|1] +-- os.spawn : string or table with program in [0|1] -- -- our execute: registered program with specification -local function runhandler(action,name,specification) - local kind = type(name) - if kind ~= "string" then +local osexecute = sandbox.original(os.execute) +local iopopen = sandbox.original(io.popen) +local reported = { } + +local function validcommand(name,program,template,checkers,defaults,variables,reporter,strict) + if validbinaries ~= false and (validbinaries == true or validbinaries[program]) then + if variables then + for variable, value in next, variables do + local checker = validators[checkers[variable]] + if checker then + value = checker(unquoted(value),strict) + if value then + variables[variable] = optionalquoted(value) + else + report("variable %a with value %a fails the check",variable,value) + return + end + else + report("variable %a has no checker",variable) + return + end + end + for variable, default in next, defaults do + local value = variables[variable] + if not value or value == "" then + local checker = validators[checkers[variable]] + if checker then + default = checker(unquoted(default),strict) + if default then + variables[variable] = optionalquoted(default) + else + report("variable %a with default %a fails the check",variable,default) + return + end + end + end + end + end + local command = program .. " " .. replace(template,variables) + if reporter then + reporter("executing runner %a: %s",name,command) + elseif trace then + report("executing runner %a: %s",name,command) + end + return command + elseif not reported[name] then + report("executing program %a of runner %a is not permitted",program,name) + reported[name] = true + end +end + +local runners = { + -- + -- name,program,template,checkers,variables,reporter + -- + resultof = function(...) + local command = validcommand(...) + if command then + if trace then + report("resultof: %s",command) + end + local handle = iopopen(command,"r") -- already has flush + if handle then + local result = handle:read("*all") or "" + handle:close() + return result + end + end + end, + execute = function(...) + local command = validcommand(...) + if command then + if trace then + report("execute: %s",command) + end + return osexecute(command) + end + end, + pipeto = function(...) + local command = validcommand(...) + if command then + if trace then + report("pipeto: %s",command) + end + return iopopen(command,"w") -- already has flush + end + end, +} + +function sandbox.registerrunner(specification) + if type(specification) == "string" then + local wrapped = validrunners[specification] + inspect(table.sortedkeys(validrunners)) + if wrapped then + return wrapped + else + report("unknown predefined runner %a",specification) + return + end + end + if type(specification) ~= "table" then + report("specification should be a table (or string)") return end - if norunners then - report("no runners permitted, ignoring command: %s",name) + local name = specification.name + if type(name) ~= "string" then + report("invalid name, string expected",name) return end - local spec = validrunners[name] - if not spec then - report("unknown runner: %s",name) + if validrunners[name] then + report("invalid name, runner %a already defined") return end - -- specs are already checked - local program = spec.program - local variables = { } - local checkers = spec.checkers or { } - if specification then - -- we only handle runners that are defined before the sandbox is - -- closed so in principle we cannot have user runs with no files - -- while for context runners we assume a robust specification - for k, v in next, specification do - local checker = validators[checkers[k]] - local value = checker(unquoted(v)) -- todo: write checkers - if value then - variables[k] = optionalquoted(value) - else - report("suspicious argument found, run blocked: %s",v) - return - end - end + local program = specification.program + if type(program) == "string" then + -- common for all platforms + elseif type(program) == "table" then + program = program[platform] or program.default or program.unix + end + if type(program) ~= "string" or program == "" then + report("invalid runner %a specified for platform %a",name,platform) + return end - local command = replace(program,variables) - if trace then - report("executing runner: %s",command) + local template = specification.template + if not template then + report("missing template for runner %a",name) + return end - return action(command) + local method = specification.method or "execute" + local checkers = specification.checkers or { } + local defaults = specification.defaults or { } + local runner = runners[method] + if runner then + local finalized = finalized -- so, the current situation is frozen + local wrapped = function(variables) + return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized) + end + validrunners[name] = wrapped + return wrapped + else + validrunners[name] = nil + report("invalid method for runner %a",name) + end +end + +function sandbox.getrunner(name) + return name and validrunners[name] end --- only registered (from list) -- no checking on writable so let's assume harmless --- runs +local function suspicious(str) + return (find(str,"[/\\]") or find(command,"%.%.")) and true or false +end -local function binaryhandler(action,name) - local kind = type(name) - local list = name - if kind == "string" then - list = lpegmatch(p_split,name) +local function binaryrunner(action,command,...) + if validbinaries == false then + -- nothing permitted + report("no binaries permitted, ignoring command: %s",command) + return end - local program = name[0] or name[1] - if type(program) ~= "string" or program == "" then - return --silently ignore + if type(command) ~= "string" then + -- we only handle strings, maybe some day tables + report("command should be a string") + return end - if norunners then - report("no binaries permitted, ignoring command: %s",program) + local program = lpegmatch(p_split,command) + if not program or program == "" then + report("unable to filter binary from command: %s",command) return end - if not validbinaries[program] then - report("binary is not permitted: %s",program) + if validbinaries == true then + -- everything permitted + elseif not validbinaries[program] then + report("binary not permitted, ignoring command: %s",command) + return + elseif suspicious(command) then + report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command) return end - for i=0,#list do - local n = list[i] - if n then - local v = readable(unquoted(n)) - if v then - list[i] = optionalquoted(v) - else - report("suspicious argument found, run blocked: %s",n) - return - end - end + return action(command,...) +end + +-- local function binaryrunner(action,command,...) +-- local original = command +-- if validbinaries == false then +-- -- nothing permitted +-- report("no binaries permitted, ignoring command: %s",command) +-- return +-- end +-- local program +-- if type(command) == "table" then +-- program = command[0] +-- if program then +-- command = concat(command," ",0) +-- else +-- program = command[1] +-- if program then +-- command = concat(command," ") +-- end +-- end +-- elseif type(command) = "string" then +-- program = lpegmatch(p_split,command) +-- else +-- report("command should be a string or table") +-- return +-- end +-- if not program or program == "" then +-- report("unable to filter binary from command: %s",command) +-- return +-- end +-- if validbinaries == true then +-- -- everything permitted +-- elseif not validbinaries[program] then +-- report("binary not permitted, ignoring command: %s",command) +-- return +-- elseif find(command,"[/\\]") or find(command,"%.%.") then +-- report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command) +-- return +-- end +-- return action(original,...) +-- end + +local function dummyrunner(action,command,...) + if type(command) == "table" then + command = concat(command," ",command[0] and 0 or 1) end - return action(name) + report("ignoring command: %s",command) end sandbox.filehandlerone = filehandlerone sandbox.filehandlertwo = filehandlertwo sandbox.iohandler = iohandler -sandbox.runhandler = runhandler -sandbox.binaryhandler = binaryhandler function sandbox.disablerunners() - norunners = true + validbinaries = false end -local execute = sandbox.original(os.execute) +function sandbox.disablelibraries() + validlibraries = false +end + +if FFISUPPORTED and ffi then + + function sandbox.disablelibraries() + validlibraries = false + for k, v in next, ffi do + if k ~= "gc" then + ffi[k] = nil + end + end + end + + local load = ffi.load + + if load then + + local reported = { } + + function ffi.load(name,...) + if validlibraries == false then + -- all blocked + elseif validlibraries == true then + -- all permitted + return load(name,...) + elseif validlibraries[name] then + -- 'name' permitted + return load(name,...) + else + -- 'name' not permitted + end + if not reported[name] then + report("using library %a is not permitted",name) + reported[name] = true + end + return nil + end + + end -function sandbox.run(name,specification) - return runhandler(execute,name,specification) end ------------------- @@ -360,16 +600,18 @@ local register = sandbox.register if io then overload(io.open, filehandlerone,"io.open") - overload(io.popen, filehandlerone,"io.popen") + overload(io.popen, binaryrunner, "io.popen") overload(io.input, iohandler, "io.input") overload(io.output, iohandler, "io.output") overload(io.lines, filehandlerone,"io.lines") end if os then - overload(os.execute, binaryhandler, "os.execute") - overload(os.spawn, binaryhandler, "os.spawn") - overload(os.exec, binaryhandler, "os.exec") + overload(os.execute, binaryrunner, "os.execute") + overload(os.spawn, dummyrunner, "os.spawn") + overload(os.exec, dummyrunner, "os.exec") + overload(os.resultof, binaryrunner, "os.resultof") + overload(os.pipeto, binaryrunner, "os.pipeto") overload(os.rename, filehandlertwo,"os.rename") overload(os.remove, filehandlerone,"os.remove") end @@ -406,6 +648,11 @@ if epdf then epdf.open = register(epdf.open, filehandlerone,"epdf.open") end +sandbox.registerroot = registerroot +sandbox.registerbinary = registerbinary +sandbox.registerlibrary = registerlibrary +sandbox.validfilename = validfilename + -- not used in a normal mkiv run : os.spawn = os.execute -- not used in a normal mkiv run : os.exec = os.exec diff --git a/tex/context/base/mkiv/util-sci.lua b/tex/context/base/mkiv/util-sci.lua index 43d873b63..e028d2f95 100644 --- a/tex/context/base/mkiv/util-sci.lua +++ b/tex/context/base/mkiv/util-sci.lua @@ -17,11 +17,25 @@ utilities.scite = scite local report = logs.reporter("scite") -local lexerroot = file.dirname(resolvers.find_file("scite-context-lexer.lua")) +do + local lexerroot = "c:/data/system/scite/wscite/context/lexers" + if not lexerroot then + lexerroot = file.dirname(resolvers.find_file("scite-context-lexer.lua")) + end + if lfs.isdir(lexerroot) then + package.extraluapath(lexerroot) + package.extraluapath(lexerroot.."/themes") + package.extraluapath(lexerroot.."/data") + report("using lexer root %a",lexerroot) + else + report("no valid lexer root") + end +end local knownlexers = { tex = "tex", mkiv = "tex", mkvi = "tex", mkxi = "tex", mkix = "tex", mkii = "tex", cld = "tex", lua = "lua", lfg = "lua", lus = "lua", + mp = "mps", mpiv = "mps", mpii = "mps", w = "web", ww = "web", c = "cpp", h = "cpp", cpp = "cpp", hpp = "cpp", cxx = "cpp", hxx = "cpp", xml = "xml", lmx = "xml", ctx = "xml", xsl = "xml", xsd = "xml", rlx = "xml", css = "xml", dtd = "xml", @@ -34,20 +48,16 @@ lexer = nil -- main lexer, global (for the moment needed for themes) local function loadscitelexer() if not lexer then - dir.push(lexerroot) - lexer = dofile("scite-context-lexer.lua") - dofile("themes/scite-context-theme.lua") - dir.pop() + lexer = require("scite-context-lexer") + require("scite-context-theme") -- uses lexer end return lexer end local loadedlexers = setmetatableindex(function(t,k) local l = knownlexers[k] or k - dir.push(lexerroot) loadscitelexer() local v = lexer.load(formatters["scite-context-lexer-%s"](l)) - dir.pop() t[l] = v t[k] = v return v @@ -57,8 +67,8 @@ scite.loadedlexers = loadedlexers scite.knownlexers = knownlexers scite.loadscitelexer = loadscitelexer -local f_fore_bold = formatters['.%s { display: inline ; font-weight: bold ; color: #%s%s%s ; }'] -local f_fore_none = formatters['.%s { display: inline ; font-weight: normal ; color: #%s%s%s ; }'] +local f_fore_bold = formatters['.%s { display: inline ; font-weight: bold ; color: #%02X%02X%02X ; }'] +local f_fore_none = formatters['.%s { display: inline ; font-weight: normal ; color: #%02X%02X%02X ; }'] local f_none_bold = formatters['.%s { display: inline ; font-weight: bold ; }'] local f_none_none = formatters['.%s { display: inline ; font-weight: normal ; }'] local f_div_class = formatters['<div class="%s">%s</div>'] @@ -91,7 +101,7 @@ local function exportcsslexing() if not css then loadscitelexer() local function black(f) - return (f[1] == f[2]) and (f[2] == f[3]) and (f[3] == '00') + return (#f == 0 and f[1] == 0) or ((f[1] == f[2]) and (f[2] == f[3]) and (f[3] == 0)) end local result, r = { }, 0 for k, v in table.sortedhash(lexer.context.styles) do @@ -99,17 +109,10 @@ local function exportcsslexing() local fore = v.fore r = r + 1 if fore and not black(fore) then - if bold then - result[r] = f_fore_bold(k,fore[1],fore[2],fore[3]) - else - result[r] = f_fore_none(k,fore[1],fore[2],fore[3]) - end + local cr, cg, cb = fore[1], fore[2], fore[3] + result[r] = (bold and f_fore_bold or f_fore_none)(k,cr,cg or cr,cb or cr) else - if bold then - result[r] = f_none_bold(k) - else - result[r] = f_none_none(k) - end + result[r] = (bold and f_none_bold or f_none_none)(k) end end css = concat(result,"\n") diff --git a/tex/context/base/mkiv/util-seq.lua b/tex/context/base/mkiv/util-seq.lua index 32fe59096..5836f5eca 100644 --- a/tex/context/base/mkiv/util-seq.lua +++ b/tex/context/base/mkiv/util-seq.lua @@ -293,7 +293,7 @@ sequencers.compile = compile -- todo: use sequencer (can have arguments and returnvalues etc now) -local template_yes = [[ +local template_yes_state = [[ %s return function(head%s) local ok, done = false, false @@ -301,6 +301,13 @@ return function(head%s) return head, done end]] +local template_yes_nostate = [[ +%s +return function(head%s) +%s + return head, true +end]] + local template_nop = [[ return function() return false, false @@ -308,6 +315,7 @@ end]] function sequencers.nodeprocessor(t,nofarguments) -- todo: handle 'kind' in plug into tostring local list, order, kind, gskip, askip = t.list, t.order, t.kind, t.gskip, t.askip + local nostate = t.nostate local vars, calls, args, n = { }, { }, nil, 0 if nofarguments == 0 then args = "" @@ -335,18 +343,24 @@ function sequencers.nodeprocessor(t,nofarguments) -- todo: handle 'kind' in plug n = n + 1 vars[n] = formatters["local %s = %s"](localized,action) -- only difference with tostring is kind and rets (why no return) - if kind[action] == "nohead" then - calls[n] = formatters[" ok = %s(head%s) done = done or ok"](localized,args) + if nostate then + if kind[action] == "nohead" then + calls[n] = formatters[" %s(head%s)"](localized,args) + else + calls[n] = formatters[" head = %s(head%s)"](localized,args) + end else - calls[n] = formatters[" head, ok = %s(head%s) done = done or ok"](localized,args) + if kind[action] == "nohead" then + calls[n] = formatters[" ok = %s(head%s) if ok then done = true end"](localized,args) + else + calls[n] = formatters[" head, ok = %s(head%s) if ok then done = true end"](localized,args) + end end --- local s = " print('" .. tostring(group) .. " " .. tostring(action) .. " : ' .. tostring(head)) " --- calls[n] = s .. calls[n] .. s end end end end - local processor = #calls > 0 and formatters[template_yes](concat(vars,"\n"),args,concat(calls,"\n")) or template_nop + local processor = #calls > 0 and formatters[nostate and template_yes_nostate or template_yes_state](concat(vars,"\n"),args,concat(calls,"\n")) or template_nop -- print(processor) return processor end diff --git a/tex/context/base/mkiv/util-sql-imp-client.lua b/tex/context/base/mkiv/util-sql-imp-client.lua index 9a0fbc299..a2763feac 100644 --- a/tex/context/base/mkiv/util-sql-imp-client.lua +++ b/tex/context/base/mkiv/util-sql-imp-client.lua @@ -1,4 +1,4 @@ -if not modules then modules = { } end modules ['util-sql-client'] = { +if not modules then modules = { } end modules ['util-sql-imp-client'] = { version = 1.001, comment = "companion to util-sql.lua", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -26,6 +26,8 @@ local serialize = sql.serialize local deserialize = sql.deserialize local getserver = sql.getserver +local osclock = os.gettimeofday + -- Experiments with an p/action demonstrated that there is not much gain. We could do a runtime -- capture but creating all the small tables is not faster and it doesn't work well anyway. @@ -107,11 +109,11 @@ local function splitdata(data) -- todo: hash on first line ... maybe move to cli end end p = Cf(Ct("") * p,rawset) * newline^1 -if getserver() == "mssql" then - p = skipfirst * skipdashes * Ct(p^0) -else - p = skipfirst * Ct(p^0) -end + if getserver() == "mssql" then + p = skipfirst * skipdashes * Ct(p^0) + else + p = skipfirst * Ct(p^0) + end cache[first] = { parser = p, keys = keys } local entries = lpegmatch(p,data) return entries or { }, keys @@ -132,6 +134,11 @@ local t_runner = { mssql = [[sqlcmd -S %host% %?U: -U "%username%" ?% %?P: -P "%password%" ?% -I -W -w 65535 -s"]] .. "\t" .. [[" -m 1 -i "%queryfile%" -o "%resultfile%"]], } +local t_runner_login = { + mysql = [[mysql --login-path="%login%" --batch --database="%database%" --default-character-set=utf8 < "%queryfile%" > "%resultfile%"]], + mssql = [[sqlcmd -S %host% %?U: -U "%username%" ?% %?P: -P "%password%" ?% -I -W -w 65535 -s"]] .. "\t" .. [[" -m 1 -i "%queryfile%" -o "%resultfile%"]], +} + local t_preamble = { mysql = [[ SET GLOBAL SQL_MODE=ANSI_QUOTES; @@ -144,10 +151,10 @@ SET NOCOUNT ON; ]], } -local function dataprepared(specification,client) +local function dataprepared(specification) local query = preparetemplate(specification) if query then - local preamble = t_preamble[getserver()] or t_preamble.mysql + local preamble = t_preamble[getserver()] or t_preamble.mysql if preamble then preamble = replacetemplate(preamble,specification.variables,'sql') query = preamble .. "\n" .. query @@ -165,14 +172,16 @@ local function dataprepared(specification,client) end end -local function datafetched(specification,client) - local runner = t_runner[getserver()] or t_runner.mysql +local function datafetched(specification) + local runner = (specification.login and t_runner_login or t_runner)[getserver()] or t_runner.mysql local command = replacetemplate(runner,specification) if trace_sql then local t = osclock() report_state("command: %s",command) + -- for now we don't use sandbox.registerrunners as this module is + -- also used outside context local okay = os.execute(command) - report_state("fetchtime: %.3f sec",osclock()-t) -- not okay under linux + report_state("fetchtime: %.3f sec, return code: %i",osclock()-t,okay) -- not okay under linux return okay == 0 else return os.execute(command) == 0 @@ -220,12 +229,12 @@ local function execute(specification) report_state("error in specification") return end - if not dataprepared(specification,methods.client) then + if not dataprepared(specification) then report_state("error in preparation") return end - if not datafetched(specification,methods.client) then - report_state("error in fetching, query: %s",string.collapsespaces(io.loaddata(specification.queryfile))) + if not datafetched(specification) then + report_state("error in fetching, query: %s",string.collapsespaces(io.loaddata(specification.queryfile) or "?")) return end local data = dataloaded(specification) diff --git a/tex/context/base/mkiv/util-sql-imp-library.lua b/tex/context/base/mkiv/util-sql-imp-library.lua index 15754e26a..e16853612 100644 --- a/tex/context/base/mkiv/util-sql-imp-library.lua +++ b/tex/context/base/mkiv/util-sql-imp-library.lua @@ -1,4 +1,4 @@ -if not modules then modules = { } end modules ['util-sql-library'] = { +if not modules then modules = { } end modules ['util-sql-imp-library'] = { version = 1.001, comment = "companion to util-sql.lua", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -143,7 +143,7 @@ local function fetched(specification,query,converter) local q = query[i] local r, m = connection:execute(q) if m then - report_state("error in query to host %a: %s",specification.host,string.collapsespaces(q)) + report_state("error in query to host %a: %s",specification.host,string.collapsespaces(q or "?")) if m then report_state("message: %s",m) end diff --git a/tex/context/base/mkiv/util-sql-imp-sqlite.lua b/tex/context/base/mkiv/util-sql-imp-sqlite.lua new file mode 100644 index 000000000..1a960c1c3 --- /dev/null +++ b/tex/context/base/mkiv/util-sql-imp-sqlite.lua @@ -0,0 +1,237 @@ +if not modules then modules = { } end modules ['util-sql-imp-sqlite'] = { + version = 1.001, + comment = "companion to util-sql.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local next = next + +local sql = require("util-sql") +----- sql = utilities.sql +local sqlite = require("swiglib.sqlite.core") +local swighelpers = require("swiglib.helpers.core") + +-- sql.sqlite = sqlite -- maybe in the module itself + +-- inspect(table.sortedkeys(sqlite)) + +local trace_sql = false trackers.register("sql.trace", function(v) trace_sql = v end) +local trace_queries = false trackers.register("sql.queries",function(v) trace_queries = v end) +local report_state = logs.reporter("sql","sqlite") + +local helpers = sql.helpers +local methods = sql.methods +local validspecification = helpers.validspecification +local preparetemplate = helpers.preparetemplate +local splitdata = helpers.splitdata +local serialize = sql.serialize +local deserialize = sql.deserialize +local getserver = sql.getserver + +local setmetatable = setmetatable +local formatters = string.formatters + +local get_list_item = sqlite.char_p_array_getitem +local is_okay = sqlite.SQLITE_OK +local execute_query = sqlite.sqlite3_exec_lua_callback +local error_message = sqlite.sqlite3_errmsg + +local new_db = sqlite.new_sqlite3_p_array +local open_db = sqlite.sqlite3_open +local get_db = sqlite.sqlite3_p_array_getitem +local close_db = sqlite.sqlite3_close +local dispose_db = sqlite.delete_sqlite3_p_array + +local cache = { } + +setmetatable(cache, { + __gc = function(t) + for k, v in next, t do + if trace_sql then + report_state("closing session %a",k) + end + close_db(v.dbh) + dispose_db(v.db) + end + end +}) + +-- synchronous journal_mode locking_mode 1000 logger inserts +-- +-- normal normal normal 6.8 +-- off off normal 0.1 +-- normal off normal 2.1 +-- normal persist normal 5.8 +-- normal truncate normal 4.2 +-- normal truncate exclusive 4.1 + +local f_preamble = formatters[ [[ +ATTACH `%s` AS `%s` ; +PRAGMA `%s`.synchronous = normal ; +PRAGMA journal_mode = truncate ; +]] ] + +local function execute(specification) + if trace_sql then + report_state("executing sqlite") + end + if not validspecification(specification) then + report_state("error in specification") + end + local query = preparetemplate(specification) + if not query then + report_state("error in preparation") + return + end + local base = specification.database -- or specification.presets and specification.presets.database + if not base then + report_state("no database specified") + return + end + local filename = file.addsuffix(base,"db") + local result = { } + local keys = { } + local id = specification.id + local db = nil + local dbh = nil + local okay = false + local preamble = nil + if id then + local session = cache[id] + if session then + dbh = session.dbh + okay = is_okay + else + db = new_db(1) + okay = open_db(filename,db) + dbh = get_db(db,0) + preamble = f_preamble(filename,base,base) + if okay ~= is_okay then + report_state("no session database specified") + else + cache[id] = { + name = filename, + db = db, + dbh = dbh, + } + end + end + else + db = new_db(1) + okay = open_db(filename,db) + dbh = get_db(db,0) + preamble = f_preamble(filename,base,base) + end + if okay ~= is_okay then + report_state("no database opened") + else + local converter = specification.converter + local keysdone = false + local nofrows = 0 + local callback = nil + if preamble then + query = preamble .. query -- only needed in open + end + if converter then + converter = converter.sqlite + callback = function(data,nofcolumns,values,fields) + local column = { } + for i=0,nofcolumns-1 do + column[i+1] = get_list_item(values,i) + end + nofrows = nofrows + 1 + result[nofrows] = converter(column) + return is_okay + end + -- + -- callback = converter.sqlite + else + callback = function(data,nofcolumns,values,fields) + local column = { } + for i=0,nofcolumns-1 do + local field + if keysdone then + field = keys[i+1] + else + field = get_list_item(fields,i) + keys[i+1] = field + end + column[field] = get_list_item(values,i) + end + nofrows = nofrows + 1 + keysdone = true + result[nofrows] = column + return is_okay + end + end + local okay = execute_query(dbh,query,callback,nil,nil) + if okay ~= is_okay then + report_state("error: %s",error_message(dbh)) + -- elseif converter then + -- result = converter.sqlite(result) + end + end + if not id then + close_db(dbh) + dispose_db(db) + end + return result, keys +end + +local wraptemplate = [[ +local converters = utilities.sql.converters +local deserialize = utilities.sql.deserialize + +local tostring = tostring +local tonumber = tonumber +local booleanstring = string.booleanstring + +%s + +return function(cells) + -- %s (not needed) + -- %s (not needed) + return { + %s + } +end +]] + +local celltemplate = "cells[%s]" + +-- todo: how to deal with result ... pass via temp global .. bah .. or +-- also pass the execute here ... not now +-- +-- local wraptemplate = [[ +-- local converters = utilities.sql.converters +-- local deserialize = utilities.sql.deserialize +-- +-- local tostring = tostring +-- local tonumber = tonumber +-- local booleanstring = string.booleanstring +-- +-- local get_list_item = utilities.sql.sqlite.char_p_array_getitem +-- local is_okay = utilities.sql.sqlite.SQLITE_OK +-- +-- %s +-- +-- return function(data,nofcolumns,values,fields) +-- -- no %s (data) needed +-- -- no %s (i) needed +-- local cells = { } +-- for i=0,nofcolumns-1 do +-- cells[i+1] = get_list_item(values,i) +-- end +-- result[#result+1] = { %s } +-- return is_okay +-- end +-- ]] + +methods.sqlite = { + execute = execute, + usesfiles = false, + wraptemplate = wraptemplate, + celltemplate = celltemplate, +} diff --git a/tex/context/base/mkiv/util-sql-imp-swiglib.lua b/tex/context/base/mkiv/util-sql-imp-swiglib.lua index af7012392..786b4bffc 100644 --- a/tex/context/base/mkiv/util-sql-imp-swiglib.lua +++ b/tex/context/base/mkiv/util-sql-imp-swiglib.lua @@ -1,4 +1,4 @@ -if not modules then modules = { } end modules ['util-sql-swiglib'] = { +if not modules then modules = { } end modules ['util-sql-imp-swiglib'] = { version = 1.001, comment = "companion to util-sql.lua", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", @@ -132,31 +132,31 @@ end -- -local typemap = mysql.MYSQL_TYPE_VAR_STRING and { - [mysql.MYSQL_TYPE_VAR_STRING ] = "string", - [mysql.MYSQL_TYPE_STRING ] = "string", - [mysql.MYSQL_TYPE_DECIMAL ] = "number", - [mysql.MYSQL_TYPE_SHORT ] = "number", - [mysql.MYSQL_TYPE_LONG ] = "number", - [mysql.MYSQL_TYPE_FLOAT ] = "number", - [mysql.MYSQL_TYPE_DOUBLE ] = "number", - [mysql.MYSQL_TYPE_LONGLONG ] = "number", - [mysql.MYSQL_TYPE_INT24 ] = "number", - [mysql.MYSQL_TYPE_YEAR ] = "number", - [mysql.MYSQL_TYPE_TINY ] = "number", - [mysql.MYSQL_TYPE_TINY_BLOB ] = "binary", - [mysql.MYSQL_TYPE_MEDIUM_BLOB] = "binary", - [mysql.MYSQL_TYPE_LONG_BLOB ] = "binary", - [mysql.MYSQL_TYPE_BLOB ] = "binary", - [mysql.MYSQL_TYPE_DATE ] = "date", - [mysql.MYSQL_TYPE_NEWDATE ] = "date", - [mysql.MYSQL_TYPE_DATETIME ] = "datetime", - [mysql.MYSQL_TYPE_TIME ] = "time", - [mysql.MYSQL_TYPE_TIMESTAMP ] = "time", - [mysql.MYSQL_TYPE_ENUM ] = "set", - [mysql.MYSQL_TYPE_SET ] = "set", - [mysql.MYSQL_TYPE_NULL ] = "null", -} +-- local typemap = mysql.MYSQL_TYPE_VAR_STRING and { +-- [mysql.MYSQL_TYPE_VAR_STRING ] = "string", +-- [mysql.MYSQL_TYPE_STRING ] = "string", +-- [mysql.MYSQL_TYPE_DECIMAL ] = "number", +-- [mysql.MYSQL_TYPE_SHORT ] = "number", +-- [mysql.MYSQL_TYPE_LONG ] = "number", +-- [mysql.MYSQL_TYPE_FLOAT ] = "number", +-- [mysql.MYSQL_TYPE_DOUBLE ] = "number", +-- [mysql.MYSQL_TYPE_LONGLONG ] = "number", +-- [mysql.MYSQL_TYPE_INT24 ] = "number", +-- [mysql.MYSQL_TYPE_YEAR ] = "number", +-- [mysql.MYSQL_TYPE_TINY ] = "number", +-- [mysql.MYSQL_TYPE_TINY_BLOB ] = "binary", +-- [mysql.MYSQL_TYPE_MEDIUM_BLOB] = "binary", +-- [mysql.MYSQL_TYPE_LONG_BLOB ] = "binary", +-- [mysql.MYSQL_TYPE_BLOB ] = "binary", +-- [mysql.MYSQL_TYPE_DATE ] = "date", +-- [mysql.MYSQL_TYPE_NEWDATE ] = "date", +-- [mysql.MYSQL_TYPE_DATETIME ] = "datetime", +-- [mysql.MYSQL_TYPE_TIME ] = "time", +-- [mysql.MYSQL_TYPE_TIMESTAMP ] = "time", +-- [mysql.MYSQL_TYPE_ENUM ] = "set", +-- [mysql.MYSQL_TYPE_SET ] = "set", +-- [mysql.MYSQL_TYPE_NULL ] = "null", +-- } -- real_escape_string @@ -436,7 +436,7 @@ local function datafetched(specification,query,converter) local q = query[i] local r, m = connection:execute(q) if m then - report_state("error in query, stage: %s",string.collapsespaces(q)) + report_state("error in query, stage: %s",string.collapsespaces(q or "?")) message = message and format("%s\n%s",message,m) or m end if type(r) == "table" then diff --git a/tex/context/base/mkiv/util-sql-loggers.lua b/tex/context/base/mkiv/util-sql-loggers.lua index ceb1ff75c..4473f8971 100644 --- a/tex/context/base/mkiv/util-sql-loggers.lua +++ b/tex/context/base/mkiv/util-sql-loggers.lua @@ -65,12 +65,21 @@ local template = [[ DEFAULT CHARSET = utf8 ; ]] +local sqlite_template = [[ + CREATE TABLE IF NOT EXISTS %basename% ( + `id` INTEGER PRIMARY KEY AUTOINCREMENT, + `time` INTEGER NOT NULL, + `type` INTEGER NOT NULL, + `action` TEXT NOT NULL, + `data` TEXT + ) ; +]] + function loggers.createdb(presets,datatable) local db = checkeddb(presets,datatable) - db.execute { - template = template, + template = db.usedmethod == "sqlite" and sqlite_template or template, variables = { basename = db.basename, }, @@ -115,7 +124,11 @@ local template =[[ ) ; ]] -function loggers.save(db,data) -- beware, we pass type and action in the data (saves a table) +-- beware, when we either pass a dat afield explicitly or we're using +-- a flat table and then nill type and action in the data (which +-- saves a table) + +function loggers.save(db,data) if data then @@ -123,8 +136,16 @@ function loggers.save(db,data) -- beware, we pass type and action in the data (s local kind = totype[data.type] local action = data.action or "unknown" - data.type = nil - data.action = nil + local extra = data.data + + if extra then + -- we have a dedicated data table + data = extra + else + -- we have a flat table + data.type = nil + data.action = nil + end db.execute { template = template, @@ -141,28 +162,49 @@ function loggers.save(db,data) -- beware, we pass type and action in the data (s end --- local template =[[ --- REMOVE FROM --- %basename% --- WHERE --- `token` = '%token%' ; --- ]] --- --- function loggers.remove(db,token) --- --- db.execute { --- template = template, --- variables = { --- basename = db.basename, --- token = token, --- }, --- } --- --- if trace_sql then --- report("removed: %s",token) --- end --- --- end +local template =[[ + DELETE FROM %basename% %WHERE% ; +]] + +function loggers.cleanup(db,specification) + + specification = specification or { } + + local today = os.date("*t") + local before = specification.before or today + local where = { } + + if type(before) == "number" then + before = os.date(before) + end + + before = os.time { + day = before.day or today.day, + month = before.month or today.month, + year = before.year or today.year, + hour = before.hour or 0, + minute = before.minute or 0, + second = before.second or 0, + isdst = true, + } + + where[#where+1] = format("`time` < %s",before) + + db.execute { + template = template, + variables = { + basename = db.basename, + WHERE = format("WHERE\n%s",concat(where," AND ")), + }, + } + + if db.usedmethod == "sqlite" then + db.execute { + template = "VACUUM ;", + } + end + +end local template_nop =[[ SELECT diff --git a/tex/context/base/mkiv/util-sql-tickets.lua b/tex/context/base/mkiv/util-sql-tickets.lua index 5e958299d..f392c0b91 100644 --- a/tex/context/base/mkiv/util-sql-tickets.lua +++ b/tex/context/base/mkiv/util-sql-tickets.lua @@ -53,7 +53,7 @@ tickets.statustags = statustags local s_unknown = status.unknown local s_pending = status.pending local s_busy = status.busy -local s_finished = status.finished +----- s_finished = status.finished local s_dependent = status.dependent local s_error = status.error local s_deleted = status.deleted @@ -398,7 +398,8 @@ local template_cleanup_nop =[[ function tickets.cleanupdb(db,delta,nodata) -- maybe delta in db - local time = delta and (ostime() - delta) or 0 + local now = ostime() + local time = delta and (now - delta) or now local records, keys = db.execute { template = nodata and template_cleanup_nop or template_cleanup_yes, diff --git a/tex/context/base/mkiv/util-sql.lua b/tex/context/base/mkiv/util-sql.lua index 84cbb1692..09056c048 100644 --- a/tex/context/base/mkiv/util-sql.lua +++ b/tex/context/base/mkiv/util-sql.lua @@ -65,8 +65,6 @@ local P, S, V, C, Cs, Ct, Cc, Cg, Cf, patterns, lpegmatch = lpeg.P, lpeg.S, lpeg local concat = table.concat local osuuid = os.uuid -local osclock = os.clock or os.time -local ostime = os.time local setmetatableindex = table.setmetatableindex local trace_sql = false trackers.register("sql.trace", function(v) trace_sql = v end) @@ -242,8 +240,9 @@ local function validspecification(specification) setmetatable(specification,defaults) end local templatefile = specification.templatefile or "query" - local queryfile = specification.queryfile or presets.queryfile or file.nameonly(templatefile) .. "-temp.sql" - local resultfile = specification.resultfile or presets.resultfile or file.nameonly(templatefile) .. "-temp.dat" + local name = file.nameonly(templatefile) + local queryfile = specification.queryfile or presets.queryfile or format("%s-temp.sql",name) + local resultfile = specification.resultfile or presets.resultfile or format("%s-temp.dat",name) specification.queryfile = queryfile specification.resultfile = resultfile if trace_sql then @@ -313,21 +312,36 @@ sql.setserver("mysql") -- helper: +local sqlmethods = sql.methods + function sql.usedatabase(presets,datatable) local name = datatable or presets.datatable if name then - local method = presets.method and sql.methods[presets.method] or sql.methods.client + local usedmethod = presets.method + local method = usedmethod and sqlmethods[usedmethod] + if not method then + usedmethod = currentmethod + method = usedmethod and sqlmethods[usedmethod] + end + if not method then + usedmethod = sql.methods.client + method = usedmethod and sqlmethods[usedmethod] + end local base = presets.database or "test" local basename = format("`%s`.`%s`",base,name) local execute = nil local m_execute = method.execute - if method.usesfiles then + if not m_execute then + execute = function() + report_state("no valid execute handler") + end + elseif method.usesfiles then local queryfile = presets.queryfile or format("%s-temp.sql",name) local resultfile = presets.resultfile or format("%s-temp.dat",name) execute = function(specification) -- variables template - if not specification.presets then specification.presets = presets end - if not specification.queryfile then specification.queryfile = queryfile end - if not specification.resultfile then specification.resultfile = queryfile end + if not specification.presets then specification.presets = presets end + if not specification.queryfile then specification.queryfile = queryfile end + if not specification.resultfile then specification.resultfile = resultfile end return m_execute(specification) end else @@ -349,6 +363,7 @@ function sql.usedatabase(presets,datatable) end end return { + usedmethod = usedmethod, presets = preset, base = base, name = name, diff --git a/tex/context/base/mkiv/util-str.lua b/tex/context/base/mkiv/util-str.lua index 28b75dbc5..cebbc6be2 100644 --- a/tex/context/base/mkiv/util-str.lua +++ b/tex/context/base/mkiv/util-str.lua @@ -10,7 +10,7 @@ utilities = utilities or { } utilities.strings = utilities.strings or { } local strings = utilities.strings -local format, gsub, rep, sub = string.format, string.gsub, string.rep, string.sub +local format, gsub, rep, sub, find = string.format, string.gsub, string.rep, string.sub, string.find local load, dump = load, string.dump local tonumber, type, tostring = tonumber, type, tostring local unpack, concat = table.unpack, table.concat @@ -141,6 +141,7 @@ local pattern = )^1) function strings.tabtospace(str,tab) + -- no real gain in first checking if a \t is there return lpegmatch(pattern,str,1,tab or 7) end @@ -385,6 +386,43 @@ function number.signed(i) end end +-- maybe to util-num + +local digit = patterns.digit +local period = patterns.period +local three = digit * digit * digit + +local splitter = Cs ( + (((1 - (three^1 * period))^1 + C(three)) * (Carg(1) * three)^1 + C((1-period)^1)) + * (P(1)/"" * Carg(2)) * C(2) +) + +patterns.formattednumber = splitter + +function number.formatted(n,sep1,sep2) + local s = type(s) == "string" and n or format("%0.2f",n) + if sep1 == true then + return lpegmatch(splitter,s,1,".",",") + elseif sep1 == "." then + return lpegmatch(splitter,s,1,sep1,sep2 or ",") + elseif sep1 == "," then + return lpegmatch(splitter,s,1,sep1,sep2 or ".") + else + return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".") + end +end + +-- print(number.formatted(1)) +-- print(number.formatted(12)) +-- print(number.formatted(123)) +-- print(number.formatted(1234)) +-- print(number.formatted(12345)) +-- print(number.formatted(123456)) +-- print(number.formatted(1234567)) +-- print(number.formatted(12345678)) +-- print(number.formatted(12345678,true)) +-- print(number.formatted(1234.56,"!","?")) + local zero = P("0")^1 / "" local plus = P("+") / "" local minus = P("-") @@ -412,6 +450,31 @@ function number.sparseexponent(f,n) return tostring(n) end +local hf = { } +local hs = { } + +setmetatable(hf, { __index = function(t,k) + local v = "%." .. k .. "f" + t[k] = v + return v +end } ) + +setmetatable(hs, { __index = function(t,k) + local v = "%" .. k .. "s" + t[k] = v + return v +end } ) + +function number.formattedfloat(n,b,a) + local s = format(hf[a],n) + local l = (b or 0) + (a or 0) + 1 + if #s < l then + return format(hs[l],s) + else + return s + end +end + local template = [[ %s %s @@ -442,6 +505,7 @@ local autodouble=string.autodouble local sequenced=table.sequenced local formattednumber=number.formatted local sparseexponent=number.sparseexponent +local formattedfloat=number.formattedfloat ]] else @@ -467,6 +531,7 @@ else sequenced = table.sequenced, formattednumber = number.formatted, sparseexponent = number.sparseexponent, + formattedfloat = number.formattedfloat } end @@ -484,6 +549,9 @@ setmetatable(arguments, { __index = }) local prefix_any = C((S("+- .") + R("09"))^0) +local prefix_sub = (C((S("+-") + R("09"))^0) + Cc(0)) + * P(".") + * (C((S("+-") + R("09"))^0) + Cc(0)) local prefix_tab = P("{") * C((1-P("}"))^0) * P("}") + C((1-R("az","AZ","09","%%"))^0) -- we've split all cases as then we can optimize them (let's omit the fuzzy u) @@ -557,6 +625,11 @@ local format_F = function(f) -- beware, no cast to number end end +local format_k = function(b,a) -- slow + n = n + 1 + return format("formattedfloat(a%s,%i,%i)",n,b or 0, a or 0) +end + local format_g = function(f) n = n + 1 return format("format('%%%sg',a%s)",f,n) @@ -732,43 +805,6 @@ local format_W = function(f) -- handy when doing depth related indent return format("nspaces[%s]",tonumber(f) or 0) end --- maybe to util-num - -local digit = patterns.digit -local period = patterns.period -local three = digit * digit * digit - -local splitter = Cs ( - (((1 - (three^1 * period))^1 + C(three)) * (Carg(1) * three)^1 + C((1-period)^1)) - * (P(1)/"" * Carg(2)) * C(2) -) - -patterns.formattednumber = splitter - -function number.formatted(n,sep1,sep2) - local s = type(s) == "string" and n or format("%0.2f",n) - if sep1 == true then - return lpegmatch(splitter,s,1,".",",") - elseif sep1 == "." then - return lpegmatch(splitter,s,1,sep1,sep2 or ",") - elseif sep1 == "," then - return lpegmatch(splitter,s,1,sep1,sep2 or ".") - else - return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".") - end -end - --- print(number.formatted(1)) --- print(number.formatted(12)) --- print(number.formatted(123)) --- print(number.formatted(1234)) --- print(number.formatted(12345)) --- print(number.formatted(123456)) --- print(number.formatted(1234567)) --- print(number.formatted(12345678)) --- print(number.formatted(12345678,true)) --- print(number.formatted(1234.56,"!","?")) - local format_m = function(f) n = n + 1 if not f or f == "" then @@ -801,9 +837,16 @@ end local format_extension = function(extensions,f,name) local extension = extensions[name] or "tostring(%s)" local f = tonumber(f) or 1 + local w = find(extension,"%.%.%.") if f == 0 then + if w then + extension = gsub(extension,"%.%.%.","") + end return extension elseif f == 1 then + if w then + extension = gsub(extension,"%.%.%.","%%s") + end n = n + 1 local a = "a" .. n return format(extension,a,a) -- maybe more times? @@ -811,10 +854,16 @@ local format_extension = function(extensions,f,name) local a = "a" .. (n + f + 1) return format(extension,a,a) else + if w then + extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s") + end + -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we + -- cache we don't save much and there are hardly any extensions anyway local t = { } for i=1,f do n = n + 1 - t[#t+1] = "a" .. n + -- t[#t+1] = "a" .. n + t[i] = "a" .. n end return format(extension,unpack(t)) end @@ -824,6 +873,8 @@ end -- extensions : %!tag! +-- can be made faster but not called that often + local builder = Cs { "start", start = ( ( @@ -840,6 +891,7 @@ local builder = Cs { "start", + V("S") -- new + V("Q") -- new + V("N") -- new + + V("k") -- new -- + V("r") + V("h") + V("H") + V("u") + V("U") @@ -852,10 +904,10 @@ local builder = Cs { "start", + V("a") -- new + V("A") -- new + V("j") + V("J") -- stripped e E - + V("m") + V("M") -- new + + V("m") + V("M") -- new (formatted number) + V("z") -- new -- - -- + V("?") -- ignores probably messed up % + -- + V("?") -- ignored, probably messed up % ) + V("*") ) @@ -879,6 +931,7 @@ local builder = Cs { "start", ["S"] = (prefix_any * P("S")) / format_S, -- %S => %s (tostring) ["Q"] = (prefix_any * P("Q")) / format_S, -- %Q => %q (tostring) ["N"] = (prefix_any * P("N")) / format_N, -- %N => tonumber (strips leading zeros) + ["k"] = (prefix_sub * P("k")) / format_k, -- %k => like f but with n.m ["c"] = (prefix_any * P("c")) / format_c, -- %c => utf character (extension to regular) ["C"] = (prefix_any * P("C")) / format_C, -- %c => U+.... utf character -- @@ -1065,10 +1118,6 @@ patterns.luaquoted = Cs(Cc('"') * ((1-S('"\n'))^1 + P('"')/'\\"' + P('\n')/'\\n" -- escaping by lpeg is faster for strings without quotes, slower on a string with quotes, but -- faster again when other q-escapables are found (the ones we don't need to escape) --- add(formatters,"xml", [[lpegmatch(xmlescape,%s)]],[[local xmlescape = lpeg.patterns.xmlescape]]) --- add(formatters,"tex", [[lpegmatch(texescape,%s)]],[[local texescape = lpeg.patterns.texescape]]) --- add(formatters,"lua", [[lpegmatch(luaescape,%s)]],[[local luaescape = lpeg.patterns.luaescape]]) - if _LUAVERSION < 5.2 then add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape") diff --git a/tex/context/base/mkiv/util-tab.lua b/tex/context/base/mkiv/util-tab.lua index a6239adf4..fb2702228 100644 --- a/tex/context/base/mkiv/util-tab.lua +++ b/tex/context/base/mkiv/util-tab.lua @@ -12,7 +12,7 @@ local tables = utilities.tables local format, gmatch, gsub, sub = string.format, string.gmatch, string.gsub, string.sub local concat, insert, remove, sort = table.concat, table.insert, table.remove, table.sort -local setmetatable, getmetatable, tonumber, tostring = setmetatable, getmetatable, tonumber, tostring +local setmetatable, getmetatable, tonumber, tostring, rawget = setmetatable, getmetatable, tonumber, tostring, rawget local type, next, rawset, tonumber, tostring, load, select = type, next, rawset, tonumber, tostring, load, select local lpegmatch, P, Cs, Cc = lpeg.match, lpeg.P, lpeg.Cs, lpeg.Cc local sortedkeys, sortedpairs = table.sortedkeys, table.sortedpairs @@ -169,7 +169,8 @@ function table.tocsv(t,specification) r[f] = tostring(field) end end - result[#result+1] = concat(r,separator) + -- result[#result+1] = concat(r,separator) + result[i+1] = concat(r,separator) end return concat(result,"\n") else @@ -485,11 +486,12 @@ end local selfmapper = { __index = function(t,k) t[k] = k return k end } -function table.twowaymapper(t) - if not t then - t = { } - else - for i=0,#t do +function table.twowaymapper(t) -- takes a 0/1 .. n indexed table and returns + if not t then -- it with string-numbers as indices + reverse + t = { } -- mapping (all strings) .. used in cvs etc but + else -- typically a helper that one forgets about + local zero = rawget(t,0) -- so it might move someplace else + for i=zero and 0 or 1,#t do local ti = t[i] -- t[1] = "one" if ti then local i = tostring(i) @@ -497,7 +499,6 @@ function table.twowaymapper(t) t[ti] = i -- t["one"] = "1" end end - t[""] = t[0] or "" end -- setmetatableindex(t,"key") setmetatable(t,selfmapper) @@ -563,98 +564,68 @@ local original_serialize = table.serialize -- the extensive one, the one we star -- latest lua for the value of #n (with holes) .. anyway for tracing purposes we want -- indices / keys being sorted, so it will never be real fast -local function serialize(root,name,specification) - - if type(specification) == "table" then - return original_serialize(root,name,specification) -- the original one - end +local is_simple_table = table.is_simple_table - local t -- = { } - local n = 1 - local unknown = false - --- local function simple_table(t) --- local ts = #t --- if ts > 0 then --- local n = 0 --- for _, v in next, t do --- n = n + 1 --- if type(v) == "table" then +-- local function is_simple_table(t) +-- local nt = #t +-- if nt > 0 then +-- local n = 0 +-- for _, v in next, t do +-- n = n + 1 +-- if type(v) == "table" then +-- return nil +-- end +-- end +-- -- local haszero = t[0] +-- local haszero = rawget(t,0) -- don't trigger meta +-- if n == nt then +-- local tt = { } +-- for i=1,nt do +-- local v = t[i] +-- local tv = type(v) +-- if tv == "number" then +-- tt[i] = v -- not needed tostring(v) +-- elseif tv == "string" then +-- tt[i] = format("%q",v) -- f_string(v) +-- elseif tv == "boolean" then +-- tt[i] = v and "true" or "false" +-- else -- return nil -- end -- end --- if n == ts then --- local tt = { } --- local nt = 0 --- for i=1,ts do --- local v = t[i] --- local tv = type(v) --- nt = nt + 1 --- if tv == "number" then --- tt[nt] = v --- elseif tv == "string" then --- tt[nt] = format("%q",v) -- f_string(v) --- elseif tv == "boolean" then --- tt[nt] = v and "true" or "false" --- else --- return nil --- end +-- return tt +-- elseif haszero and (n == nt + 1) then +-- local tt = { } +-- for i=0,nt do +-- local v = t[i] +-- local tv = type(v) +-- if tv == "number" then +-- tt[i+1] = v -- not needed tostring(v) +-- elseif tv == "string" then +-- tt[i+1] = format("%q",v) -- f_string(v) +-- elseif tv == "boolean" then +-- tt[i+1] = v and "true" or "false" +-- else +-- return nil -- end --- return tt -- end +-- tt[1] = "[0] = " .. tt[1] +-- return tt -- end --- return nil -- end +-- return nil +-- end - local function simple_table(t) - local nt = #t - if nt > 0 then - local n = 0 - for _, v in next, t do - n = n + 1 - if type(v) == "table" then - return nil - end - end - local haszero = t[0] - if n == nt then - local tt = { } - for i=1,nt do - local v = t[i] - local tv = type(v) - if tv == "number" then - tt[i] = v -- not needed tostring(v) - elseif tv == "string" then - tt[i] = format("%q",v) -- f_string(v) - elseif tv == "boolean" then - tt[i] = v and "true" or "false" - else - return nil - end - end - return tt - elseif haszero and (n == nt + 1) then - local tt = { } - for i=0,nt do - local v = t[i] - local tv = type(v) - if tv == "number" then - tt[i+1] = v -- not needed tostring(v) - elseif tv == "string" then - tt[i+1] = format("%q",v) -- f_string(v) - elseif tv == "boolean" then - tt[i+1] = v and "true" or "false" - else - return nil - end - end - tt[1] = "[0] = " .. tt[1] - return tt - end - end - return nil +local function serialize(root,name,specification) + + if type(specification) == "table" then + return original_serialize(root,name,specification) -- the original one end + local t -- = { } + local n = 1 + local unknown = false + local function do_serialize(root,name,depth,level,indexed) if level > 0 then n = n + 1 @@ -680,7 +651,8 @@ local function serialize(root,name,specification) local last = 0 last = #root for k=1,last do - if root[k] == nil then + if rawget(root,k) == nil then + -- if root[k] == nil then last = k - 1 break end @@ -703,7 +675,7 @@ local function serialize(root,name,specification) if next(v) == nil then -- tricky as next is unpredictable in a hash n = n + 1 t[n] = f_val_not(depth) else - local st = simple_table(v) + local st = is_simple_table(v) if st then n = n + 1 t[n] = f_val_seq(depth,st) else @@ -747,7 +719,7 @@ local function serialize(root,name,specification) n = n + 1 t[n] = f_key_str_value_not(depth,tostring(k)) end else - local st = simple_table(v) + local st = is_simple_table(v) if not st then do_serialize(v,k,depth,level+1) elseif tk == "number" then @@ -810,14 +782,15 @@ local function serialize(root,name,specification) if root then -- The dummy access will initialize a table that has a delayed initialization - -- using a metatable. (maybe explicitly test for metatable) + -- using a metatable. (maybe explicitly test for metatable). This can crash on + -- metatables that check the index against a number. if getmetatable(root) then -- todo: make this an option, maybe even per subtable - local dummy = root._w_h_a_t_e_v_e_r_ + local dummy = root._w_h_a_t_e_v_e_r_ -- needed root._w_h_a_t_e_v_e_r_ = nil end -- Let's forget about empty tables. if next(root) ~= nil then - local st = simple_table(root) + local st = is_simple_table(root) if st then return t[1] .. f_fin_seq(st) -- todo: move up and in one go else @@ -833,5 +806,10 @@ end table.serialize = serialize if setinspector then - setinspector("table",function(v) if type(v) == "table" then print(serialize(v,"table",{})) return true end end) + setinspector("table",function(v) + if type(v) == "table" then + print(serialize(v,"table",{ metacheck = false })) + return true + end + end) end diff --git a/tex/context/fonts/mkiv/bonum-math.lfg b/tex/context/fonts/mkiv/bonum-math.lfg new file mode 100644 index 000000000..00576aaef --- /dev/null +++ b/tex/context/fonts/mkiv/bonum-math.lfg @@ -0,0 +1,19 @@ +local kern_200 = { bottomright = { { kern = -200 } } } +local kern_100 = { bottomright = { { kern = -100 } } } + +return { + name = "bonum-math", + version = "1.00", + comment = "Goodies that complement bonum.", + author = "Hans Hagen", + copyright = "ConTeXt development team", + mathematics = { + kerns = { + [0x1D449] = kern_200, -- + [0x1D44A] = kern_100, -- 𝑊 + }, + alternates = { + dotless = { feature = 'dtls', value = 1, comment = "Mathematical Dotless Forms" }, + }, + }, +} diff --git a/tex/context/fonts/mkiv/cambria-math.lfg b/tex/context/fonts/mkiv/cambria-math.lfg index 6415069e6..ae875e64d 100644 --- a/tex/context/fonts/mkiv/cambria-math.lfg +++ b/tex/context/fonts/mkiv/cambria-math.lfg @@ -44,6 +44,11 @@ return { mathematics = { parameters = { DisplayOperatorMinHeight = FixDisplayOperatorMinHeight, - } - } + }, + -- kernpairs = { -- \setupmathematics[kernpairs=yes] + -- [0x1D44E] = { + -- [0x1D44F] = 1000, -- 𝑎𝑏 demo + -- } + -- }, + }, } diff --git a/tex/context/fonts/mkiv/dejavu-math.lfg b/tex/context/fonts/mkiv/dejavu-math.lfg new file mode 100644 index 000000000..d28c69060 --- /dev/null +++ b/tex/context/fonts/mkiv/dejavu-math.lfg @@ -0,0 +1,18 @@ +local kern_250 = { bottomright = { { kern = -250 } } } + +return { + name = "dejavu-math", + version = "1.00", + comment = "Goodies that complement dejavu.", + author = "Hans Hagen", + copyright = "ConTeXt development team", + mathematics = { + kerns = { + [0x1D449] = kern_250, -- + [0x1D44A] = kern_250, -- 𝑊 + }, + alternates = { + dotless = { feature = 'dtls', value = 1, comment = "Mathematical Dotless Forms" }, + }, + }, +} diff --git a/tex/context/fonts/mkiv/hanbatanglvt.lfg b/tex/context/fonts/mkiv/hanbatanglvt.lfg index 333743348..a7ec0224a 100644 --- a/tex/context/fonts/mkiv/hanbatanglvt.lfg +++ b/tex/context/fonts/mkiv/hanbatanglvt.lfg @@ -1,19 +1,30 @@ --- Maybe some day I will do this more efficient but for the moment it's okay. (We need --- access to the names table then.) - -local f_uni_base = string.formatters["uni%04X"] -local f_uni_plus = string.formatters["uni%04X.y%s"] - -local function range(first,last) - local t = { } - for i=first,last do - t[#t+1] = f_uni_base(i) - for j=0,19 do - t[#t+1] = f_uni_plus(i,j) - end - end - return t -end +-- local f_uni_base = string.formatters["uni%04X"] +-- local f_uni_plus = string.formatters["uni%04X.y%s"] +-- +-- local function range(first,last) +-- local t = { } +-- for i=first,last do +-- t[#t+1] = f_uni_base(i) +-- for j=0,19 do +-- t[#t+1] = f_uni_plus(i,j) +-- end +-- end +-- return t +-- end +-- +-- return { +-- name = "hanbatanglvt", +-- version = "1.00", +-- comment = "Goodies that complement the hanbatanglvt fonts.", +-- author = "Hans Hagen", +-- colorschemes = { +-- default = { +-- range(0x01100,0x0115F), -- jamo_initial (r/c) +-- range(0x01160,0x011A7), -- jamo_medial (g/m) +-- range(0x011A8,0x011FF), -- jamo_final (b/y) +-- } +-- } +-- } return { name = "hanbatanglvt", @@ -22,9 +33,10 @@ return { author = "Hans Hagen", colorschemes = { default = { - range(0x01100,0x0115F), -- jamo_initial (r/c) - range(0x01160,0x011A7), -- jamo_medial (g/m) - range(0x011A8,0x011FF), -- jamo_final (b/y) + { "0x01100:0x0115F" }, -- jamo_initial (r/c) + { "0x01160:0x011A7" }, -- jamo_medial (g/m) + { "0x011A8:0x011FF" }, -- jamo_final (b/y) } } } + diff --git a/tex/context/fonts/mkiv/koeielettersot.lfg b/tex/context/fonts/mkiv/koeielettersot.lfg new file mode 100644 index 000000000..74bf2dd49 --- /dev/null +++ b/tex/context/fonts/mkiv/koeielettersot.lfg @@ -0,0 +1,16 @@ +return { + name = "koeielettersot", + version = "1.00", + comment = "Goodies that complement koeielettersot", + author = "Hans Hagen", + copyright = "ConTeXt development team", + mathematics = { + rules = { + ["radical.extender"] = "radical.extender", + ["radical.end"] = "radical.end", + ["hrule.begin"] = "rule.begin", + ["hrule.extender"] = "rule.ex", + ["hrule.end"] = "rule.end", + } + } +} diff --git a/tex/context/fonts/mkiv/lm.lfg b/tex/context/fonts/mkiv/lm.lfg index 546d18def..aebedd01b 100644 --- a/tex/context/fonts/mkiv/lm.lfg +++ b/tex/context/fonts/mkiv/lm.lfg @@ -1,6 +1,9 @@ -- In order to be able to use beta math fonts, we use our own file name and -- always remap. +local kern_150 = { bottomright = { { kern = -150 } } } +local kern_200 = { bottomright = { { kern = -200 } } } + return { name = "latin modern", version = "1.00", @@ -14,11 +17,24 @@ return { -- mathematics.tweaks.fixoverline, }, }, + kerns = { + [0x1D449] = kern_150, -- + [0x1D44A] = kern_200, -- 𝑊 + }, dimensions = { -- always applied -- default = { -- }, -- driven by 'mathdimensions' feature + default = { + -- the root is quite displaced + [0x221A] = { + -- 73, -960, 853, 40 + yoffset = 960 - 40, + height = 960, + depth = 40, + }, + }, signs = { -- set dimensions -- [0x00B1] = { -- ± diff --git a/tex/context/fonts/mkiv/lucida-opentype-math.lfg b/tex/context/fonts/mkiv/lucida-opentype-math.lfg index 946458dea..29206da1a 100644 --- a/tex/context/fonts/mkiv/lucida-opentype-math.lfg +++ b/tex/context/fonts/mkiv/lucida-opentype-math.lfg @@ -1,3 +1,5 @@ +----- kern_250 = { bottomright = { { kern = -250 } }, force = true } + return { name = "lucida-opentype-math", version = "1.00", @@ -13,6 +15,10 @@ return { zero = { feature = 'ss05', value = 1, comment = "Mathematical Alternative Zero" }, partial = { feature = 'ss20', value = 1, comment = "Mathematical Alternative Upright Partial Differential" }, }, + -- kerns = { + -- [0x1D449] = kern_250, -- + -- [0x1D44A] = kern_250, -- 𝑊 + -- }, dimensions = { default = { -- experimental values [0x2044] = { xoffset = 275, width = 600 }, diff --git a/tex/context/fonts/mkiv/minion-math.lfg b/tex/context/fonts/mkiv/minion-math.lfg new file mode 100644 index 000000000..a4f539ec7 --- /dev/null +++ b/tex/context/fonts/mkiv/minion-math.lfg @@ -0,0 +1,30 @@ +local kern_100 = { bottomright = { { kern = -100 } } } +local kern_150 = { bottomright = { { kern = -150 } } } +local kern_200 = { bottomright = { { kern = -200 } } } + +return { + name = "minion-math", + version = "1.00", + comment = "Goodies that complement minion math.", + author = "Hans Hagen", + copyright = "ConTeXt development team", + designsizes = { + ["Minion-Math"] = { + ["8.4pt"] = "file:MinionMath-Tiny.otf", + ["9.8pt"] = "file:MinionMath-Capt.otf", + default = "file:MinionMath-Regular.otf", + }, + ["Minion-BoldMath"] = { + default = "file:MinionMath-Semibold.otf", + }, + ["Minion-MediumMath"] = { + default = "file:MinionMath-Semibold.otf", + }, + }, + mathematics = { + kerns = { + [0x1D449] = kern_200, -- 𝑉 + [0x1D44A] = kern_150, -- 𝑊 + }, + }, +} diff --git a/tex/context/fonts/mkiv/minion.lfg b/tex/context/fonts/mkiv/minion.lfg new file mode 100644 index 000000000..84f01b6a9 --- /dev/null +++ b/tex/context/fonts/mkiv/minion.lfg @@ -0,0 +1,54 @@ +-- We just assume that Minion Pro is used. After all it's a commercial font so +-- that is probably whey people will buy. + +return { + name = "minion", + version = "1.00", + comment = "Goodies that complement minion pro.", + author = "Hans Hagen and Mathias Schickel", + copyright = "ConTeXt development team", + designsizes = { + ["Minion-Regular"] = { + ["9.5pt"] = "file:MinionPro-Capt.otf", + ["12.5pt"] = "file:MinionPro-Regular.otf", + ["14.5pt"] = "file:MinionPro-Subh.otf", + ["16pt"] = "file:MinionPro-Disp.otf", + default = "file:MinionPro-Regular.otf", + }, + ["Minion-Italic"] = { + ["9.5pt"] = "file:MinionPro-ItCapt.otf", + ["12.5pt"] = "file:MinionPro-It.otf", + ["14.5pt"] = "file:MinionPro-ItSubh.otf", + ["16pt"] = "file:MinionPro-ItDisp.otf", + default = "file:MinionPro-It.otf", + }, + ["Minion-Bold"] = { + ["9.5pt"] = "file:MinionPro-BoldCapt.otf", + ["12.5pt"] = "file:MinionPro-Bold.otf", + ["14.5pt"] = "file:MinionPro-BoldSubh.otf", + ["16pt"] = "file:MinionPro-BoldDisp.otf", + default = "file:MinionPro-Bold.otf", + }, + ["Minion-BoldItalic"] = { + ["9.5pt"] = "file:MinionPro-BoldItCapt.otf", + ["12.5pt"] = "file:MinionPro-BoldIt.otf", + ["14.5pt"] = "file:MinionPro-BoldItSubh.otf", + ["16pt"] = "file:MinionPro-BoldItDisp.otf", + default = "file:MinionPro-It.otf", + }, + ["Minion-Medium"] = { + ["9.5pt"] = "file:MinionPro-SemiboldCapt.otf", + ["12.5pt"] = "file:MinionPro-Semibold.otf", + ["14.5pt"] = "file:MinionPro-SemiboldSubh.otf", + ["16pt"] = "file:MinionPro-SemiboldDisp.otf", + default = "file:MinionPro-Semibold.otf", + }, + ["Minion-MediumItalic"] = { + ["9.5pt"] = "file:MinionPro-SemiboldItCapt.otf", + ["12.5pt"] = "file:MinionPro-SemiboldIt.otf", + ["14.5pt"] = "file:MinionPro-SemiboldItSubh.otf", + ["16pt"] = "file:MinionPro-SemiboldItDisp.otf", + default = "file:MinionPro-SemiboldIt.otf", + }, + }, +} diff --git a/tex/context/fonts/mkiv/pagella-math.lfg b/tex/context/fonts/mkiv/pagella-math.lfg new file mode 100644 index 000000000..40d50383b --- /dev/null +++ b/tex/context/fonts/mkiv/pagella-math.lfg @@ -0,0 +1,19 @@ +local kern_200 = { bottomright = { { kern = -200 } } } +local kern_100 = { bottomright = { { kern = -100 } } } + +return { + name = "pagella-math", + version = "1.00", + comment = "Goodies that complement pagella.", + author = "Hans Hagen", + copyright = "ConTeXt development team", + mathematics = { + kerns = { + [0x1D449] = kern_200, -- + [0x1D44A] = kern_100, -- 𝑊 + }, + alternates = { + dotless = { feature = 'dtls', value = 1, comment = "Mathematical Dotless Forms" }, + }, + }, +} diff --git a/tex/context/fonts/mkiv/schola-math.lfg b/tex/context/fonts/mkiv/schola-math.lfg new file mode 100644 index 000000000..9787c18a9 --- /dev/null +++ b/tex/context/fonts/mkiv/schola-math.lfg @@ -0,0 +1,19 @@ +local kern_200_050 = { bottomright = { { kern = -200 } }, topright = { { kern = 50 } } } +local kern_100_050 = { bottomright = { { kern = -100 } }, topright = { { kern = 50 } } } + +return { + name = "schola-math", + version = "1.00", + comment = "Goodies that complement schola.", + author = "Hans Hagen", + copyright = "ConTeXt development team", + mathematics = { + kerns = { + [0x1D449] = kern_200_050, -- + [0x1D44A] = kern_100_050, -- 𝑊 + }, + alternates = { + dotless = { feature = 'dtls', value = 1, comment = "Mathematical Dotless Forms" }, + }, + }, +} diff --git a/tex/context/fonts/mkiv/stix-two-math.lfg b/tex/context/fonts/mkiv/stix-two-math.lfg new file mode 100644 index 000000000..ded97f92e --- /dev/null +++ b/tex/context/fonts/mkiv/stix-two-math.lfg @@ -0,0 +1,27 @@ +return { + name = "stix-two-math", + version = "1.00", + comment = "Goodies that complement stix two opentype.", + author = "Hans Hagen", + copyright = "ConTeXt development team", + mathematics = { + -- these tags are suggestions and can still change + alternates = { + calligraphic = { feature = 'ss01', value = 1, comment = "Mathematical Alternative Calligraphic Characters" }, + italic = { feature = 'ss02', value = 1, comment = "Mathematical Alternative Lowercase Italic" }, + barred = { feature = 'ss03', value = 1, comment = "Mathematical Alternative Barred Characters" }, -- hbar, lambdabar etc + primes = { feature = 'ss04', value = 1, comment = "Mathematical Alternative Primes" }, -- larger/lower primes, minute etc + arrow = { feature = 'ss05', value = 1, comment = "Mathematical Alternative Smaller Arrows" }, + narrower = { feature = 'ss06', value = 1, comment = "Mathematical Alternative Narrower Elements" }, -- narrower/shorter element etc + small = { feature = 'ss07', value = 1, comment = "Mathematical Alternative Smaller Operators" }, + upright = { feature = 'ss08', value = 1, comment = "Mathematical Alternative Upright Symbols" }, -- upright integrals etc. + negated = { feature = 'ss09', value = 1, comment = "Mathematical Alternative Negated Symbols" }, + relation = { feature = 'ss10', value = 1, comment = "Mathematical Alternative Relations" }, + negatedset = { feature = 'ss09', value = 1, comment = "Mathematical Alternative Negated Set Symbols" }, + -- todo = { feature = 'ss14', value = 1, comment = "" }, + circled = { feature = 'ss16', value = 1, comment = "Mathematical Alternative Circled Operators" }, + }, + }, +} + + diff --git a/tex/context/fonts/mkiv/termes-math.lfg b/tex/context/fonts/mkiv/termes-math.lfg new file mode 100644 index 000000000..557216cb1 --- /dev/null +++ b/tex/context/fonts/mkiv/termes-math.lfg @@ -0,0 +1,19 @@ +local kern_200 = { bottomright = { { kern = -200 } } } +local kern_100 = { bottomright = { { kern = -100 } } } + +return { + name = "termes-math", + version = "1.00", + comment = "Goodies that complement termes.", + author = "Hans Hagen", + copyright = "ConTeXt development team", + mathematics = { + kerns = { + [0x1D449] = kern_200, -- + [0x1D44A] = kern_100, -- 𝑊 + }, + alternates = { + dotless = { feature = 'dtls', value = 1, comment = "Mathematical Dotless Forms" }, + }, + }, +} diff --git a/tex/context/fonts/mkiv/type-imp-asana.mkiv b/tex/context/fonts/mkiv/type-imp-asana.mkiv index b87c969e2..c48d3b7ad 100644 --- a/tex/context/fonts/mkiv/type-imp-asana.mkiv +++ b/tex/context/fonts/mkiv/type-imp-asana.mkiv @@ -21,7 +21,7 @@ \starttypescript [\s!math] [asana] [\s!name] \loadfontgoodies[asana-math] - \definefontsynonym [MathRoman] [AsanaMath] [\s!features=\s!math\mathsizesuffix,\s!goodies=asana-math] + \definefontsynonym [MathRoman] [AsanaMath] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=asana-math] \stoptypescript \starttypescript[asana] diff --git a/tex/context/fonts/mkiv/type-imp-cambria.mkiv b/tex/context/fonts/mkiv/type-imp-cambria.mkiv index 8154817bd..f5679fd92 100644 --- a/tex/context/fonts/mkiv/type-imp-cambria.mkiv +++ b/tex/context/fonts/mkiv/type-imp-cambria.mkiv @@ -42,15 +42,15 @@ \starttypescript [\s!math] [cambria,cambria-m,cambria-a] [\s!name] \loadfontgoodies[cambria-math] - \definefontsynonym [\s!MathRoman] [CambriaMath] [\s!features=\s!math\mathsizesuffix,\s!goodies=cambria-math] + \definefontsynonym [\s!MathRoman] [CambriaMath] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=cambria-math] \stoptypescript \starttypescript [\s!math] [cambria-x] [\s!name] \loadfontgoodies[cambria-math] - \definefontsynonym [\s!MathRoman] [CambriaMath] [\s!features=\s!math,\s!goodies=cambria-math] + \definefontsynonym [\s!MathRoman] [CambriaMath] [\s!features={\s!math,mathextra},\s!goodies=cambria-math] \stoptypescript \starttypescript [\s!math] [cambria-y] [\s!name] \loadfontgoodies[cambria-math] - \definefontsynonym [\s!MathRoman] [CambriaMath] [\s!features=\s!math-nostack\mathsizesuffix,\s!goodies=cambria-math] + \definefontsynonym [\s!MathRoman] [CambriaMath] [\s!features={\s!math-nostack\mathsizesuffix,mathextra},\s!goodies=cambria-math] \stoptypescript \starttypescript [\s!serif] [cambria,cambria-m,cambria-a] [\s!name] diff --git a/tex/context/fonts/mkiv/type-imp-dejavu.mkiv b/tex/context/fonts/mkiv/type-imp-dejavu.mkiv index 41cf1f701..710aada5d 100644 --- a/tex/context/fonts/mkiv/type-imp-dejavu.mkiv +++ b/tex/context/fonts/mkiv/type-imp-dejavu.mkiv @@ -40,15 +40,15 @@ \stoptypescript \starttypescript [\s!math][dejavu][\s!name] - %\loadfontgoodies[dejavu] - \definefontsynonym[\s!MathRoman][file:dejavu-math.otf][\s!features=\s!math\mathsizesuffix] + \loadfontgoodies[dejavu-math] + \definefontsynonym[\s!MathRoman][file:texgyredejavu-math][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=dejavu-math] \stoptypescript \starttypescript[dejavu] \definetypeface [dejavu] [\s!rm] [\s!serif] [dejavu] [\s!default] \definetypeface [dejavu] [\s!ss] [\s!sans] [dejavu] [\s!default] \definetypeface [dejavu] [\s!tt] [\s!mono] [dejavu] [\s!default] -% \definetypeface [dejavu] [\s!mm] [\s!math] [xits] [\s!default] [\s!rscale=1.2] + % \definetypeface [dejavu] [\s!mm] [\s!math] [xits] [\s!default] [\s!rscale=1.2] \definetypeface [dejavu] [\s!mm] [\s!math] [dejavu] [\s!default] \stoptypescript @@ -99,7 +99,7 @@ \definetypeface [dejavu-condensed] [\s!rm] [\s!serif] [dejavu-condensed] [\s!default] \definetypeface [dejavu-condensed] [\s!ss] [\s!sans] [dejavu-condensed] [\s!default] \definetypeface [dejavu-condensed] [\s!tt] [\s!mono] [dejavu-condensed] [\s!default] -% \definetypeface [dejavu-condensed] [\s!mm] [\s!math] [xits] [\s!default] [\s!rscale=1.2] + % \definetypeface [dejavu-condensed] [\s!mm] [\s!math] [xits] [\s!default] [\s!rscale=1.2] \definetypeface [dejavu-condensed] [\s!mm] [\s!math] [dejavu] [\s!default] \stoptypescript diff --git a/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv b/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv index 838654d49..cd474242f 100644 --- a/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv +++ b/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv @@ -11,6 +11,8 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. +% Why so many features ... dead slow too + \definefontfeature [eb-garamond-normal] [default] @@ -32,7 +34,7 @@ \setups[font:fallback:serif] \definefontsynonym [Serif] [file:ebgaramond-regular] [features=eb-garamond-normal] \definefontsynonym [SerifItalic] [file:ebgaramond-italic] [features=eb-garamond-normal] - \definefontsynonym [SerifBold] [file:ebgaramond-bold] [features=eb-garamond-normal] + \definefontsynonym [SerifBold] [file:ebgaramond-regular] [features=eb-garamond-normal] % there is no bold \definefontsynonym [SerifCaps] [Serif] [features=eb-garamond-smallcaps] \stoptypescript diff --git a/tex/context/fonts/mkiv/type-imp-euler.mkiv b/tex/context/fonts/mkiv/type-imp-euler.mkiv index d3b552b56..e98a6e963 100644 --- a/tex/context/fonts/mkiv/type-imp-euler.mkiv +++ b/tex/context/fonts/mkiv/type-imp-euler.mkiv @@ -49,7 +49,7 @@ \starttypescript [\s!math] [eulernova] [\s!name] \loadfontgoodies[euler-math] - \definefontsynonym [MathRoman] [\s!file:euler.otf] [\s!features=\s!math\mathsizesuffix] + \definefontsynonym [MathRoman] [\s!file:euler.otf] [\s!features={\s!math\mathsizesuffix,mathextra}] \stoptypescript \starttypescript [pagella-eulernova] @@ -67,11 +67,11 @@ \stoptypescript \starttypescript [\s!math] [euleroverpagella] [\s!name] - \definefontsynonym [MathRoman] [texgyrepagella-math] [\s!features=\s!math\mathsizesuffix,\s!fallbacks=euleroverpagella] + \definefontsynonym [MathRoman] [texgyrepagella-math] [\s!features={\s!math\mathsizesuffix,mathextra},\s!fallbacks=euleroverpagella] \stoptypescript \starttypescript [\s!math] [pagellaovereuler] [\s!name] - \definefontsynonym [MathRoman] [\s!file:euler.otf] [\s!features=\s!math\mathsizesuffix,\s!fallbacks=pagellaovereuler] + \definefontsynonym [MathRoman] [\s!file:euler.otf] [\s!features={\s!math\mathsizesuffix,mathextra},\s!fallbacks=pagellaovereuler] \stoptypescript \starttypescript [pagella-with-euler] diff --git a/tex/context/fonts/mkiv/type-imp-gentium.mkiv b/tex/context/fonts/mkiv/type-imp-gentium.mkiv index b2ad35a96..751ca87e7 100644 --- a/tex/context/fonts/mkiv/type-imp-gentium.mkiv +++ b/tex/context/fonts/mkiv/type-imp-gentium.mkiv @@ -7,6 +7,8 @@ %D date=\currentdate, %D copyright={Mojca and Thomas}] +% One probably has to enable the 'aalt' feature too. + \starttypescript [serif] [gentium] \definefontsynonym [Gentium-Roman] [file:GentiumPlus-R] [features=default] \definefontsynonym [Gentium-Italic] [file:GentiumPlus-I] [features=default] diff --git a/tex/context/fonts/mkiv/type-imp-ipaex.mkiv b/tex/context/fonts/mkiv/type-imp-ipaex.mkiv index b11f96878..9a071ed3c 100644 --- a/tex/context/fonts/mkiv/type-imp-ipaex.mkiv +++ b/tex/context/fonts/mkiv/type-imp-ipaex.mkiv @@ -94,7 +94,7 @@ \definefontsynonym[ipaexgmonoboldslanted] [\s!file:ipaexg][\s!features=jp-slanted,\s!fallbacks=jp-monoboldslanted] \definefontsynonym[ipaexgmonocaps] [\s!file:ipaexg][\s!features=jp-default,\s!fallbacks=jp-monocaps] \stoptypescript - + \starttypescript [\s!serif] [ipaexm] [\s!name] \definefontsynonym[\s!Serif] [ipaexm] \definefontsynonym[\s!SerifBold] [ipaexmbold] diff --git a/tex/context/fonts/mkiv/type-imp-koeielettersot.mkiv b/tex/context/fonts/mkiv/type-imp-koeielettersot.mkiv new file mode 100644 index 000000000..e3e8fc277 --- /dev/null +++ b/tex/context/fonts/mkiv/type-imp-koeielettersot.mkiv @@ -0,0 +1,179 @@ +%D \module +%D [ file=type-cowotf, +%D version=2016.09.16, +%D title=\CONTEXT\ Typescript Macros, +%D subtitle=Cow Fonts (otf version), +%D author={Taco Hoekwater \& Hans Hagen}, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D The cow fonts are a project of Duane Bibby, Hans Hagen and Taco +%D Hoekwater. + +\unprotect + +\definefontfeature + [sheepdigits] + [mode=node, + script=latn, + ss01=yes] + +\definefontfeature + [mathsheepdigits] + [sheepdigits] + [mode=base] + +\definefontfeature + [cowslogos] + [mode=node, + script=latn, + ss02=yes, + dlig=yes] + +\definefontfeature + [cowsligatures] + [mode=node, + script=latn, + dlig=yes] + +\definefontfeature + [cowscolors] + [mode=node, + colr=yes, + ss02=yes, + dlig=yes] + +\definefontfeature + [cowsdefault] + [default] + [mode=node, + compose=yes] + +\definefontfeature + [sheepdefault] + [cowsdefault,sheepdigits] + +\definefontfeature + [cowscolored] + [cowsdefault,cowscolors] + +\definefontfeature + [sheepcolored] + [sheepdefault,cowscolors] + +\starttypescriptcollection[koeielettersot] + + \loadfontgoodies[koeielettersot] + + \starttypescript [\s!all] [cowsotf] + \definefontsynonym [Cows] [koeielettersot][\s!features=cowsdefault] + \definefontsynonym [CowsLogo] [koeielettersot][\s!features=cowslogos] + \definefontsynonym [CowsMathRoman][koeielettersot][\s!features=mathextra,\s!goodies=koeielettersot] + \stoptypescript + + \starttypescript [\s!all] [koeielettersotf,sheepotf] + \definefontsynonym [Sheep] [koeielettersot][\s!features=sheepdefault] + \definefontsynonym [SheepLogo] [koeielettersot][\s!features=cowslogos] + \definefontsynonym [SheepMathRoman][koeielettersot][\s!features={mathsheepdigits,mathextra},\s!goodies=koeielettersot] + \stoptypescript + +% \definefontsynonym[\s!MathRoman][file:texgyredejavu-math][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=dejavu-math] + + \starttypescript [\s!all] [coloredcowsotf] + \definefontsynonym [Cows] [koeielettersot][\s!features=cowscolored] + \definefontsynonym [CowsLogo] [koeielettersot][\s!features=cowslogos] + \definefontsynonym [CowsMathRoman][koeielettersot][\s!features=mathextra,\s!goodies=koeielettersot] + \stoptypescript + + \starttypescript [\s!all] [coloredsheepotf] + \definefontsynonym [Sheep] [koeielettersot][\s!features=sheepcolored] + \definefontsynonym [SheepLogo] [koeielettersot][\s!features=cowslogos] + \definefontsynonym [SheepMathRoman][koeielettersot][\s!features={mathsheepdigits,mathextra},\s!goodies=koeielettersot] + \stoptypescript + + \starttypescript [\s!serif] [cowsotf,coloredcowsotf] + \setups[\s!font:\s!fallback:\s!serif] + \definefontsynonym [\s!Serif] [Cows] + \definefontsynonym [\s!Serif Logo][CowsLogo] + \stoptypescript + + \starttypescript [\s!serif] [koeielettersotf,sheepotf,coloredsheepotf] + \setups[\s!font:\s!fallback:\s!serif] + \definefontsynonym [\s!Serif] [Sheep] + \definefontsynonym [\s!Serif Logo][SheepLogo] + \stoptypescript + + \starttypescript [\s!math] [cowsotf,coloredcowsotf] + \definefontsynonym [\s!MathRoman][CowsMathRoman] + \enablemathrules % uses \fontclass, for now this way + \stoptypescript + + \starttypescript [\s!math] [koeielettersotf,sheepotf,coloredsheepotf] + \definefontsynonym [\s!MathRoman][SheepMathRoman] + \enablemathrules % uses \fontclass, for now this way + \stoptypescript + + \starttypescript [koeieletters,cows,sheep,coloredcows,coloredsheep] + \definetypeface [\typescriptone][\s!rm][\s!serif][\typescriptone otf][\s!default] + \definetypeface [\typescriptone][\s!ss][\s!serif][\typescriptone otf][\s!default] + \definetypeface [\typescriptone][\s!mm][\s!math] [\typescriptone otf][\s!default] + \definetypeface [\typescriptone][\s!tt][\s!mono] [modern] [\s!default][\s!rscale=0.85] + \stoptypescript + +\stoptypescriptcollection + +\protect + +\continueifinputfile{type-imp-koeielettersot.mkiv} + +\starttext + +\setupbodyfont[cows] + +\input tufte + +\stoptext + +\starttext + +\loadtypescriptfile[cowotf] + +\definecolor[cowred] [r=.50] +\definecolor[cowgreen] [g=.50] +\definecolor[cowblue] [b=.50] +\definecolor[cowyellow][y=.25] + +\startluacode + fonts.handlers.otf.registerpalette("demo", { + { g = .50 }, + { y = .25 }, + { b = .50 }, + { r = .50 }, + }) +\stopluacode + +\definefontcolorpalette[cows][cowgreen,cowyellow,cowblue,cowred] + +\adaptfontfeature[cowscolored] [colr=cows] + +\setupbodyfont[coloredcows,12pt] + +\input zapf + +\definefontsynonym + [CowsColored] + [koeielettersot] + +\showotfcomposition + {koeielettersot*default,cowscolors} + {1} + {context} + +\scale[width=\textwidth]{\getnamedglyphdirect{CowsColored*default,cowscolors}{contextlogo}} +\scale[width=\textwidth]{\definedfont[CowsColored*default,cowscolors]context} + +\stoptext diff --git a/tex/context/fonts/mkiv/type-imp-latinmodern.mkiv b/tex/context/fonts/mkiv/type-imp-latinmodern.mkiv index fe4b669bd..63f74027b 100644 --- a/tex/context/fonts/mkiv/type-imp-latinmodern.mkiv +++ b/tex/context/fonts/mkiv/type-imp-latinmodern.mkiv @@ -28,7 +28,7 @@ \starttypescriptcollection[latinmodern] - \starttypescript [\s!serif] [simple] [\s!name]% for old times sake (manuals) + \starttypescript [\s!serif] [simple] [\s!name] \definefontsynonym [\s!Simple] [\s!file:lmmonoproplt10-regular] [\s!features=\s!default] \stoptypescript @@ -82,9 +82,9 @@ \starttypescript [\s!serif] [modern-variable,latin-modern-variable-designsize,latin-modern-variable] [\s!name] \loadfontgoodies[lm] \definefontsynonym [\s!Serif] [LMTypewriterVarWd-Regular] [\s!features=\s!default] - \definefontsynonym [\s!SerifBold] [LMTypewriterVarWd-Oblique] [\s!features=\s!default] + \definefontsynonym [\s!SerifBold] [LMTypewriterVarWd-Dark] [\s!features=\s!default] \definefontsynonym [\s!SerifItalic] [LMTypewriterVarWd-Oblique] [\s!features=\s!default] - \definefontsynonym [\s!SerifSlanted] [LMTypewriterVarWd-Dark] [\s!features=\s!default] + \definefontsynonym [\s!SerifSlanted] [LMTypewriterVarWd-Oblique] [\s!features=\s!default] \definefontsynonym [\s!SerifBoldItalic] [LMTypewriterVarWd-DarkOblique] [\s!features=\s!default] \definefontsynonym [\s!SerifBoldSlanted] [LMTypewriterVarWd-DarkOblique] [\s!features=\s!default] \definefontsynonym [\s!SerifCaps] [LMTypewriterVarWd-Regular] [\s!features=\s!default] @@ -173,14 +173,14 @@ % \starttypescript [\s!math] [modern,latin-modern] % \loadfontgoodies[lm] -% \definefontsynonym [LMMathRoman-Regular] [\v!file:latinmodern-math-regular.otf] [\s!features=\s!math\mathsizesuffix,\s!goodies=lm] -% \definefontsynonym [LMMathRoman-Bold] [\v!file:latinmodern-math-regular.otf] [\s!features=\s!math\mathsizesuffix,\s!goodies=lm] +% \definefontsynonym [LMMathRoman-Regular] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=lm] +% \definefontsynonym [LMMathRoman-Bold] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=lm] % \stoptypescript \starttypescript [\s!math] [modern,latin-modern] \loadfontgoodies[lm] - \definefontsynonym [LMMathRoman-Regular] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math},\s!goodies=lm] - \definefontsynonym [LMMathRoman-Bold] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math},\s!goodies=lm] + \definefontsynonym [LMMathRoman-Regular] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math,mathextra},\s!goodies=lm] + \definefontsynonym [LMMathRoman-Bold] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math,mathextra},\s!goodies=lm] \stoptypescript \starttypescript [modern-designsize-virtual] diff --git a/tex/context/fonts/mkiv/type-imp-libertinus.mkiv b/tex/context/fonts/mkiv/type-imp-libertinus.mkiv new file mode 100644 index 000000000..1ceda8737 --- /dev/null +++ b/tex/context/fonts/mkiv/type-imp-libertinus.mkiv @@ -0,0 +1,82 @@ +%D \module +%D [ file=type-imp-libertinus, +%D version=2016.08.18, +%D title=\CONTEXT\ Typescript Macros, +%D subtitle=Libertine fonts, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This typescript (submitted by by Henri Menke) is a follow up on libertine +%D which is no longer maintained cq.\ developed further. + +\starttypescriptcollection[libertinus] + + \starttypescript [\s!serif] [libertinus] + \definefontsynonym [LibertinusSerif-Regular] [\s!file:libertinusserif-regular] + \definefontsynonym [LibertinusSerif-Italic] [\s!file:libertinusserif-italic] + \definefontsynonym [LibertinusSerif-Slanted] [\s!file:libertinusserif-italic] + \definefontsynonym [LibertinusSerif-Bold] [\s!file:libertinusserif-bold] + \definefontsynonym [LibertinusSerif-BoldItalic] [\s!file:libertinusserif-bolditalic] + \definefontsynonym [LibertinusSerif-BoldSlanted] [\s!file:libertinusserif-bolditalic] + \stoptypescript + + \starttypescript [\s!serif] [libertinus] [\s!name] + \setups[\s!font:\s!fallback:\s!serif] + \definefontsynonym [\s!Serif] [LibertinusSerif-Regular] [\s!features=\s!default] + \definefontsynonym [\s!SerifItalic] [LibertinusSerif-Italic] [\s!features=\s!default] + \definefontsynonym [\s!SerifSlanted] [LibertinusSerif-Slanted] [\s!features=\s!default] + \definefontsynonym [\s!SerifBold] [LibertinusSerif-Bold] [\s!features=\s!default] + \definefontsynonym [\s!SerifBoldItalic] [LibertinusSerif-BoldItalic] [\s!features=\s!default] + \definefontsynonym [\s!SerifBoldSlanted] [LibertinusSerif-BoldSlanted] [\s!features=\s!default] + \definefontsynonym [SerifCaps] [LibertinusSerif-Regular] [\s!features=\s!smallcaps] + \stoptypescript + + \starttypescript [\s!sans] [libertinus] + \setups[\s!font:\s!fallback:\s!sans] + \definefontsynonym [LibertinusSans-Regular] [\s!file:libertinussans-regular] + \definefontsynonym [LibertinusSans-Italic] [\s!file:libertinussans-italic] + \definefontsynonym [LibertinusSans-Slanted] [\s!file:libertinussans-italic] + \definefontsynonym [LibertinusSans-Bold] [\s!file:libertinussans-bold] + \definefontsynonym [LibertinusSans-BoldItalic] [\s!file:libertinussans-bold] + \definefontsynonym [LibertinusSans-BoldSlanted] [\s!file:libertinussans-bold] + \stoptypescript + + \starttypescript [\s!sans] [libertinus] [\s!name] + \setups[\s!font:\s!fallback:\s!sans] + \definefontsynonym [\s!Sans] [LibertinusSans-Regular] [\s!features=\s!default] + \definefontsynonym [\s!SansBold] [LibertinusSans-Bold] [\s!features=\s!default] + \definefontsynonym [\s!SansItalic] [LibertinusSans-Italic] [\s!features=\s!default] + \definefontsynonym [\s!SansSlanted] [LibertinusSans-Slanted] [\s!features=\s!default] + \definefontsynonym [\s!SansBoldItalic] [LibertinusSans-BoldSlanted] [\s!features=\s!default] + \definefontsynonym [SansCaps] [LibertinusSans-Regular] [\s!features=\s!smallcaps] + \stoptypescript + + \starttypescript [\s!mono] [libertinus] + \setups[\s!font:\s!fallback:\s!mono] + \definefontsynonym [LibertinusMono-Regular] [\s!file:libertinusmono-regular] + \stoptypescript + + \starttypescript [\s!mono] [libertinus] [\s!name] + \setups[\s!font:\s!fallback:\s!mono] + \definefontsynonym [\s!Mono] [LibertinusMono-Regular] [\s!features=\s!default] + \stoptypescript + + \starttypescript [\s!math] [libertinus] [\s!name] + \definefontsynonym[\s!MathRoman ] [\s!file:libertinusmath-regular.otf] [\s!features={\s!math\mathsizesuffix,mathextra}] + \definefontsynonym[\s!MathRomanBold] [\s!file:libertinusmath-regular.otf] [\s!features={\s!math\mathsizesuffix,mathextra}] + \stoptypescript + + \starttypescript [libertinus] + \definetypeface [libertinus] [\s!rm] [\s!serif] [libertinus] [\s!default] + \definetypeface [libertinus] [\s!ss] [\s!sans] [libertinus] [\s!default] + \definetypeface [libertinus] [\s!tt] [\s!mono] [libertinus] [\s!default] + \definetypeface [libertinus] [\s!mm] [\s!math] [libertinus] [\s!default] + \quittypescriptscanning + \stoptypescript + +\stoptypescriptcollection diff --git a/tex/context/fonts/mkiv/type-imp-lucida-opentype.mkiv b/tex/context/fonts/mkiv/type-imp-lucida-opentype.mkiv index f39ed6e1f..61002ff06 100644 --- a/tex/context/fonts/mkiv/type-imp-lucida-opentype.mkiv +++ b/tex/context/fonts/mkiv/type-imp-lucida-opentype.mkiv @@ -65,8 +65,8 @@ \stoptypescript \starttypescript [\s!math] [lucidaot,lucidadk] - \definefontsynonym [\s!MathRoman] [\s!file:LucidaBrightMathOT.otf] [\s!features=\s!math\mathsizesuffix,\s!goodies=lucida-opentype-math] - \definefontsynonym [\s!MathRomanBold] [\s!file:LucidaBrightMathOT-Demi.otf] [\s!features=\s!math\mathsizesuffix,\s!goodies=lucida-opentype-math] + \definefontsynonym [\s!MathRoman] [\s!file:LucidaBrightMathOT.otf] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=lucida-opentype-math] + \definefontsynonym [\s!MathRomanBold] [\s!file:LucidaBrightMathOT-Demi.otf] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=lucida-opentype-math] \stoptypescript \starttypescript [\s!handwriting] [lucidaot,lucidadk] diff --git a/tex/context/fonts/mkiv/type-imp-minion.mkiv b/tex/context/fonts/mkiv/type-imp-minion.mkiv new file mode 100644 index 000000000..b158deddf --- /dev/null +++ b/tex/context/fonts/mkiv/type-imp-minion.mkiv @@ -0,0 +1,54 @@ +%D \module +%D [ file=type-imp-minion, +%D version=2016.06.14, +%D title=\CONTEXT\ Typescript Macros, +%D subtitle=Minion, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\definefontfallback[MinionMathFallback] [file:latinmodern-math.otf][uppercasescript] +\definefontfallback[MinionBoldMathFallback][file:latinmodern-math.otf][uppercasescript] + +\starttypescriptcollection[minion] + + \starttypescript [\s!serif][minion][\s!all] + \loadfontgoodies[minion] + \definefontsynonym[\s!Serif] [Minion-Regular] [\s!features=\s!default,\s!goodies=minion] + \definefontsynonym[\s!SerifBold] [Minion-Bold] [\s!features=\s!default,\s!goodies=minion] + \definefontsynonym[\s!SerifItalic] [Minion-Italic] [\s!features=\s!default,\s!goodies=minion] + \definefontsynonym[\s!SerifBoldItalic][Minion-BoldItalic][\s!features=\s!default,\s!goodies=minion] + \stoptypescript + + \starttypescript [\s!serif][minion-medium][\s!all] + \loadfontgoodies[minion] + \definefontsynonym[\s!Serif] [Minion-Regular] [\s!features=\s!default,\s!goodies=minion] + \definefontsynonym[\s!SerifBold] [Minion-Medium] [\s!features=\s!default,\s!goodies=minion] + \definefontsynonym[\s!SerifItalic] [Minion-Italic] [\s!features=\s!default,\s!goodies=minion] + \definefontsynonym[\s!SerifBoldItalic][Minion-MediumItalic][\s!features=\s!default,\s!goodies=minion] + \stoptypescript + + \starttypescript [\s!math][minion][\s!all] + \loadfontgoodies[minion-math] + \definefontsynonym[\s!MathRoman] [Minion-Math] [\s!features={\s!math\mathsizesuffix,mathextra},\s!designsize=\s!auto,\s!goodies=minion-math,\s!fallbacks=MinionMathFallback] + \definefontsynonym[\s!MathRomanBold][Minion-BoldMath][\s!features={\s!math\mathsizesuffix,mathextra},\s!designsize=\s!auto,\s!goodies=minion-math,\s!fallbacks=MinionBoldMathFallback] + \stoptypescript + + \starttypescript [\s!math][minion-medium][\s!all] + \loadfontgoodies[minion-math] + \definefontsynonym[\s!MathRoman] [Minion-Math] [\s!features={\s!math\mathsizesuffix,mathextra},\s!designsize=\s!auto,\s!goodies=minion-math,\s!fallbacks=MinionMathFallback] + \definefontsynonym[\s!MathRomanBold][Minion-MediumMath][\s!features={\s!math\mathsizesuffix,mathextra},\s!designsize=\s!auto,\s!goodies=minion-math,\s!fallbacks=MinionBoldMathFallback] + \stoptypescript + + \starttypescript [minion,minion-medium] + \definetypeface [\typescriptone] [\s!rm] [\s!serif] [\typescriptone] [\s!default] + \definetypeface [\typescriptone] [\s!ss] [\s!sans] [dejavu] [\s!default] [\s!rscale=0.8] + \definetypeface [\typescriptone] [\s!tt] [\s!mono] [dejavu] [\s!default] [\s!rscale=0.8] + \definetypeface [\typescriptone] [\s!mm] [\s!math] [\typescriptone] [\s!default] + \stoptypescript + +\stoptypescriptcollection diff --git a/tex/context/fonts/mkiv/type-imp-source.mkiv b/tex/context/fonts/mkiv/type-imp-source.mkiv new file mode 100644 index 000000000..91396f965 --- /dev/null +++ b/tex/context/fonts/mkiv/type-imp-source.mkiv @@ -0,0 +1,66 @@ +%D \module +%D [ file=type-imp-source, +%D version=2010.06.21, +%D title=\CONTEXT\ Typescript Macros, +%D subtitle=Adobe Source Fonts (https://fonts.google.com/), +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\starttypescriptcollection[source] + + \definefontfeature[source-serif-slanted][slant=0.2] + + \starttypescript [\s!serif] [source] [\s!name] + \setups[\s!font:\s!fallback:\s!serif] + \definefontsynonym [\s!Serif] [\s!file:SourceSerifPro-Regular.ttf] [\s!features=\s!default] + \definefontsynonym [\s!SerifBold] [\s!file:SourceSerifPro-Bold.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!SerifBold] [\s!file:SourceSerifPro-Semibold.ttf] [\s!features=\s!default] + \definefontsynonym [\s!SerifItalic] [\s!file:SourceSerifPro-Regular.ttf] [\s!features={\s!default,source-serif-slanted}] + \definefontsynonym [\s!SerifBoldItalic] [\s!file:SourceSerifPro-Bold.ttf] [\s!features={\s!default,source-serif-slanted}] + \stoptypescript + + \starttypescript [\s!sans] [source] [\s!name] + \setups[\s!font:\s!fallback:\s!sans] + % \definefontsynonym [\s!Sans] [\s!file:SourceSansPro-ExtraLight.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!Sans] [\s!file:SourceSansPro-Light.ttf] [\s!features=\s!default] + \definefontsynonym [\s!Sans] [\s!file:SourceSansPro-Regular.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!SansBold] [\s!file:SourceSansPro-Semibold.ttf] [\s!features=\s!default] + \definefontsynonym [\s!SansBold] [\s!file:SourceSansPro-Bold.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!SansBold] [\s!file:SourceSansPro-Black.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!SansItalic] [\s!file:SourceSansPro-ExtraLightItalic.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!SansItalic] [\s!file:SourceSansPro-LightItalic.ttf] [\s!features=\s!default] + \definefontsynonym [\s!SansItalic] [\s!file:SourceSansPro-Italic.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!SansBoldItalic] [\s!file:SourceSansPro-SemiboldItalic.ttf] [\s!features=\s!default] + \definefontsynonym [\s!SansBoldItalic] [\s!file:SourceSansPro-BoldItalic.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!SansBoldItalic] [\s!file:SourceSansPro-BlackItalic.ttf] [\s!features=\s!default] + \stoptypescript + + \starttypescript [\s!mono] [source] [\s!name] + \setups[\s!font:\s!fallback:\s!mono] + % \definefontsynonym [\s!Mono] [\s!file:SourceCodePro-ExtraLight.ttf] [\s!features=\s!none] + % \definefontsynonym [\s!Mono] [\s!file:SourceCodePro-Light.ttf] [\s!features=\s!none] + \definefontsynonym [\s!Mono] [\s!file:SourceCodePro-Regular.ttf] [\s!features=\s!none] + % \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Medium.ttf] [\s!features=\s!none] + % \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Semibold.ttf] [\s!features=\s!none] + \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Bold.ttf] [\s!features=\s!none] + % \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Black.ttf] [\s!features=\s!none] + \stoptypescript + + \starttypescript [\s!math][source][\s!name] + % \loadfontgoodies[texgyre] + \definefontsynonym[\s!MathRoman][file:texgyredejavu-math][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=dejavu-math] + \stoptypescript + + \starttypescript[source] + \definetypeface [source] [\s!rm] [\s!serif] [source] [\s!default] + \definetypeface [source] [\s!ss] [\s!sans] [source] [\s!default] + \definetypeface [source] [\s!tt] [\s!mono] [source] [\s!default] + \definetypeface [source] [\s!mm] [\s!math] [source] [\s!default] % [\s!rscale=1.2] + \stoptypescript + +\stoptypescriptcollection diff --git a/tex/context/fonts/mkiv/type-imp-stix.mkiv b/tex/context/fonts/mkiv/type-imp-stix.mkiv new file mode 100644 index 000000000..697037b43 --- /dev/null +++ b/tex/context/fonts/mkiv/type-imp-stix.mkiv @@ -0,0 +1,64 @@ +%D \module +%D [ file=type-otf, +%D version=2007.07.30, +%D title=\CONTEXT\ Typescript Macros, +%D subtitle=Stix, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D We provide typescripts for version one and two of the stix fonts. There is a +%D xits variant based on the first (not opentype) release that also provides +%D bidirectional math. + +\definefontfeature + [stixtwomath] + [ss02=yes] % otherwise weird (non italic) g + +\starttypescriptcollection[stix] + + % version one + + \starttypescript [\s!math] [stix] [\s!name] + \definefontsynonym[MathRoman][\s!file:stixmath-regular.otf] [\s!features={\s!math\mathsizesuffix,mathextra}] + \stoptypescript + + \starttypescript [\s!serif] [stix] [\s!name] + \setups[\s!font:\s!fallback:\s!serif] + \definefontsynonym[\s!Serif] [\s!file:stix-regular.otf] [\s!features=\s!default] + \definefontsynonym[\s!SerifBold] [\s!file:stix-bold.otf] [\s!features=\s!default] + \definefontsynonym[\s!SerifItalic] [\s!file:stix-italic.otf] [\s!features=\s!default] + \definefontsynonym[\s!SerifBoldItalic][\s!file:stix-bolditalic.otf][\s!features=\s!default] + \stoptypescript + + \starttypescript[stix] + \definetypeface [stix] [\s!rm] [\s!serif] [stix] [\s!default] + \definetypeface [stix] [\s!mm] [\s!math] [stix] [\s!default] + \stoptypescript + + % version two + + \starttypescript [\s!math] [stixtwo] [\s!name] + \definefontsynonym[MathRoman][\s!file:stix2math.otf] [\s!features={\s!math\mathsizesuffix,stixtwomath,mathextra},\s!goodies=stix-two-math] + \stoptypescript + + \starttypescript [\s!serif] [stixtwo] [\s!name] + \setups[\s!font:\s!fallback:\s!serif] + \definefontsynonym[\s!Serif] [\s!file:stix2text-regular.otf] [\s!features=\s!default] + \definefontsynonym[\s!SerifBold] [\s!file:stix2text-bold.otf] [\s!features=\s!default] + \definefontsynonym[\s!SerifItalic] [\s!file:stix2text-italic.otf] [\s!features=\s!default] + \definefontsynonym[\s!SerifBoldItalic][\s!file:stix2text-bolditalic.otf][\s!features=\s!default] + \stoptypescript + + \starttypescript[stixtwo] + \definetypeface [\typescriptone] [\s!rm] [\s!serif] [stixtwo] [\s!default] + \definetypeface [\typescriptone] [\s!ss] [\s!serif] [stixtwo] [\s!default] + \definetypeface [\typescriptone] [\s!tt] [\s!mono] [dejavu] [\s!default] [\s!rscale=0.895] + \definetypeface [\typescriptone] [\s!mm] [\s!math] [stixtwo] [\s!default] + \stoptypescript + +\stoptypescriptcollection diff --git a/tex/context/fonts/mkiv/type-imp-texgyre.mkiv b/tex/context/fonts/mkiv/type-imp-texgyre.mkiv index 86db8c603..a7c2d06be 100644 --- a/tex/context/fonts/mkiv/type-imp-texgyre.mkiv +++ b/tex/context/fonts/mkiv/type-imp-texgyre.mkiv @@ -215,6 +215,8 @@ \stoptypescriptcollection +% tricky: we cannot mix now as the file is loaded only once + \startmode[txmath] \starttypescriptcollection[texgyre-math-times] @@ -234,8 +236,9 @@ \starttypescriptcollection[texgyre-math-times] \starttypescript [\s!math][times,termes][\s!all] - \loadfontgoodies[texgyre] - \definefontsynonym[\s!MathRoman][file:texgyre-termes-math-regular.otf][\s!features=\s!math\mathsizesuffix,\s!goodies=texgyre] + % \loadfontgoodies[texgyre] + % \definefontsynonym[\s!MathRoman][file:texgyre-termes-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre] + \definefontsynonym[\s!MathRoman][file:texgyretermes-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=termes-math] \stoptypescript \stoptypescriptcollection @@ -261,8 +264,9 @@ \starttypescriptcollection[texgyre-math-pagella] \starttypescript [\s!math][palatino,pagella][\s!all] - \loadfontgoodies[texgyre] - \definefontsynonym[\s!MathRoman][file:texgyre-pagella-math-regular.otf][\s!features=\s!math\mathsizesuffix,\s!goodies=texgyre] + % \loadfontgoodies[texgyre] + % \definefontsynonym[\s!MathRoman][file:texgyre-pagella-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre] + \definefontsynonym[\s!MathRoman][file:texgyrepagella-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=pagella-math] \stoptypescript \stoptypescriptcollection @@ -272,8 +276,9 @@ \starttypescriptcollection[texgyre-math-bonum] \starttypescript [\s!math][bookman,bonum][\s!all] - \loadfontgoodies[texgyre] - \definefontsynonym[\s!MathRoman][file:texgyre-bonum-math-regular.otf][\s!features=\s!math\mathsizesuffix,\s!goodies=texgyre] + % \loadfontgoodies[texgyre] + % \definefontsynonym[\s!MathRoman][file:texgyre-bonum-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre] + \definefontsynonym[\s!MathRoman][file:texgyrebonum-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=bonum-math] \stoptypescript \stoptypescriptcollection @@ -281,8 +286,11 @@ \starttypescriptcollection[texgyre-math-schola] \starttypescript [\s!math][schoolbook,schola][\s!all] - \loadfontgoodies[texgyre] - \definefontsynonym[\s!MathRoman][file:texgyre-schola-math-regular.otf][\s!features=\s!math\mathsizesuffix,\s!goodies=texgyre] + % \loadfontgoodies[texgyre] + % \definefontsynonym[\s!MathRoman][file:texgyre-schola-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre] + \definefontsynonym[\s!MathRoman][file:texgyreschola-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=schola-math] \stoptypescript \stoptypescriptcollection + + diff --git a/tex/context/fonts/mkiv/type-imp-xits.mkiv b/tex/context/fonts/mkiv/type-imp-xits.mkiv index f83050e14..145ddc7a8 100644 --- a/tex/context/fonts/mkiv/type-imp-xits.mkiv +++ b/tex/context/fonts/mkiv/type-imp-xits.mkiv @@ -23,12 +23,12 @@ \starttypescript [\s!math] [xits,xitsbidi] [\s!name] \loadfontgoodies[xits-math] - \definefontsynonym[\s!MathRoman ][\s!file:xits-math.otf] [\s!features=\s!math\mathsizesuffix,\s!goodies=xits-math] - \definefontsynonym[\s!MathRoman L2R][\s!file:xits-math.otf] [\s!features=\s!math\mathsizesuffix-l2r,\s!goodies=xits-math] - \definefontsynonym[\s!MathRoman R2L][\s!file:xits-math.otf] [\s!features=\s!math\mathsizesuffix-r2l,\s!goodies=xits-math] - \definefontsynonym[\s!MathRomanBold ][\s!file:xits-mathbold.otf][\s!features=\s!math\mathsizesuffix,\s!goodies=xits-math] - \definefontsynonym[\s!MathRomanBold L2R][\s!file:xits-mathbold.otf][\s!features=\s!math\mathsizesuffix-l2r,\s!goodies=xits-math] - \definefontsynonym[\s!MathRomanBold R2L][\s!file:xits-mathbold.otf][\s!features=\s!math\mathsizesuffix-r2l,\s!goodies=xits-math] + \definefontsynonym[\s!MathRoman ][\s!file:xits-math.otf] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=xits-math] + \definefontsynonym[\s!MathRoman L2R][\s!file:xits-math.otf] [\s!features={\s!math\mathsizesuffix-l2r,mathextra},\s!goodies=xits-math] + \definefontsynonym[\s!MathRoman R2L][\s!file:xits-math.otf] [\s!features={\s!math\mathsizesuffix-r2l,mathextra},\s!goodies=xits-math] + \definefontsynonym[\s!MathRomanBold ][\s!file:xits-mathbold.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=xits-math] + \definefontsynonym[\s!MathRomanBold L2R][\s!file:xits-mathbold.otf][\s!features={\s!math\mathsizesuffix-l2r,mathextra},\s!goodies=xits-math] + \definefontsynonym[\s!MathRomanBold R2L][\s!file:xits-mathbold.otf][\s!features={\s!math\mathsizesuffix-r2l,mathextra},\s!goodies=xits-math] \stoptypescript \starttypescript [\s!serif] [xits] [\s!name] diff --git a/tex/context/fonts/mkiv/xits-math.lfg b/tex/context/fonts/mkiv/xits-math.lfg index 8e1274365..372224940 100644 --- a/tex/context/fonts/mkiv/xits-math.lfg +++ b/tex/context/fonts/mkiv/xits-math.lfg @@ -27,16 +27,21 @@ return { -- italics = { -- ["xits-math"] = italics, -- }, + -- kernpairs = { + -- [0x1D44A] = { -- 𝑊 + -- [0x1D434] = -200, -- 𝐴 + -- }, + -- }, alternates = { - cal = { feature = 'ss01', value = 1, comment = "Mathematical Calligraphic Alphabet" }, - greekssup = { feature = 'ss02', value = 1, comment = "Mathematical Greek Sans Serif Alphabet" }, - greekssit = { feature = 'ss03', value = 1, comment = "Mathematical Italic Sans Serif Digits" }, - monobfnum = { feature = 'ss04', value = 1, comment = "Mathematical Bold Monospace Digits" }, - mathbbbf = { feature = 'ss05', value = 1, comment = "Mathematical Bold Double-Struck Alphabet" }, - mathbbit = { feature = 'ss06', value = 1, comment = "Mathematical Italic Double-Struck Alphabet" }, - mathbbbi = { feature = 'ss07', value = 1, comment = "Mathematical Bold Italic Double-Struck Alphabet" }, - upint = { feature = 'ss08', value = 1, comment = "Upright Integrals" }, - vertnot = { feature = 'ss09', value = 1, comment = "Negated Symbols With Vertical Stroke" }, + calligraphic = { feature = 'ss01', value = 1, comment = "Mathematical Calligraphic Alphabet" }, + greekssup = { feature = 'ss02', value = 1, comment = "Mathematical Greek Sans Serif Alphabet" }, + greekssit = { feature = 'ss03', value = 1, comment = "Mathematical Italic Sans Serif Digits" }, + monobfnum = { feature = 'ss04', value = 1, comment = "Mathematical Bold Monospace Digits" }, + mathbbbf = { feature = 'ss05', value = 1, comment = "Mathematical Bold Double-Struck Alphabet" }, + mathbbit = { feature = 'ss06', value = 1, comment = "Mathematical Italic Double-Struck Alphabet" }, + mathbbbi = { feature = 'ss07', value = 1, comment = "Mathematical Bold Italic Double-Struck Alphabet" }, + upint = { feature = 'ss08', value = 1, comment = "Upright Integrals" }, + vertnot = { feature = 'ss09', value = 1, comment = "Negated Symbols With Vertical Stroke" }, }, } } diff --git a/tex/context/interface/mkii/cont-nl.xml b/tex/context/interface/mkii/cont-nl.xml index ac955ae54..ac0b3a4dd 100644 --- a/tex/context/interface/mkii/cont-nl.xml +++ b/tex/context/interface/mkii/cont-nl.xml @@ -1211,7 +1211,7 @@ <cd:command name="localfootnotes" type="environment" file="core-not.tex" category="footnotes"> <cd:sequence> - <cd:string value="localfootnotes"/> + <cd:string value="lokalevoetnoten"/> </cd:sequence> </cd:command> @@ -2740,7 +2740,7 @@ <cd:command name="marginblock" type="environment" file="page-flt.tex"> <cd:sequence> - <cd:string value="marginblock"/> + <cd:string value="margeblok"/> </cd:sequence> </cd:command> @@ -7122,7 +7122,7 @@ <cd:command name="linecorrection" type="environment"> <cd:sequence> - <cd:string value="linecorrection"/> + <cd:string value="regelcorrectie"/> </cd:sequence> </cd:command> @@ -7221,7 +7221,7 @@ <cd:command name="alignment" type="environment" file="core-spa.tex"> <cd:sequence> - <cd:string value="alignment"/> + <cd:string value="uitlijnen"/> </cd:sequence> <cd:arguments> <cd:keywords n="1" optional="yes" list="yes"> diff --git a/tex/context/interface/mkii/keys-cs.xml b/tex/context/interface/mkii/keys-cs.xml index ce8e41016..9ce2a779a 100644 --- a/tex/context/interface/mkii/keys-cs.xml +++ b/tex/context/interface/mkii/keys-cs.xml @@ -79,6 +79,7 @@ <cd:variable name='all' value='vse'/> <cd:variable name='alphabetic' value='alphabetic'/> <cd:variable name='always' value='vzdy'/> + <cd:variable name='anchor' value='anchor'/> <cd:variable name='and' value='and'/> <cd:variable name='answerarea' value='answerarea'/> <cd:variable name='appendices' value='dodatky'/> @@ -172,9 +173,11 @@ <cd:variable name='down' value='down'/> <cd:variable name='each' value='kazdy'/> <cd:variable name='edge' value='hrana'/> + <cd:variable name='effective' value='effective'/> <cd:variable name='eight' value='eight'/> <cd:variable name='embed' value='embed'/> <cd:variable name='empty' value='prazdne'/> + <cd:variable name='enable' value='enable'/> <cd:variable name='end' value='end'/> <cd:variable name='endnote' value='endnote'/> <cd:variable name='enumeration' value='vycet'/> @@ -209,9 +212,10 @@ <cd:variable name='force' value='sila'/> <cd:variable name='foreground' value='popredi'/> <cd:variable name='formula' value='rovnice'/> - <cd:variable name='formulae' value='rovnice'/> + <cd:variable name='formulas' value='rovnice'/> <cd:variable name='forward' value='vpred'/> <cd:variable name='four' value='ctyri'/> + <cd:variable name='fractions' value='fractions'/> <cd:variable name='frame' value='ramecek'/> <cd:variable name='framedtext' value='oramovanytext'/> <cd:variable name='friday' value='patek'/> @@ -236,6 +240,7 @@ <cd:variable name='here' value='zde'/> <cd:variable name='hereafter' value='nize'/> <cd:variable name='hidden' value='skryte'/> + <cd:variable name='hiddenbar' value='hiddenbar'/> <cd:variable name='hiding' value='skryt'/> <cd:variable name='high' value='vysoko'/> <cd:variable name='horizontal' value='horizontalne'/> @@ -379,6 +384,7 @@ <cd:variable name='note' value='note'/> <cd:variable name='nothanging' value='nothanging'/> <cd:variable name='nothyphenated' value='nothyphenated'/> + <cd:variable name='notjoinedup' value='notjoinedup'/> <cd:variable name='november' value='listopad'/> <cd:variable name='nowhere' value='nikde'/> <cd:variable name='nowhite' value='zadnabila'/> @@ -627,6 +633,7 @@ <cd:constant name='anchor' value='anchor'/> <cd:constant name='andtext' value='andtext'/> <cd:constant name='apa' value='apa'/> + <cd:constant name='arguments' value='arguments'/> <cd:constant name='arrow' value='sipka'/> <cd:constant name='artauthor' value='artauthor'/> <cd:constant name='artauthoretaldisplay' value='artauthoretaldisplay'/> @@ -727,6 +734,7 @@ <cd:constant name='controls' value='controls'/> <cd:constant name='conversion' value='konverze'/> <cd:constant name='convertfile' value='konverzesouboru'/> + <cd:constant name='copies' value='copies'/> <cd:constant name='corner' value='roh'/> <cd:constant name='coupling' value='propojeni'/> <cd:constant name='couplingway' value='zpusobpropojeni'/> @@ -775,6 +783,7 @@ <cd:constant name='etaloption' value='etaloption'/> <cd:constant name='etaltext' value='etaltext'/> <cd:constant name='evenmargin' value='sudamarginalie'/> + <cd:constant name='exact' value='exact'/> <cd:constant name='exitoffset' value='exitoffset'/> <cd:constant name='expansion' value='expanzen'/> <cd:constant name='export' value='export'/> @@ -817,6 +826,7 @@ <cd:constant name='frameoffset' value='offsetramecku'/> <cd:constant name='frameradius' value='polomerramecku'/> <cd:constant name='frames' value='ramecky'/> + <cd:constant name='freeregion' value='freeregion'/> <cd:constant name='from' value='z'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> @@ -1166,6 +1176,7 @@ <cd:constant name='splitoffset' value='splitoffset'/> <cd:constant name='spot' value='spot'/> <cd:constant name='stack' value='stack'/> + <cd:constant name='stackname' value='stackname'/> <cd:constant name='start' value='start'/> <cd:constant name='starter' value='starter'/> <cd:constant name='state' value='status'/> @@ -1176,6 +1187,7 @@ <cd:constant name='strip' value='strip'/> <cd:constant name='strut' value='strut'/> <cd:constant name='style' value='pismeno'/> + <cd:constant name='stylealternative' value='stylealternative'/> <cd:constant name='sub' value='pod'/> <cd:constant name='subtitle' value='podtitulek'/> <cd:constant name='suffix' value='suffix'/> @@ -1231,6 +1243,7 @@ <cd:constant name='topspace' value='svrchnimezera'/> <cd:constant name='topstate' value='statusvrsku'/> <cd:constant name='totalnumber' value='totalnumber'/> + <cd:constant name='transform' value='transform'/> <cd:constant name='translate' value='translate'/> <cd:constant name='trimoffset' value='trimoffset'/> <cd:constant name='type' value='typ'/> @@ -1317,6 +1330,7 @@ <cd:command name='Words' value='Slova'/> <cd:command name='about' value='oref'/> <cd:command name='adaptlayout' value='prizpusobvzhled'/> + <cd:command name='alignment' value='alignment'/> <cd:command name='arg' value='arg'/> <cd:command name='at' value='pref'/> <cd:command name='atleftmargin' value='atleftmargin'/> @@ -1533,11 +1547,13 @@ <cd:command name='leftmargindistance' value='vzdalenostlevemarginalie'/> <cd:command name='leftmarginwidth' value='sirkalevemarginalie'/> <cd:command name='leg' value='leg'/> + <cd:command name='linecorrection' value='linecorrection'/> <cd:command name='linewidth' value='tloustkacary'/> <cd:command name='listheight' value='vyskaseznamu'/> <cd:command name='listlength' value='delkaseznamu'/> <cd:command name='listsymbol' value='listsymbol'/> <cd:command name='listwidth' value='sirkaseznamu'/> + <cd:command name='localfootnotes' value='localfootnotes'/> <cd:command name='logfields' value='zaznamovepole'/> <cd:command name='lohi' value='nivy'/> <cd:command name='low' value='nizky'/> @@ -1546,6 +1562,7 @@ <cd:command name='makeupheight' value='vyskasazby'/> <cd:command name='makeupwidth' value='sirkasazby'/> <cd:command name='mar' value='okr'/> + <cd:command name='marginblock' value='marginblock'/> <cd:command name='margindistance' value='vzdalenostmarginalie'/> <cd:command name='marginrule' value='marginalnilinka'/> <cd:command name='margintext' value='marginalnitext'/> @@ -1645,6 +1662,7 @@ <cd:command name='rightmarginwidth' value='sirkapravemarginalie'/> <cd:command name='romannumerals' value='rimskecislice'/> <cd:command name='rotate' value='otocit'/> + <cd:command name='savebuffer' value='savebuffer'/> <cd:command name='scale' value='meritko'/> <cd:command name='screen' value='obrazovka'/> <cd:command name='selectblocks' value='vyberbloky'/> @@ -1680,7 +1698,9 @@ <cd:command name='setupcombinations' value='nastavspojeni'/> <cd:command name='setupcombinedlist' value='nastavkombinovanyseznam'/> <cd:command name='setupcomment' value='nastavkomentar'/> + <cd:command name='setupdescription' value='setupdescription'/> <cd:command name='setupdescriptions' value='nastavpopisy'/> + <cd:command name='setupenumeration' value='setupenumeration'/> <cd:command name='setupenumerations' value='nastavvycty'/> <cd:command name='setupexternalfigures' value='nastavexterniobrazy'/> <cd:command name='setupfield' value='nastavpole'/> @@ -1695,8 +1715,10 @@ <cd:command name='setupfootnotedefinition' value='nastavdefinicipoznamekpodcarou'/> <cd:command name='setupfootnotes' value='nastavpoznamkypodcarou'/> <cd:command name='setupforms' value='setupforms'/> + <cd:command name='setupformula' value='setupformula'/> <cd:command name='setupformulas' value='nastavrovnice'/> <cd:command name='setupframed' value='nastavoramovani'/> + <cd:command name='setupframedtext' value='setupframedtext'/> <cd:command name='setupframedtexts' value='nastavoramovanetexty'/> <cd:command name='setuphead' value='nastavnadpis'/> <cd:command name='setupheader' value='nastavzahlavi'/> @@ -1725,7 +1747,9 @@ <cd:command name='setuplinewidth' value='nastavsirkucary'/> <cd:command name='setuplist' value='nastavseznam'/> <cd:command name='setupmakeup' value='nastavupravu'/> + <cd:command name='setupmarginblock' value='setupmarginblock'/> <cd:command name='setupmarginblocks' value='nastavmarginalniblok'/> + <cd:command name='setupmargindata' value='setupmargindata'/> <cd:command name='setupmarginrules' value='nastavmarginalnilinky'/> <cd:command name='setupmarking' value='nastavznaceni'/> <cd:command name='setupmathalignment' value='setupmathalignment'/> @@ -1904,6 +1928,7 @@ <cd:command name='testcolumn' value='testcolumn'/> <cd:command name='testpage' value='testpage'/> <cd:command name='tex' value='tex'/> + <cd:command name='textbackground' value='textbackground'/> <cd:command name='textheight' value='vyskatextu'/> <cd:command name='textreference' value='odkaznatext'/> <cd:command name='textrule' value='textovalinka'/> diff --git a/tex/context/interface/mkii/keys-de.xml b/tex/context/interface/mkii/keys-de.xml index 5c7ecc651..404f8da89 100644 --- a/tex/context/interface/mkii/keys-de.xml +++ b/tex/context/interface/mkii/keys-de.xml @@ -79,6 +79,7 @@ <cd:variable name='all' value='alles'/> <cd:variable name='alphabetic' value='alphabetic'/> <cd:variable name='always' value='immer'/> + <cd:variable name='anchor' value='anchor'/> <cd:variable name='and' value='und'/> <cd:variable name='answerarea' value='answerarea'/> <cd:variable name='appendices' value='anhaenge'/> @@ -172,9 +173,11 @@ <cd:variable name='down' value='down'/> <cd:variable name='each' value='jede'/> <cd:variable name='edge' value='kante'/> + <cd:variable name='effective' value='effective'/> <cd:variable name='eight' value='acht'/> <cd:variable name='embed' value='embed'/> <cd:variable name='empty' value='leer'/> + <cd:variable name='enable' value='enable'/> <cd:variable name='end' value='end'/> <cd:variable name='endnote' value='endnote'/> <cd:variable name='enumeration' value='nummerierung'/> @@ -209,9 +212,10 @@ <cd:variable name='force' value='zwinge'/> <cd:variable name='foreground' value='vordergrund'/> <cd:variable name='formula' value='formel'/> - <cd:variable name='formulae' value='formeln'/> + <cd:variable name='formulas' value='formeln'/> <cd:variable name='forward' value='vorwaerts'/> <cd:variable name='four' value='vier'/> + <cd:variable name='fractions' value='fractions'/> <cd:variable name='frame' value='rahmen'/> <cd:variable name='framedtext' value='umrahmtertext'/> <cd:variable name='friday' value='freitag'/> @@ -236,6 +240,7 @@ <cd:variable name='here' value='hier'/> <cd:variable name='hereafter' value='nachher'/> <cd:variable name='hidden' value='versteckt'/> + <cd:variable name='hiddenbar' value='hiddenbar'/> <cd:variable name='hiding' value='verbergen'/> <cd:variable name='high' value='hoch'/> <cd:variable name='horizontal' value='horizontal'/> @@ -379,6 +384,7 @@ <cd:variable name='note' value='note'/> <cd:variable name='nothanging' value='nothanging'/> <cd:variable name='nothyphenated' value='nothyphenated'/> + <cd:variable name='notjoinedup' value='notjoinedup'/> <cd:variable name='november' value='november'/> <cd:variable name='nowhere' value='nirgens'/> <cd:variable name='nowhite' value='keinweiss'/> @@ -627,6 +633,7 @@ <cd:constant name='anchor' value='anchor'/> <cd:constant name='andtext' value='andtext'/> <cd:constant name='apa' value='apa'/> + <cd:constant name='arguments' value='arguments'/> <cd:constant name='arrow' value='pfeil'/> <cd:constant name='artauthor' value='artauthor'/> <cd:constant name='artauthoretaldisplay' value='artauthoretaldisplay'/> @@ -727,6 +734,7 @@ <cd:constant name='controls' value='controls'/> <cd:constant name='conversion' value='konversion'/> <cd:constant name='convertfile' value='konvertieredatei'/> + <cd:constant name='copies' value='copies'/> <cd:constant name='corner' value='winkel'/> <cd:constant name='coupling' value='verknuepfung'/> <cd:constant name='couplingway' value='verkopplungsart'/> @@ -775,6 +783,7 @@ <cd:constant name='etaloption' value='etaloption'/> <cd:constant name='etaltext' value='etaltext'/> <cd:constant name='evenmargin' value='geraderand'/> + <cd:constant name='exact' value='exact'/> <cd:constant name='exitoffset' value='exitoffset'/> <cd:constant name='expansion' value='expansion'/> <cd:constant name='export' value='export'/> @@ -817,6 +826,7 @@ <cd:constant name='frameoffset' value='rahmenoffset'/> <cd:constant name='frameradius' value='rahmenradius'/> <cd:constant name='frames' value='umrahmen'/> + <cd:constant name='freeregion' value='freeregion'/> <cd:constant name='from' value='von'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> @@ -1166,6 +1176,7 @@ <cd:constant name='splitoffset' value='splitoffset'/> <cd:constant name='spot' value='spot'/> <cd:constant name='stack' value='stack'/> + <cd:constant name='stackname' value='stackname'/> <cd:constant name='start' value='start'/> <cd:constant name='starter' value='starter'/> <cd:constant name='state' value='status'/> @@ -1176,6 +1187,7 @@ <cd:constant name='strip' value='strip'/> <cd:constant name='strut' value='strut'/> <cd:constant name='style' value='stil'/> + <cd:constant name='stylealternative' value='stylealternative'/> <cd:constant name='sub' value='unter'/> <cd:constant name='subtitle' value='untertitel'/> <cd:constant name='suffix' value='suffix'/> @@ -1231,6 +1243,7 @@ <cd:constant name='topspace' value='kopfspatium'/> <cd:constant name='topstate' value='statusoben'/> <cd:constant name='totalnumber' value='totalnumber'/> + <cd:constant name='transform' value='transform'/> <cd:constant name='translate' value='translate'/> <cd:constant name='trimoffset' value='trimoffset'/> <cd:constant name='type' value='typ'/> @@ -1317,6 +1330,7 @@ <cd:command name='Words' value='Woerter'/> <cd:command name='about' value='ueber'/> <cd:command name='adaptlayout' value='passelayoutan'/> + <cd:command name='alignment' value='alignment'/> <cd:command name='arg' value='arg'/> <cd:command name='at' value='bei'/> <cd:command name='atleftmargin' value='atleftmargin'/> @@ -1533,11 +1547,13 @@ <cd:command name='leftmargindistance' value='linkemarginalafstand'/> <cd:command name='leftmarginwidth' value='linkemarginalbreite'/> <cd:command name='leg' value='leg'/> + <cd:command name='linecorrection' value='linecorrection'/> <cd:command name='linewidth' value='liniendicke'/> <cd:command name='listheight' value='listenhoehe'/> <cd:command name='listlength' value='listenlaenge'/> <cd:command name='listsymbol' value='listsymbol'/> <cd:command name='listwidth' value='listenbreite'/> + <cd:command name='localfootnotes' value='localfootnotes'/> <cd:command name='logfields' value='registrierefelder'/> <cd:command name='lohi' value='tiho'/> <cd:command name='low' value='tief'/> @@ -1546,6 +1562,7 @@ <cd:command name='makeupheight' value='satzhoehe'/> <cd:command name='makeupwidth' value='satzbreite'/> <cd:command name='mar' value='mar'/> + <cd:command name='marginblock' value='marginblock'/> <cd:command name='margindistance' value='marginalafstand'/> <cd:command name='marginrule' value='marginallinie'/> <cd:command name='margintext' value='marginaltext'/> @@ -1645,6 +1662,7 @@ <cd:command name='rightmarginwidth' value='rechtemarginalbreite'/> <cd:command name='romannumerals' value='roemischezahlen'/> <cd:command name='rotate' value='drehen'/> + <cd:command name='savebuffer' value='savebuffer'/> <cd:command name='scale' value='format'/> <cd:command name='screen' value='bildschirm'/> <cd:command name='selectblocks' value='waehlebloeckeaus'/> @@ -1680,7 +1698,9 @@ <cd:command name='setupcombinations' value='stellekombinationein'/> <cd:command name='setupcombinedlist' value='stellezusammengestelltelisteein'/> <cd:command name='setupcomment' value='stellekommentarein'/> + <cd:command name='setupdescription' value='setupdescription'/> <cd:command name='setupdescriptions' value='definierebeschreibungen'/> + <cd:command name='setupenumeration' value='setupenumeration'/> <cd:command name='setupenumerations' value='stellebeschreibungein'/> <cd:command name='setupexternalfigures' value='stelleexterneabbildungenein'/> <cd:command name='setupfield' value='stellefeldein'/> @@ -1695,8 +1715,10 @@ <cd:command name='setupfootnotedefinition' value='stellefussnotendefinitionein'/> <cd:command name='setupfootnotes' value='stellefussnotenein'/> <cd:command name='setupforms' value='setupforms'/> + <cd:command name='setupformula' value='setupformula'/> <cd:command name='setupformulas' value='stelleformelnein'/> <cd:command name='setupframed' value='stelleumrahmtein'/> + <cd:command name='setupframedtext' value='setupframedtext'/> <cd:command name='setupframedtexts' value='stelleumrahmtetexteein'/> <cd:command name='setuphead' value='stelleueberschriftein'/> <cd:command name='setupheader' value='stellekopfzeileein'/> @@ -1725,7 +1747,9 @@ <cd:command name='setuplinewidth' value='stellelinienbreiteein'/> <cd:command name='setuplist' value='stellelisteein'/> <cd:command name='setupmakeup' value='stelleumbruchein'/> + <cd:command name='setupmarginblock' value='setupmarginblock'/> <cd:command name='setupmarginblocks' value='stellemarginalblockein'/> + <cd:command name='setupmargindata' value='setupmargindata'/> <cd:command name='setupmarginrules' value='stellemarginallinieein'/> <cd:command name='setupmarking' value='stellebeschriftungein'/> <cd:command name='setupmathalignment' value='setupmathalignment'/> @@ -1904,6 +1928,7 @@ <cd:command name='testcolumn' value='testcolumn'/> <cd:command name='testpage' value='testpage'/> <cd:command name='tex' value='tex'/> + <cd:command name='textbackground' value='textbackground'/> <cd:command name='textheight' value='texthoehe'/> <cd:command name='textreference' value='textreferenz'/> <cd:command name='textrule' value='textlinie'/> diff --git a/tex/context/interface/mkii/keys-en.xml b/tex/context/interface/mkii/keys-en.xml index 621cbd763..a1c935db8 100644 --- a/tex/context/interface/mkii/keys-en.xml +++ b/tex/context/interface/mkii/keys-en.xml @@ -79,6 +79,7 @@ <cd:variable name='all' value='all'/> <cd:variable name='alphabetic' value='alphabetic'/> <cd:variable name='always' value='always'/> + <cd:variable name='anchor' value='anchor'/> <cd:variable name='and' value='and'/> <cd:variable name='answerarea' value='answerarea'/> <cd:variable name='appendices' value='appendices'/> @@ -172,9 +173,11 @@ <cd:variable name='down' value='down'/> <cd:variable name='each' value='each'/> <cd:variable name='edge' value='edge'/> + <cd:variable name='effective' value='effective'/> <cd:variable name='eight' value='eight'/> <cd:variable name='embed' value='embed'/> <cd:variable name='empty' value='empty'/> + <cd:variable name='enable' value='enable'/> <cd:variable name='end' value='end'/> <cd:variable name='endnote' value='endnote'/> <cd:variable name='enumeration' value='enumeration'/> @@ -209,9 +212,10 @@ <cd:variable name='force' value='force'/> <cd:variable name='foreground' value='foreground'/> <cd:variable name='formula' value='formula'/> - <cd:variable name='formulae' value='formulae'/> + <cd:variable name='formulas' value='formulas'/> <cd:variable name='forward' value='forward'/> <cd:variable name='four' value='four'/> + <cd:variable name='fractions' value='fractions'/> <cd:variable name='frame' value='frame'/> <cd:variable name='framedtext' value='framedtext'/> <cd:variable name='friday' value='friday'/> @@ -236,6 +240,7 @@ <cd:variable name='here' value='here'/> <cd:variable name='hereafter' value='hereafter'/> <cd:variable name='hidden' value='hidden'/> + <cd:variable name='hiddenbar' value='hiddenbar'/> <cd:variable name='hiding' value='hiding'/> <cd:variable name='high' value='high'/> <cd:variable name='horizontal' value='horizontal'/> @@ -379,6 +384,7 @@ <cd:variable name='note' value='note'/> <cd:variable name='nothanging' value='nothanging'/> <cd:variable name='nothyphenated' value='nothyphenated'/> + <cd:variable name='notjoinedup' value='notjoinedup'/> <cd:variable name='november' value='november'/> <cd:variable name='nowhere' value='nowhere'/> <cd:variable name='nowhite' value='nowhite'/> @@ -627,6 +633,7 @@ <cd:constant name='anchor' value='anchor'/> <cd:constant name='andtext' value='andtext'/> <cd:constant name='apa' value='apa'/> + <cd:constant name='arguments' value='arguments'/> <cd:constant name='arrow' value='arrow'/> <cd:constant name='artauthor' value='artauthor'/> <cd:constant name='artauthoretaldisplay' value='artauthoretaldisplay'/> @@ -727,6 +734,7 @@ <cd:constant name='controls' value='controls'/> <cd:constant name='conversion' value='conversion'/> <cd:constant name='convertfile' value='convertfile'/> + <cd:constant name='copies' value='copies'/> <cd:constant name='corner' value='corner'/> <cd:constant name='coupling' value='coupling'/> <cd:constant name='couplingway' value='couplingway'/> @@ -775,6 +783,7 @@ <cd:constant name='etaloption' value='etaloption'/> <cd:constant name='etaltext' value='etaltext'/> <cd:constant name='evenmargin' value='evenmargin'/> + <cd:constant name='exact' value='exact'/> <cd:constant name='exitoffset' value='exitoffset'/> <cd:constant name='expansion' value='expansion'/> <cd:constant name='export' value='export'/> @@ -817,6 +826,7 @@ <cd:constant name='frameoffset' value='frameoffset'/> <cd:constant name='frameradius' value='frameradius'/> <cd:constant name='frames' value='frames'/> + <cd:constant name='freeregion' value='freeregion'/> <cd:constant name='from' value='from'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> @@ -1166,6 +1176,7 @@ <cd:constant name='splitoffset' value='splitoffset'/> <cd:constant name='spot' value='spot'/> <cd:constant name='stack' value='stack'/> + <cd:constant name='stackname' value='stackname'/> <cd:constant name='start' value='start'/> <cd:constant name='starter' value='starter'/> <cd:constant name='state' value='state'/> @@ -1176,6 +1187,7 @@ <cd:constant name='strip' value='strip'/> <cd:constant name='strut' value='strut'/> <cd:constant name='style' value='style'/> + <cd:constant name='stylealternative' value='stylealternative'/> <cd:constant name='sub' value='sub'/> <cd:constant name='subtitle' value='subtitle'/> <cd:constant name='suffix' value='suffix'/> @@ -1231,6 +1243,7 @@ <cd:constant name='topspace' value='topspace'/> <cd:constant name='topstate' value='topstate'/> <cd:constant name='totalnumber' value='totalnumber'/> + <cd:constant name='transform' value='transform'/> <cd:constant name='translate' value='translate'/> <cd:constant name='trimoffset' value='trimoffset'/> <cd:constant name='type' value='type'/> @@ -1317,6 +1330,7 @@ <cd:command name='Words' value='Words'/> <cd:command name='about' value='about'/> <cd:command name='adaptlayout' value='adaptlayout'/> + <cd:command name='alignment' value='alignment'/> <cd:command name='arg' value='arg'/> <cd:command name='at' value='at'/> <cd:command name='atleftmargin' value='atleftmargin'/> @@ -1533,11 +1547,13 @@ <cd:command name='leftmargindistance' value='leftmargindistance'/> <cd:command name='leftmarginwidth' value='leftmarginwidth'/> <cd:command name='leg' value='leg'/> + <cd:command name='linecorrection' value='linecorrection'/> <cd:command name='linewidth' value='linethickness'/> <cd:command name='listheight' value='listheight'/> <cd:command name='listlength' value='listlength'/> <cd:command name='listsymbol' value='listsymbol'/> <cd:command name='listwidth' value='listwidth'/> + <cd:command name='localfootnotes' value='localfootnotes'/> <cd:command name='logfields' value='logfields'/> <cd:command name='lohi' value='lohi'/> <cd:command name='low' value='low'/> @@ -1546,6 +1562,7 @@ <cd:command name='makeupheight' value='makeupheight'/> <cd:command name='makeupwidth' value='makeupwidth'/> <cd:command name='mar' value='mar'/> + <cd:command name='marginblock' value='marginblock'/> <cd:command name='margindistance' value='margindistance'/> <cd:command name='marginrule' value='marginrule'/> <cd:command name='margintext' value='margintext'/> @@ -1645,6 +1662,7 @@ <cd:command name='rightmarginwidth' value='rightmarginwidth'/> <cd:command name='romannumerals' value='romannumerals'/> <cd:command name='rotate' value='rotate'/> + <cd:command name='savebuffer' value='savebuffer'/> <cd:command name='scale' value='scale'/> <cd:command name='screen' value='screen'/> <cd:command name='selectblocks' value='selectblocks'/> @@ -1680,7 +1698,9 @@ <cd:command name='setupcombinations' value='setupcombinations'/> <cd:command name='setupcombinedlist' value='setupcombinedlist'/> <cd:command name='setupcomment' value='setupcomment'/> + <cd:command name='setupdescription' value='setupdescription'/> <cd:command name='setupdescriptions' value='setupdescriptions'/> + <cd:command name='setupenumeration' value='setupenumeration'/> <cd:command name='setupenumerations' value='setupenumerations'/> <cd:command name='setupexternalfigures' value='setupexternalfigures'/> <cd:command name='setupfield' value='setupfield'/> @@ -1695,8 +1715,10 @@ <cd:command name='setupfootnotedefinition' value='setupfootnotedefinition'/> <cd:command name='setupfootnotes' value='setupfootnotes'/> <cd:command name='setupforms' value='setupforms'/> + <cd:command name='setupformula' value='setupformula'/> <cd:command name='setupformulas' value='setupformulae'/> <cd:command name='setupframed' value='setupframed'/> + <cd:command name='setupframedtext' value='setupframedtext'/> <cd:command name='setupframedtexts' value='setupframedtexts'/> <cd:command name='setuphead' value='setuphead'/> <cd:command name='setupheader' value='setupheader'/> @@ -1725,7 +1747,9 @@ <cd:command name='setuplinewidth' value='setuplinewidth'/> <cd:command name='setuplist' value='setuplist'/> <cd:command name='setupmakeup' value='setupmakeup'/> + <cd:command name='setupmarginblock' value='setupmarginblock'/> <cd:command name='setupmarginblocks' value='setupmarginblocks'/> + <cd:command name='setupmargindata' value='setupmargindata'/> <cd:command name='setupmarginrules' value='setupmarginrules'/> <cd:command name='setupmarking' value='setupmarking'/> <cd:command name='setupmathalignment' value='setupmathalignment'/> @@ -1904,6 +1928,7 @@ <cd:command name='testcolumn' value='testcolumn'/> <cd:command name='testpage' value='testpage'/> <cd:command name='tex' value='tex'/> + <cd:command name='textbackground' value='textbackground'/> <cd:command name='textheight' value='textheight'/> <cd:command name='textreference' value='textreference'/> <cd:command name='textrule' value='textrule'/> diff --git a/tex/context/interface/mkii/keys-fr.xml b/tex/context/interface/mkii/keys-fr.xml index 301f94628..db6e35ac6 100644 --- a/tex/context/interface/mkii/keys-fr.xml +++ b/tex/context/interface/mkii/keys-fr.xml @@ -79,6 +79,7 @@ <cd:variable name='all' value='tout'/> <cd:variable name='alphabetic' value='alphabetic'/> <cd:variable name='always' value='toujours'/> + <cd:variable name='anchor' value='anchor'/> <cd:variable name='and' value='and'/> <cd:variable name='answerarea' value='answerarea'/> <cd:variable name='appendices' value='annexes'/> @@ -172,9 +173,11 @@ <cd:variable name='down' value='down'/> <cd:variable name='each' value='chaque'/> <cd:variable name='edge' value='bord'/> + <cd:variable name='effective' value='effective'/> <cd:variable name='eight' value='eight'/> <cd:variable name='embed' value='embed'/> <cd:variable name='empty' value='vide'/> + <cd:variable name='enable' value='enable'/> <cd:variable name='end' value='end'/> <cd:variable name='endnote' value='notefin'/> <cd:variable name='enumeration' value='enumeration'/> @@ -209,9 +212,10 @@ <cd:variable name='force' value='force'/> <cd:variable name='foreground' value='premierplan'/> <cd:variable name='formula' value='formule'/> - <cd:variable name='formulae' value='formules'/> + <cd:variable name='formulas' value='formules'/> <cd:variable name='forward' value='avance'/> <cd:variable name='four' value='quatre'/> + <cd:variable name='fractions' value='fractions'/> <cd:variable name='frame' value='cadre'/> <cd:variable name='framedtext' value='texteencadre'/> <cd:variable name='friday' value='vendredi'/> @@ -236,6 +240,7 @@ <cd:variable name='here' value='ici'/> <cd:variable name='hereafter' value='suivant'/> <cd:variable name='hidden' value='cache'/> + <cd:variable name='hiddenbar' value='hiddenbar'/> <cd:variable name='hiding' value='cache'/> <cd:variable name='high' value='haut'/> <cd:variable name='horizontal' value='horizontale'/> @@ -379,6 +384,7 @@ <cd:variable name='note' value='note'/> <cd:variable name='nothanging' value='nonsuspendu'/> <cd:variable name='nothyphenated' value='nothyphenated'/> + <cd:variable name='notjoinedup' value='notjoinedup'/> <cd:variable name='november' value='novembre'/> <cd:variable name='nowhere' value='nulpart'/> <cd:variable name='nowhite' value='sansblanc'/> @@ -627,6 +633,7 @@ <cd:constant name='anchor' value='anchor'/> <cd:constant name='andtext' value='andtext'/> <cd:constant name='apa' value='apa'/> + <cd:constant name='arguments' value='arguments'/> <cd:constant name='arrow' value='fleche'/> <cd:constant name='artauthor' value='artauthor'/> <cd:constant name='artauthoretaldisplay' value='artauthoretaldisplay'/> @@ -727,6 +734,7 @@ <cd:constant name='controls' value='controles'/> <cd:constant name='conversion' value='conversion'/> <cd:constant name='convertfile' value='conversionfichier'/> + <cd:constant name='copies' value='copies'/> <cd:constant name='corner' value='coin'/> <cd:constant name='coupling' value='couplage'/> <cd:constant name='couplingway' value='modecouplage'/> @@ -775,6 +783,7 @@ <cd:constant name='etaloption' value='etaloption'/> <cd:constant name='etaltext' value='etaltext'/> <cd:constant name='evenmargin' value='margepaire'/> + <cd:constant name='exact' value='exact'/> <cd:constant name='exitoffset' value='exitoffset'/> <cd:constant name='expansion' value='expansion'/> <cd:constant name='export' value='export'/> @@ -817,6 +826,7 @@ <cd:constant name='frameoffset' value='decalagecadre'/> <cd:constant name='frameradius' value='rayoncadre'/> <cd:constant name='frames' value='cadres'/> + <cd:constant name='freeregion' value='freeregion'/> <cd:constant name='from' value='de'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> @@ -1166,6 +1176,7 @@ <cd:constant name='splitoffset' value='splitoffset'/> <cd:constant name='spot' value='spot'/> <cd:constant name='stack' value='stack'/> + <cd:constant name='stackname' value='stackname'/> <cd:constant name='start' value='demarre'/> <cd:constant name='starter' value='starter'/> <cd:constant name='state' value='etat'/> @@ -1176,6 +1187,7 @@ <cd:constant name='strip' value='strip'/> <cd:constant name='strut' value='strut'/> <cd:constant name='style' value='style'/> + <cd:constant name='stylealternative' value='stylealternative'/> <cd:constant name='sub' value='sous'/> <cd:constant name='subtitle' value='soustitre'/> <cd:constant name='suffix' value='suffix'/> @@ -1231,6 +1243,7 @@ <cd:constant name='topspace' value='espacesup'/> <cd:constant name='topstate' value='etatsup'/> <cd:constant name='totalnumber' value='totalnumber'/> + <cd:constant name='transform' value='transform'/> <cd:constant name='translate' value='translate'/> <cd:constant name='trimoffset' value='trimoffset'/> <cd:constant name='type' value='type'/> @@ -1317,6 +1330,7 @@ <cd:command name='Words' value='Mots'/> <cd:command name='about' value='concernant'/> <cd:command name='adaptlayout' value='adaptedisposition'/> + <cd:command name='alignment' value='alignment'/> <cd:command name='arg' value='arg'/> <cd:command name='at' value='a'/> <cd:command name='atleftmargin' value='atleftmargin'/> @@ -1533,11 +1547,13 @@ <cd:command name='leftmargindistance' value='distancemargegauche'/> <cd:command name='leftmarginwidth' value='largeurmargegauche'/> <cd:command name='leg' value='leg'/> + <cd:command name='linecorrection' value='linecorrection'/> <cd:command name='linewidth' value='largeurligne'/> <cd:command name='listheight' value='hauteurliste'/> <cd:command name='listlength' value='llongueurliste'/> <cd:command name='listsymbol' value='listesymbole'/> <cd:command name='listwidth' value='largeurliste'/> + <cd:command name='localfootnotes' value='localfootnotes'/> <cd:command name='logfields' value='logchamp'/> <cd:command name='lohi' value='baha'/> <cd:command name='low' value='bas'/> @@ -1546,6 +1562,7 @@ <cd:command name='makeupheight' value='hauteurmakeup'/> <cd:command name='makeupwidth' value='largeurmakeup'/> <cd:command name='mar' value='mar'/> + <cd:command name='marginblock' value='marginblock'/> <cd:command name='margindistance' value='distancemarge'/> <cd:command name='marginrule' value='margereglee'/> <cd:command name='margintext' value='textemarge'/> @@ -1645,6 +1662,7 @@ <cd:command name='rightmarginwidth' value='largeurmargedroite'/> <cd:command name='romannumerals' value='chiffresromains'/> <cd:command name='rotate' value='oriente'/> + <cd:command name='savebuffer' value='savebuffer'/> <cd:command name='scale' value='echelle'/> <cd:command name='screen' value='ecran'/> <cd:command name='selectblocks' value='selectionneblocs'/> @@ -1680,7 +1698,9 @@ <cd:command name='setupcombinations' value='reglecombinaisons'/> <cd:command name='setupcombinedlist' value='reglelisteimbriquee'/> <cd:command name='setupcomment' value='reglecommentaire'/> + <cd:command name='setupdescription' value='setupdescription'/> <cd:command name='setupdescriptions' value='regledescriptions'/> + <cd:command name='setupenumeration' value='setupenumeration'/> <cd:command name='setupenumerations' value='regleenumerations'/> <cd:command name='setupexternalfigures' value='reglefiguresexternes'/> <cd:command name='setupfield' value='reglechamp'/> @@ -1695,8 +1715,10 @@ <cd:command name='setupfootnotedefinition' value='definitnotepdp'/> <cd:command name='setupfootnotes' value='reglenotepdp'/> <cd:command name='setupforms' value='regleformulaires'/> + <cd:command name='setupformula' value='setupformula'/> <cd:command name='setupformulas' value='regleformules'/> <cd:command name='setupframed' value='regleencadre'/> + <cd:command name='setupframedtext' value='setupframedtext'/> <cd:command name='setupframedtexts' value='setupframedtexts'/> <cd:command name='setuphead' value='regletete'/> <cd:command name='setupheader' value='regleentete'/> @@ -1725,7 +1747,9 @@ <cd:command name='setuplinewidth' value='regleepaisseurligne'/> <cd:command name='setuplist' value='regleliste'/> <cd:command name='setupmakeup' value='reglemakeup'/> + <cd:command name='setupmarginblock' value='setupmarginblock'/> <cd:command name='setupmarginblocks' value='regleblocmarge'/> + <cd:command name='setupmargindata' value='setupmargindata'/> <cd:command name='setupmarginrules' value='reglemargereglee'/> <cd:command name='setupmarking' value='reglemarquage'/> <cd:command name='setupmathalignment' value='setupmathalignment'/> @@ -1904,6 +1928,7 @@ <cd:command name='testcolumn' value='testcolumn'/> <cd:command name='testpage' value='testpage'/> <cd:command name='tex' value='tex'/> + <cd:command name='textbackground' value='textbackground'/> <cd:command name='textheight' value='hauteurtexte'/> <cd:command name='textreference' value='referencetexte'/> <cd:command name='textrule' value='ligneregleetexte'/> diff --git a/tex/context/interface/mkii/keys-it.xml b/tex/context/interface/mkii/keys-it.xml index 458acd5c1..86d6868b4 100644 --- a/tex/context/interface/mkii/keys-it.xml +++ b/tex/context/interface/mkii/keys-it.xml @@ -79,6 +79,7 @@ <cd:variable name='all' value='tutti'/> <cd:variable name='alphabetic' value='alphabetic'/> <cd:variable name='always' value='sempre'/> + <cd:variable name='anchor' value='anchor'/> <cd:variable name='and' value='and'/> <cd:variable name='answerarea' value='answerarea'/> <cd:variable name='appendices' value='appendici'/> @@ -172,9 +173,11 @@ <cd:variable name='down' value='down'/> <cd:variable name='each' value='ogni'/> <cd:variable name='edge' value='bordo'/> + <cd:variable name='effective' value='effective'/> <cd:variable name='eight' value='eight'/> <cd:variable name='embed' value='embed'/> <cd:variable name='empty' value='vuoto'/> + <cd:variable name='enable' value='enable'/> <cd:variable name='end' value='end'/> <cd:variable name='endnote' value='endnote'/> <cd:variable name='enumeration' value='enumerazione'/> @@ -209,9 +212,10 @@ <cd:variable name='force' value='forza'/> <cd:variable name='foreground' value='foreground'/> <cd:variable name='formula' value='formula'/> - <cd:variable name='formulae' value='formule'/> + <cd:variable name='formulas' value='formule'/> <cd:variable name='forward' value='avanti'/> <cd:variable name='four' value='quattro'/> + <cd:variable name='fractions' value='fractions'/> <cd:variable name='frame' value='cornice'/> <cd:variable name='framedtext' value='testoincorniciato'/> <cd:variable name='friday' value='venerdi'/> @@ -236,6 +240,7 @@ <cd:variable name='here' value='qui'/> <cd:variable name='hereafter' value='seguente'/> <cd:variable name='hidden' value='nascosto'/> + <cd:variable name='hiddenbar' value='hiddenbar'/> <cd:variable name='hiding' value='nascondere'/> <cd:variable name='high' value='alto'/> <cd:variable name='horizontal' value='orizzontale'/> @@ -379,6 +384,7 @@ <cd:variable name='note' value='note'/> <cd:variable name='nothanging' value='nonsospeso'/> <cd:variable name='nothyphenated' value='nonsillabato'/> + <cd:variable name='notjoinedup' value='notjoinedup'/> <cd:variable name='november' value='novembre'/> <cd:variable name='nowhere' value='danessunaparte'/> <cd:variable name='nowhite' value='nobianco'/> @@ -627,6 +633,7 @@ <cd:constant name='anchor' value='anchor'/> <cd:constant name='andtext' value='andtext'/> <cd:constant name='apa' value='apa'/> + <cd:constant name='arguments' value='arguments'/> <cd:constant name='arrow' value='freccia'/> <cd:constant name='artauthor' value='artauthor'/> <cd:constant name='artauthoretaldisplay' value='artauthoretaldisplay'/> @@ -727,6 +734,7 @@ <cd:constant name='controls' value='controlli'/> <cd:constant name='conversion' value='conversione'/> <cd:constant name='convertfile' value='convertifile'/> + <cd:constant name='copies' value='copies'/> <cd:constant name='corner' value='angolo'/> <cd:constant name='coupling' value='accoppiamento'/> <cd:constant name='couplingway' value='modoaccoppiamento'/> @@ -775,6 +783,7 @@ <cd:constant name='etaloption' value='etaloption'/> <cd:constant name='etaltext' value='etaltext'/> <cd:constant name='evenmargin' value='marginepari'/> + <cd:constant name='exact' value='exact'/> <cd:constant name='exitoffset' value='exitoffset'/> <cd:constant name='expansion' value='espansione'/> <cd:constant name='export' value='export'/> @@ -817,6 +826,7 @@ <cd:constant name='frameoffset' value='offsetcornice'/> <cd:constant name='frameradius' value='raggiocornice'/> <cd:constant name='frames' value='cornici'/> + <cd:constant name='freeregion' value='freeregion'/> <cd:constant name='from' value='da'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> @@ -1166,6 +1176,7 @@ <cd:constant name='splitoffset' value='splitoffset'/> <cd:constant name='spot' value='spot'/> <cd:constant name='stack' value='stack'/> + <cd:constant name='stackname' value='stackname'/> <cd:constant name='start' value='inizia'/> <cd:constant name='starter' value='starter'/> <cd:constant name='state' value='stato'/> @@ -1176,6 +1187,7 @@ <cd:constant name='strip' value='strip'/> <cd:constant name='strut' value='strut'/> <cd:constant name='style' value='stile'/> + <cd:constant name='stylealternative' value='stylealternative'/> <cd:constant name='sub' value='sotto'/> <cd:constant name='subtitle' value='sottotitolo'/> <cd:constant name='suffix' value='suffix'/> @@ -1231,6 +1243,7 @@ <cd:constant name='topspace' value='spaziocima'/> <cd:constant name='topstate' value='statocima'/> <cd:constant name='totalnumber' value='totalnumber'/> + <cd:constant name='transform' value='transform'/> <cd:constant name='translate' value='translate'/> <cd:constant name='trimoffset' value='trimoffset'/> <cd:constant name='type' value='type'/> @@ -1317,6 +1330,7 @@ <cd:command name='Words' value='Parole'/> <cd:command name='about' value='intorno'/> <cd:command name='adaptlayout' value='adattalayout'/> + <cd:command name='alignment' value='alignment'/> <cd:command name='arg' value='arg'/> <cd:command name='at' value='al'/> <cd:command name='atleftmargin' value='atleftmargin'/> @@ -1533,11 +1547,13 @@ <cd:command name='leftmargindistance' value='distanzamarginesinistro'/> <cd:command name='leftmarginwidth' value='ampiezzamarginesinistro'/> <cd:command name='leg' value='leg'/> + <cd:command name='linecorrection' value='linecorrection'/> <cd:command name='linewidth' value='spessoreriga'/> <cd:command name='listheight' value='altezzaelenco'/> <cd:command name='listlength' value='lunghezzaelenco'/> <cd:command name='listsymbol' value='listsymbol'/> <cd:command name='listwidth' value='ampiezzaelenco'/> + <cd:command name='localfootnotes' value='localfootnotes'/> <cd:command name='logfields' value='logcampi'/> <cd:command name='lohi' value='pedap'/> <cd:command name='low' value='ped'/> @@ -1546,6 +1562,7 @@ <cd:command name='makeupheight' value='altezzamakeup'/> <cd:command name='makeupwidth' value='ampiezzamakeup'/> <cd:command name='mar' value='mar'/> + <cd:command name='marginblock' value='marginblock'/> <cd:command name='margindistance' value='distanzamargine'/> <cd:command name='marginrule' value='lineamargine'/> <cd:command name='margintext' value='testoinmargine'/> @@ -1645,6 +1662,7 @@ <cd:command name='rightmarginwidth' value='ampiezzamarginedestro'/> <cd:command name='romannumerals' value='numeriromani'/> <cd:command name='rotate' value='ruota'/> + <cd:command name='savebuffer' value='savebuffer'/> <cd:command name='scale' value='scala'/> <cd:command name='screen' value='schermo'/> <cd:command name='selectblocks' value='selezionablocchi'/> @@ -1680,7 +1698,9 @@ <cd:command name='setupcombinations' value='impostacombinazioni'/> <cd:command name='setupcombinedlist' value='impostaelencocombinato'/> <cd:command name='setupcomment' value='impostacommento'/> + <cd:command name='setupdescription' value='setupdescription'/> <cd:command name='setupdescriptions' value='impostadescrizioni'/> + <cd:command name='setupenumeration' value='setupenumeration'/> <cd:command name='setupenumerations' value='impostaenumerazioni'/> <cd:command name='setupexternalfigures' value='impostafigureesterne'/> <cd:command name='setupfield' value='impostacampo'/> @@ -1695,8 +1715,10 @@ <cd:command name='setupfootnotedefinition' value='impostadefinizionenotepdp'/> <cd:command name='setupfootnotes' value='impostanotepdp'/> <cd:command name='setupforms' value='impostaforms'/> + <cd:command name='setupformula' value='setupformula'/> <cd:command name='setupformulas' value='impostaformule'/> <cd:command name='setupframed' value='impostaincorniciato'/> + <cd:command name='setupframedtext' value='setupframedtext'/> <cd:command name='setupframedtexts' value='impostatestiincorniciati'/> <cd:command name='setuphead' value='impostatesta'/> <cd:command name='setupheader' value='impostainstestazione'/> @@ -1725,7 +1747,9 @@ <cd:command name='setuplinewidth' value='impostaampiezzariga'/> <cd:command name='setuplist' value='impostaelenco'/> <cd:command name='setupmakeup' value='impostamakeup'/> + <cd:command name='setupmarginblock' value='setupmarginblock'/> <cd:command name='setupmarginblocks' value='impostablocchimargine'/> + <cd:command name='setupmargindata' value='setupmargindata'/> <cd:command name='setupmarginrules' value='impostalineemargine'/> <cd:command name='setupmarking' value='impostamarcatura'/> <cd:command name='setupmathalignment' value='setupmathalignment'/> @@ -1904,6 +1928,7 @@ <cd:command name='testcolumn' value='testcolumn'/> <cd:command name='testpage' value='testpage'/> <cd:command name='tex' value='tex'/> + <cd:command name='textbackground' value='textbackground'/> <cd:command name='textheight' value='altezzatesto'/> <cd:command name='textreference' value='riferimentotesto'/> <cd:command name='textrule' value='lineatesto'/> diff --git a/tex/context/interface/mkii/keys-nl.xml b/tex/context/interface/mkii/keys-nl.xml index 5e214c8bb..1c6077d1e 100644 --- a/tex/context/interface/mkii/keys-nl.xml +++ b/tex/context/interface/mkii/keys-nl.xml @@ -79,6 +79,7 @@ <cd:variable name='all' value='alles'/> <cd:variable name='alphabetic' value='alphabetic'/> <cd:variable name='always' value='altijd'/> + <cd:variable name='anchor' value='anker'/> <cd:variable name='and' value='en'/> <cd:variable name='answerarea' value='antwoordgebied'/> <cd:variable name='appendices' value='bijlagen'/> @@ -142,7 +143,7 @@ <cd:variable name='color' value='kleur'/> <cd:variable name='column' value='kolom'/> <cd:variable name='columns' value='kolommen'/> - <cd:variable name='combination' value='combination'/> + <cd:variable name='combination' value='combinatie'/> <cd:variable name='command' value='commando'/> <cd:variable name='commands' value='commandos'/> <cd:variable name='comment' value='commentaar'/> @@ -172,9 +173,11 @@ <cd:variable name='down' value='omlaag'/> <cd:variable name='each' value='elk'/> <cd:variable name='edge' value='rand'/> + <cd:variable name='effective' value='effectief'/> <cd:variable name='eight' value='acht'/> <cd:variable name='embed' value='sluitin'/> <cd:variable name='empty' value='leeg'/> + <cd:variable name='enable' value='enable'/> <cd:variable name='end' value='eind'/> <cd:variable name='endnote' value='eindnoot'/> <cd:variable name='enumeration' value='doornummering'/> @@ -209,9 +212,10 @@ <cd:variable name='force' value='forceer'/> <cd:variable name='foreground' value='voorgrond'/> <cd:variable name='formula' value='formule'/> - <cd:variable name='formulae' value='formules'/> + <cd:variable name='formulas' value='formules'/> <cd:variable name='forward' value='vooruit'/> <cd:variable name='four' value='vier'/> + <cd:variable name='fractions' value='fractions'/> <cd:variable name='frame' value='kader'/> <cd:variable name='framedtext' value='kadertekst'/> <cd:variable name='friday' value='vrijdag'/> @@ -236,6 +240,7 @@ <cd:variable name='here' value='hier'/> <cd:variable name='hereafter' value='hieronder'/> <cd:variable name='hidden' value='verborgen'/> + <cd:variable name='hiddenbar' value='hiddenbar'/> <cd:variable name='hiding' value='verbergen'/> <cd:variable name='high' value='hoog'/> <cd:variable name='horizontal' value='horizontaal'/> @@ -379,6 +384,7 @@ <cd:variable name='note' value='note'/> <cd:variable name='nothanging' value='niethangend'/> <cd:variable name='nothyphenated' value='nietafgebroken'/> + <cd:variable name='notjoinedup' value='nietaansluitend'/> <cd:variable name='november' value='november'/> <cd:variable name='nowhere' value='nergens'/> <cd:variable name='nowhite' value='geenwit'/> @@ -627,6 +633,7 @@ <cd:constant name='anchor' value='anker'/> <cd:constant name='andtext' value='andtext'/> <cd:constant name='apa' value='apa'/> + <cd:constant name='arguments' value='argumenten'/> <cd:constant name='arrow' value='pijl'/> <cd:constant name='artauthor' value='artauthor'/> <cd:constant name='artauthoretaldisplay' value='artauthoretaldisplay'/> @@ -727,6 +734,7 @@ <cd:constant name='controls' value='sturing'/> <cd:constant name='conversion' value='conversie'/> <cd:constant name='convertfile' value='converteerfile'/> + <cd:constant name='copies' value='kopieen'/> <cd:constant name='corner' value='hoek'/> <cd:constant name='coupling' value='koppeling'/> <cd:constant name='couplingway' value='koppelwijze'/> @@ -775,6 +783,7 @@ <cd:constant name='etaloption' value='etaloption'/> <cd:constant name='etaltext' value='etaltext'/> <cd:constant name='evenmargin' value='evenmarge'/> + <cd:constant name='exact' value='exact'/> <cd:constant name='exitoffset' value='exitoffset'/> <cd:constant name='expansion' value='expansie'/> <cd:constant name='export' value='exporteer'/> @@ -817,6 +826,7 @@ <cd:constant name='frameoffset' value='kaderoffset'/> <cd:constant name='frameradius' value='kaderstraal'/> <cd:constant name='frames' value='hokjes'/> + <cd:constant name='freeregion' value='vrijgebied'/> <cd:constant name='from' value='van'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> @@ -1166,6 +1176,7 @@ <cd:constant name='splitoffset' value='splitsoffset'/> <cd:constant name='spot' value='spot'/> <cd:constant name='stack' value='stapel'/> + <cd:constant name='stackname' value='stapelnaam'/> <cd:constant name='start' value='start'/> <cd:constant name='starter' value='opener'/> <cd:constant name='state' value='status'/> @@ -1176,6 +1187,7 @@ <cd:constant name='strip' value='strip'/> <cd:constant name='strut' value='strut'/> <cd:constant name='style' value='letter'/> + <cd:constant name='stylealternative' value='stylevariant'/> <cd:constant name='sub' value='sub'/> <cd:constant name='subtitle' value='subtitel'/> <cd:constant name='suffix' value='suffix'/> @@ -1231,6 +1243,7 @@ <cd:constant name='topspace' value='kopwit'/> <cd:constant name='topstate' value='bovenstatus'/> <cd:constant name='totalnumber' value='totalnumber'/> + <cd:constant name='transform' value='transformatie'/> <cd:constant name='translate' value='translate'/> <cd:constant name='trimoffset' value='trimoffset'/> <cd:constant name='type' value='type'/> @@ -1317,6 +1330,7 @@ <cd:command name='Words' value='Woorden'/> <cd:command name='about' value='about'/> <cd:command name='adaptlayout' value='paslayoutaan'/> + <cd:command name='alignment' value='uitlijnen'/> <cd:command name='arg' value='arg'/> <cd:command name='at' value='op'/> <cd:command name='atleftmargin' value='oplinkermarge'/> @@ -1533,11 +1547,13 @@ <cd:command name='leftmargindistance' value='linkermargeafstand'/> <cd:command name='leftmarginwidth' value='linkermargebreedte'/> <cd:command name='leg' value='leg'/> + <cd:command name='linecorrection' value='regelcorrectie'/> <cd:command name='linewidth' value='lijndikte'/> <cd:command name='listheight' value='lijsthoogte'/> <cd:command name='listlength' value='lijstlengte'/> <cd:command name='listsymbol' value='lijstsymbool'/> <cd:command name='listwidth' value='lijstbreedte'/> + <cd:command name='localfootnotes' value='lokalevoetnoten'/> <cd:command name='logfields' value='registreervelden'/> <cd:command name='lohi' value='laho'/> <cd:command name='low' value='laag'/> @@ -1546,6 +1562,7 @@ <cd:command name='makeupheight' value='zethoogte'/> <cd:command name='makeupwidth' value='zetbreedte'/> <cd:command name='mar' value='mar'/> + <cd:command name='marginblock' value='margeblok'/> <cd:command name='margindistance' value='margeafstand'/> <cd:command name='marginrule' value='kantlijn'/> <cd:command name='margintext' value='margetekst'/> @@ -1645,6 +1662,7 @@ <cd:command name='rightmarginwidth' value='rechtermargebreedte'/> <cd:command name='romannumerals' value='romeins'/> <cd:command name='rotate' value='roteer'/> + <cd:command name='savebuffer' value='bewaarbuffer'/> <cd:command name='scale' value='schaal'/> <cd:command name='screen' value='scherm'/> <cd:command name='selectblocks' value='selecteerblokken'/> @@ -1680,7 +1698,9 @@ <cd:command name='setupcombinations' value='stelcombinatiesin'/> <cd:command name='setupcombinedlist' value='stelsamengesteldelijstin'/> <cd:command name='setupcomment' value='stelcommentaarin'/> + <cd:command name='setupdescription' value='steldoordefinierenin'/> <cd:command name='setupdescriptions' value='steldoordefinierenin'/> + <cd:command name='setupenumeration' value='steldoornummerenin'/> <cd:command name='setupenumerations' value='steldoornummerenin'/> <cd:command name='setupexternalfigures' value='stelexternefigurenin'/> <cd:command name='setupfield' value='stelveldin'/> @@ -1695,8 +1715,10 @@ <cd:command name='setupfootnotedefinition' value='stelvoetnootdefinitiein'/> <cd:command name='setupfootnotes' value='stelvoetnotenin'/> <cd:command name='setupforms' value='stelformulierenin'/> + <cd:command name='setupformula' value='stelformulein'/> <cd:command name='setupformulas' value='stelformulesin'/> <cd:command name='setupframed' value='stelomlijndin'/> + <cd:command name='setupframedtext' value='stelkadertekstin'/> <cd:command name='setupframedtexts' value='stelkadertekstenin'/> <cd:command name='setuphead' value='stelkopin'/> <cd:command name='setupheader' value='stelhoofdin'/> @@ -1725,7 +1747,9 @@ <cd:command name='setuplinewidth' value='stellijndiktein'/> <cd:command name='setuplist' value='stellijstin'/> <cd:command name='setupmakeup' value='stelopmaakin'/> + <cd:command name='setupmarginblock' value='stelmargeblokkenin'/> <cd:command name='setupmarginblocks' value='stelmargeblokkenin'/> + <cd:command name='setupmargindata' value='stelinmargein'/> <cd:command name='setupmarginrules' value='stelkantlijnin'/> <cd:command name='setupmarking' value='stelmarkeringin'/> <cd:command name='setupmathalignment' value='stelwiskundeuitlijnenin'/> @@ -1904,6 +1928,7 @@ <cd:command name='testcolumn' value='testkolom'/> <cd:command name='testpage' value='testpagina'/> <cd:command name='tex' value='tex'/> + <cd:command name='textbackground' value='tekstachtergrond'/> <cd:command name='textheight' value='teksthoogte'/> <cd:command name='textreference' value='tekstreferentie'/> <cd:command name='textrule' value='tekstlijn'/> @@ -1937,7 +1962,7 @@ <cd:command name='useexternalsoundtrack' value='gebruikexterngeluidsfragment'/> <cd:command name='usemodule' value='gebruikmodule'/> <cd:command name='usemodules' value='gebruikmodules'/> - <cd:command name='usepath' value='gebruikgebied'/> + <cd:command name='usepath' value='gebruikpad'/> <cd:command name='usereferences' value='gebruikreferenties'/> <cd:command name='usespecials' value='gebruikspecials'/> <cd:command name='usesymbols' value='gebruiksymbolen'/> diff --git a/tex/context/interface/mkii/keys-pe.xml b/tex/context/interface/mkii/keys-pe.xml index 1afb96c9a..91f778c5e 100644 --- a/tex/context/interface/mkii/keys-pe.xml +++ b/tex/context/interface/mkii/keys-pe.xml @@ -79,6 +79,7 @@ <cd:variable name='all' value='همه'/> <cd:variable name='alphabetic' value='alphabetic'/> <cd:variable name='always' value='همواره'/> + <cd:variable name='anchor' value='anchor'/> <cd:variable name='and' value='and'/> <cd:variable name='answerarea' value='answerarea'/> <cd:variable name='appendices' value='پیوستها'/> @@ -172,9 +173,11 @@ <cd:variable name='down' value='down'/> <cd:variable name='each' value='هر'/> <cd:variable name='edge' value='لبه'/> + <cd:variable name='effective' value='effective'/> <cd:variable name='eight' value='eight'/> <cd:variable name='embed' value='embed'/> <cd:variable name='empty' value='تهی'/> + <cd:variable name='enable' value='enable'/> <cd:variable name='end' value='end'/> <cd:variable name='endnote' value='تهنوشت'/> <cd:variable name='enumeration' value='شمارهبندی'/> @@ -209,9 +212,10 @@ <cd:variable name='force' value='اجبار'/> <cd:variable name='foreground' value='پیشزمینه'/> <cd:variable name='formula' value='فرمول'/> - <cd:variable name='formulae' value='فرمولها'/> + <cd:variable name='formulas' value='فرمولها'/> <cd:variable name='forward' value='بهجلو'/> <cd:variable name='four' value='چهار'/> + <cd:variable name='fractions' value='fractions'/> <cd:variable name='frame' value='قالب'/> <cd:variable name='framedtext' value='متنقالبی'/> <cd:variable name='friday' value='جمعه'/> @@ -236,6 +240,7 @@ <cd:variable name='here' value='اینجا'/> <cd:variable name='hereafter' value='ازاینبهبعد'/> <cd:variable name='hidden' value='پنهانی'/> + <cd:variable name='hiddenbar' value='hiddenbar'/> <cd:variable name='hiding' value='پنهانکردن'/> <cd:variable name='high' value='بلند'/> <cd:variable name='horizontal' value='افقی'/> @@ -379,6 +384,7 @@ <cd:variable name='note' value='note'/> <cd:variable name='nothanging' value='بدونآویزانکردن'/> <cd:variable name='nothyphenated' value='بدونشکست'/> + <cd:variable name='notjoinedup' value='notjoinedup'/> <cd:variable name='november' value='نوامبر'/> <cd:variable name='nowhere' value='هیچحا'/> <cd:variable name='nowhite' value='سفیدنه'/> @@ -627,6 +633,7 @@ <cd:constant name='anchor' value='anchor'/> <cd:constant name='andtext' value='andtext'/> <cd:constant name='apa' value='apa'/> + <cd:constant name='arguments' value='arguments'/> <cd:constant name='arrow' value='پیکان'/> <cd:constant name='artauthor' value='artauthor'/> <cd:constant name='artauthoretaldisplay' value='artauthoretaldisplay'/> @@ -727,6 +734,7 @@ <cd:constant name='controls' value='کنترلها'/> <cd:constant name='conversion' value='تبدیل'/> <cd:constant name='convertfile' value='پروندهتبدیل'/> + <cd:constant name='copies' value='copies'/> <cd:constant name='corner' value='گوشه'/> <cd:constant name='coupling' value='تزویج'/> <cd:constant name='couplingway' value='روشتزویج'/> @@ -775,6 +783,7 @@ <cd:constant name='etaloption' value='etaloption'/> <cd:constant name='etaltext' value='etaltext'/> <cd:constant name='evenmargin' value='حاشیهزوج'/> + <cd:constant name='exact' value='exact'/> <cd:constant name='exitoffset' value='exitoffset'/> <cd:constant name='expansion' value='گسترش'/> <cd:constant name='export' value='export'/> @@ -817,6 +826,7 @@ <cd:constant name='frameoffset' value='آفستقالب'/> <cd:constant name='frameradius' value='شعاعقالب'/> <cd:constant name='frames' value='قالبها'/> + <cd:constant name='freeregion' value='freeregion'/> <cd:constant name='from' value='از'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> @@ -1166,6 +1176,7 @@ <cd:constant name='splitoffset' value='شکافتنآفست'/> <cd:constant name='spot' value='لکه'/> <cd:constant name='stack' value='توده'/> + <cd:constant name='stackname' value='stackname'/> <cd:constant name='start' value='شروع'/> <cd:constant name='starter' value='starter'/> <cd:constant name='state' value='وضعیت'/> @@ -1176,6 +1187,7 @@ <cd:constant name='strip' value='strip'/> <cd:constant name='strut' value='بست'/> <cd:constant name='style' value='سبک'/> + <cd:constant name='stylealternative' value='stylealternative'/> <cd:constant name='sub' value='زیر'/> <cd:constant name='subtitle' value='زیرعنوان'/> <cd:constant name='suffix' value='پسوند'/> @@ -1231,6 +1243,7 @@ <cd:constant name='topspace' value='فضایبالا'/> <cd:constant name='topstate' value='وضعیتبالا'/> <cd:constant name='totalnumber' value='totalnumber'/> + <cd:constant name='transform' value='transform'/> <cd:constant name='translate' value='translate'/> <cd:constant name='trimoffset' value='trimoffset'/> <cd:constant name='type' value='تایپ'/> @@ -1317,6 +1330,7 @@ <cd:command name='Words' value='Words'/> <cd:command name='about' value='درمورد'/> <cd:command name='adaptlayout' value='تنظیمطرحبندی'/> + <cd:command name='alignment' value='alignment'/> <cd:command name='arg' value='افزودن'/> <cd:command name='at' value='در'/> <cd:command name='atleftmargin' value='درحاشیهچپ'/> @@ -1533,11 +1547,13 @@ <cd:command name='leftmargindistance' value='فاصلهحاشیهچپ'/> <cd:command name='leftmarginwidth' value='عرضحاشیهچپ'/> <cd:command name='leg' value='پا'/> + <cd:command name='linecorrection' value='linecorrection'/> <cd:command name='linewidth' value='عرضخط'/> <cd:command name='listheight' value='ارتفاعخط'/> <cd:command name='listlength' value='طوللیست'/> <cd:command name='listsymbol' value='نمادلیست'/> <cd:command name='listwidth' value='عرضلیست'/> + <cd:command name='localfootnotes' value='localfootnotes'/> <cd:command name='logfields' value='میدانهایگزارش'/> <cd:command name='lohi' value='پابا'/> <cd:command name='low' value='پایین'/> @@ -1546,6 +1562,7 @@ <cd:command name='makeupheight' value='ارتفاعآرایش'/> <cd:command name='makeupwidth' value='عرضآرایش'/> <cd:command name='mar' value='حاش'/> + <cd:command name='marginblock' value='marginblock'/> <cd:command name='margindistance' value='فاصلهحاشیه'/> <cd:command name='marginrule' value='خطحاشیه'/> <cd:command name='margintext' value='متنحاشیه'/> @@ -1645,6 +1662,7 @@ <cd:command name='rightmarginwidth' value='عرضحاشیهراست'/> <cd:command name='romannumerals' value='اعدادلاتین'/> <cd:command name='rotate' value='دوران'/> + <cd:command name='savebuffer' value='savebuffer'/> <cd:command name='scale' value='مقیاس'/> <cd:command name='screen' value='پرده'/> <cd:command name='selectblocks' value='انتخاببلوکها'/> @@ -1680,7 +1698,9 @@ <cd:command name='setupcombinations' value='بارگذاریترکیبها'/> <cd:command name='setupcombinedlist' value='بارگذاریلیستترکیبی'/> <cd:command name='setupcomment' value='بارگذاریتوضیح'/> + <cd:command name='setupdescription' value='setupdescription'/> <cd:command name='setupdescriptions' value='بارگذاریشرح'/> + <cd:command name='setupenumeration' value='setupenumeration'/> <cd:command name='setupenumerations' value='بارگذاریشمارهگذاریها'/> <cd:command name='setupexternalfigures' value='بارگذاریشکلهایخارجی'/> <cd:command name='setupfield' value='بارگذاریمیدان'/> @@ -1695,8 +1715,10 @@ <cd:command name='setupfootnotedefinition' value='بارگذاریتعریفپانوشت'/> <cd:command name='setupfootnotes' value='بارگذاریپانوشتها'/> <cd:command name='setupforms' value='بارگذاریطرح'/> + <cd:command name='setupformula' value='setupformula'/> <cd:command name='setupformulas' value='بارگذاریفرمولها'/> <cd:command name='setupframed' value='بارگذاریقالبی'/> + <cd:command name='setupframedtext' value='setupframedtext'/> <cd:command name='setupframedtexts' value='بارگذاریمتنقالبی'/> <cd:command name='setuphead' value='بارگذاریسر'/> <cd:command name='setupheader' value='بارگذاریسربرگ'/> @@ -1725,7 +1747,9 @@ <cd:command name='setuplinewidth' value='بارگذاریعرضخط'/> <cd:command name='setuplist' value='بارگذاریلیست'/> <cd:command name='setupmakeup' value='بارگذاریآرایش'/> + <cd:command name='setupmarginblock' value='setupmarginblock'/> <cd:command name='setupmarginblocks' value='بارگذاریبلوکهایحاشیه'/> + <cd:command name='setupmargindata' value='setupmargindata'/> <cd:command name='setupmarginrules' value='بارگذاریخطهایحاشیه'/> <cd:command name='setupmarking' value='بارگذارینشانهگذاری'/> <cd:command name='setupmathalignment' value='بارگذاریتنظیمریاضی'/> @@ -1904,6 +1928,7 @@ <cd:command name='testcolumn' value='ستونامتحان'/> <cd:command name='testpage' value='صفحهتست'/> <cd:command name='tex' value='تک'/> + <cd:command name='textbackground' value='textbackground'/> <cd:command name='textheight' value='ارتفاعمتن'/> <cd:command name='textreference' value='مرجعمتن'/> <cd:command name='textrule' value='خطمتن'/> diff --git a/tex/context/interface/mkii/keys-ro.xml b/tex/context/interface/mkii/keys-ro.xml index 8a7707a2d..a4566c4b4 100644 --- a/tex/context/interface/mkii/keys-ro.xml +++ b/tex/context/interface/mkii/keys-ro.xml @@ -79,6 +79,7 @@ <cd:variable name='all' value='tot'/> <cd:variable name='alphabetic' value='alphabetic'/> <cd:variable name='always' value='totdeauna'/> + <cd:variable name='anchor' value='anchor'/> <cd:variable name='and' value='and'/> <cd:variable name='answerarea' value='answerarea'/> <cd:variable name='appendices' value='apendixuri'/> @@ -172,9 +173,11 @@ <cd:variable name='down' value='down'/> <cd:variable name='each' value='fiecare'/> <cd:variable name='edge' value='bordura'/> + <cd:variable name='effective' value='effective'/> <cd:variable name='eight' value='eight'/> <cd:variable name='embed' value='embed'/> <cd:variable name='empty' value='gol'/> + <cd:variable name='enable' value='enable'/> <cd:variable name='end' value='end'/> <cd:variable name='endnote' value='endnote'/> <cd:variable name='enumeration' value='enumerare'/> @@ -209,9 +212,10 @@ <cd:variable name='force' value='fortat'/> <cd:variable name='foreground' value='primplan'/> <cd:variable name='formula' value='formula'/> - <cd:variable name='formulae' value='formule'/> + <cd:variable name='formulas' value='formule'/> <cd:variable name='forward' value='avans'/> <cd:variable name='four' value='patru'/> + <cd:variable name='fractions' value='fractions'/> <cd:variable name='frame' value='incadrat'/> <cd:variable name='framedtext' value='textinconjurat'/> <cd:variable name='friday' value='vineri'/> @@ -236,6 +240,7 @@ <cd:variable name='here' value='aici'/> <cd:variable name='hereafter' value='urmator'/> <cd:variable name='hidden' value='ascuns'/> + <cd:variable name='hiddenbar' value='hiddenbar'/> <cd:variable name='hiding' value='ascundere'/> <cd:variable name='high' value='inalt'/> <cd:variable name='horizontal' value='orizontal'/> @@ -379,6 +384,7 @@ <cd:variable name='note' value='note'/> <cd:variable name='nothanging' value='nothanging'/> <cd:variable name='nothyphenated' value='nedespsilabe'/> + <cd:variable name='notjoinedup' value='notjoinedup'/> <cd:variable name='november' value='noiembrie'/> <cd:variable name='nowhere' value='niciunde'/> <cd:variable name='nowhite' value='faraalb'/> @@ -627,6 +633,7 @@ <cd:constant name='anchor' value='anchor'/> <cd:constant name='andtext' value='andtext'/> <cd:constant name='apa' value='apa'/> + <cd:constant name='arguments' value='arguments'/> <cd:constant name='arrow' value='sageata'/> <cd:constant name='artauthor' value='artauthor'/> <cd:constant name='artauthoretaldisplay' value='artauthoretaldisplay'/> @@ -727,6 +734,7 @@ <cd:constant name='controls' value='controale'/> <cd:constant name='conversion' value='conversie'/> <cd:constant name='convertfile' value='convertestefisier'/> + <cd:constant name='copies' value='copies'/> <cd:constant name='corner' value='colt'/> <cd:constant name='coupling' value='cuplare'/> <cd:constant name='couplingway' value='modcuplare'/> @@ -775,6 +783,7 @@ <cd:constant name='etaloption' value='etaloption'/> <cd:constant name='etaltext' value='etaltext'/> <cd:constant name='evenmargin' value='marginepara'/> + <cd:constant name='exact' value='exact'/> <cd:constant name='exitoffset' value='exitoffset'/> <cd:constant name='expansion' value='expansiune'/> <cd:constant name='export' value='export'/> @@ -817,6 +826,7 @@ <cd:constant name='frameoffset' value='offsetframe'/> <cd:constant name='frameradius' value='razaframe'/> <cd:constant name='frames' value='frames'/> + <cd:constant name='freeregion' value='freeregion'/> <cd:constant name='from' value='dela'/> <cd:constant name='functioncolor' value='functioncolor'/> <cd:constant name='functionstyle' value='functionstyle'/> @@ -1166,6 +1176,7 @@ <cd:constant name='splitoffset' value='splitoffset'/> <cd:constant name='spot' value='spot'/> <cd:constant name='stack' value='stack'/> + <cd:constant name='stackname' value='stackname'/> <cd:constant name='start' value='start'/> <cd:constant name='starter' value='starter'/> <cd:constant name='state' value='stare'/> @@ -1176,6 +1187,7 @@ <cd:constant name='strip' value='strip'/> <cd:constant name='strut' value='strut'/> <cd:constant name='style' value='stil'/> + <cd:constant name='stylealternative' value='stylealternative'/> <cd:constant name='sub' value='sub'/> <cd:constant name='subtitle' value='subtitlu'/> <cd:constant name='suffix' value='suffix'/> @@ -1231,6 +1243,7 @@ <cd:constant name='topspace' value='spatiusus'/> <cd:constant name='topstate' value='staresus'/> <cd:constant name='totalnumber' value='totalnumber'/> + <cd:constant name='transform' value='transform'/> <cd:constant name='translate' value='translate'/> <cd:constant name='trimoffset' value='trimoffset'/> <cd:constant name='type' value='type'/> @@ -1317,6 +1330,7 @@ <cd:command name='Words' value='Cuvinte'/> <cd:command name='about' value='despre'/> <cd:command name='adaptlayout' value='adapteazaaspect'/> + <cd:command name='alignment' value='alignment'/> <cd:command name='arg' value='arg'/> <cd:command name='at' value='la'/> <cd:command name='atleftmargin' value='atleftmargin'/> @@ -1533,11 +1547,13 @@ <cd:command name='leftmargindistance' value='distantamarginestanga'/> <cd:command name='leftmarginwidth' value='latimemarginestanga'/> <cd:command name='leg' value='leg'/> + <cd:command name='linecorrection' value='linecorrection'/> <cd:command name='linewidth' value='grosimelinie'/> <cd:command name='listheight' value='inaltimelista'/> <cd:command name='listlength' value='lungimelista'/> <cd:command name='listsymbol' value='listsymbol'/> <cd:command name='listwidth' value='latimelista'/> + <cd:command name='localfootnotes' value='localfootnotes'/> <cd:command name='logfields' value='logcampuri'/> <cd:command name='lohi' value='jossus'/> <cd:command name='low' value='jos'/> @@ -1546,6 +1562,7 @@ <cd:command name='makeupheight' value='inaltimemakeup'/> <cd:command name='makeupwidth' value='latimemakeup'/> <cd:command name='mar' value='mar'/> + <cd:command name='marginblock' value='marginblock'/> <cd:command name='margindistance' value='distantamargine'/> <cd:command name='marginrule' value='liniemargine'/> <cd:command name='margintext' value='textmarginal'/> @@ -1645,6 +1662,7 @@ <cd:command name='rightmarginwidth' value='latimemarginedreapta'/> <cd:command name='romannumerals' value='numereromane'/> <cd:command name='rotate' value='roteste'/> + <cd:command name='savebuffer' value='savebuffer'/> <cd:command name='scale' value='scala'/> <cd:command name='screen' value='ecran'/> <cd:command name='selectblocks' value='selecteazablocuri'/> @@ -1680,7 +1698,9 @@ <cd:command name='setupcombinations' value='seteazacombinari'/> <cd:command name='setupcombinedlist' value='seteazalistacombinata'/> <cd:command name='setupcomment' value='seteazacomentariu'/> + <cd:command name='setupdescription' value='setupdescription'/> <cd:command name='setupdescriptions' value='seteazadescriere'/> + <cd:command name='setupenumeration' value='setupenumeration'/> <cd:command name='setupenumerations' value='seteazaenumerare'/> <cd:command name='setupexternalfigures' value='seteazafiguriexterne'/> <cd:command name='setupfield' value='seteazacamp'/> @@ -1695,8 +1715,10 @@ <cd:command name='setupfootnotedefinition' value='seteazadefinireanotasubsol'/> <cd:command name='setupfootnotes' value='seteazanotasubsol'/> <cd:command name='setupforms' value='seteazaformulare'/> + <cd:command name='setupformula' value='setupformula'/> <cd:command name='setupformulas' value='seteazaformule'/> <cd:command name='setupframed' value='seteazainconjurat'/> + <cd:command name='setupframedtext' value='setupframedtext'/> <cd:command name='setupframedtexts' value='definestetexteinconjurate'/> <cd:command name='setuphead' value='seteazatitlu'/> <cd:command name='setupheader' value='seteazaantet'/> @@ -1725,7 +1747,9 @@ <cd:command name='setuplinewidth' value='seteazagrosimelinie'/> <cd:command name='setuplist' value='seteazalista'/> <cd:command name='setupmakeup' value='seteazamakeup'/> + <cd:command name='setupmarginblock' value='setupmarginblock'/> <cd:command name='setupmarginblocks' value='seteazablocurimarginale'/> + <cd:command name='setupmargindata' value='setupmargindata'/> <cd:command name='setupmarginrules' value='seteazaliniimargine'/> <cd:command name='setupmarking' value='seteazamarcaje'/> <cd:command name='setupmathalignment' value='setupmathalignment'/> @@ -1904,6 +1928,7 @@ <cd:command name='testcolumn' value='testcolumn'/> <cd:command name='testpage' value='testpage'/> <cd:command name='tex' value='tex'/> + <cd:command name='textbackground' value='textbackground'/> <cd:command name='textheight' value='inaltimetext'/> <cd:command name='textreference' value='referintatext'/> <cd:command name='textrule' value='riglatext'/> diff --git a/tex/context/interface/mkiv/context-en.xml b/tex/context/interface/mkiv/context-en.xml new file mode 100644 index 000000000..e8353dbdc --- /dev/null +++ b/tex/context/interface/mkiv/context-en.xml @@ -0,0 +1,45488 @@ +<?xml version='1.0'?> +<!-- expanded and compacted i-context.xml --> +<cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> + <cd:interface file="i-anchor.xml"> + <cd:command file="pack-box.mkiv" name="defineanchor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayer"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayer"/> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="anchor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayer"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayer"/> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-attachment.xml"> + <cd:command file="scrn-wid.mkvi" name="defineattachment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupattachment"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-wid.mkvi" name="setupattachment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="subtitle"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="author"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="file"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="name"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="buffer"> + <cd:constant type="cd:buffer"/> + </cd:parameter> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant default="yes" type="normal"/> + <cd:constant type="hidden"/> + </cd:parameter> + <cd:parameter name="symbol"> + <cd:constant type="Graph"/> + <cd:constant type="Paperclip"/> + <cd:constant type="Pushpin"/> + <cd:constant type="Default"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="fit"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="fit"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="fit"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="textlayer"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="leftedge"/> + <cd:constant type="rightedge"/> + <cd:constant type="inmargin"/> + <cd:constant type="leftmargin"/> + <cd:constant type="rightmargin"/> + <cd:constant default="yes" type="text"/> + <cd:constant type="high"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-wid.mkvi" name="registerattachment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupattachment"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-wid.mkvi" generated="yes" name="attachment" variant="example"> + <cd:sequence> + <cd:variable value="attachment"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupattachment"/> + </cd:assignments> + </cd:arguments> + <cd:instances> + <cd:constant value="attachment"/> + </cd:instances> + </cd:command> + <cd:command file="scrn-wid.mkvi" generated="yes" name="attachment" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="attachment"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupattachment"/> + </cd:assignments> + </cd:arguments> + <cd:instances> + <cd:constant value="attachment"/> + </cd:instances> + </cd:command> + <cd:command file="scrn-wid.mkvi" name="placeattachments"/> + <cd:command file="scrn-wid.mkvi" name="attachment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupattachment"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-wid.mkvi" name="attachment" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupattachment"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-attribute.xml"> + <cd:command file="attr-ini.mkiv" name="pushattribute"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="attr-ini.mkiv" name="popattribute"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="attr-ini.mkiv" name="installattributestack"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="attr-ini.mkiv" name="defineattribute"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant default="yes" type="local"/> + <cd:constant type="global"/> + <cd:constant default="yes" type="public"/> + <cd:constant type="private"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="attr-ini.mkiv" name="definesystemattribute"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant default="yes" type="local"/> + <cd:constant type="global"/> + <cd:constant type="public"/> + <cd:constant default="yes" type="private"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="attr-ini.mkiv" name="newattribute"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="attr-ini.mkiv" name="dosetattribute"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="attr-ini.mkiv" name="doresetattribute"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="attr-ini.mkiv" name="dogetattribute"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="attr-ini.mkiv" name="dogetattributeid"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="attr-ini.mkiv" name="resetallattributes"/> + <cd:command file="attr-ini.mkiv" name="savecurrentattributes"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="attr-ini.mkiv" name="restorecurrentattributes"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="attr-ini.mkiv" name="showattributes"/> + </cd:interface> + <cd:interface file="i-backend.xml"> + <cd:command file="back-ini.mkiv" name="setupbackend"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="export"> + <cd:constant type="yes"/> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="xhtml"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="file"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="intent"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="space"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="xmpfile"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="format"> + <cd:constant type="version"/> + <cd:constant type="default"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="level"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="option"> + <cd:constant type="always"/> + <cd:constant type="never"/> + </cd:parameter> + <cd:parameter name="profile"> + <cd:constant type="cd:file"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-background.xml"> + <cd:command file="pack-bck.mkvi" name="definebackground"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbackground"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-bck.mkvi" name="setupbackground"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="leftoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="topoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bottomoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-bck.mkvi" generated="yes" name="background" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="background"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbackground"/> + </cd:assignments> + </cd:arguments> + <cd:instances> + <cd:constant value="background"/> + </cd:instances> + </cd:command> + <cd:command file="pack-bck.mkvi" name="background" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbackground"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-bck.mkvi" generated="yes" name="background" variant="example"> + <cd:sequence> + <cd:variable value="background"/> + </cd:sequence> + <cd:arguments> + <cd:content/> + </cd:arguments> + <cd:instances> + <cd:constant value="background"/> + </cd:instances> + </cd:command> + <cd:command file="pack-bck.mkvi" name="background"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-bck.mkvi" name="backgroundline"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="page-bck.mkiv" name="setupbackgrounds"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="top"/> + <cd:constant type="header"/> + <cd:constant type="text"/> + <cd:constant type="footer"/> + <cd:constant type="bottom"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="leftedge"/> + <cd:constant type="leftmargin"/> + <cd:constant type="text"/> + <cd:constant type="rightmargin"/> + <cd:constant type="rightedge"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-bck.mkiv" name="setupbackgrounds" variant="page"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="paper"/> + <cd:constant type="page"/> + <cd:constant type="leftpage"/> + <cd:constant type="rightpage"/> + <cd:constant type="text"/> + <cd:constant type="hidden"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="push" end="pop" file="page-bck.mkiv" name="background" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-bck.mkiv" name="doifelsesomebackground"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-bck.mkiv" name="doifsomebackgroundelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-bck.mkiv" name="doifsomebackground"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-bar.xml"> + <cd:command file="node-rul.mkiv" name="definebar"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbar"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="setupbar"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="continue"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="all"/> + </cd:parameter> + <cd:parameter name="empty"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="unit"> + <cd:constant default="yes" type="ex"/> + <cd:constant type="em"/> + <cd:constant type="pt"/> + <cd:constant type="in"/> + <cd:constant type="cm"/> + <cd:constant type="mm"/> + <cd:constant type="sp"/> + <cd:constant type="bp"/> + <cd:constant type="pc"/> + <cd:constant type="dd"/> + <cd:constant type="cc"/> + <cd:constant type="nc"/> + </cd:parameter> + <cd:parameter name="order"> + <cd:constant default="yes" type="foreground"/> + <cd:constant type="background"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="dy"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="max"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="foregroundstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="foregroundcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="mp"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" generated="yes" name="bar" variant="example"> + <cd:sequence> + <cd:variable value="bar"/> + </cd:sequence> + <cd:arguments> + <cd:content/> + </cd:arguments> + <cd:instances> + <cd:constant value="overbar"/> + <cd:constant value="underbar"/> + <cd:constant value="overstrike"/> + <cd:constant value="understrike"/> + <cd:constant value="overbars"/> + <cd:constant value="underbars"/> + <cd:constant value="overstrikes"/> + <cd:constant value="understrikes"/> + <cd:constant value="underrandom"/> + <cd:constant value="underrandoms"/> + <cd:constant value="underdash"/> + <cd:constant value="underdashes"/> + <cd:constant value="underdot"/> + <cd:constant value="underdots"/> + <cd:constant value="nobar"/> + <cd:constant value="hiddenbar"/> + </cd:instances> + </cd:command> + <cd:command file="node-rul.mkiv" name="bar" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="setbar"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="directsetbar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command begin="push" end="pop" file="node-rul.mkiv" name="bar" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="overbar"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="underbar"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="hiddenbar"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="overstrike"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="understrike"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="overbars"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="underbars"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="overstrikes"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="understrikes"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="underrandom"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="underrandoms"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="underdash"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="underdashes"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="underdot"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="underdots"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="nobar"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="resetbar"/> + </cd:interface> + <cd:interface file="i-blackrule.xml"> + <cd:command file="pack-mrl.mkiv" name="setupblackrules"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="width"> + <cd:constant type="max"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="max"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="max"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant default="yes" type="a"/> + <cd:constant type="b"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="type"> + <cd:constant type="mp"/> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="mp"> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-mrl.mkiv" name="blackrule"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupblackrules"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-mrl.mkiv" name="blackrules"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupblackrules"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-mrl.mkiv" name="vl"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-mrl.mkiv" name="hl"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-mis.mkiv" name="somekindoftab"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="alternative"> + <cd:constant type="horizontal"/> + <cd:constant default="yes" type="vertical"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="m"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-bleed.xml"> + <cd:command file="pack-box.mkiv" name="setupbleeding"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="hoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="voffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="t"/> + <cd:constant type="b"/> + <cd:constant default="yes" type="l"/> + <cd:constant type="r"/> + <cd:constant type="bl"/> + <cd:constant type="lb"/> + <cd:constant type="br"/> + <cd:constant type="rb"/> + <cd:constant type="tl"/> + <cd:constant type="lt"/> + <cd:constant type="tr"/> + <cd:constant type="rt"/> + </cd:parameter> + <cd:parameter name="stretch"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="page"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="bleed"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbleeding"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="bleedwidth"/> + <cd:command file="pack-box.mkiv" name="bleedheight"/> + </cd:interface> + <cd:interface file="i-block.xml"> + <cd:command file="strc-blk.mkiv" name="defineblock"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupblock"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-blk.mkiv" name="setupblock"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inner"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="begin" end="end" file="strc-blk.mkiv" generated="yes" name="block" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="block"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="+"/> + <cd:constant type="-"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-blk.mkiv" name="hideblocks"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="+"/> + <cd:constant type="-"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-blk.mkiv" name="keepblocks"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="+"/> + <cd:constant type="-"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-blk.mkiv" name="useblocks"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="+"/> + <cd:constant type="-"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="criterium"> + <cd:constant default="yes" type="text"/> + <cd:constant type="cd:section"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-blk.mkiv" name="processblocks"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="+"/> + <cd:constant type="-"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="criterium"> + <cd:constant default="yes" type="text"/> + <cd:constant type="cd:section"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-blk.mkiv" name="selectblocks"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="+"/> + <cd:constant type="-"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="criterium"> + <cd:constant default="yes" type="text"/> + <cd:constant type="cd:section"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-bookmark.xml"> + <cd:command file="strc-bkm.mkiv" name="setupbookmark"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="force"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="number"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="numberseparatorset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="numberconversionset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="numberstarter"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="numberstopper"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="numbersegments"> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="*"/> + <cd:constant method="range" prefix="cd:number" type="all"/> + <cd:constant type="cd:section"/> + <cd:constant method="range" prefix="cd:section" type="cd:section"/> + <cd:constant method="range" prefix="cd:section" type="*"/> + <cd:constant method="range" prefix="cd:section" type="all"/> + </cd:parameter> + <cd:parameter name="sectionblock"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-bkm.mkiv" name="bookmark"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:section"/> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="src-bkm.mkiv" name="placebookmarks"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:section"/> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:section"/> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbookmark"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-boxes.xml"> + <cd:command file="supp-box.mkiv" name="doiftext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="doifelsetext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="doiftextelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="dowithnextbox"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="dowithnextboxcs"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="nextboxwd"/> + <cd:command file="supp-box.mkiv" name="nextboxht"/> + <cd:command file="supp-box.mkiv" name="nextboxdp"/> + <cd:command file="supp-box.mkiv" name="nextboxhtdp"/> + <cd:command file="supp-box.mkiv" name="flushnextbox"/> + <cd:command file="supp-box.mkiv" name="nextbox"/> + <cd:command file="supp-box.mkiv" name="nextdepth"/> + <cd:command file="supp-box.mkiv" name="dowithnextboxcontent"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="dowithnextboxcontentcs"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="rlap"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="llap"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="clap"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="tlap"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="blap"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="reshapebox"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command begin="beginof" end="endof" file="supp-box.mkiv" name="shapebox" type="environment"/> + <cd:command file="supp-box.mkiv" name="flushshapebox"/> + <cd:command file="supp-box.mkiv" name="innerflushshapebox"/> + <cd:command file="supp-box.mkiv" name="shapedhbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="processtokens"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="doboundtext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="limitatetext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant prefix="cd:sign" type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="limitatetext" variant="list"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant prefix="cd:sign" type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="limtatefirstline"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="processisolatedchars"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="processisolatedwords"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="applytocharacters"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="applytowords"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="applytosplitstringchar"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="applytosplitstringword"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="applytosplitstringline"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="applytosplitstringcharspaced"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="applytosplitstringwordspaced"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="applytosplitstringlinespaced"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="sbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="inlinedbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="struttedbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="topskippedbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="centeredbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="centerednextbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="centerbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="setrigidcolumnhsize"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="setrigidcolumnbalance"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="vboxtohbox" type="environment"/> + <cd:command file="supp-box.mkiv" name="vboxtohboxseparator" type="environment"/> + <cd:command file="supp-box.mkiv" name="convertvboxtohbox"/> + <cd:command file="supp-box.mkiv" name="hboxestohbox" type="environment"/> + <cd:command file="supp-box.mkiv" name="unhhbox"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:delimiter name="with"/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="hboxofvbox"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="doifcontent"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="overlay" type="environment"/> + <cd:command file="supp-box.mkiv" name="fakebox"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="lbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="cbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="rbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="ltop"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="ctop"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="rtop"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="tbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="bbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="lhbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="mhbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="rhbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="lefthbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="midhbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="righthbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="boxofsize"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="none" list="yes" optional="yes"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="limitatelines"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="fittopbaselinegrid"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="boxcursor"/> + <cd:command file="supp-box.mkiv" name="placedbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="rightbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="leftbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="topbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="bottombox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="lefttopbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="righttopbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="leftbottombox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="rightbottombox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="topleftbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="toprightbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="bottomleftbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="bottomrightbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="middlebox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="baselinemiddlebox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="baselineleftbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="baselinerightbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="lrtbbox"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="toplinebox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="setstackbox"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="initializeboxstack"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="savebox"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="restorebox"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="foundbox"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="doifelsebox"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="doifboxelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="localpushbox"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="localpopbox"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="globalpushbox"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="globalpopbox"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="removedepth"/> + <cd:command file="supp-box.mkiv" name="obeydepth"/> + <cd:command file="supp-box.mkiv" name="undepthed"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="removebottomthings"/> + <cd:command file="supp-box.mkiv" name="removelastskip"/> + <cd:command file="supp-box.mkiv" name="makestrutofbox"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="raisebox"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="lowerbox"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="halfwaybox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="depthonlybox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="naturalhbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="naturalvbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="naturalvtop"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="naturalvcenter"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="naturalhpack"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="naturalvpack"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="frozenhbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="setboxllx"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="setboxlly"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="gsetboxllx"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="gsetboxlly"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="getboxllx"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="getboxlly"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="directgetboxllx"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="directgetboxlly"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="shownextbox"> + <cd:arguments> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="spreadhbox"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="minimalhbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="nodetostring"> + <cd:arguments> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="getnaturaldimensions"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="lastnaturalboxwd"/> + <cd:command file="supp-box.mkiv" name="lastnaturalboxht"/> + <cd:command file="supp-box.mkiv" name="lastnaturalboxdp"/> + <cd:command file="supp-box.mkiv" name="naturalwd"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="doifelserighttoleftinbox"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="doifrighttoleftinboxelse"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="runninghbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command begin="begin" end="end" file="supp-box.mkiv" name="vbox" type="environment"/> + <cd:command begin="begin" end="end" file="supp-box.mkiv" name="hbox" type="environment"/> + <cd:command begin="begin" end="end" file="supp-box.mkiv" name="vtop" type="environment"/> + <cd:command file="supp-box.mkiv" name="setvboxregister"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="sethboxregister"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="setvtopregister"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="flushboxregister"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="vboxregister" type="environment"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="hboxregister" type="environment"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="vtopregister" type="environment"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" name="righttolefthbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" name="lefttorighthbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" name="righttoleftvbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" name="lefttorightvbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" name="righttoleftvtop"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" name="lefttorightvtop"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" name="autodirhbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" name="autodirvbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" name="autodirvtop"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" name="leftorrighthbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" name="leftorrightvbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" name="leftorrightvtop"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" name="ibox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" name="obox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" name="definehbox"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ali.mkiv" generated="yes" name="hbox" variant="example"> + <cd:sequence> + <cd:string value="hbox"/> + <cd:variable value="box"/> + </cd:sequence> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="lastlinewidth"/> + </cd:interface> + <cd:interface file="i-buffer.xml"> + <cd:command file="buff-ini.mkiv" name="doifelsebuffer"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" name="doifbufferelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" name="resetbuffer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:buffer"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" name="buffer" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" name="grabbufferdata"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:category"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" name="grabbufferdatadirect"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command begin="set" end="end" file="buff-ini.mkiv" name="buffer" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" name="setupbuffer"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" name="definebuffer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbuffer"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" name="getbuffer"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" name="getdefinedbuffer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:buffer"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" name="inlinebuffer"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" generated="yes" name="buffer" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="buffer"/> + </cd:sequence> + <cd:instances> + <cd:constant value="hiding"/> + </cd:instances> + </cd:command> + <cd:command file="buff-ini.mkiv" generated="yes" name="getbuffer" variant="example"> + <cd:sequence> + <cd:string value="get"/> + <cd:variable value="buffer"/> + </cd:sequence> + </cd:command> + <cd:command file="buff-ini.mkiv" name="hiding" type="environment"/> + <cd:command file="buff-ini.mkiv" name="processtexbuffer"> + <cd:sequence> + <cd:string value="processTEXbuffer"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" name="savebuffer" variant="list"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" name="savebuffer"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="list"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="file"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="prefix"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" name="ctxluabuffer"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" name="mkvibuffer"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ini.mkiv" name="getbufferdata"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="typebuffer"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptyping"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" generated="yes" name="typebuffer" variant="example"> + <cd:sequence> + <cd:string value="type"/> + <cd:variable value="buffer"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptyping"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="typedefinedbuffer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:buffer"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptyping"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-button.xml"> + <cd:command file="scrn-but.mkvi" name="definebutton"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbutton"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-but.mkvi" name="setupbutton"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="samepage"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + <cd:constant type="empty"/> + <cd:constant type="none"/> + <cd:constant type="normal"/> + <cd:constant type="default"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="contrastcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="hidden"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-but.mkvi" generated="yes" name="button" variant="example"> + <cd:sequence> + <cd:variable value="button"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbutton"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + <cd:instances> + <cd:constant value="button"/> + </cd:instances> + </cd:command> + <cd:command file="scrn-but.mkvi" name="button"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbutton"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-but.mkvi" name="overlaybutton"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-but.mkvi" name="overlaybutton" variant="direct"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-but.mkvi" name="MPmenubuttons"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="overlayrollbutton"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="definepushbutton"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfieldcontentframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="pushbutton"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="definepushsymbol"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="n"/> + <cd:constant type="r"/> + <cd:constant type="d"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="rollbutton" variant="interactionmenu"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupinteractionmenu"/> + </cd:assignments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="rollbutton" variant="button"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupbutton"/> + </cd:assignments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-capitals.xml"> + <cd:command file="typo-cap.mkiv" name="definecapitals"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcapitals"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="setupcapitals"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="title"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="sc"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="setcharactercasing"> + <cd:arguments> + <cd:keywords> + <cd:constant type="reset"/> + <cd:constant type="WORD"/> + <cd:constant type="word"/> + <cd:constant type="Word"/> + <cd:constant type="Words"/> + <cd:constant type="capital"/> + <cd:constant type="Capital"/> + <cd:constant type="none"/> + <cd:constant type="random"/> + <cd:constant type="mixed"/> + <cd:constant type="camel"/> + <cd:constant type="cap"/> + <cd:constant type="Cap"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="WORD"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="word"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="Word"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="Words"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="camel"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="WORDS"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="words"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="pseudosmallcapped"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="pseudoSmallcapped"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="pseudoSmallCapped"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="pseudoMixedCapped"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="realsmallcapped"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="realSmallcapped"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="realSmallCapped"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="notsmallcapped"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="smallcapped"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="Smallcapped"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="SmallCapped"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="autocap"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="mixedcaps"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="kap"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="Caps"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="uppercased"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="lowercased"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="randomizetext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cap.mkiv" name="randomized" type="environment"/> + </cd:interface> + <cd:interface file="i-catcodes.xml"> + <cd:command file="catc-ctx.mkiv" name="texcode" type="environment"/> + <cd:command file="catc-ctx.mkiv" name="contextcode" type="environment"/> + <cd:command file="catc-ctx.mkiv" name="contextdefinitioncode" type="environment"/> + <cd:command begin="un" end="" file="catc-def.mkiv" name="protect" type="environment"/> + <cd:command file="catc-ini.mkiv" name="newcatcodetable"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="catc-ini.mkiv" name="catcodetable" type="environment"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="catc-ini.mkiv" name="extendedcatcodetable" type="environment"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="catc-act.mkiv" name="installactivecharacter"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="catc-act.mkiv" name="defineactivecharacter"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="catc-act.mkiv" name="installanddefineactivecharacter"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="catc-act.mkiv" name="makecharacteractive"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="catc-ini.mkiv" name="permitcircumflexescape"/> + <cd:command file="catc-ini.mkiv" name="permitcaretescape"/> + <cd:command file="catc-ini.mkiv" name="letcatcodecommand"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="catc-ini.mkiv" name="defcatcodecommand"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="catc-ini.mkiv" name="uedcatcodecommand"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command begin="push" end="pop" file="catc-ini.mkiv" name="catcodetable" type="environment"/> + <cd:command file="catc-ini.mkiv" name="restorecatcodes"/> + <cd:command file="catc-ini.mkiv" name="setcatcodetable"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="catc-ini.mkiv" name="tracecatcodetables"/> + <cd:command file="catc-ini.mkiv" name="catcodetablename"/> + <cd:command file="catc-sym.mkiv" name="rescan"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="catc-sym.mkiv" name="rescanwithsetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-character.xml"> + <cd:command file="catc-sym.mkiv" name="letteropenbrace"/> + <cd:command file="catc-sym.mkiv" name="letterclosebrace"/> + <cd:command file="catc-sym.mkiv" name="letterampersand"/> + <cd:command file="catc-sym.mkiv" name="letterless"/> + <cd:command file="catc-sym.mkiv" name="lettermore"/> + <cd:command file="catc-sym.mkiv" name="letterhash"/> + <cd:command file="catc-sym.mkiv" name="letterdoublequote"/> + <cd:command file="catc-sym.mkiv" name="lettersinglequote"/> + <cd:command file="catc-sym.mkiv" name="letterdollar"/> + <cd:command file="catc-sym.mkiv" name="letterpercent"/> + <cd:command file="catc-sym.mkiv" name="letterhat"/> + <cd:command file="catc-sym.mkiv" name="letterunderscore"/> + <cd:command file="catc-sym.mkiv" name="letterbar"/> + <cd:command file="catc-sym.mkiv" name="lettertilde"/> + <cd:command file="catc-sym.mkiv" name="letterbackslash"/> + <cd:command file="catc-sym.mkiv" name="letterslash"/> + <cd:command file="catc-sym.mkiv" name="letterquestionmark"/> + <cd:command file="catc-sym.mkiv" name="letterat"/> + <cd:command file="catc-sym.mkiv" name="lettercolon"/> + <cd:command file="catc-sym.mkiv" name="letterescape"/> + <cd:command file="catc-sym.mkiv" name="letterbgroup"/> + <cd:command file="catc-sym.mkiv" name="letteregroup"/> + <cd:command file="catc-sym.mkiv" name="letterleftbrace"/> + <cd:command file="catc-sym.mkiv" name="letterrightbrace"/> + <cd:command file="catc-sym.mkiv" name="letterexclamationmark"/> + <cd:command file="char-ini.mkiv" name="utfchar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="char-ini.mkiv" name="safechar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="char-ini.mkiv" name="checkedchar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="char-ini.mkiv" name="textormathchar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="char-ini.mkiv" name="chardescription"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="enco-ini.mkiv" name="percent"/> + <cd:command file="enco-ini.mkiv" name="procent"/> + <cd:command file="enco-ini.mkiv" name="ampersand"/> + <cd:command file="enco-ini.mkiv" name="dollar"/> + <cd:command file="enco-ini.mkiv" name="hash"/> + <cd:command file="enco-ini.mkiv" name="hyphen"/> + <cd:command file="enco-ini.mkiv" name="lowerleftsingleninequote"/> + <cd:command file="enco-ini.mkiv" name="lowerleftdoubleninequote"/> + <cd:command file="enco-ini.mkiv" name="lowerrightsingleninequote"/> + <cd:command file="enco-ini.mkiv" name="lowerrightdoubleninequote"/> + <cd:command file="enco-ini.mkiv" name="upperleftsingleninequote"/> + <cd:command file="enco-ini.mkiv" name="upperleftdoubleninequote"/> + <cd:command file="enco-ini.mkiv" name="upperrightsingleninequote"/> + <cd:command file="enco-ini.mkiv" name="upperrightdoubleninequote"/> + <cd:command file="enco-ini.mkiv" name="upperleftsinglesixquote"/> + <cd:command file="enco-ini.mkiv" name="upperleftdoublesixquote"/> + <cd:command file="enco-ini.mkiv" name="upperrightsinglesixquote"/> + <cd:command file="enco-ini.mkiv" name="upperrightdoublesixquote"/> + <cd:command file="enco-ini.mkiv" name="leftsubguillemot"/> + <cd:command file="enco-ini.mkiv" name="rightsubguillemot"/> + <cd:command file="enco-ini.mkiv" name="textcontrolspace"/> + <cd:command file="enco-ini.mkiv" name="textvisiblespace"/> + <cd:command file="enco-ini.mkiv" name="textminus"/> + <cd:command file="enco-ini.mkiv" name="textplus"/> + </cd:interface> + <cd:interface file="i-characteralign.xml"> + <cd:command file="typo-tal.mkiv" name="singalcharacteralign"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-tal.mkiv" name="setcharacteralign"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="number" type="cd:text"/> + <cd:constant method="apply" prefix="text" type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-tal.mkiv" name="resetcharacteralign"/> + <cd:command file="typo-tal.mkiv" name="alignmentcharacter"/> + <cd:command file="typo-tal.mkiv" name="characteralign" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="number" type="cd:text"/> + <cd:constant method="apply" prefix="text" type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-tal.mkiv" name="checkcharacteralign"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-characterspacing.xml"> + <cd:command file="typo-spa.mkiv" name="definecharacterspacing"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-spa.mkiv" name="setupcharacterspacing"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="left"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="0"/> + <cd:constant type="1"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-spa.mkiv" name="setcharacterspacing"> + <cd:arguments> + <cd:keywords> + <cd:constant type="reset"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-spa.mkiv" name="resetcharacterspacing"/> + </cd:interface> + <cd:interface file="i-characterstripping.xml"> + <cd:command file="typo-rep.mkiv" name="setcharacterstripping"> + <cd:arguments> + <cd:keywords> + <cd:constant type="reset"/> + <cd:constant type="1"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-rep.mkiv" name="resetcharacterstripping"/> + <cd:command file="typo-rep.mkiv" name="forcecharacterstripping"/> + </cd:interface> + <cd:interface file="i-charwidth.xml"> + <cd:command file="typo-lan.mkiv" name="charwidthlanguage"/> + <cd:command file="typo-lan.mkiv" name="averagecharwidth"/> + <cd:command file="typo-lan.mkiv" name="languagecharwidth"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:language"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-chemical.xml"> + <cd:command file="chem-ini.mkiv" name="molecule"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="chem-ini.mkiv" name="chem"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="chem-str.mkiv" name="setupchemical"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="strut"> + <cd:inherit name="value-strut"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant default="yes" type="fit"/> + <cd:constant type="none"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant default="yes" type="fit"/> + <cd:constant type="none"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant default="yes" type="fit"/> + <cd:constant type="none"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant default="yes" type="fit"/> + <cd:constant type="none"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="top"> + <cd:constant default="yes" type="fit"/> + <cd:constant type="none"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="bottom"> + <cd:constant default="yes" type="fit"/> + <cd:constant type="none"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="scale"> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant default="yes" type="normal"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="rotation"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="symalign"> + <cd:constant default="yes" type="auto"/> + </cd:parameter> + <cd:parameter name="axis"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + </cd:parameter> + <cd:parameter name="framecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="unit"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="factor"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="frame"> + <cd:constant type="on"/> + <cd:constant type="off"/> + </cd:parameter> + <cd:parameter name="rulecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="bodyfont"> + <cd:inherit name="setupbodyfont"/> + </cd:parameter> + <cd:parameter name="size"> + <cd:constant type="small"/> + <cd:constant default="yes" type="medium"/> + <cd:constant type="big"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="chem-str.mkiv" name="setupchemicalframed"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="chem-str.mkiv" name="definechemical"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="chem-str.mkiv" name="definechemicalsymbol"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="chem-str.mkiv" name="chemicalsymbol"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="chem-str.mkiv" name="chemicaltext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="chem-str.mkiv" name="chemical" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupchemical"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="chem-str.mkiv" name="chemical"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="chem-str.mkiv" name="chemicaltoptext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="chem-str.mkiv" name="chemicalbottext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="chem-str.mkiv" name="chemicalmidtext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="chem-str.mkiv" name="definechemicals"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupchemical"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-cleaning.xml"> + <cd:command begin="push" end="pop" file="typo-chr.mkiv" name="punctuation" type="environment"/> + <cd:command file="typo-chr.mkiv" name="removepunctuation"/> + <cd:command file="typo-chr.mkiv" name="markcontent"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="reset"/> + <cd:constant default="yes" type="all"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-chr.mkiv" name="markedcontent" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="reset"/> + <cd:constant default="yes" type="all"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-chr.mkiv" name="removemarkedcontent"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-cln.mkiv" name="setcharactercleaning"> + <cd:arguments> + <cd:keywords> + <cd:constant type="reset"/> + <cd:constant type="1"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-clipping.xml"> + <cd:command file="grph-trf.mkiv" name="setupclipping"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="hoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="voffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="x"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="y"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="nx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="ny"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="sx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="sy"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="leftoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="topoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bottomoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="mp"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="grph-trf.mkiv" name="clip"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupclipping"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-collector.xml"> + <cd:command file="pack-box.mkiv" name="definecollector"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcollector"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="setupcollector"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="rotation"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="corner"> + <cd:constant default="yes" type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant default="yes" type="top"/> + <cd:constant type="bottom"/> + </cd:parameter> + <cd:parameter name="x"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="y"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="hoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="voffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="line"/> + <cd:constant type="l"/> + <cd:constant type="c"/> + <cd:constant type="r"/> + <cd:constant type="m"/> + <cd:constant type="t"/> + <cd:constant type="b"/> + <cd:constant type="g"/> + </cd:parameter> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="setcollector"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcollector"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="resetcollector"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="flushcollector"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="composedcollector"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="adaptcollector"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcollector"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="collectedtext"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcollector"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-color.xml"> + <cd:command file="colo-ext.mkiv" name="negatecolorbox"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ext.mkiv" name="colorintent" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="knockout"/> + <cd:constant type="overprint"/> + <cd:constant type="none"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ext.mkiv" name="overprint" type="environment"/> + <cd:command file="colo-ext.mkiv" name="knockout" type="environment"/> + <cd:command file="colo-ext.mkiv" name="textcolorintent" type="environment"/> + <cd:command file="colo-grp.mkiv" name="definecolorgroup"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="gray"/> + <cd:constant default="yes" type="rgb"/> + <cd:constant type="cmyk"/> + <cd:constant type="spot"/> + </cd:keywords> + <cd:triplet list="yes"/> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="definecolor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="r"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="g"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="b"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="c"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="m"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="y"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="k"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="h"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="s"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="v"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="x"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="a"> + <cd:constant type="cd:number"/> + <cd:constant type="none"/> + <cd:constant type="normal"/> + <cd:constant type="multiply"/> + <cd:constant type="screen"/> + <cd:constant type="overlay"/> + <cd:constant type="softlight"/> + <cd:constant type="hardlight"/> + <cd:constant type="colordodge"/> + <cd:constant type="colorburn"/> + <cd:constant type="darken"/> + <cd:constant type="lighten"/> + <cd:constant type="difference"/> + <cd:constant type="exclusion"/> + <cd:constant type="hue"/> + <cd:constant type="saturation"/> + <cd:constant type="color"/> + <cd:constant type="luminosity"/> + </cd:parameter> + <cd:parameter name="t"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="definecolor" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="defineglobalcolor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="definecolor"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="defineglobalcolor" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="definenamedcolor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="definecolor"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="definenamedcolor" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="defineprocesscolor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:color"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="definecolor"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="definespotcolor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="a"> + <cd:constant type="cd:number"/> + <cd:constant type="none"/> + <cd:constant type="normal"/> + <cd:constant type="multiply"/> + <cd:constant type="screen"/> + <cd:constant type="overlay"/> + <cd:constant type="softlight"/> + <cd:constant type="hardlight"/> + <cd:constant type="colordodge"/> + <cd:constant type="colorburn"/> + <cd:constant type="darken"/> + <cd:constant type="lighten"/> + <cd:constant type="difference"/> + <cd:constant type="exclusion"/> + <cd:constant type="hue"/> + <cd:constant type="saturation"/> + <cd:constant type="color"/> + <cd:constant type="luminosity"/> + </cd:parameter> + <cd:parameter name="t"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="e"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="p"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="definemultitonecolor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:color"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + <cd:assignments list="yes"> + <cd:inherit name="definecolor"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="definespotcolor"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="definetransparency" variant="1"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="definetransparency" variant="2"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="a"> + <cd:constant type="cd:number"/> + <cd:constant type="none"/> + <cd:constant type="normal"/> + <cd:constant type="multiply"/> + <cd:constant type="screen"/> + <cd:constant type="overlay"/> + <cd:constant type="softlight"/> + <cd:constant type="hardlight"/> + <cd:constant type="colordodge"/> + <cd:constant type="colorburn"/> + <cd:constant type="darken"/> + <cd:constant type="lighten"/> + <cd:constant type="difference"/> + <cd:constant type="exclusion"/> + <cd:constant type="hue"/> + <cd:constant type="saturation"/> + <cd:constant type="color"/> + <cd:constant type="luminosity"/> + </cd:parameter> + <cd:parameter name="t"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="definetransparency" variant="3"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="switchtocolor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="color"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="coloronly"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="transparent"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="graycolor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="colored" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="colored"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="definecolor"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="color" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="coloronly" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="transparent" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="directcolor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="directcolored" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="directcolored"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="definecolor"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="currentcolor" type="environment"/> + <cd:command file="colo-ini.mkiv" name="colorset" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="usecolors"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="setupcolor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="setupcolors"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="spot"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="expansion"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="factor"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="rgb"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="cmyk"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="conversion"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + <cd:constant type="always"/> + </cd:parameter> + <cd:parameter name="pagecolormodel"> + <cd:constant type="auto"/> + <cd:constant default="yes" type="none"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="textcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="intent"> + <cd:constant type="overprint"/> + <cd:constant type="knockout"/> + <cd:constant default="yes" type="none"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="push" end="pop" file="colo-ini.mkiv" name="color" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command begin="save" end="restore" file="colo-ini.mkiv" name="color" type="environment"/> + <cd:command file="colo-ini.mkiv" name="definepalet"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:name"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="definepalet" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="getpaletsize"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="paletsize"/> + <cd:command file="colo-ini.mkiv" name="setuppalet"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="setcolormodell"> + <cd:arguments> + <cd:keywords> + <cd:constant type="black"/> + <cd:constant type="bw"/> + <cd:constant type="gray"/> + <cd:constant type="rgb"/> + <cd:constant type="cmyk"/> + <cd:constant default="yes" type="all"/> + <cd:constant type="none"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="protectedcolors" type="environment"/> + <cd:command file="colo-ini.mkiv" name="defineintermediatecolor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:color"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="a"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="t"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="color-ini.mkiv" name="doifelsecolor"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:color"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="color-ini.mkiv" name="doifcolorelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:color"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="color-ini.mkiv" name="doifcolor"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:color"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="textcolor" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="MPcolor"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="MPcoloronly"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="MPtransparency"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="MPoptions"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="colorvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="grayvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="colorcomponents"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="transparencycomponents"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="processcolorcomponents"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="doifelseblack"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:color"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="doifblackelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:color"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="doifelsedrawingblack"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-ini.mkiv" name="doifdrawingblackelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-run.mkiv" name="showcolorbar"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-run.mkiv" name="showcolor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-run.mkiv" name="showcolorset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-run.mkiv" name="showcolorcomponents"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-run.mkiv" name="showpalet"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant default="yes" type="horizontal"/> + <cd:constant type="vertical"/> + <cd:constant type="number"/> + <cd:constant type="value"/> + <cd:constant type="name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-run.mkiv" name="comparepalet"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-run.mkiv" name="showcolorgroup"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant default="yes" type="horizontal"/> + <cd:constant type="vertical"/> + <cd:constant type="number"/> + <cd:constant type="value"/> + <cd:constant type="name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="colo-run.mkiv" name="comparecolorgroup"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-columns.xml"> + <cd:command file="page-mul.mkiv" name="setupcolumns"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="option"> + <cd:constant type="background"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="direction"> + <cd:constant type="left"/> + <cd:constant default="yes" type="right"/> + </cd:parameter> + <cd:parameter name="balance"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:constant type="setupalign"/> + </cd:parameter> + <cd:parameter name="tolerance"> + <cd:constant type="setuptolerance"/> + </cd:parameter> + <cd:parameter name="blank"> + <cd:inherit name="blank"/> + </cd:parameter> + <cd:parameter name="ntop"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="rule"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + <cd:constant type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-mul.mkiv" name="columns" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcolumns"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-mul.mkiv" name="setupcolumnspan"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-mul.mkiv" name="columnspan" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcolumnspan"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-mul.mkiv" name="setsimplecolumnhsize"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="lines"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-mul.mkiv" name="simplecolumns" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setsimplecolumnhsize"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-combination.xml"> + <cd:command file="pack-com.mkiv" name="definecombination"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcombination"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-com.mkiv" name="setupcombination"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="nx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="ny"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="fit"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="fit"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant type="top"/> + <cd:constant default="yes" type="bottom"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="label"/> + <cd:constant default="yes" type="text"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="continue"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-com.mkiv" name="combination" type="environment" variant="matrix"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:matrix"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-com.mkiv" name="combination" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcombination"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-com.mkiv" name="floatcombination" type="environment" variant="matrix"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:matrix"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-com.mkiv" name="floatcombination" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcombination"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-commandhandler.xml"> + <cd:command file="mult-aux.mkiv" name="installparameterhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installrootparameterhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installparameterhashhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installparametersethandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installstyleandcolorhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installdefinehandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installsetuphandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installswitchsetuphandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installautosetuphandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installbasicparameterhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installbasicautosetuphandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installcommandhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installswitchcommandhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installautocommandhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installsimplecommandhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installdirectparameterhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installdirectsetuphandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installdirectparametersethandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installdirectstyleandcolorhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installdirectcommandhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installsetuponlycommandhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="relateparameterhandlers"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installactionhandler"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installnamespace"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installcorenamespace"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="definenamespace"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="name"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="parent"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="list"/> + </cd:parameter> + <cd:parameter name="setup"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="list"/> + </cd:parameter> + <cd:parameter name="set"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="list"/> + </cd:parameter> + <cd:parameter name="frame"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="listnamespaces"/> + <cd:command file="mult-aux.mkiv" name="showparentchain"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="doifelsecommandhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="doifcommandhandlerelse"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="doifcommandhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="doifnotcommandhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installdefinitionset"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installdefinitionsetmember"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="installparentinjector"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="installframedcommandhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="installframedautocommandhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="installsimpleframedcommandhandler"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-comment.xml"> + <cd:command file="scrn-wid.mkvi" name="definecomment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcomment"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-wid.mkvi" name="setupcomment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant default="yes" type="normal"/> + <cd:constant type="hidden"/> + </cd:parameter> + <cd:parameter name="symbol"> + <cd:constant type="Comment"/> + <cd:constant type="Help"/> + <cd:constant type="Insert"/> + <cd:constant type="Key"/> + <cd:constant type="Newparagraph"/> + <cd:constant type="Note"/> + <cd:constant type="Paragraph"/> + <cd:constant type="Default"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="fit"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="fit"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="fit"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="subtitle"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="author"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="nx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="ny"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="option"> + <cd:constant type="xml"/> + <cd:constant type="max"/> + </cd:parameter> + <cd:parameter name="textlayer"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="leftedge"/> + <cd:constant type="rightedge"/> + <cd:constant type="inmargin"/> + <cd:constant type="leftmargin"/> + <cd:constant type="rightmargin"/> + <cd:constant type="text"/> + <cd:constant default="yes" type="high"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-wid.mkvi" generated="yes" name="comment" variant="example"> + <cd:sequence> + <cd:variable value="comment"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcomment"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + <cd:instances> + <cd:constant value="comment"/> + </cd:instances> + </cd:command> + <cd:command file="scrn-wid.mkvi" generated="yes" name="comment" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="comment"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcomment"/> + </cd:assignments> + </cd:arguments> + <cd:instances> + <cd:constant value="comment"/> + </cd:instances> + </cd:command> + <cd:command file="scrn-wid.mkvi" name="placecomments"/> + <cd:command file="scrn-wid.mkvi" name="comment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcomment"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-wid.mkvi" name="comment" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcomment"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-conversion.xml"> + <cd:command file="core-con.mkiv" name="numbers"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="Numbers"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="romannumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="Romannumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="abjadnumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="abjadnodotnumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="abjadnaivenumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="languagecharacters"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="languageCharacters"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="alphabeticnumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="Alphabeticnumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="thainumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="devanagarinumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="gurmurkhinumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="gujaratinumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="tibetannumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="greeknumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="Greeknumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="arabicnumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="persiannumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="arabicdecimals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="persiandecimals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="arabicexnumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="koreannumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="koreannumeralsp"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="koreannumeralsc"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="koreanparentnumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="koreancirclenumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="chinesenumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="chinesecapnumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="chineseallnumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="character"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="Character"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="characters"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="Characters"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="monthlong"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="monthshort"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="convertmonth"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="month"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="MONTH"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="MONTHLONG"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="MONTHSHORT"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="weekday"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="WEEKDAY"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="dayoftheweek"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="getdayoftheweek"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="doifelseleapyear"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="doifleapyearelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="dayspermonth"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="getdayspermonth"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="currentdate"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="year"/> + <cd:constant type="month"/> + <cd:constant type="day"/> + <cd:constant type="weekday"/> + <cd:constant type="y"/> + <cd:constant type="yy"/> + <cd:constant type="Y"/> + <cd:constant type="m"/> + <cd:constant type="mm"/> + <cd:constant type="M"/> + <cd:constant type="d"/> + <cd:constant type="dd"/> + <cd:constant type="D"/> + <cd:constant type="w"/> + <cd:constant type="W"/> + <cd:constant type="space"/> + <cd:constant type="\\\\\\\\␣"/> + <cd:constant type="month:mnem"/> + <cd:constant type="m:mnem"/> + <cd:constant type="d:ord"/> + <cd:constant type="day:ord"/> + <cd:constant type="dd:ord"/> + <cd:constant type="D:ord"/> + <cd:constant type="cd:text"/> + <cd:constant type="referral"/> + <cd:constant type="day:+"/> + <cd:constant type="day:++"/> + <cd:constant type="d:+"/> + <cd:constant type="d:++"/> + <cd:constant type="dd:+"/> + <cd:constant type="dd:++"/> + <cd:constant type="D:+"/> + <cd:constant type="D:++"/> + <cd:constant type="month:jalali"/> + <cd:constant type="m:jalali"/> + <cd:constant type="jalali:to"/> + <cd:constant type="jalali:from"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="date"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="d"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="m"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="y"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="currentdate"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="rawdate"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:inherit name="currentdate"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="currenttime"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="h"/> + <cd:constant type="m"/> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="processmonth"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="processyear"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="defineconversion"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:csname"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="defineconversion" variant="list"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="convertnumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="empty"/> + <cd:constant type="default"/> + <cd:constant type="none"/> + <cd:constant type="month"/> + <cd:constant type="month:mnem"/> + <cd:constant type="character"/> + <cd:constant type="Character"/> + <cd:constant type="characters"/> + <cd:constant type="Characters"/> + <cd:constant type="a"/> + <cd:constant type="A"/> + <cd:constant type="Numbers"/> + <cd:constant type="word"/> + <cd:constant type="words"/> + <cd:constant type="Word"/> + <cd:constant type="Words"/> + <cd:constant type="n"/> + <cd:constant type="N"/> + <cd:constant type="romannumerals"/> + <cd:constant type="Romannumerals"/> + <cd:constant type="i"/> + <cd:constant type="I"/> + <cd:constant type="r"/> + <cd:constant type="R"/> + <cd:constant type="KR"/> + <cd:constant type="RK"/> + <cd:constant type="greek"/> + <cd:constant type="Greek"/> + <cd:constant type="g"/> + <cd:constant type="G"/> + <cd:constant type="abjadnumerals"/> + <cd:constant type="abjadnodotnumerals"/> + <cd:constant type="abjadnaivenumerals"/> + <cd:constant type="thainumerals"/> + <cd:constant type="devanagarinumerals"/> + <cd:constant type="gurmurkhinumerals"/> + <cd:constant type="gujaratinnumerals"/> + <cd:constant type="tibetannumerals"/> + <cd:constant type="greeknumerals"/> + <cd:constant type="Greeknumerals"/> + <cd:constant type="arabicnumerals"/> + <cd:constant type="persiannumerals"/> + <cd:constant type="arabicexnumerals"/> + <cd:constant type="arabicdecimals"/> + <cd:constant type="persiandecimals"/> + <cd:constant type="koreannumerals"/> + <cd:constant type="koreanparentnumerals"/> + <cd:constant type="koreancirclenumerals"/> + <cd:constant type="kr"/> + <cd:constant type="kr-p"/> + <cd:constant type="kr-c"/> + <cd:constant type="chinesenumerals"/> + <cd:constant type="chinesecapnumerals"/> + <cd:constant type="chineseallnumerals"/> + <cd:constant type="cn"/> + <cd:constant type="cn-c"/> + <cd:constant type="cn-a"/> + <cd:constant type="sloveniannumerals"/> + <cd:constant type="slovenianNumerals"/> + <cd:constant type="spanishnumerals"/> + <cd:constant type="spanishNumerals"/> + <cd:constant type="mathgreek"/> + <cd:constant type="set␣0"/> + <cd:constant type="set␣1"/> + <cd:constant type="set␣2"/> + <cd:constant type="set␣3"/> + <cd:constant type="continued"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="uconvertnumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:inherit name="convertnumber"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="doifelseconversiondefined"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="doifconversiondefinedelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="doifelseconversionnumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="doifconversionnumberelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="wordtonumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="three"/> + <cd:constant type="four"/> + <cd:constant type="five"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="highordinalstr"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="ordinalstr"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="ordinaldaynumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="verbosenumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="VerboseNumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="smallcappedromannumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="smallcappedcharacters"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="sloveniannumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="slovenianNumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="spanishnumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="spanishNumerals"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="unihex"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-con.mkiv" name="continuednumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-counter.xml"> + <cd:command file="strc-num.mkiv" name="definecounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcounter"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="setupcounter"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="start"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="counter"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="page"/> + </cd:parameter> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="way"> + <cd:constant method="none" prefix="by" type="page"/> + <cd:constant method="none" prefix="by" type="block"/> + <cd:constant method="none" prefix="by" type="text"/> + <cd:constant method="none" prefix="by" type="head"/> + <cd:constant method="none" prefix="by" type="cd:section"/> + </cd:parameter> + <cd:parameter name="prefix"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="prefixseparatorset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="prefixconversion"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="prefixconversionset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="prefixstarter"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="prefixstopper"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="prefixset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="prefixsegments"> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="*"/> + <cd:constant method="range" prefix="cd:number" type="all"/> + <cd:constant type="cd:section"/> + <cd:constant method="range" prefix="cd:section" type="cd:section"/> + <cd:constant method="range" prefix="cd:section" type="*"/> + <cd:constant method="range" prefix="cd:section" type="all"/> + </cd:parameter> + <cd:parameter name="numberorder"> + <cd:constant type="reverse"/> + </cd:parameter> + <cd:parameter name="numberseparatorset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="numberconversion"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="numberconversionset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="numberstarter"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="numberstopper"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="numbersegments"> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="*"/> + <cd:constant method="range" prefix="cd:number" type="all"/> + </cd:parameter> + <cd:parameter name="type"> + <cd:constant type="first"/> + <cd:constant type="previous"/> + <cd:constant type="next"/> + <cd:constant type="last"/> + <cd:constant default="yes" type="number"/> + </cd:parameter> + <cd:parameter name="criterium"> + <cd:constant type="strict"/> + <cd:constant type="positive"/> + <cd:constant type="all"/> + </cd:parameter> + <cd:parameter name="prefixconnector"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="doifelsecounter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="doifcounterelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="doifcounter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="doifnotcounter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="setcounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="setcounterown"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="restartcounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="resetcounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="incrementcounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="decrementcounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="rawcounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="lastcounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="firstcounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="nextcounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="prevcounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="countersubs"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="savecounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="restorecounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="showcounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="incrementedcounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="decrementedcounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="rawcountervalue"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="lastcountervalue"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="firstcountervalue"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="nextcountervalue"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="prevcountervalue"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="rawsubcountervalue"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="lastsubcountervalue"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="firstsubcountervalue"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="nextsubcountervalue"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="prevsubcountervalue"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="convertedcounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcounter"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="convertedsubcounter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="*"/> + <cd:constant method="range" prefix="cd:number" type="all"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcounter"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="directconvertedcounter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="first"/> + <cd:constant type="previous"/> + <cd:constant type="next"/> + <cd:constant type="last"/> + <cd:constant type="number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="doifelsedefinedcounter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="doifdefinedcounterelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="doifdefinedcounter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-num.mkiv" name="doifundefinedcounter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ini.mkvi" name="defineresetset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + <cd:constant method="range" prefix="cd:sectionblock" type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ini.mkvi" name="defineseparatorset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + <cd:constant method="range" prefix="cd:sectionblock" type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ini.mkvi" name="defineconversionset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + <cd:constant method="range" prefix="cd:sectionblock" type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ini.mkvi" name="defineprefixset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + <cd:constant method="range" prefix="cd:sectionblock" type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:section"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:section"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-dataset.xml"> + <cd:command file="core-dat.mkiv" name="definedataset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupdataset"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-dat.mkiv" name="setupdataset"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="delay"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-dat.mkiv" name="setdataset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-dat.mkiv" name="datasetvariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + <cd:constant type="realpage"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-define.xml"> + <cd:command file="core-sys.mkiv" name="define"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="core-sys.mkiv" name="defineexpandable"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-delimitedtext.xml"> + <cd:command file="typo-del.mkiv" name="definedelimitedtext"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupdelimitedtext"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="setupdelimitedtext"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="language"> + <cd:constant type="local"/> + <cd:constant type="global"/> + <cd:constant type="cd:language"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="font"/> + </cd:parameter> + <cd:parameter name="repeat"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="text"/> + <cd:constant type="paragraph"/> + <cd:constant default="yes" type="margin"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="middle"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="nextleft"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="nextright"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="spacebefore"> + <cd:inherit name="blank"/> + </cd:parameter> + <cd:parameter name="spaceafter"> + <cd:inherit name="blank"/> + </cd:parameter> + <cd:parameter name="leftmargin"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightmargin"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="indenting"> + <cd:inherit name="setupindenting"/> + </cd:parameter> + <cd:parameter name="indentnext"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="symstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="symcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" generated="yes" name="delimitedtext" variant="example"> + <cd:sequence> + <cd:variable value="delimitedtext"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + <cd:instances> + <cd:constant value="quotation"/> + <cd:constant value="quote"/> + <cd:constant value="blockquote"/> + <cd:constant value="speech"/> + <cd:constant value="aside"/> + </cd:instances> + </cd:command> + <cd:command file="typo-del.mkiv" generated="yes" name="delimitedtext" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="delimitedtext"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="startnarrower"/> + </cd:keywords> + </cd:arguments> + <cd:instances> + <cd:constant value="quotation"/> + <cd:constant value="quote"/> + <cd:constant value="blockquote"/> + <cd:constant value="speech"/> + <cd:constant value="aside"/> + </cd:instances> + </cd:command> + <cd:command file="typo-del.mkiv" name="delimitedtext"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="delimitedtext" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="startnarrower"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="delimited"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="delimited" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="startnarrower"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="quotation"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="quotation" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="startnarrower"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="quote"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="quote" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="blockquote"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="blockquote" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="startnarrower"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="speech"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="aside" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="startnarrower"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="aside"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="speech" type="environment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="startnarrower"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="setupquotation"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupdelimitedtext"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="setupquote"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupdelimitedtext"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="subsentence"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="subsentence" type="environment"/> + </cd:interface> + <cd:interface file="i-description.xml"> + <cd:command file="strc-des.mkvi" name="definedescription"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupdescription"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-des.mkvi" name="setupdescription"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="title"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="level"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="text"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="headcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant default="yes" type="left"/> + <cd:constant type="right"/> + <cd:constant type="inmargin"/> + <cd:constant type="inleft"/> + <cd:constant type="inright"/> + <cd:constant type="margin"/> + <cd:constant type="leftmargin"/> + <cd:constant type="rightmargin"/> + <cd:constant type="innermargin"/> + <cd:constant type="outermargin"/> + <cd:constant type="serried"/> + <cd:constant type="hanging"/> + <cd:constant type="top"/> + <cd:constant type="command"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="headalign"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="indenting"> + <cd:inherit name="setupindenting"/> + </cd:parameter> + <cd:parameter name="display"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="indentnext"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="line"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="none"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="hang"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="none"/> + <cd:constant type="margin"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="closesymbol"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="closecommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="expansion"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="xml"/> + </cd:parameter> + <cd:parameter name="sample"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="headstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="headcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-des.mkvi" generated="yes" name="description" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="description"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="list"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-des.mkvi" generated="yes" name="description" type="environment" variant="example:title"> + <cd:sequence> + <cd:variable value="description"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-des.mkvi" generated="yes" name="description" variant="example"> + <cd:sequence> + <cd:variable value="description"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="none"> + <cd:constant type="cd:content"/> + </cd:keywords> + <cd:delimiter name="par"/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-digits.xml"> + <cd:command file="typo-dig.mkiv" name="setdigitsmanipulation"> + <cd:arguments> + <cd:keywords> + <cd:constant type="reset"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-dig.mkiv" name="resetdigitsmanipulation"/> + <cd:command file="typo-dig.mkiv" name="equaldigits"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-dig.mkiv" name="dummydigit"/> + </cd:interface> + <cd:interface file="i-dimension.xml"> + <cd:command file="mult-dim.mkvi" name="assigndimension"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant method="none" prefix="cd:sign" type="small"/> + <cd:constant method="none" prefix="cd:sign" type="medium"/> + <cd:constant method="none" prefix="cd:sign" type="big"/> + <cd:constant type="none"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-dim.mkvi" name="assignalfadimension"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="none"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-dim.mkvi" name="assignwidth"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-dim.mkvi" name="assignvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-direction.xml"> + <cd:command file="typo-dir.mkiv" name="setupdirections"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="bidi"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + <cd:constant type="local"/> + <cd:constant type="global"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant default="yes" type="default"/> + </cd:parameter> + <cd:parameter name="fences"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-dir.mkiv" name="setdirection"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-dir.mkiv" name="resetdirection"/> + <cd:command file="supp-dir.mkiv" name="showdirsinmargin"/> + <cd:command file="supp-dir.mkiv" name="istltdir"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="TLT"/> + <cd:constant type="TRT"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-dir.mkiv" name="istrtdir"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="TLT"/> + <cd:constant type="TRT"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-document.xml"> + <cd:command file="file-job.mkvi" name="text" type="environment"/> + <cd:command begin="autostart" end="autostop" file="file-job.mkvi" name="text" type="environment"/> + <cd:command file="file-job.mkvi" name="notext" type="environment"/> + <cd:command file="file-job.mkvi" name="environment" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + <cd:constant type="*"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="environment" type="environment" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:file"/> + <cd:constant type="*"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="environment" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="useenvironment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="currentenvironment"/> + <cd:command file="file-job.mkvi" name="project" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + <cd:constant type="*"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="project" type="environment" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:file"/> + <cd:constant type="*"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="project"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="project" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="useproject"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="currentproject"/> + <cd:command file="file-job.mkvi" name="product" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + <cd:constant type="*"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="product" type="environment" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:file"/> + <cd:constant type="*"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="product"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="product" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="useproduct"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="currentproduct"/> + <cd:command file="file-job.mkvi" name="component" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + <cd:constant type="*"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="component" type="environment" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:file"/> + <cd:constant type="*"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="component"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="component" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="usecomponent"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="currentcomponent"/> + <cd:command file="file-job.mkvi" name="document" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupdocument"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="setupdocument"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="metadata:author"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="metadata:title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="metadata:subject"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="metadata:keywords"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="presetdocument"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupdocument"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="documentvariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-dummy.xml"> + <cd:command file="mult-aux.mkiv" name="getdummyparameters"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="dummyparameter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="directdummyparameter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="setdummyparameter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="letdummyparameter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="usedummystyleandcolor"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="usedummystyleparameter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-aux.mkiv" name="usedummycolorparameter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-effect.xml"> + <cd:command file="attr-eff.mkiv" name="defineeffect"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupeffect"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="attr-eff.mkiv" name="setupeffect"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="method"> + <cd:constant default="yes" type="none"/> + <cd:constant type="command"/> + </cd:parameter> + <cd:parameter name="stretch"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant default="yes" type="normal"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + <cd:constant type="both"/> + <cd:constant type="hidden"/> + <cd:constant type="stretch"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="attr-eff.mkiv" name="effect" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="attr-eff.mkiv" generated="yes" name="effect" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="effect"/> + </cd:sequence> + </cd:command> + <cd:command file="attr-eff.mkiv" name="effect"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-enumeration.xml"> + <cd:command file="strc-enu.mkvi" name="defineenumeration"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupenumeration"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-enu.mkvi" name="setupenumeration"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="title"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="number"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="numbercommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="titledistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="titlestyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="titlecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="titlecommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="titleleft"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="titleright"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="symbol"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="starter"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="stopper"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="coupling"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="counter"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="level"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="text"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="headcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="inmargin"/> + <cd:constant type="inleft"/> + <cd:constant type="inright"/> + <cd:constant type="margin"/> + <cd:constant type="leftmargin"/> + <cd:constant type="rightmargin"/> + <cd:constant type="innermargin"/> + <cd:constant type="outermargin"/> + <cd:constant type="serried"/> + <cd:constant type="hanging"/> + <cd:constant default="yes" type="top"/> + <cd:constant type="command"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="headalign"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="indenting"> + <cd:inherit name="setupindenting"/> + </cd:parameter> + <cd:parameter name="display"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="indentnext"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="line"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="none"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="hang"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="none"/> + <cd:constant type="margin"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="closesymbol"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="closecommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="expansion"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="xml"/> + </cd:parameter> + <cd:parameter name="sample"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="headstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="headcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:inherit name="setupcounter"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-enu.mkvi" generated="yes" name="enumeration" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="enumeration"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="list"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-enu.mkvi" generated="yes" name="enumeration" type="environment" variant="example:title"> + <cd:sequence> + <cd:variable value="enumeration"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-enu.mkvi" generated="yes" name="enumeration" variant="example"> + <cd:sequence> + <cd:variable value="enumeration"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="none"> + <cd:constant type="cd:content"/> + </cd:keywords> + <cd:delimiter name="par"/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-export.xml"> + <cd:command file="back-exp.mkiv" name="setelementexporttag"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant default="yes" type="export"/> + <cd:constant type="nature"/> + <cd:constant type="pdf"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="inline"/> + <cd:constant type="display"/> + <cd:constant type="mixed"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="back-exp.mkiv" name="setupexport"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="align"> + <cd:constant type="flushleft"/> + <cd:constant type="middle"/> + <cd:constant type="flushright"/> + <cd:constant type="normal"/> + </cd:parameter> + <cd:parameter name="bodyfont"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="subtitle"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="author"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="html"/> + <cd:constant type="div"/> + </cd:parameter> + <cd:parameter name="properties"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="hyphen"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="cssfile"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="firstpage"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="lastpage"> + <cd:constant type="cd:file"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-field.xml"> + <cd:command file="scrn-fld.mkvi" name="presetfieldsymbols"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="definefieldcategory"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfieldcategory"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="setupfieldcategory"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="start"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="type"> + <cd:constant type="radio"/> + <cd:constant type="sub"/> + <cd:constant type="text"/> + <cd:constant type="line"/> + <cd:constant type="push"/> + <cd:constant type="check"/> + <cd:constant type="signature"/> + </cd:parameter> + <cd:parameter name="values"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="default"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="fieldframecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="fieldbackgroundcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant type="flushleft"/> + <cd:constant type="center"/> + <cd:constant type="flushright"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="symbol"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="fieldlayer"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="option"> + <cd:constant type="readonly"/> + <cd:constant type="required"/> + <cd:constant type="protected"/> + <cd:constant type="sorted"/> + <cd:constant type="unavailable"/> + <cd:constant type="nocheck"/> + <cd:constant type="fixed"/> + <cd:constant type="file"/> + <cd:constant type="hidden"/> + <cd:constant type="printable"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="clickin"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="clickout"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="regionin"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="regionout"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="afterkey"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="format"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="validate"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="calculate"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="focusin"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="focusout"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="openpage"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="closepage"> + <cd:constant type="cd:reference"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="doifelsefieldcategory"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="doiffieldcategoryelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="definefieldbody"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfieldbody"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="setupfieldbody"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="category"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:inherit name="setupfieldcategory"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="fieldbody"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfieldbody"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="definefieldbodyset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="doifelsefieldbody"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="doiffieldbodyelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="definefield"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="radio"/> + <cd:constant type="sub"/> + <cd:constant type="text"/> + <cd:constant type="line"/> + <cd:constant type="push"/> + <cd:constant type="check"/> + <cd:constant type="signature"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="definesubfield"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="clonefield"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="copyfield"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="fitfieldframed"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="fitfield"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfieldbody"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="setupfieldlabelframed"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="setupfieldcontentframed"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupframed"/> + <cd:inherit name="setupfieldcategory"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="setupfieldtotalframed"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="reset"/> + <cd:constant type="label"/> + <cd:constant type="frame"/> + <cd:constant type="horizontal"/> + <cd:constant type="vertical"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="setupfield"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="reset"/> + <cd:constant type="label"/> + <cd:constant type="frame"/> + <cd:constant type="horizontal"/> + <cd:constant type="vertical"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfieldtotalframed"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfieldlabelframed"/> + </cd:assignments> + <cd:assignments list="yes"> + <cd:inherit name="setupfieldcontentframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="setupfields"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="reset"/> + <cd:constant type="label"/> + <cd:constant type="frame"/> + <cd:constant type="horizontal"/> + <cd:constant type="vertical"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfieldtotalframed"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfieldlabelframed"/> + </cd:assignments> + <cd:assignments list="yes"> + <cd:inherit name="setupfieldcontentframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="field"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="definefieldstack"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfieldcategory"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="fieldstack"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfieldcategory"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-figure.xml"> + <cd:command file="grph-fig.mkiv" name="figure" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="externalfigure"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="grph-fig.mkiv" name="referring"> + <cd:arguments> + <cd:position list="yes"/> + <cd:position list="yes"/> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-fig.mkiv" name="marking"> + <cd:arguments> + <cd:position list="yes"/> + <cd:position list="yes"/> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-fig.mkiv" name="remark"> + <cd:arguments> + <cd:position list="yes"/> + <cd:position list="yes"/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-fig.mkiv" name="colorbar"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:color"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-file.xml"> + <cd:command file="file-ini.mkvi" name="input"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="input" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="doiffile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="doifnotfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="doifelsefile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="doiffileelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-sys.mkiv" name="jobfilename"/> + <cd:command file="core-sys.mkiv" name="jobfilesuffix"/> + <cd:command file="core-sys.mkiv" name="inputfilebarename"/> + <cd:command file="core-sys.mkiv" name="inputfilerealsuffix"/> + <cd:command file="core-sys.mkiv" name="inputfilesuffix"/> + <cd:command file="core-sys.mkiv" name="inputfilename"/> + <cd:command file="core-sys.mkiv" name="outputfilename"/> + <cd:command file="file-ini.mkvi" name="readingfile" type="environment"/> + <cd:command begin="push" end="pop" file="file-ini.mkvi" name="endofline" type="environment"/> + <cd:command file="file-ini.mkvi" name="restoreendofline"/> + <cd:command file="file-ini.mkvi" name="inputgivenfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="doifelsepath"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:path"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="doifpathelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:path"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="doifelsefileexists"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="doiffileexistselse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="doifelsepathexists"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:path"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="doifpathexistselse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:path"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="doifelseparentfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="doifparentfileelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="splitfilename"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="splitofffull"/> + <cd:command file="file-ini.mkvi" name="splitoffpath"/> + <cd:command file="file-ini.mkvi" name="splitoffbase"/> + <cd:command file="file-ini.mkvi" name="splitoffname"/> + <cd:command file="file-ini.mkvi" name="splitofftype"/> + <cd:command file="file-ini.mkvi" name="splitoffkind"/> + <cd:command file="file-ini.mkvi" name="splitoffroot"/> + <cd:command file="file-job.mkvi" name="doifelseinputfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="doifinputfileelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-ini.mkvi" name="processfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="usepath"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:path"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="usesubpath"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:path"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command begin="push" end="pop" file="file-job.mkvi" name="path" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:path"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="resetpath"/> + <cd:command file="file-job.mkvi" name="allinputpaths"/> + <cd:command file="file-ini.mkvi" name="locatefilepath"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="locatedfilepath"/> + <cd:command file="file-job.mkvi" name="usezipfile"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="processfilemany"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="processfileonce"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="processfilenone"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="loadtexfile"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="loadluafile"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="loadcldfile"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="loadanyfile"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="loadtexfileonce"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="loadluafileonce"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="loadcldfileonce"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="loadanyfileonce"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-job.mkvi" name="continueifinputfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-res.mkvi" name="readjobfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-res.mkvi" name="readlocfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-res.mkvi" name="readsysfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-res.mkvi" name="readfixfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:path"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-res.mkvi" name="readsetfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:path"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-res.mkvi" name="readfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-res.mkvi" name="ReadFile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-res.mkvi" name="readtexfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-res.mkvi" name="readxmlfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-res.mkvi" name="doifelselocfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-res.mkvi" name="doiflocfileelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-res.mkvi" name="locfilename"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-sys.mkvi" name="definefilesynonym"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-sys.mkvi" name="definefilefallback"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-sys.mkvi" name="truefilename"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-filler.xml"> + <cd:command file="spac-flr.mkiv" name="definefiller"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfiller"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-flr.mkiv" name="setupfiller"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="leftmargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightmargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant default="yes" type="symbol"/> + <cd:constant type="stretch"/> + <cd:constant type="rule"/> + <cd:constant type="space"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant default="yes" type="local"/> + <cd:constant type="global"/> + <cd:constant type="middle"/> + <cd:constant type="broad"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="middle"/> + <cd:constant type="flushleft"/> + <cd:constant type="flushright"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + </cd:parameter> + <cd:parameter name="symbol"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-flr.mkiv" name="filler"> + <cd:arguments> + <cd:keywords> + <cd:constant type="sym"/> + <cd:constant type="symbol"/> + <cd:constant type="rule"/> + <cd:constant type="width"/> + <cd:constant type="space"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-flr.mkiv" name="checkedfiller"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="sym"/> + <cd:constant type="symbol"/> + <cd:constant type="rule"/> + <cd:constant type="width"/> + <cd:constant type="space"/> + <cd:constant type="cd:name"/> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="definelinefiller"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplinefiller"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="setuplinefiller"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="location"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant default="yes" type="both"/> + </cd:parameter> + <cd:parameter name="scope"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant default="yes" type="local"/> + </cd:parameter> + <cd:parameter name="mp"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="threshold"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="textstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="textcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="setuplinefillers"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setuplinefiller"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="linefiller" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="filler"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplinefiller"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="setlinefiller"> + <cd:arguments> + <cd:keywords> + <cd:constant type="filler"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-fillinline.xml"> + <cd:command file="pack-mrl.mkiv" name="setupfillinlines"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-mrl.mkiv" name="fillinline"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupfillinlines"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-fillinrule.xml"> + <cd:command file="pack-mrl.mkiv" name="setupfillinrules"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="interlinespace"> + <cd:constant default="yes" type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="fit"/> + <cd:constant default="yes" type="broad"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="separator"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-mrl.mkiv" name="fillinrules"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfillinrules"/> + </cd:assignments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-mrl.mkiv" name="fillintext"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfillinrules"/> + </cd:assignments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-firstline.xml"> + <cd:command file="typo-fln.mkiv" name="definefirstline"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfirstline"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-fln.mkiv" name="setupfirstline"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant default="yes" type="line"/> + <cd:constant type="word"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-fln.mkiv" name="setfirstline"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-fln.mkiv" name="applytofirstcharacter"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-fittingpage.xml"> + <cd:command file="page-app.mkiv" name="definefittingpage"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfittingpage"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-app.mkiv" name="setupfittingpage"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="pagestate"> + <cd:constant type="start"/> + <cd:constant default="yes" type="stop"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="page"/> + </cd:parameter> + <cd:parameter name="scale"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="paper"> + <cd:constant type="auto"/> + <cd:constant default="yes" type="defaut"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-app.mkiv" name="fittingpage" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfittingpage"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-app.mkiv" generated="yes" name="fittingpage" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="fittingpage"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfittingpage"/> + </cd:assignments> + </cd:arguments> + <cd:instances> + <cd:constant value="TEXpage"/> + <cd:constant value="MPpage"/> + </cd:instances> + </cd:command> + <cd:command file="page-app.mkiv" name="TEXpage" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfittingpage"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-app.mkiv" name="setupTEXpage"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupfittingpage"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="meta-fig.mkiv" name="MPpage" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfittingpage"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="meta-fig.mkiv" name="setupMPpage"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupfittingpage"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-floats.xml"> + <cd:command file="strc-flt.mkvi" name="definefloat"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:plural"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfloat"/> + </cd:assignments> + </cd:arguments> + <cd:instances> + <cd:constant value="chemical"/> + <cd:constant value="figure"/> + <cd:constant value="table"/> + <cd:constant value="intermezzo"/> + <cd:constant value="graphic"/> + </cd:instances> + </cd:command> + <cd:command file="strc-flt.mkvi" name="definefloat" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:plural"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:singular"/> + </cd:keywords> + </cd:arguments> + <cd:instances> + <cd:constant value="chemical"/> + <cd:constant value="figure"/> + <cd:constant value="table"/> + <cd:constant value="intermezzo"/> + <cd:constant value="graphic"/> + </cd:instances> + </cd:command> + <cd:command file="strc-flt.mkvi" name="setupfloat"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="indentnext"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="default"> + <cd:inherit name="placefloat"/> + </cd:parameter> + <cd:parameter name="fallback"> + <cd:inherit name="placefloat"/> + </cd:parameter> + <cd:parameter name="inner"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="criterium"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="sidemethod"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="textmethod"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="sidealign"> + <cd:constant type="height"/> + <cd:constant type="depth"/> + <cd:constant type="line"/> + <cd:constant type="halfline"/> + <cd:constant type="grid"/> + <cd:constant default="yes" type="normal"/> + </cd:parameter> + <cd:parameter name="grid"> + <cd:constant type="cd:string"/> + </cd:parameter> + <cd:parameter name="local"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="availablewidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="availableheight"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="minwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="middle"/> + <cd:constant type="flushleft"/> + <cd:constant type="flushright"/> + <cd:constant type="center"/> + <cd:constant type="max"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + <cd:constant type="innermargin"/> + <cd:constant type="outermargin"/> + <cd:constant type="inneredge"/> + <cd:constant type="outeredge"/> + <cd:constant type="backspace"/> + <cd:constant type="cutspace"/> + <cd:constant type="leftmargin"/> + <cd:constant type="rightmargin"/> + <cd:constant type="leftedge"/> + <cd:constant type="rightedge"/> + </cd:parameter> + <cd:parameter name="leftmargindistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightmargindistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="leftmargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightmargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="innermargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="outermargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bottombefore"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="bottomafter"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="spacebefore"> + <cd:constant type="none"/> + <cd:inherit name="blank"/> + </cd:parameter> + <cd:parameter name="spaceafter"> + <cd:constant type="none"/> + <cd:inherit name="blank"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + <cd:constant type="none"/> + <cd:constant type="overlay"/> + </cd:parameter> + <cd:parameter name="sidespacebefore"> + <cd:constant type="none"/> + <cd:inherit name="blank"/> + </cd:parameter> + <cd:parameter name="sidespaceafter"> + <cd:constant type="none"/> + <cd:inherit name="blank"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="ntop"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="nbottom"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="step"> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant default="yes" type="big"/> + <cd:constant type="line"/> + <cd:constant type="depth"/> + </cd:parameter> + <cd:parameter name="nlines"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="cache"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" name="setupfloatcaption"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="suffix"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="suffixseparator"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="suffixstopper"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="middle"/> + <cd:constant type="low"/> + <cd:constant type="high"/> + <cd:constant type="grid"/> + <cd:constant type="overlay"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + <cd:constant type="innermargin"/> + <cd:constant type="outermargin"/> + <cd:constant type="leftmargin"/> + <cd:constant type="rightmargin"/> + <cd:constant type="lefthanging"/> + <cd:constant type="righthanging"/> + <cd:constant type="hang"/> + <cd:constant type="top"/> + <cd:constant default="yes" type="bottom"/> + <cd:constant type="stretch"/> + <cd:constant type="none"/> + <cd:constant type="default"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="numbercommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="textcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="spacebefore"> + <cd:inherit name="blank"/> + </cd:parameter> + <cd:parameter name="spaceinbetween"> + <cd:inherit name="blank"/> + </cd:parameter> + <cd:parameter name="spaceafter"> + <cd:inherit name="blank"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="topoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bottomoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="number"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="group"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="leftmargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightmargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="innermargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="outermargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant default="yes" type="fit"/> + <cd:constant type="max"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="minwidth"> + <cd:constant default="yes" type="fit"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:inherit name="setupcounter"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" name="setupcaption"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupfloatcaption"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" generated="yes" name="placefloat" variant="instance"> + <cd:sequence> + <cd:string value="place"/> + <cd:instance value="float"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="split"/> + <cd:constant type="always"/> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + <cd:constant type="backspace"/> + <cd:constant type="cutspace"/> + <cd:constant type="inleft"/> + <cd:constant type="inright"/> + <cd:constant type="inmargin"/> + <cd:constant type="leftmargin"/> + <cd:constant type="rightmargin"/> + <cd:constant type="leftedge"/> + <cd:constant type="rightedge"/> + <cd:constant type="innermargin"/> + <cd:constant type="outermargin"/> + <cd:constant type="inneredge"/> + <cd:constant type="outeredge"/> + <cd:constant type="text"/> + <cd:constant type="opposite"/> + <cd:constant type="reset"/> + <cd:constant type="height"/> + <cd:constant type="depth"/> + <cd:constant method="none" prefix="cd:sign" type="line"/> + <cd:constant type="halfline"/> + <cd:constant type="grid"/> + <cd:constant type="high"/> + <cd:constant type="low"/> + <cd:constant type="fit"/> + <cd:constant type="90"/> + <cd:constant type="180"/> + <cd:constant type="270"/> + <cd:constant type="nonumber"/> + <cd:constant type="none"/> + <cd:constant type="local"/> + <cd:constant type="here"/> + <cd:constant type="force"/> + <cd:constant type="margin"/> + <cd:constant method="none" prefix="cd:sign" type="hang"/> + <cd:constant type="hanging"/> + <cd:constant type="tall"/> + <cd:constant type="both"/> + <cd:constant type="middle"/> + <cd:constant type="offset"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="auto"/> + <cd:constant type="page"/> + <cd:constant type="leftpage"/> + <cd:constant type="rightpage"/> + <cd:constant type="header"/> + <cd:constant type="footer"/> + <cd:constant type="somewhere"/> + <cd:constant type="effective"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + <cd:instances> + <cd:constant value="chemical"/> + <cd:constant value="figure"/> + <cd:constant value="table"/> + <cd:constant value="intermezzo"/> + <cd:constant value="graphic"/> + </cd:instances> + </cd:command> + <cd:command file="strc-flt.mkvi" name="placefloat"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="split"/> + <cd:constant type="always"/> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + <cd:constant type="backspace"/> + <cd:constant type="cutspace"/> + <cd:constant type="inleft"/> + <cd:constant type="inright"/> + <cd:constant type="inmargin"/> + <cd:constant type="leftmargin"/> + <cd:constant type="rightmargin"/> + <cd:constant type="leftedge"/> + <cd:constant type="rightedge"/> + <cd:constant type="innermargin"/> + <cd:constant type="outermargin"/> + <cd:constant type="inneredge"/> + <cd:constant type="outeredge"/> + <cd:constant type="text"/> + <cd:constant type="opposite"/> + <cd:constant type="reset"/> + <cd:constant type="height"/> + <cd:constant type="depth"/> + <cd:constant method="none" prefix="cd:sign" type="line"/> + <cd:constant type="halfline"/> + <cd:constant type="grid"/> + <cd:constant type="high"/> + <cd:constant type="low"/> + <cd:constant type="fit"/> + <cd:constant type="90"/> + <cd:constant type="180"/> + <cd:constant type="270"/> + <cd:constant type="nonumber"/> + <cd:constant type="none"/> + <cd:constant type="local"/> + <cd:constant type="here"/> + <cd:constant type="force"/> + <cd:constant type="margin"/> + <cd:constant method="none" prefix="cd:sign" type="hang"/> + <cd:constant type="hanging"/> + <cd:constant type="tall"/> + <cd:constant type="both"/> + <cd:constant type="middle"/> + <cd:constant type="offset"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="auto"/> + <cd:constant type="page"/> + <cd:constant type="leftpage"/> + <cd:constant type="rightpage"/> + <cd:constant type="header"/> + <cd:constant type="footer"/> + <cd:constant type="somewhere"/> + <cd:constant type="effective"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" generated="yes" name="placefloat" type="environment" variant="instance"> + <cd:sequence> + <cd:string value="place"/> + <cd:instance value="float"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="marking"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="list"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="split"/> + <cd:constant type="always"/> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + <cd:constant type="backspace"/> + <cd:constant type="cutspace"/> + <cd:constant type="inleft"/> + <cd:constant type="inright"/> + <cd:constant type="inmargin"/> + <cd:constant type="leftmargin"/> + <cd:constant type="rightmargin"/> + <cd:constant type="leftedge"/> + <cd:constant type="rightedge"/> + <cd:constant type="innermargin"/> + <cd:constant type="outermargin"/> + <cd:constant type="inneredge"/> + <cd:constant type="outeredge"/> + <cd:constant type="text"/> + <cd:constant type="opposite"/> + <cd:constant type="reset"/> + <cd:constant type="height"/> + <cd:constant type="depth"/> + <cd:constant method="none" prefix="cd:sign" type="line"/> + <cd:constant type="halfline"/> + <cd:constant type="grid"/> + <cd:constant type="high"/> + <cd:constant type="low"/> + <cd:constant type="fit"/> + <cd:constant type="90"/> + <cd:constant type="180"/> + <cd:constant type="270"/> + <cd:constant type="nonumber"/> + <cd:constant type="none"/> + <cd:constant type="local"/> + <cd:constant type="here"/> + <cd:constant type="force"/> + <cd:constant type="margin"/> + <cd:constant method="none" prefix="cd:sign" type="hang"/> + <cd:constant type="hanging"/> + <cd:constant type="tall"/> + <cd:constant type="both"/> + <cd:constant type="middle"/> + <cd:constant type="offset"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="auto"/> + <cd:constant type="page"/> + <cd:constant type="leftpage"/> + <cd:constant type="rightpage"/> + <cd:constant type="header"/> + <cd:constant type="footer"/> + <cd:constant type="somewhere"/> + <cd:constant type="effective"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + <cd:instances> + <cd:constant value="chemical"/> + <cd:constant value="figure"/> + <cd:constant value="table"/> + <cd:constant value="intermezzo"/> + <cd:constant value="graphic"/> + </cd:instances> + </cd:command> + <cd:command file="strc-flt.mkvi" generated="yes" name="floattext" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="float"/> + <cd:string value="text"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="split"/> + <cd:constant type="always"/> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + <cd:constant type="backspace"/> + <cd:constant type="cutspace"/> + <cd:constant type="inleft"/> + <cd:constant type="inright"/> + <cd:constant type="inmargin"/> + <cd:constant type="leftmargin"/> + <cd:constant type="rightmargin"/> + <cd:constant type="leftedge"/> + <cd:constant type="rightedge"/> + <cd:constant type="innermargin"/> + <cd:constant type="outermargin"/> + <cd:constant type="inneredge"/> + <cd:constant type="outeredge"/> + <cd:constant type="text"/> + <cd:constant type="opposite"/> + <cd:constant type="reset"/> + <cd:constant type="height"/> + <cd:constant type="depth"/> + <cd:constant method="none" prefix="cd:sign" type="line"/> + <cd:constant type="halfline"/> + <cd:constant type="grid"/> + <cd:constant type="high"/> + <cd:constant type="low"/> + <cd:constant type="fit"/> + <cd:constant type="90"/> + <cd:constant type="180"/> + <cd:constant type="270"/> + <cd:constant type="nonumber"/> + <cd:constant type="none"/> + <cd:constant type="local"/> + <cd:constant type="here"/> + <cd:constant type="force"/> + <cd:constant type="margin"/> + <cd:constant method="none" prefix="cd:sign" type="hang"/> + <cd:constant type="hanging"/> + <cd:constant type="tall"/> + <cd:constant type="both"/> + <cd:constant type="middle"/> + <cd:constant type="offset"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="auto"/> + <cd:constant type="page"/> + <cd:constant type="leftpage"/> + <cd:constant type="rightpage"/> + <cd:constant type="header"/> + <cd:constant type="footer"/> + <cd:constant type="somewhere"/> + <cd:constant type="effective"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" generated="yes" name="placelistoffloats" variant="example"> + <cd:sequence> + <cd:string value="placelistof"/> + <cd:variable value="floats"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" generated="yes" name="completelistoffloats" variant="example"> + <cd:sequence> + <cd:string value="completelistof"/> + <cd:variable value="floats"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" name="floatuserdataparameter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" name="doifelserightpagefloat"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" name="doifrightpagefloatelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" name="doifelseoddpagefloat"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" name="doifoddpagefloatelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" name="doifelsemainfloatbody"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" name="doifmainfloatbodyelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" name="setuplocalfloats"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" name="noflocalfloats"/> + <cd:command file="strc-flt.mkvi" name="resetlocalfloats"/> + <cd:command file="strc-flt.mkvi" name="somelocalfloat"/> + <cd:command file="strc-flt.mkvi" name="getlocalfloats"/> + <cd:command file="strc-flt.mkvi" name="flushlocalfloats"/> + <cd:command file="strc-flt.mkvi" name="getlocalfloat"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-flt.mkvi" name="forcelocalfloats"/> + <cd:command file="tabl-tsp.mkiv" name="setupfloatsplitting"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="lines"> + <cd:constant type="auto"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="conversion"> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tsp.mkiv" name="splitfloat"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfloatsplitting"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tsp.mkiv" name="doifnotinsidesplitfloat"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-flt.mkiv" name="placenamedfloat"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-flt.mkiv" name="placefloatwithsetups"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="split"/> + <cd:constant type="always"/> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + <cd:constant type="backspace"/> + <cd:constant type="cutspace"/> + <cd:constant type="inleft"/> + <cd:constant type="inright"/> + <cd:constant type="inmargin"/> + <cd:constant type="leftmargin"/> + <cd:constant type="rightmargin"/> + <cd:constant type="leftedge"/> + <cd:constant type="rightedge"/> + <cd:constant type="innermargin"/> + <cd:constant type="outermargin"/> + <cd:constant type="inneredge"/> + <cd:constant type="outeredge"/> + <cd:constant type="text"/> + <cd:constant type="opposite"/> + <cd:constant type="reset"/> + <cd:constant type="height"/> + <cd:constant type="depth"/> + <cd:constant method="none" prefix="cd:sign" type="line"/> + <cd:constant type="halfline"/> + <cd:constant type="grid"/> + <cd:constant type="high"/> + <cd:constant type="low"/> + <cd:constant type="fit"/> + <cd:constant type="90"/> + <cd:constant type="180"/> + <cd:constant type="270"/> + <cd:constant type="nonumber"/> + <cd:constant type="none"/> + <cd:constant type="local"/> + <cd:constant type="here"/> + <cd:constant type="force"/> + <cd:constant type="margin"/> + <cd:constant method="none" prefix="cd:sign" type="hang"/> + <cd:constant type="hanging"/> + <cd:constant type="tall"/> + <cd:constant type="both"/> + <cd:constant type="middle"/> + <cd:constant type="offset"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="auto"/> + <cd:constant type="page"/> + <cd:constant type="leftpage"/> + <cd:constant type="rightpage"/> + <cd:constant type="header"/> + <cd:constant type="footer"/> + <cd:constant type="somewhere"/> + <cd:constant type="effective"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-fontfamily.xml"> + <cd:command file="font-sel.mkvi" name="definefontfamily"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant default="yes" type="rm"/> + <cd:constant type="ss"/> + <cd:constant type="tt"/> + <cd:constant type="mm"/> + <cd:constant type="hw"/> + <cd:constant type="cg"/> + <cd:constant type="roman"/> + <cd:constant type="serif"/> + <cd:constant type="regular"/> + <cd:constant type="sansserif"/> + <cd:constant type="sans"/> + <cd:constant type="support"/> + <cd:constant type="teletype"/> + <cd:constant type="type"/> + <cd:constant type="mono"/> + <cd:constant type="handwritten"/> + <cd:constant type="calligraphic"/> + <cd:constant type="math"/> + <cd:constant type="mathematics"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="rscale"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="designsize"> + <cd:constant type="default"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="goodies"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="features"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="tf"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bf"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="it"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="sl"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bi"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bs"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="sc"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-sel.mkvi" name="definefontfamily" variant="preset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant default="yes" type="rm"/> + <cd:constant type="ss"/> + <cd:constant type="tt"/> + <cd:constant type="mm"/> + <cd:constant type="hw"/> + <cd:constant type="cg"/> + <cd:constant type="roman"/> + <cd:constant type="serif"/> + <cd:constant type="regular"/> + <cd:constant type="sansserif"/> + <cd:constant type="sans"/> + <cd:constant type="support"/> + <cd:constant type="teletype"/> + <cd:constant type="type"/> + <cd:constant type="mono"/> + <cd:constant type="handwritten"/> + <cd:constant type="calligraphic"/> + <cd:constant type="math"/> + <cd:constant type="mathematics"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sel.mkvi" name="definefallbackfamily"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant default="yes" type="rm"/> + <cd:constant type="ss"/> + <cd:constant type="tt"/> + <cd:constant type="mm"/> + <cd:constant type="hw"/> + <cd:constant type="cg"/> + <cd:constant type="roman"/> + <cd:constant type="serif"/> + <cd:constant type="regular"/> + <cd:constant type="sansserif"/> + <cd:constant type="sans"/> + <cd:constant type="support"/> + <cd:constant type="teletype"/> + <cd:constant type="type"/> + <cd:constant type="mono"/> + <cd:constant type="handwritten"/> + <cd:constant type="calligraphic"/> + <cd:constant type="math"/> + <cd:constant type="mathematics"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="rscale"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="designsize"> + <cd:constant type="default"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="goodies"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="range"> + <cd:constant type="cd:number"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:number"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="check"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="force"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="features"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="tf"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bf"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="it"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="sl"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bi"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bs"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="sc"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-sel.mkvi" name="definefallbackfamily" variant="preset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant default="yes" type="rm"/> + <cd:constant type="ss"/> + <cd:constant type="tt"/> + <cd:constant type="mm"/> + <cd:constant type="hw"/> + <cd:constant type="cg"/> + <cd:constant type="roman"/> + <cd:constant type="serif"/> + <cd:constant type="regular"/> + <cd:constant type="sansserif"/> + <cd:constant type="sans"/> + <cd:constant type="support"/> + <cd:constant type="teletype"/> + <cd:constant type="type"/> + <cd:constant type="mono"/> + <cd:constant type="handwritten"/> + <cd:constant type="calligraphic"/> + <cd:constant type="math"/> + <cd:constant type="mathematics"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sel.mkvi" name="definefontfamilypreset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="definefontfamily"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-sel.mkvi" name="definefontfamilypreset" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-fonts.xml"> + <cd:command file="font-col.mkvi" name="definefontfallback"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:font"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="rscale"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="force"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="check"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:number"/> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-col.mkvi" name="resetfontfallback"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-emp.mkvi" name="emphasistypeface"/> + <cd:command file="font-emp.mkvi" name="emphasisboldface"/> + <cd:command file="font-emp.mkvi" name="normalboldface"/> + <cd:command file="font-emp.mkvi" name="normaltypeface"/> + <cd:command file="font-emp.mkvi" name="swaptypeface"/> + <cd:command file="font-emp.mkvi" name="typeface"/> + <cd:command file="font-emp.mkvi" name="boldface"/> + <cd:command file="font-emp.mkvi" name="swapface"/> + <cd:command file="font-fea.mkvi" name="definefontfeature"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="language"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="script"> + <cd:constant type="cd:name"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="mode"> + <cd:constant type="node"/> + <cd:constant type="base"/> + <cd:constant type="auto"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="liga"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="kern"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="extrakerns"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="tlig"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="trep"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="missing"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="dummies"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="analyze"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="unicoding"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="expansion"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="protrusion"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="nostackmath"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="realdimensions"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="itlc"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="textitalics"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="mathitalics"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="slant"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="extend"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="dimensions"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="boundingbox"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="compose"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="char-ligatures"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="compat-ligatures"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="goodies"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="extrafeatures"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="featureset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="colorsheme"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="postprocessor"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="mathdimensions"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="keepligatures"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="devanagari"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="features"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="tcom"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="anum"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="mathsize"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="decomposehangul"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="mathalternatives"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="mathgaps"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="checkmarks"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="cd:name"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="mathnolimitsmode"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="adaptfontfeature"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="definefontfeature"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="fontfeaturelist"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="addfeature"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="addfeature" variant="direct"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="subtractfeature"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="subtractfeature" variant="direct"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="replacefeature"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="replacefeature" variant="direct"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="resetandaddfeature"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="resetandaddfeature" variant="direct"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="resetfeature"/> + <cd:command file="font-fea.mkvi" name="revivefeature"/> + <cd:command file="font-fea.mkvi" name="setfontfeature"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="feature"> + <cd:arguments> + <cd:keywords> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="="/> + <cd:constant type="!"/> + <cd:constant type=">"/> + <cd:constant type="<"/> + <cd:constant type="more"/> + <cd:constant type="less"/> + <cd:constant type="new"/> + <cd:constant type="reset"/> + <cd:constant type="default"/> + <cd:constant type="old"/> + <cd:constant type="local"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="feature" variant="direct"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="="/> + <cd:constant type="!"/> + <cd:constant type=">"/> + <cd:constant type="<"/> + <cd:constant type="more"/> + <cd:constant type="less"/> + <cd:constant type="new"/> + <cd:constant type="reset"/> + <cd:constant type="default"/> + <cd:constant type="old"/> + <cd:constant type="local"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="doifelsecurrentfonthasfeature"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="doifcurrentfonthasfeatureelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="doaddfeature"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="dosubtractfeature"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="doreplacefeature"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkvi" name="doresetandafffeature"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fil.mkvi" name="fontclass" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="each"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fil.mkvi" name="classfont"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fil.mkvi" name="definefontsynonym"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="features"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="fallbacks"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="goodies"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="designsize"> + <cd:constant type="auto"/> + <cd:constant type="default"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-fil.mkvi" name="definefontfile"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="features"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="fallbacks"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="goodies"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="designsize"> + <cd:constant type="auto"/> + <cd:constant type="default"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-fil.mkvi" name="truefontname"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fil.mkvi" name="expandfontsynonym"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fil.mkvi" name="doifelsefontsynonym"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fil.mkvi" name="doiffontsynonymelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fil.mkvi" name="tracedfontname"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fil.mkvi" name="fontclassname"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-gds.mkvi" name="loadfontgoodies"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-gds.mkvi" name="setfontcolorsheme"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-gds.mkvi" name="resetfontcolorsheme"/> + <cd:command file="font-ini.mkvi" name="definedfont"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="font" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="bodyfontsize"/> + <cd:command file="font-ini.mkvi" name="normalizebodyfontsize"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="thenormalizedbodyfontsize"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fil.mkvi" name="mapfontsize"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="definefontstyle"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="definefontsize"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="definefontalternative"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="definefont"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupinterlinespace"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="definefont" variant="argument"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="definefrozenfont"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="definebodyfontenvironment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="default"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="big"> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="small"> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="a"> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="b"> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="c"> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="d"> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="text"> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="x"> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="xx"> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="script"> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="scriptscript"> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="interlinespace"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="em"> + <cd:constant type="slanted"/> + <cd:constant type="italic"/> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="*"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-fil.mkvi" name="processbodyfontenvironmentlist"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="font-fil.mkvi" name="bodyfontenvironmentlist"/> + <cd:command file="font-fil.mkvi" name="registerfontclass"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-fil.mkvi" name="setcurrentfontclass"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="tx"/> + <cd:command file="font-ini.mkvi" name="txx"/> + <cd:command file="font-fil.mkvi" name="definebodyfont"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + <cd:constant type="default"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant default="yes" type="rm"/> + <cd:constant type="ss"/> + <cd:constant type="tt"/> + <cd:constant type="hw"/> + <cd:constant type="cg"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="tf"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="bf"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="it"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="sl"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="bi"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="bs"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="sc"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="mr"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="mrlr"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="mrrl"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="mb"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="mblr"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="mbrl"> + <cd:constant type="cd:file"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-fil.mkvi" name="definebodyfont" variant="argument"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + <cd:constant type="default"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant default="yes" type="rm"/> + <cd:constant type="ss"/> + <cd:constant type="tt"/> + <cd:constant type="hw"/> + <cd:constant type="cg"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkiv" name="setupfonts"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="language"> + <cd:constant default="yes" type="no"/> + <cd:constant type="auto"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkiv" name="setupbodyfont"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:name"/> + <cd:constant type="global"/> + <cd:constant type="reset"/> + <cd:constant type="x"/> + <cd:constant type="xx"/> + <cd:constant type="small"/> + <cd:constant type="big"/> + <cd:constant type="script"/> + <cd:constant type="scriptscript"/> + <cd:constant type="rm"/> + <cd:constant type="ss"/> + <cd:constant type="tt"/> + <cd:constant type="hw"/> + <cd:constant type="cg"/> + <cd:constant type="roman"/> + <cd:constant type="serif"/> + <cd:constant type="regular"/> + <cd:constant type="sans"/> + <cd:constant type="sansserif"/> + <cd:constant type="support"/> + <cd:constant type="type"/> + <cd:constant type="teletype"/> + <cd:constant type="mono"/> + <cd:constant type="handwritten"/> + <cd:constant type="calligraphic"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="switchtobodyfont"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:inherit name="setupbodyfont"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkiv" name="fastswitchtobodyfont"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="x"/> + <cd:constant type="xx"/> + <cd:constant type="small"/> + <cd:constant type="big"/> + <cd:constant type="script"/> + <cd:constant type="scriptscript"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="usebodyfont"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:inherit name="setupbodyfont"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="usebodyfontparameter"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="fontchar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="fontcharbyindex"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="tochar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkiv" name="switchstyleonly"> + <cd:arguments> + <cd:keywords> + <cd:constant type="rm"/> + <cd:constant type="ss"/> + <cd:constant type="tt"/> + <cd:constant type="hw"/> + <cd:constant type="cg"/> + <cd:constant type="roman"/> + <cd:constant type="serif"/> + <cd:constant type="regular"/> + <cd:constant type="sans"/> + <cd:constant type="sansserif"/> + <cd:constant type="support"/> + <cd:constant type="type"/> + <cd:constant type="teletype"/> + <cd:constant type="mono"/> + <cd:constant type="handwritten"/> + <cd:constant type="calligraphic"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkiv" name="switchstyleonly" variant="command"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="definebodyfontswitch"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:inherit name="setupbodyfont"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="setsmallbodyfont"/> + <cd:command file="font-ini.mkvi" name="setbigbodyfont"/> + <cd:command file="font-ini.mkvi" name="setmainbodyfont"/> + <cd:command file="font-ini.mkvi" name="restoreglobalbodyfont"/> + <cd:command file="font-ini.mkvi" name="predefinefont"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="predefinedfont"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-run.mkiv" name="showbodyfont"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:inherit name="setupbodyfont"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-run.mkiv" name="showbodyfontenvironment"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:inherit name="setupbodyfont"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-run.mkiv" name="showfont"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-run.mkiv" name="showfontstyle"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="setupbodyfont"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="rm"/> + <cd:constant type="ss"/> + <cd:constant type="tt"/> + <cd:constant type="mm"/> + <cd:constant type="hw"/> + <cd:constant type="cg"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="tf"/> + <cd:constant type="bf"/> + <cd:constant type="it"/> + <cd:constant type="sl"/> + <cd:constant type="bi"/> + <cd:constant type="bs"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="all"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-run.mkiv" name="showligature"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-run.mkiv" name="showligatures"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-run.mkiv" name="showfontstrip"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:inherit name="setupbodyfont"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-run.mkiv" name="showminimalbaseline"/> + <cd:command file="font-run.mkiv" name="showkerning"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-run.mkiv" name="showcharratio"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-run.mkiv" name="showfontparameters"/> + <cd:command file="font-pre.mkiv" name="setsmallcaps"/> + <cd:command file="font-pre.mkiv" name="setoldstyle"/> + <cd:command file="font-pre.mkiv" name="settabular"/> + <cd:command file="font-pre.mkiv" name="setfractions"/> + <cd:command file="font-pre.mkiv" name="setsuperiors"/> + <cd:command file="font-pre.mkiv" name="tinyfont"/> + <cd:command file="font-pre.mkiv" name="infofont"/> + <cd:command file="font-pre.mkiv" name="infofontbold"/> + <cd:command file="font-pre.mkiv" name="smallbodyfont"/> + <cd:command file="font-pre.mkiv" name="bigbodyfont"/> + <cd:command file="font-pre.mkiv" name="smaller"/> + <cd:command file="font-pre.mkiv" name="bigger"/> + <cd:command file="font-pre.mkiv" name="normal"/> + <cd:command file="font-pre.mkiv" name="bold"/> + <cd:command file="font-pre.mkiv" name="mono"/> + <cd:command file="font-pre.mkiv" name="monobold"/> + <cd:command file="font-pre.mkiv" name="slanted"/> + <cd:command file="font-pre.mkiv" name="italic"/> + <cd:command file="font-pre.mkiv" name="boldslanted"/> + <cd:command file="font-pre.mkiv" name="slantedbold"/> + <cd:command file="font-pre.mkiv" name="bolditalic"/> + <cd:command file="font-pre.mkiv" name="italicbold"/> + <cd:command file="font-pre.mkiv" name="small"/> + <cd:command file="font-pre.mkiv" name="smallnormal"/> + <cd:command file="font-pre.mkiv" name="smallbold"/> + <cd:command file="font-pre.mkiv" name="smalltype"/> + <cd:command file="font-pre.mkiv" name="smallslanted"/> + <cd:command file="font-pre.mkiv" name="smallboldslanted"/> + <cd:command file="font-pre.mkiv" name="smallslantedbold"/> + <cd:command file="font-pre.mkiv" name="smallbolditalic"/> + <cd:command file="font-pre.mkiv" name="smallitalicbold"/> + <cd:command file="font-pre.mkiv" name="sans"/> + <cd:command file="font-pre.mkiv" name="sansserif"/> + <cd:command file="font-pre.mkiv" name="roman"/> + <cd:command file="font-pre.mkiv" name="serif"/> + <cd:command file="font-pre.mkiv" name="regular"/> + <cd:command file="font-pre.mkiv" name="handwritten"/> + <cd:command file="font-pre.mkiv" name="calligraphic"/> + <cd:command file="font-pre.mkiv" name="sansnormal"/> + <cd:command file="font-pre.mkiv" name="sansbold"/> + <cd:command file="font-pre.mkiv" name="serifnormal"/> + <cd:command file="font-pre.mkiv" name="serifbold"/> + <cd:command file="font-pre.mkiv" name="mononormal"/> + <cd:command file="font-pre.mkiv" name="monobold"/> + <cd:command file="font-sol.mkvi" name="definefontsolution"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupfontsolution"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-sol.mkvi" name="setupfontsolution"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="goodies"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="solution"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="less"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="more"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="preroll"/> + <cd:constant type="split"/> + <cd:constant type="normal"/> + <cd:constant type="reverse"/> + <cd:constant type="random"/> + </cd:parameter> + <cd:parameter name="criterium"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-sol.mkvi" name="setfontsolution"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sol.mkvi" name="resetfontsolution"/> + <cd:command file="font-sol.mkvi" name="fontsolution" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sty.mkvi" name="definealternativestyle"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sty.mkvi" name="applyalternativestyle"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sty.mkvi" name="dontconvertfont"/> + <cd:command file="font-sty.mkvi" name="redoconvertfont"/> + <cd:command file="font-sty.mkvi" name="definestyle"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupstyle"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-sty.mkvi" name="setupstyle"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="method"> + <cd:constant type="command"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-sty.mkvi" generated="yes" name="style" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="style"/> + </cd:sequence> + </cd:command> + <cd:command file="font-sty.mkvi" generated="yes" name="style" variant="example"> + <cd:sequence> + <cd:variable value="style"/> + </cd:sequence> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sty.mkvi" name="style" type="environment" variant="argument"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sty.mkvi" name="style" type="environment"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupstyle"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-sty.mkvi" name="style" variant="argument"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sty.mkvi" name="style"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupstyle"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sty.mkvi" name="definestyleinstance"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="rm"/> + <cd:constant type="ss"/> + <cd:constant type="tt"/> + <cd:constant type="mm"/> + <cd:constant type="hw"/> + <cd:constant type="cg"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="tf"/> + <cd:constant type="bf"/> + <cd:constant type="it"/> + <cd:constant type="sl"/> + <cd:constant type="bi"/> + <cd:constant type="bs"/> + <cd:constant type="sc"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sty.mkvi" name="styleinstance"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sym.mkvi" name="doifelseitalic"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sym.mkvi" name="doifitalicelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="getprivateslot"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-ini.mkvi" name="getprivatechar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sym.mkvi" name="glyphfontfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sym.mkvi" name="getnamedglyphstyled"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sym.mkvi" name="getnamedglyphdirect"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sym.mkvi" name="getglyphstyled"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sym.mkvi" name="getglyphdirect"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sym.mkvi" name="resolvedglyphstyled"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sym.mkvi" name="resolvedglyphdirect"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sym.mkvi" name="setfont"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sym.mkvi" name="doifelsefontchar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-sym.mkvi" name="doiffontcharelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-tra.mkiv" name="showchardata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-tra.mkiv" name="showfontdata"/> + <cd:command file="font-tra.mkiv" name="doifelsefontpresent"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-tra.mkiv" name="doiffontpresentelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-tra.mkiv" name="showotfcomposition"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="-1"/> + <cd:constant type="1"/> + <cd:constant type="+1"/> + <cd:constant type="l2r"/> + <cd:constant type="r2l"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="font-var.mkvi" name="fontclass"/> + <cd:command file="font-var.mkvi" name="fontbody"/> + <cd:command file="font-var.mkvi" name="fontstyle"/> + <cd:command file="font-var.mkvi" name="fontalternative"/> + <cd:command file="font-var.mkvi" name="fontsize"/> + <cd:command file="font-var.mkvi" name="fontface"/> + <cd:command file="type-ini.mkvi" name="typescriptone"/> + <cd:command file="type-ini.mkvi" name="typescripttwo"/> + <cd:command file="type-ini.mkvi" name="typescriptthree"/> + <cd:command file="type-ini.mkvi" name="typescriptcollection" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="type-ini.mkvi" name="usetypescriptfile"> + <cd:arguments> + <cd:keywords> + <cd:constant type="reset"/> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="type-ini.mkvi" name="usetypescript"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="serif"/> + <cd:constant type="sans"/> + <cd:constant type="mono"/> + <cd:constant type="math"/> + <cd:constant type="handwriting"/> + <cd:constant type="calligraphy"/> + <cd:constant type="casual"/> + <cd:constant type="all"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + <cd:constant type="fallback"/> + <cd:constant type="default"/> + <cd:constant type="dtp"/> + <cd:constant type="simple"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="size"/> + <cd:constant type="name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="type-ini.mkvi" name="loadtypescriptfile"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="type-ini.mkvi" name="quittypescriptscanning"/> + <cd:command file="type-ini.mkvi" name="definetypescriptsynonym"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="type-ini.mkvi" name="typescript" type="environment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="serif"/> + <cd:constant type="sans"/> + <cd:constant type="mono"/> + <cd:constant type="math"/> + <cd:constant type="handwriting"/> + <cd:constant type="calligraphy"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="size"/> + <cd:constant type="name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="type-ini.mkvi" name="definetypescriptprefix"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="type-ini.mkvi" name="typescriptprefix"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="type-ini.mkvi" name="definetypeface"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="rm"/> + <cd:constant type="ss"/> + <cd:constant type="tt"/> + <cd:constant type="mm"/> + <cd:constant type="hw"/> + <cd:constant type="cg"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="serif"/> + <cd:constant type="sans"/> + <cd:constant type="mono"/> + <cd:constant type="math"/> + <cd:constant type="handwriting"/> + <cd:constant type="calligraphy"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant default="yes" type="default"/> + <cd:constant type="dtp"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="rscale"> + <cd:constant type="auto"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="features"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="fallbacks"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="goodies"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="designsize"> + <cd:constant type="auto"/> + <cd:constant type="default"/> + </cd:parameter> + <cd:parameter name="direction"> + <cd:constant type="both"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="hand-ini.mkiv" name="setupfontexpansion"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="vector"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="factor"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="stretch"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="shrink"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="step"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="hand-ini.mkiv" name="setupfontprotrusion"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="vector"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="factor"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="font-fea.mkiv" name="blockligatures"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:list"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-form.xml"> + <cd:command file="scrn-fld.mkvi" name="setupforms"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="method"> + <cd:constant default="yes" type="XML"/> + <cd:constant type="HTML"/> + <cd:constant type="PDF"/> + </cd:parameter> + <cd:parameter name="export"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-formula.xml"> + <cd:command file="math-for.mkiv" name="defineformula"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupformula"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-for.mkiv" name="setupformula"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="location"> + <cd:constant type="left"/> + <cd:constant default="yes" type="right"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant type="flushleft"/> + <cd:constant type="center"/> + <cd:constant type="flushright"/> + <cd:constant type="normal"/> + </cd:parameter> + <cd:parameter name="strut"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="spacebefore"> + <cd:inherit name="blank"/> + </cd:parameter> + <cd:parameter name="spaceafter"> + <cd:inherit name="blank"/> + </cd:parameter> + <cd:parameter name="numbercommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="numberstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="numbercolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="option"> + <cd:constant type="packed"/> + <cd:constant type="tight"/> + <cd:constant type="middle"/> + <cd:constant type="frame"/> + <cd:inherit name="setupbodyfont"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="leftmargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightmargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="indentnext"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="grid"> + <cd:inherit name="snaptogrid"/> + </cd:parameter> + <cd:parameter name="frame"> + <cd:constant type="number"/> + </cd:parameter> + <cd:inherit name="setupcounter"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-for.mkiv" name="definesubformula"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsubformula"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-for.mkiv" name="setupsubformula"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="indentnext"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat.mkiv" generated="yes" name="formula" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="formula"/> + <cd:string value="formula"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="packed"/> + <cd:constant type="tight"/> + <cd:constant type="middle"/> + <cd:constant type="frame"/> + <cd:inherit name="setupbodyfont"/> + </cd:keywords> + </cd:arguments> + <cd:instances> + <cd:constant value="sp"/> + <cd:constant value="sd"/> + <cd:constant value="mp"/> + <cd:constant value="md"/> + </cd:instances> + </cd:command> + <cd:command file="strc-mat.mkiv" name="formula" type="environment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="packed"/> + <cd:constant type="tight"/> + <cd:constant type="middle"/> + <cd:constant type="frame"/> + <cd:inherit name="setupbodyfont"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat.mkiv" name="spformula" type="environment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="packed"/> + <cd:constant type="tight"/> + <cd:constant type="middle"/> + <cd:constant type="frame"/> + <cd:inherit name="setupbodyfont"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat.mkiv" name="sdformula" type="environment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="packed"/> + <cd:constant type="tight"/> + <cd:constant type="middle"/> + <cd:constant type="frame"/> + <cd:inherit name="setupbodyfont"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat.mkiv" name="mpformula" type="environment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="packed"/> + <cd:constant type="tight"/> + <cd:constant type="middle"/> + <cd:constant type="frame"/> + <cd:inherit name="setupbodyfont"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat.mkiv" name="mdformula" type="environment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="packed"/> + <cd:constant type="tight"/> + <cd:constant type="middle"/> + <cd:constant type="frame"/> + <cd:inherit name="setupbodyfont"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat.mkiv" name="defineformulaalternative"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:csname"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:csname"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat.mkiv" name="formula"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="packed"/> + <cd:constant type="tight"/> + <cd:constant type="middle"/> + <cd:constant type="frame"/> + <cd:inherit name="setupbodyfont"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat.mkiv" name="displaymath" type="environment"/> + <cd:command file="strc-mat.mkiv" name="formulas" type="environment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat.mkiv" name="subformulas" type="environment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat.mkiv" name="namedsubformulas" type="environment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat.mkiv" name="placeformula"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat.mkiv" name="placeformula" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="suffix"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:reference"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat.mkiv" name="placeformula" type="environment" variant="argument"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat.mkiv" name="placenamedformula"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat.mkiv" name="placesubformula"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat" name="formulanumber"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mat" name="placecurrentformulanumber"/> + </cd:interface> + <cd:interface file="i-fraction.xml"> + <cd:command file="math-frc.mkiv" name="definemathfraction"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathfraction"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-frc.mkiv" name="setupmathfraction"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="topdistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bottomdistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="strut"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + <cd:constant type="math"/> + <cd:constant type="tight"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant default="yes" type="inner"/> + <cd:constant type="outer"/> + <cd:constant type="both"/> + </cd:parameter> + <cd:parameter name="rule"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant default="yes" type="auto"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="mathstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="no"/> + <cd:constant default="yes" type="none"/> + <cd:constant type="overlay"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-frc.mkiv" generated="yes" name="fraction" variant="example"> + <cd:sequence> + <cd:variable value="fraction"/> + </cd:sequence> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + <cd:instances> + <cd:constant value="xfrac"/> + <cd:constant value="xxfrac"/> + <cd:constant value="frac"/> + <cd:constant value="sfrac"/> + <cd:constant value="dfrac"/> + <cd:constant value="binom"/> + <cd:constant value="dbinom"/> + <cd:constant value="tbinom"/> + </cd:instances> + </cd:command> + <cd:command file="math-frc.mkiv" name="frac"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-frc.mkiv" name="xfrac"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-frc.mkiv" name="xxfrac"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-frc.mkiv" name="tfrac"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-frc.mkiv" name="sfrac"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-frc.mkiv" name="dfrac"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-frc.mkiv" name="binom"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-frc.mkiv" name="dbinom"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-frc.mkiv" name="tbinom"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-frc.mkiv" name="splitfrac"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-frc.mkiv" name="splitdfrac"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-frc.mkiv" name="cfrac"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="l"/> + <cd:constant type="c"/> + <cd:constant type="r"/> + <cd:constant type="ll"/> + <cd:constant type="lc"/> + <cd:constant type="lr"/> + <cd:constant type="cl"/> + <cd:constant type="cc"/> + <cd:constant type="cr"/> + <cd:constant type="rl"/> + <cd:constant type="rc"/> + <cd:constant type="rr"/> + </cd:keywords> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-framed.xml"> + <cd:command file="pack-rul.mkiv" name="defineframed"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="setupframed"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="corner"> + <cd:constant default="yes" type="rectangular"/> + <cd:constant type="round"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="framecorner"> + <cd:constant default="yes" type="rectangular"/> + <cd:constant type="round"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="backgroundcorner"> + <cd:constant default="yes" type="rectangular"/> + <cd:constant type="round"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="radius"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="frameradius"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="backgroundradius"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="framedepth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="backgrounddepth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="framecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="topframe"> + <cd:constant default="yes" type="on"/> + <cd:constant type="off"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="bottomframe"> + <cd:constant default="yes" type="on"/> + <cd:constant type="off"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="leftframe"> + <cd:constant default="yes" type="on"/> + <cd:constant type="off"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="rightframe"> + <cd:constant default="yes" type="on"/> + <cd:constant type="off"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="region"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="frameoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="frame"> + <cd:constant default="yes" type="on"/> + <cd:constant type="off"/> + <cd:constant type="overlay"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="background"> + <cd:constant type="foreground"/> + <cd:constant type="color"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="backgroundoffset"> + <cd:constant type="frame"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="component"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="extras"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="foregroundstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="foregroundcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="setups"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="default"/> + <cd:constant type="overlay"/> + <cd:constant type="none"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="local"/> + <cd:constant default="yes" type="fit"/> + <cd:constant type="max"/> + <cd:constant type="broad"/> + <cd:constant type="fixed"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="fit"/> + <cd:constant type="max"/> + <cd:constant default="yes" type="broad"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="strut"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + <cd:constant type="none"/> + <cd:constant type="local"/> + <cd:constant type="global"/> + </cd:parameter> + <cd:parameter name="autostrut"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="height"/> + <cd:constant type="depth"/> + <cd:constant type="high"/> + <cd:constant type="low"/> + <cd:constant type="top"/> + <cd:constant type="middle"/> + <cd:constant type="bottom"/> + <cd:constant type="line"/> + <cd:constant type="lohi"/> + <cd:constant type="hanging"/> + <cd:constant type="keep"/> + <cd:constant type="formula"/> + <cd:constant type="mathematics"/> + <cd:constant default="yes" type="normal"/> + </cd:parameter> + <cd:parameter name="autowidth"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + <cd:constant type="force"/> + </cd:parameter> + <cd:parameter name="lines"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="top"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="bottom"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="blank"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="profile"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="empty"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="loffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="roffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="toffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="boffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="orientation"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="frameddimension"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="framedparameter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="framed"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" generated="yes" name="framed" variant="example"> + <cd:sequence> + <cd:variable value="framed"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + <cd:instances> + <cd:constant value="unframed"/> + <cd:constant value="fitfieldframed"/> + </cd:instances> + </cd:command> + <cd:command file="pack-rul.mkiv" name="normalframedwithsettings"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="framed" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="fastlocalframed"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="localframed"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="directlocalframed"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="localframedwithsettings"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="placeframed"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="inframed"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="unframed"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="definemathframed"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="setupmathframed"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" generated="yes" name="mathframed" variant="example"> + <cd:sequence> + <cd:variable value="mathframed"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + <cd:instances> + <cd:constant value="mframed"/> + <cd:constant value="inmframed"/> + <cd:constant value="mcframed"/> + </cd:instances> + </cd:command> + <cd:command file="pack-rul.mkiv" name="mframed"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="inmframed"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="mcframed"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-for.mkiv" name="defineformulaframed"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupformulaframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-for.mkiv" name="setupformulaframed"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="defineframedtext"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframedtext"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="setupframedtext"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inner"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="middle"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="depthcorrection"> + <cd:constant default="yes" type="on"/> + <cd:constant type="off"/> + </cd:parameter> + <cd:parameter name="bodyfont"> + <cd:inherit name="setupbodyfont"/> + </cd:parameter> + <cd:parameter name="indenting"> + <cd:inherit name="setupindenting"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + <cd:inherit name="setupplacement"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" generated="yes" name="framedtext" variant="example"> + <cd:sequence> + <cd:variable value="framedtext"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframedtext"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + <cd:instances> + <cd:constant value="framedtext"/> + </cd:instances> + </cd:command> + <cd:command file="pack-rul.mkiv" generated="yes" name="framedtext" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="framedtext"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="middle"/> + <cd:constant type="none"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframedtext"/> + </cd:assignments> + </cd:arguments> + <cd:instances> + <cd:constant value="framedtext"/> + </cd:instances> + </cd:command> + <cd:command file="pack-rul.mkiv" name="framedtext"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframedtext"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="framedtext" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="middle"/> + <cd:constant type="none"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframedtext"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="defineframedcontent"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframedcontent"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="setupframedcontent"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="leftoffser"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="topoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bottomoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="linecorrection"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="framedcontent" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + <cd:constant type="off"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-fen.mkiv" name="installleftframerenderer"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-fen.mkiv" name="installrightframerenderer"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-fen.mkiv" name="installtopframerenderer"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-fen.mkiv" name="installbottomframerenderer"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-graphics.xml"> + <cd:command file="grph-inc.mkiv" name="defineexternalfigure"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupexternalfigure"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkvi" name="setupexternalfigure"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="label"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="page"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="object"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="prefix"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="pdf"/> + <cd:constant type="mps"/> + <cd:constant type="jpg"/> + <cd:constant type="png"/> + <cd:constant type="jp2"/> + <cd:constant type="jbig"/> + <cd:constant type="svg"/> + <cd:constant type="eps"/> + <cd:constant type="gif"/> + <cd:constant type="tif"/> + <cd:constant type="mov"/> + <cd:constant type="buffer"/> + <cd:constant type="tex"/> + <cd:constant type="cld"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="controls"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="preview"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="mask"> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="resolution"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="arguments"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="repeat"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="factor"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="max"/> + <cd:constant type="auto"/> + <cd:constant type="default"/> + </cd:parameter> + <cd:parameter name="hfactor"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="max"/> + <cd:constant type="auto"/> + <cd:constant type="default"/> + </cd:parameter> + <cd:parameter name="wfactor"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="max"/> + <cd:constant type="auto"/> + <cd:constant type="default"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="maxheight"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="equalwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="equalheight"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="scale"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="xscale"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="yscale"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="s"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="sx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="sy"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="lines"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant default="yes" type="local"/> + <cd:constant default="yes" type="global"/> + <cd:constant type="default"/> + </cd:parameter> + <cd:parameter name="directory"> + <cd:constant type="cd:path"/> + </cd:parameter> + <cd:parameter name="option"> + <cd:constant type="test"/> + <cd:constant type="frame"/> + <cd:constant type="empty"/> + </cd:parameter> + <cd:parameter name="forgroundcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="reset"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="background"> + <cd:constant type="color"/> + <cd:constant type="foreground"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="frame"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + </cd:parameter> + <cd:parameter name="backgroundcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="xmax"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="ymax"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="frames"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + </cd:parameter> + <cd:parameter name="interaction"> + <cd:constant type="yes"/> + <cd:constant type="all"/> + <cd:constant default="yes" type="none"/> + <cd:constant type="reference"/> + <cd:constant type="layer"/> + <cd:constant type="bookmark"/> + </cd:parameter> + <cd:parameter name="bodyfont"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="comment"> + <cd:constant type="cd:command"/> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="size"> + <cd:constant type="none"/> + <cd:constant type="media"/> + <cd:constant type="crop"/> + <cd:constant type="trim"/> + <cd:constant type="art"/> + </cd:parameter> + <cd:parameter name="cache"> + <cd:constant type="cd:path"/> + </cd:parameter> + <cd:parameter name="resources"> + <cd:constant type="cd:path"/> + </cd:parameter> + <cd:parameter name="display"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="conversion"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="order"> + <cd:constant type="cd:list"/> + </cd:parameter> + <cd:parameter name="crossreference"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="useexternalfigure"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupexternalfigure"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="externalfigure"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupexternalfigure"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="getfiguredimensions"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupexternalfigure"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="figurewidth"/> + <cd:command file="grph-inc.mkiv" name="figureheight"/> + <cd:command file="grph-inc.mkiv" name="figurenaturalwidth"/> + <cd:command file="grph-inc.mkiv" name="figurenaturalheight"/> + <cd:command file="grph-inc.mkiv" name="figurefullname"/> + <cd:command file="grph-inc.mkiv" name="figurefilename"/> + <cd:command file="grph-inc.mkiv" name="figurefilepath"/> + <cd:command file="grph-inc.mkiv" name="figurefiletype"/> + <cd:command file="grph-inc.mkiv" name="noffigurepages"/> + <cd:command file="grph-inc.mkiv" name="definegraphictypesynonym"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="doifelsefigure"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="doiffigureelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="registerexternalfigure"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupexternalfigure"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="usefigurebase"> + <cd:arguments> + <cd:keywords> + <cd:constant type="reset"/> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="externalfigurecollection" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="externalfigurecollectionminwidth"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="externalfigurecollectionmaxwidth"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="externalfigurecollectionminheight"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="externalfigurecollectionmaxheight"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="externalfigurecollectionparameter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="efcminwidth"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="efcmaxwidth"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="efcminheight"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="efcmaxheight"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="efcparameter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="overlayfigure"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="bitmapimage"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="color"> + <cd:constant type="rgb"/> + <cd:constant type="cmyk"/> + <cd:constant type="gray"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="x"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="y"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="grph-inc.mkiv" name="bitmapimage" type="environment"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="color"> + <cd:constant type="rgb"/> + <cd:constant type="cmyk"/> + <cd:constant type="gray"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="x"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="y"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="grph-fig.mkiv" name="typesetbuffer"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="*"/> + <cd:constant type="cd:buffer"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupexternalfigure"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="grph-fig.mkiv" name="definetypesetting"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupexternalfigure"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="grph-fig.mkiv" name="typesetfile"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:file"/> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupexternalfigure"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="backgroundimage"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="backgroundimagefill"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-grid.xml"> + <cd:command file="page-grd.mkiv" name="showgrid"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="reset"/> + <cd:constant default="yes" type="bottom"/> + <cd:constant type="top"/> + <cd:constant type="none"/> + <cd:constant default="yes" type="all"/> + <cd:constant type="lines"/> + <cd:constant type="frame"/> + <cd:constant type="nonumber"/> + <cd:constant default="yes" type="right"/> + <cd:constant type="left"/> + <cd:constant type="outer"/> + <cd:constant default="yes" type="columns"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="definegridsnapping"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="local"/> + <cd:constant type="global"/> + <cd:constant type="noheight"/> + <cd:constant type="nodepth"/> + <cd:constant type="box"/> + <cd:constant type="max"/> + <cd:constant type="min"/> + <cd:constant type="none"/> + <cd:constant type="line"/> + <cd:constant type="halfline"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="minheight"/> + <cd:constant type="maxheight"/> + <cd:constant type="mindepth"/> + <cd:constant type="maxdepth"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="strut"/> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="minheight" type="cd:number"/> + <cd:constant method="range" prefix="maxheight" type="cd:number"/> + <cd:constant method="range" prefix="mindepth" type="cd:number"/> + <cd:constant method="range" prefix="maxdepth" type="cd:number"/> + <cd:constant method="range" prefix="box" type="cd:number"/> + <cd:constant method="range" prefix="top" type="cd:number"/> + <cd:constant method="range" prefix="bottom" type="cd:number"/> + <cd:constant method="range" prefix="offset" type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="snaptogrid"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="normal"/> + <cd:constant type="standard"/> + <cd:constant type="yes"/> + <cd:constant type="strict"/> + <cd:constant type="tolerant"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="both"/> + <cd:constant type="broad"/> + <cd:constant type="fit"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="high"/> + <cd:constant type="one"/> + <cd:constant type="low"/> + <cd:constant type="none"/> + <cd:constant type="line"/> + <cd:constant type="strut"/> + <cd:constant type="box"/> + <cd:constant type="min"/> + <cd:constant type="max"/> + <cd:constant type="middle"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="snaptogrid" variant="list"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="definegridsnapping"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="placeongrid"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="normal"/> + <cd:constant type="standard"/> + <cd:constant type="yes"/> + <cd:constant type="strict"/> + <cd:constant type="tolerant"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="both"/> + <cd:constant type="broad"/> + <cd:constant type="fit"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="high"/> + <cd:constant type="one"/> + <cd:constant type="low"/> + <cd:constant type="none"/> + <cd:constant type="line"/> + <cd:constant type="strut"/> + <cd:constant type="box"/> + <cd:constant type="min"/> + <cd:constant type="max"/> + <cd:constant type="middle"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="placeongrid" variant="list"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="definegridsnapping"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="gridsnapping" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="normal"/> + <cd:constant type="standard"/> + <cd:constant type="yes"/> + <cd:constant type="strict"/> + <cd:constant type="tolerant"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="both"/> + <cd:constant type="broad"/> + <cd:constant type="fit"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="high"/> + <cd:constant type="one"/> + <cd:constant type="low"/> + <cd:constant type="none"/> + <cd:constant type="line"/> + <cd:constant type="strut"/> + <cd:constant type="box"/> + <cd:constant type="min"/> + <cd:constant type="max"/> + <cd:constant type="middle"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="gridsnapping" type="environment" variant="list"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="definegridsnapping"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="usegridparameter"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="showgridsnapping"/> + <cd:command file="meta-grd.mkiv" name="basegrid"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="nx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="ny"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="dx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="dy"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="factor"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="scale"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="xstep"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="ystep"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="xoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="yoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:constant type="middle"/> + </cd:parameter> + <cd:parameter name="unit"> + <cd:constant default="yes" type="cm"/> + <cd:constant type="mm"/> + <cd:constant type="in"/> + <cd:constant type="pc"/> + <cd:constant type="pt"/> + <cd:constant type="bp"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="meta-grd.mkiv" name="grid"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="basegrid"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-help.xml"> + <cd:command file="scrn-hlp.mkvi" name="definehelp"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuphelp"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-hlp.mkvi" name="setuphelp"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-hlp.mkvi" generated="yes" name="help" variant="example"> + <cd:sequence> + <cd:variable value="help"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + <cd:instances> + <cd:constant value="helptext"/> + </cd:instances> + </cd:command> + <cd:command file="scrn-hlp.mkvi" generated="yes" name="help" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="help"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + <cd:instances> + <cd:constant value="helptext"/> + </cd:instances> + </cd:command> + <cd:command file="scrn-hlp.mkvi" name="doifelsehelp"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-hlp.mkvi" name="doifhelpelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-hlp.mkvi" name="placehelp"/> + <cd:command file="scrn-hlp.mkvi" name="showhelp"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-hlp.mkvi" name="helptext"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-hlp.mkvi" name="helptext" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-highlight.xml"> + <cd:command file="core-sys.mkiv" name="definehighlight"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuphighlight"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-sys.mkiv" name="setuphighlight"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="command"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-sys.mkiv" generated="yes" name="highlight" variant="example"> + <cd:sequence> + <cd:variable value="highlight"/> + </cd:sequence> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-sys.mkiv" name="highlight"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-sys.mkiv" name="highlight" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-sys.mkiv" name="directhighlight"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-hspace.xml"> + <cd:command file="spac-hor.mkiv" name="definehspace"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="hspace"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="normal"/> + <cd:constant default="yes" type="default"/> + <cd:constant type="none"/> + <cd:constant type=".5"/> + <cd:constant type="1"/> + <cd:constant type="2"/> + <cd:constant type="3"/> + <cd:constant type="speech"/> + <cd:constant type="quote"/> + <cd:constant type="interquotation"/> + <cd:constant type="quotation"/> + <cd:constant type="sentence"/> + <cd:constant type="intersentence"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="hairspace"/> + <cd:command file="spac-hor.mkiv" name="thinspace"/> + <cd:command file="spac-hor.mkiv" name="medspace"/> + <cd:command file="spac-hor.mkiv" name="thickspace"/> + <cd:command file="spac-hor.mkiv" name="autoinsertnextspace"/> + <cd:command file="spac-ver.mkiv" name="hglue"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="frenchspacing"/> + <cd:command file="spac-hor.mkiv" name="newfrenchspacing"/> + <cd:command file="spac-hor.mkiv" name="nonfrenchspacing"/> + <cd:command file="spac-hor.mkiv" name="setupspacing"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="fixed"/> + <cd:constant default="yes" type="packed"/> + <cd:constant type="broad"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="space"/> + <cd:command file="spac-hor.mkiv" name="removelastspace"/> + <cd:command file="spac-hor.mkiv" name="nospace"/> + <cd:command file="spac-hor.mkiv" name="fixedspace"/> + <cd:command file="spac-hor.mkiv" name="fixedspaces"/> + <cd:command file="spac-hor.mkiv" name="keepunwantedspaces"/> + <cd:command file="spac-hor.mkiv" name="removeunwantedspaces"/> + <cd:command file="spac-hor.mkiv" name="thinspace"/> + <cd:command file="spac-hor.mkiv" name="negthinspace"/> + <cd:command file="spac-hor.mkiv" name="enspace"/> + <cd:command file="spac-hor.mkiv" name="enskip"/> + <cd:command file="spac-hor.mkiv" name="quad"/> + <cd:command file="spac-hor.mkiv" name="qquad"/> + <cd:command file="spac-hor.mkiv" name="emspace"/> + <cd:command file="spac-hor.mkiv" name="dotfskip"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="leftskipadaption"/> + <cd:command file="spac-hor.mkiv" name="rightskipadaption"/> + <cd:command file="spac-hor.mkiv" name="dosetleftskipadaption"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="dosetrightskipadaption"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="doadaptleftskip"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="doadaptrightskip"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="activatespacehandler"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + <cd:constant type="yes"/> + <cd:constant type="fixed"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="quads"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-hyphenation.xml"> + <cd:command file="lang-hyp.mkiv" name="setuphyphenation"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="method"> + <cd:constant type="original"/> + <cd:constant type="tex"/> + <cd:constant default="yes" type="default"/> + <cd:constant type="hyphenate"/> + <cd:constant type="expanded"/> + <cd:constant type="traditional"/> + <cd:constant type="none"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="lang-hyp.mkiv" name="hyphenation" type="environment"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="original"/> + <cd:constant type="tex"/> + <cd:constant default="yes" type="default"/> + <cd:constant type="hyphenate"/> + <cd:constant type="expanded"/> + <cd:constant type="traditional"/> + <cd:constant type="none"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-hyp.mkiv" name="definehypenationfeatures"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="characters"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="hyphens"> + <cd:constant type="yes"/> + <cd:constant type="all"/> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="joiners"> + <cd:constant type="yes"/> + <cd:constant type="all"/> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="rightwords"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="hyphenmin"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="lefthyphenmin"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="righthyphenmin"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="lefthyphenchar"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="righthyphenchar"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="original"/> + <cd:constant type="tex"/> + <cd:constant default="yes" type="hyphenate"/> + <cd:constant type="expanded"/> + <cd:constant type="traditional"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="rightedge"> + <cd:constant type="tex"/> + </cd:parameter> + <cd:parameter name="rightchars"> + <cd:constant type="word"/> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="lang-hyp.mkiv" name="sethyphenationfeatures"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + <cd:constant type="reset"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-hyp.mkiv" name="resethyphenationfeatures"/> + <cd:command file="lang-hyp.mkiv" name="registerhyphenationpattern"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-hyp.mkiv" name="unregisterhyphenationpattern"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-hyp.mkiv" name="showhyphenationtrace"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-hyp.mkiv" name="registerhyphenationexception"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-del.mkiv" name="setuphyphenmark"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="sign"> + <cd:constant type="normal"/> + <cd:constant default="yes" type="wide"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-brk.mkiv" name="definebreakpoints"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-brk.mkiv" name="definebreakpoint"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:character"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="type"> + <cd:constant type="1"/> + <cd:constant type="2"/> + <cd:constant type="3"/> + <cd:constant type="4"/> + <cd:constant type="5"/> + </cd:parameter> + <cd:parameter name="nleft"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="nright"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="middle"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="range"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="language"> + <cd:constant type="cd:language"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-brk.mkiv" name="setbreakpoints"> + <cd:arguments> + <cd:keywords> + <cd:constant type="reset"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-brk.mkiv" name="resetbreakpoints"/> + <cd:command file="supp-box.mkiv" name="showhyphens"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="hyphenatedword"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="hyphenatedpar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="hyphenatedfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="hyphenatedcoloredword"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="hyphenatedhbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="lang-url.mkiv" name="sethyphenatedurlbefore"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-url.mkiv" name="sethyphenatedurlafter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-url.mkiv" name="sethyphenatedurlnormal"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-url.mkiv" name="hyphenatedurl"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-url.mkiv" name="hyphenatedfilename"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-imposition.xml"> + <cd:command file="page-imp.mkiv" name="installshipoutmethod"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-imp.mkiv" name="invokepageheandler"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="normal"/> + <cd:constant type="none"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="page-imp.mkiv" name="setuparranging"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="disable"/> + <cd:constant type="mirrored"/> + <cd:constant type="doublesided"/> + <cd:constant type="negative"/> + <cd:constant type="90"/> + <cd:constant type="180"/> + <cd:constant type="270"/> + <cd:constant type="reset"/> + <cd:constant type="background"/> + <cd:constant type="normal"/> + <cd:constant type="2*16"/> + <cd:constant type="2*8"/> + <cd:constant type="2*4"/> + <cd:constant type="2*2"/> + <cd:constant type="2**2"/> + <cd:constant type="2SIDE"/> + <cd:constant type="2TOP"/> + <cd:constant type="2UP"/> + <cd:constant type="2DOWN"/> + <cd:constant type="2*4*2"/> + <cd:constant type="2*2*4"/> + <cd:constant type="2TOPSIDE"/> + <cd:constant type="2*8*Z"/> + <cd:constant type="2*6*Z"/> + <cd:constant type="1*8"/> + <cd:constant type="1*4"/> + <cd:constant type="3SIDE"/> + <cd:constant type="TRYPTICHON"/> + <cd:constant type="ZFLYER-8"/> + <cd:constant type="ZFLYER-10"/> + <cd:constant type="ZFLYER-12"/> + <cd:constant type="MAPFLYER-12"/> + <cd:constant type="DOUBLEWINDOW"/> + <cd:constant type="1*2-Conference"/> + <cd:constant type="1*4-Conference"/> + <cd:constant type="2*2*2"/> + <cd:constant type="2*2*3"/> + <cd:constant type="XY"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-imp.mkiv" name="installpagearrangement"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command begin="push" end="pop" file="page-imp.mkiv" name="arrangedpages" type="environment"/> + </cd:interface> + <cd:interface file="i-indent.xml"> + <cd:command file="spac-hor.mkiv" name="defineindenting"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant method="none" prefix="cd:sign" type="small"/> + <cd:constant method="none" prefix="cd:sign" type="medium"/> + <cd:constant method="none" prefix="cd:sign" type="big"/> + <cd:constant type="none"/> + <cd:constant type="no"/> + <cd:constant type="not"/> + <cd:constant type="first"/> + <cd:constant type="next"/> + <cd:constant type="yes"/> + <cd:constant type="always"/> + <cd:constant type="never"/> + <cd:constant type="odd"/> + <cd:constant type="even"/> + <cd:constant type="normal"/> + <cd:constant type="reset"/> + <cd:constant type="toggle"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="setupindenting"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant method="none" prefix="cd:sign" type="small"/> + <cd:constant method="none" prefix="cd:sign" type="medium"/> + <cd:constant method="none" prefix="cd:sign" type="big"/> + <cd:constant type="none"/> + <cd:constant type="no"/> + <cd:constant type="not"/> + <cd:constant type="first"/> + <cd:constant type="next"/> + <cd:constant type="yes"/> + <cd:constant type="always"/> + <cd:constant type="never"/> + <cd:constant type="odd"/> + <cd:constant type="even"/> + <cd:constant type="normal"/> + <cd:constant type="reset"/> + <cd:constant type="toggle"/> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="synchronizeindenting"/> + <cd:command file="spac-hor.mkiv" name="useindentingparameter"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command coreprimitive="yes" file="spac-hor.mkiv" name="indentation"/> + <cd:command coreprimitive="yes" file="spac-hor.mkiv" name="noindentation"/> + <cd:command coreprimitive="yes" file="spac-hor.mkiv" name="doindentation"/> + <cd:command file="spac-hor.mkiv" name="checknextindentation"> + <cd:arguments> + <cd:keywords> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="useindentnextparameter"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="dorechecknextindentation"/> + <cd:command begin="push" end="pop" file="spac-hor.mkiv" name="indentation" type="environment"/> + </cd:interface> + <cd:interface file="i-indentedtext.xml"> + <cd:command file="strc-ind.mkiv" name="defineindentedtext"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupindentedtext"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-ind.mkiv" name="setupindentedtext"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="sample"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="text"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant default="yes" type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="separator"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="headstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="headcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-ind.mkiv" generated="yes" name="indentedtext" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="indentedtext"/> + </cd:sequence> + </cd:command> + <cd:command file="strc-ind.mkiv" name="indentedtext" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-initial.xml"> + <cd:command file="typo-drp.mkiv" name="defineinitial"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupinitial"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-drp.mkiv" name="setupinitial"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="m"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="hoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="voffset"> + <cd:constant default="yes" type="line"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="font"> + <cd:constant type="cd:font"/> + </cd:parameter> + <cd:parameter name="text"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="margin"/> + <cd:constant default="yes" type="text"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="auto"/> + <cd:constant default="yes" type="none"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-drp.mkiv" name="placeinitial"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-drp.mkiv" name="setinitial"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupinitial"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-injector.xml"> + <cd:command file="typo-inj.mkiv" name="resetinjector"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-inj.mkiv" name="markinjector"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-inj.mkiv" name="checkinjector"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-inj.mkiv" name="checkpreviousinjector"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-inj.mkiv" name="checknextinjector"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-inj.mkiv" name="setinjector"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-inj.mkiv" name="showinjector"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-insertion.xml"> + <cd:command file="page-ins.mkiv" name="defineinsertion"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupinsertion"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-ins.mkiv" name="setupinsertion"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="location"> + <cd:constant default="yes" type="page"/> + <cd:constant type="text"/> + <cd:constant type="columns"/> + <cd:constant type="firstcolumn"/> + <cd:constant type="lastcolumn"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-ins.mkiv" name="doifelseinsertion"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-ins.mkiv" name="doifinsertionelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-interaction.xml"> + <cd:command file="scrn-ini.mkvi" name="defineinteraction"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupinteraction"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-ini.mkvi" name="setupinteraction"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant type="start"/> + <cd:constant default="yes" type="stop"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="contrastcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="subtitle"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="author"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="date"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="keyword"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="focus"> + <cd:constant type="standard"/> + <cd:constant type="frame"/> + <cd:constant type="width"/> + <cd:constant type="minwidth"/> + <cd:constant type="height"/> + <cd:constant type="minheight"/> + <cd:constant default="yes" type="fit"/> + <cd:constant type="tight"/> + </cd:parameter> + <cd:parameter name="menu"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + </cd:parameter> + <cd:parameter name="fieldlayer"> + <cd:constant type="auto"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="calculate"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="click"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="display"> + <cd:constant type="normal"/> + <cd:constant type="new"/> + </cd:parameter> + <cd:parameter name="page"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="page"/> + <cd:constant type="name"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="openaction"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="closeaction"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="openpageaction"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="closepageaction"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="symbolset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="focusoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-ini.mkvi" name="setupinteraction" variant="name"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-ini.mkvi" name="interaction" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="hidden"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-ini.mkvi" name="setinteraction"> + <cd:arguments> + <cd:keywords> + <cd:constant type="hidden"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-ini.mkvi" name="doifelselocation"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-ini.mkvi" name="doiflocationelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-interactionbar.xml"> + <cd:command file="scrn-bar.mkvi" name="defineinteractionbar"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupinteractionbar"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-bar.mkvi" name="setupinteractionbar"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="alternative"> + <cd:constant default="yes" type="a"/> + <cd:constant type="b"/> + <cd:constant type="c"/> + <cd:constant type="d"/> + <cd:constant type="e"/> + <cd:constant type="f"/> + <cd:constant type="g"/> + </cd:parameter> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:csname"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + <cd:constant type="max"/> + <cd:constant type="broad"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="cd:dimension"/> + <cd:constant type="max"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="step"> + <cd:constant type="small"/> + <cd:constant default="yes" type="medium"/> + <cd:constant type="big"/> + </cd:parameter> + <cd:parameter name="backgroundcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="contrastcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="symbol"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-bar.mkvi" name="interactionbar"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupinteractionbar"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-bar.mkvi" name="interactionbuttons"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupinteractionbar"/> + </cd:assignments> + <cd:keywords list="yes"> + <cd:constant type="page"/> + <cd:constant type="subpage"/> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-interactionmenu.xml"> + <cd:command file="scrn-but.mkvi" name="defineinteractionmenu"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupinteractionmenu"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-but.mkvi" name="setupinteractionmenu"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="alternative"> + <cd:constant type="vertical"/> + <cd:constant type="horizontal"/> + <cd:constant type="hidden"/> + </cd:parameter> + <cd:parameter name="category"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="leftoffset"> + <cd:constant type="overlay"/> + <cd:constant type="frame"/> + <cd:constant type="none"/> + <cd:constant type="default"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightoffset"> + <cd:constant type="overlay"/> + <cd:constant type="frame"/> + <cd:constant type="none"/> + <cd:constant type="default"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="topoffset"> + <cd:constant type="overlay"/> + <cd:constant type="frame"/> + <cd:constant type="none"/> + <cd:constant type="default"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bottomoffset"> + <cd:constant type="overlay"/> + <cd:constant type="frame"/> + <cd:constant type="none"/> + <cd:constant type="default"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="maxheight"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="itemalign"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant type="flushleft"/> + <cd:constant type="flushright"/> + <cd:constant type="low"/> + <cd:constant type="high"/> + <cd:constant type="lohi"/> + </cd:parameter> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="empty"/> + <cd:constant type="local"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="overlay"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="position"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="middle"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="samepage"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + <cd:constant type="empty"/> + <cd:constant type="none"/> + <cd:constant type="normal"/> + <cd:constant type="default"/> + </cd:parameter> + <cd:parameter name="contrastcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-but.mkvi" name="interactionmenu" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-but.mkvi" name="resetinteractionmenu"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-but.mkvi" name="includemenu"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-but.mkvi" name="interactionmenu"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupinteractionmenu"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-but.mkvi" name="menubutton" variant="interactionmenu"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupinteractionmenu"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-but.mkvi" name="menubutton" variant="button"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupbutton"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-but.mkvi" name="registermenubuttons"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-interactionscreen.xml"> + <cd:command file="scrn-pag.mkvi" name="setupinteractionscreen"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="width"> + <cd:constant type="fit"/> + <cd:constant type="max"/> + <cd:constant type="tight"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="fit"/> + <cd:constant type="max"/> + <cd:constant type="tight"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="backspace"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="horoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="veroffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="topspace"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter list="yes" name="option"> + <cd:constant type="fit"/> + <cd:constant type="max"/> + <cd:constant type="singlesided"/> + <cd:constant type="doublesided"/> + <cd:constant type="bookmark"/> + <cd:constant default="yes" type="auto"/> + <cd:constant type="none"/> + <cd:constant type="default"/> + <cd:constant type="fixed"/> + <cd:constant type="landscape"/> + <cd:constant type="portrait"/> + <cd:constant type="page"/> + <cd:constant type="paper"/> + </cd:parameter> + <cd:parameter name="copies"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="delay"> + <cd:constant default="yes" type="none"/> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-pag.mkvi" name="screen"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="page"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-interface.xml"> + <cd:command file="mult-ini.mkiv" name="defaultinterface"/> + <cd:command file="mult-ini.mkiv" name="currentinterface"/> + <cd:command file="mult-ini.mkiv" name="currentresponses"/> + <cd:command file="mult-ini.mkiv" name="interface" type="environment"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="all"/> + <cd:constant type="cd:language"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="defineinterfaceconstant"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="defineinterfacevariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="defineinterfaceelement"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="definefileconstant"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="definesystemconstant"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="definemessageconstant"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="definesystemvariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="setinterfacemessage"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="title"/> + <cd:constant type="cd:name"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="setmessagetext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="currentmessagetext"/> + <cd:command file="mult-ini.mkiv" name="getmessage"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="doifelsemessage"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="doifmessageelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="showmessage"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="writestatus"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="message"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="inlinemessage"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="displaymessage"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="showwarning"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="setinterfaceconstant"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="setinterfacevariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="setinterfaceelements"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="mult-ini.mkiv" name="setinterfacecommand"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-interlinespace.xml"> + <cd:command file="spac-ver.mkiv" name="defineinterlinespace"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupinterlinespace"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setupinterlinespace"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="line"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="minheight"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="mindepth"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="top"> + <cd:constant type="cd:number"/> + <cd:constant type="height"/> + </cd:parameter> + <cd:parameter name="bottom"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="stretch"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="shrink"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setupinterlinespace" variant="argument"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="on"/> + <cd:constant type="off"/> + <cd:constant type="reset"/> + <cd:constant type="auto"/> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="cd:number"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setupinterlinespace" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setuplocalinterlinespace"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupinterlinespace"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setuplocalinterlinespace" variant="argument"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="on"/> + <cd:constant type="off"/> + <cd:constant type="reset"/> + <cd:constant type="auto"/> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="cd:number"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setuplocalinterlinespace" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="switchtointerlinespace"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupinterlinespace"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="switchtointerlinespace" variant="argument"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="on"/> + <cd:constant type="off"/> + <cd:constant type="reset"/> + <cd:constant type="auto"/> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="cd:number"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="switchtointerlinespace" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="dosetupcheckedinterlinespace"> + <cd:arguments> + <cd:assignments delimiters="braces" list="yes"> + <cd:inherit name="setupinterlinespace"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="dosetupcheckedinterlinespace" variant="argument"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="on"/> + <cd:constant type="off"/> + <cd:constant type="reset"/> + <cd:constant type="auto"/> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="cd:number"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="dosetupcheckedinterlinespace" variant="name"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="useinterlinespaceparameter"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-interlinespace.xml"> + <cd:command file="spac-ver.mkiv" name="defineinterlinespace"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupinterlinespace"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setupinterlinespace"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="line"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="minheight"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="mindepth"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="top"> + <cd:constant type="cd:number"/> + <cd:constant type="height"/> + </cd:parameter> + <cd:parameter name="bottom"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="stretch"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="shrink"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setupinterlinespace" variant="argument"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="on"/> + <cd:constant type="off"/> + <cd:constant type="reset"/> + <cd:constant type="auto"/> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="cd:number"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setupinterlinespace" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setuplocalinterlinespace"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupinterlinespace"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setuplocalinterlinespace" variant="argument"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="on"/> + <cd:constant type="off"/> + <cd:constant type="reset"/> + <cd:constant type="auto"/> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="cd:number"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setuplocalinterlinespace" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="switchtointerlinespace"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupinterlinespace"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="switchtointerlinespace" variant="argument"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="on"/> + <cd:constant type="off"/> + <cd:constant type="reset"/> + <cd:constant type="auto"/> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="cd:number"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="switchtointerlinespace" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="dosetupcheckedinterlinespace"> + <cd:arguments> + <cd:assignments delimiters="braces" list="yes"> + <cd:inherit name="setupinterlinespace"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="dosetupcheckedinterlinespace" variant="argument"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="on"/> + <cd:constant type="off"/> + <cd:constant type="reset"/> + <cd:constant type="auto"/> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="cd:number"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="dosetupcheckedinterlinespace" variant="name"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="useinterlinespaceparameter"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-italiccorrection.xml"> + <cd:command file="typo-itc.mkvi" name="setitaliccorrection"> + <cd:arguments> + <cd:keywords> + <cd:constant type="reset"/> + <cd:constant type="1"/> + <cd:constant type="2"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-itc.mkvi" name="resetitaliccorrection"/> + <cd:command file="typo-itc.mkvi" name="italiccorrection"/> + <cd:command file="typo-itc.mkvi" name="setupitaliccorrection"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="text"/> + <cd:constant type="always"/> + <cd:constant type="global"/> + <cd:constant type="none"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-itemgroup.xml"> + <cd:command file="strc-itm.mkvi" name="defineitemgroup"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupitemgroup"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-itm.mkvi" name="setupitemgroup"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="each"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="intro"/> + <cd:constant type="random"/> + <cd:constant type="continue"/> + <cd:constant type="packed"/> + <cd:constant type="autointro"/> + <cd:constant type="broad"/> + <cd:constant type="text"/> + <cd:constant type="before"/> + <cd:constant type="after"/> + <cd:constant type="nowhite"/> + <cd:constant type="margin"/> + <cd:constant type="inmargin"/> + <cd:constant type="atmargin"/> + <cd:constant type="intext"/> + <cd:constant type="loose"/> + <cd:constant type="fit"/> + <cd:constant type="nofit"/> + <cd:constant type="paragraph"/> + <cd:constant type="joinedup"/> + <cd:constant type="serried"/> + <cd:constant type="stopper"/> + <cd:constant type="unpacked"/> + <cd:constant type="repeat"/> + <cd:constant type="norepeat"/> + <cd:constant type="reverse"/> + <cd:constant type="columns"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="three"/> + <cd:constant type="four"/> + <cd:constant type="five"/> + <cd:constant type="six"/> + <cd:constant type="seven"/> + <cd:constant type="eight"/> + <cd:constant type="nine"/> + <cd:constant type="standard"/> + <cd:constant method="factor" prefix="cd:number" type="broad"/> + <cd:constant method="factor" prefix="cd:number" type="serried"/> + <cd:constant type="horizontal"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="beforehead"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="afterhead"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="lefttext"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="righttext"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="factor"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="step"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="leftmargin"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightmargin"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="indenting"> + <cd:inherit name="setupindenting"/> + </cd:parameter> + <cd:parameter name="start"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="symalign"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant type="flushleft"/> + <cd:constant type="center"/> + <cd:constant type="flushright"/> + </cd:parameter> + <cd:parameter name="symbol"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="indentnext"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="inner"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:csname"/> + </cd:parameter> + <cd:parameter name="items"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="itemalign"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="middle"/> + <cd:constant type="flushleft"/> + <cd:constant type="flushright"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + </cd:parameter> + <cd:parameter name="alignsymbol"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="textdistance"> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="none"/> + <cd:constant default="yes" type="space"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="placestopper"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="headstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="headcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="marstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="marcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="symstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="symcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:inherit name="setupcounter"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-itm.mkvi" name="setupitemgroup" variant="assignment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + <cd:constant method="range" prefix="cd:name" type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="beforehead"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="afterhead"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="lefttext"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="righttext"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="factor"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="step"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="option"> + <cd:constant type="intro"/> + <cd:constant type="random"/> + <cd:constant type="continue"/> + <cd:constant type="packed"/> + <cd:constant type="autointro"/> + <cd:constant type="broad"/> + <cd:constant type="text"/> + <cd:constant type="before"/> + <cd:constant type="after"/> + <cd:constant type="nowhite"/> + <cd:constant type="margin"/> + <cd:constant type="inmargin"/> + <cd:constant type="atmargin"/> + <cd:constant type="intext"/> + <cd:constant type="loose"/> + <cd:constant type="fit"/> + <cd:constant type="nofit"/> + <cd:constant type="paragraph"/> + <cd:constant type="joinedup"/> + <cd:constant type="serried"/> + <cd:constant type="stopper"/> + <cd:constant type="unpacked"/> + <cd:constant type="repeat"/> + <cd:constant type="norepeat"/> + <cd:constant type="reverse"/> + <cd:constant type="columns"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="three"/> + <cd:constant type="four"/> + <cd:constant type="five"/> + <cd:constant type="six"/> + <cd:constant type="seven"/> + <cd:constant type="eight"/> + <cd:constant type="nine"/> + <cd:constant type="standard"/> + <cd:constant method="factor" prefix="cd:number" type="broad"/> + <cd:constant method="factor" prefix="cd:number" type="serried"/> + <cd:constant type="horizontal"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="leftmargin"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightmargin"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="indenting"> + <cd:inherit name="setupindenting"/> + </cd:parameter> + <cd:parameter name="start"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="symalign"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant type="flushleft"/> + <cd:constant type="center"/> + <cd:constant type="flushright"/> + </cd:parameter> + <cd:parameter name="symbol"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="indentnext"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="inner"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:csname"/> + </cd:parameter> + <cd:parameter name="items"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="itemalign"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="middle"/> + <cd:constant type="flushleft"/> + <cd:constant type="flushright"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + </cd:parameter> + <cd:parameter name="alignsymbol"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="textdistance"> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="none"/> + <cd:constant default="yes" type="space"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="placestopper"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="headstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="headcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="marstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="marcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="symstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="symcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:inherit name="setupcounter"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-itm.mkvi" name="setupitemgroups"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + <cd:constant method="range" prefix="cd:name" type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupitemgroup"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-itm.mkvi" generated="yes" name="setupitemgroup" variant="instance"> + <cd:sequence> + <cd:string value="setup"/> + <cd:instance value="itemgroup"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="each"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="setupitemgroup"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupitemgroup"/> + </cd:assignments> + </cd:arguments> + <cd:instances> + <cd:constant value="itemize"/> + </cd:instances> + </cd:command> + <cd:command file="strc-itm.mkvi" generated="yes" name="itemgroup" type="environment" variant="instance"> + <cd:sequence> + <cd:instance value="itemgroup"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="setupitemgroup"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupitemgroup"/> + </cd:assignments> + </cd:arguments> + <cd:instances> + <cd:constant value="itemize"/> + </cd:instances> + </cd:command> + <cd:command file="strc-itm.mkvi" name="itemgroup" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="setupitemgroup"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupitemgroup"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-itm.mkvi" name="item" scope="itemgroup"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-itm.mkvi" name="noitem" scope="itemgroup"/> + <cd:command file="strc-itm.mkvi" name="itemtag" scope="itemgroup"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-itm.mkvi" name="item" scope="itemgroup" type="environment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-itm.mkvi" name="head" scope="itemgroup" type="environment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-itm.mkvi" name="specialitem" scope="itemgroup" type="environment" variant="item"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant default="yes" type="item"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-itm.mkvi" name="specialitem" scope="itemgroup" type="environment" variant="symbol"> + <cd:arguments> + <cd:keywords> + <cd:constant type="sym"/> + <cd:constant type="ran"/> + <cd:constant type="mar"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-itm.mkvi" name="specialitem" scope="itemgroup" type="environment" variant="none"> + <cd:arguments> + <cd:keywords> + <cd:constant type="sub"/> + <cd:constant type="its"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-items.xml"> + <cd:command file="typo-itm.mkiv" name="defineitems"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupitems"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-itm.mkiv" name="setupitems"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="alternative"> + <cd:constant default="yes" type="left"/> + <cd:constant type="right"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="inmargin"/> + </cd:parameter> + <cd:parameter name="textwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="symbol"> + <cd:constant type="none"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:constant type="left"/> + <cd:constant default="yes" type="middle"/> + <cd:constant type="right"/> + <cd:constant type="flushleft"/> + <cd:constant type="flushright"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + <cd:constant type="margin"/> + </cd:parameter> + <cd:parameter name="textalign"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant default="yes" type="flushleft"/> + <cd:constant type="flushright"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-itm.mkiv" name="items"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupitems"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-javascript.xml"> + <cd:command file="java-ini.mkiv" name="JScode" type="environment"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="none"> + <cd:constant type="uses"/> + </cd:keywords> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="java-ini.mkiv" name="JSpreamble" type="environment"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="none"> + <cd:constant type="used"/> + </cd:keywords> + <cd:keywords delimiters="none"> + <cd:constant type="now"/> + <cd:constant type="later"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="java-ini.mkiv" name="setJSpreamble"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="java-ini.mkiv" name="addtoJSpreamble"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="java-ini.mkiv" name="useJSscripts"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-kerning.xml"> + <cd:command file="typo-krn.mkiv" name="definecharacterkerning"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupcharacterkerning"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-krn.mkiv" name="setupcharacterkerning"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="factor"> + <cd:constant type="max"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="features"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-krn.mkiv" name="setcharacterkerning"> + <cd:arguments> + <cd:keywords> + <cd:constant type="reset"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-krn.mkiv" name="resetcharacterkerning"/> + <cd:command file="typo-krn.mkiv" generated="yes" name="characterkerning" variant="example"> + <cd:sequence> + <cd:variable value="characterkerning"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-krn.mkiv" name="kerncharacters"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-krn.mkiv" name="letterspacing"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-krn.mkiv" name="stretched"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupstretched"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-krn.mkiv" name="setupstretched"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupcharacterkerning"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-label.xml"> + <cd:command file="strc-lab.mkiv" name="definelabel"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplabel"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lab.mkiv" name="setuplabel"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="title"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="number"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="numbercommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="titledistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="titlestyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="titlecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="titlecommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="titleleft"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="titleright"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="symbol"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="starter"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="stopper"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="coupling"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="counter"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="level"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="text"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="headcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="inmargin"/> + <cd:constant type="inleft"/> + <cd:constant type="inright"/> + <cd:constant type="margin"/> + <cd:constant type="leftmargin"/> + <cd:constant type="rightmargin"/> + <cd:constant type="innermargin"/> + <cd:constant type="outermargin"/> + <cd:constant type="serried"/> + <cd:constant type="hanging"/> + <cd:constant type="top"/> + <cd:constant type="command"/> + <cd:constant default="yes" type="intext"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="headalign"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="indenting"> + <cd:inherit name="setupindenting"/> + </cd:parameter> + <cd:parameter name="display"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="indentnext"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="line"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="none"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="hang"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="none"/> + <cd:constant type="margin"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="closesymbol"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="closecommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="expansion"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="xml"/> + </cd:parameter> + <cd:parameter name="referenceprefix"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="sample"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="headstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="headcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:inherit name="setupcounter"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lab.mkiv" generated="yes" name="label" variant="example"> + <cd:sequence> + <cd:variable value="label"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-lab.mkiv" generated="yes" name="currentlabel" variant="example"> + <cd:sequence> + <cd:string value="current"/> + <cd:variable value="label"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-labeltext.xml"> + <cd:command file="lang-lab.mkiv" name="definelabelclass"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-lab.mkiv" generated="yes" name="setuplabeltext" variant="instance"> + <cd:sequence> + <cd:string value="setup"/> + <cd:instance value="label"/> + <cd:string value="text"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="lang-lab.mkiv" generated="yes" name="presetlabeltext" variant="instance"> + <cd:sequence> + <cd:string value="preset"/> + <cd:instance value="label"/> + <cd:string value="text"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="lang-lab.mkiv" generated="yes" name="copylabeltext" variant="instance"> + <cd:sequence> + <cd:string value="copy"/> + <cd:instance value="label"/> + <cd:string value="text"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:key"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="lang-lab.mkiv" generated="yes" name="labeltext" type="environment" variant="instance"> + <cd:sequence> + <cd:instance value="label"/> + <cd:string value="text"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="lang-lab.mkiv" generated="yes" name="labellanguage" variant="instance"> + <cd:sequence> + <cd:instance value="label"/> + <cd:string value="language"/> + </cd:sequence> + <cd:instances/> + </cd:command> + <cd:command file="lang-lab.mkiv" generated="yes" name="labeltext" variant="instance"> + <cd:sequence> + <cd:instance value="label"/> + <cd:string value="text"/> + </cd:sequence> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="lang-lab.mkiv" generated="yes" name="labeltexts" variant="instance"> + <cd:sequence> + <cd:instance value="label"/> + <cd:string value="texts"/> + </cd:sequence> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="lang-lab.mkiv" generated="yes" name="leftlabeltext" variant="instance"> + <cd:sequence> + <cd:string value="left"/> + <cd:instance value="label"/> + <cd:string value="text"/> + </cd:sequence> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="lang-lab.mkiv" generated="yes" name="rightlabeltext" variant="instance"> + <cd:sequence> + <cd:string value="right"/> + <cd:instance value="label"/> + <cd:string value="text"/> + </cd:sequence> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + <cd:instances/> + </cd:command> + </cd:interface> + <cd:interface file="i-language.xml"> + <cd:command file="lang-ini.mkiv" name="installlanguage"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setuplanguage"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="lang-ini.mkiv" name="installlanguage" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:language"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-ini.mkiv" name="setuplanguage"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:language"/> + <cd:constant type="default"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="default"> + <cd:constant type="cd:language"/> + </cd:parameter> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="date"> + <cd:inherit name="currentdate"/> + </cd:parameter> + <cd:parameter name="patterns"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="lefthyphenmin"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="righthyphenmin"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="lefthyphenchar"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="righthyphenchar"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="setups"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="spacing"> + <cd:constant default="yes" type="broad"/> + <cd:constant type="packed"/> + </cd:parameter> + <cd:parameter name="font"> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="text"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="limittext"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="hyphen"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="compoundhyphen"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="leftcompoundhyphen"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="rightcompoundhyphen"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="leftquote"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="rightquote"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="leftquotation"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="rightquotation"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="leftspeech"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="rightspeech"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="leftsentence"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="middlespeech"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="rightsentence"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="midsentence"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="leftsubsentence"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="rightsubsentence"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="factor"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="lang-ini.mkiv" name="doifelselanguage"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-ini.mkiv" name="doiflanguageelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-ini.mkiv" name="doifelsepatterns"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-ini.mkiv" name="doifpatternselse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:language"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-ini.mkiv" generated="yes" name="language" variant="example"> + <cd:sequence> + <cd:variable value="language"/> + </cd:sequence> + </cd:command> + <cd:command file="lang-ini.mkiv" name="language"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:language"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-ini.mkiv" name="mainlanguage"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:language"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-ini.mkiv" name="uselanguageparameter"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="lang-ini.mkiv" name="exceptions" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:language"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-ini.mkiv" name="currentlanguage"/> + <cd:command file="lang-ini.mkiv" name="currentmainlanguage"/> + <cd:command file="lang-lab.mkiv" name="commalistsentence"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-layer.xml"> + <cd:command file="pack-box.mkiv" name="setuplayeredtext"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="layeredtext"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayer"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayeredtext"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="placelayeredtext"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayer"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayeredtext"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="setlayerframed"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayer"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="setlayerframed" variant="combination"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayer"/> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="setlayertext"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayer"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-lyr.mkiv" name="definelayer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayer"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-lyr.mkiv" name="setuplayer"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + <cd:constant type="continue"/> + <cd:constant type="next"/> + <cd:constant type="repeat"/> + </cd:parameter> + <cd:parameter name="option"> + <cd:constant type="test"/> + </cd:parameter> + <cd:parameter name="page"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="region"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="rotation"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="position"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="overlay"/> + </cd:parameter> + <cd:parameter name="hoffset"> + <cd:constant type="max"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="voffset"> + <cd:constant type="max"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="dx"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="dy"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="sx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="sy"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="x"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="y"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="corner"> + <cd:constant default="yes" type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant default="yes" type="top"/> + <cd:constant type="bottom"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="grid"/> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="line"/> + <cd:constant type="l"/> + <cd:constant type="c"/> + <cd:constant type="r"/> + <cd:constant type="m"/> + <cd:constant type="t"/> + <cd:constant type="b"/> + <cd:constant type="g"/> + </cd:parameter> + <cd:parameter name="line"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="column"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="direction"> + <cd:constant default="yes" type="normal"/> + <cd:constant type="reverse"/> + </cd:parameter> + <cd:parameter name="doublesided"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="fit"/> + <cd:constant default="yes" type="overlay"/> + </cd:parameter> + <cd:parameter name="repeat"> + <cd:constant type="yes"/> + </cd:parameter> + <cd:parameter name="preset"> + <cd:constant type="lefttop"/> + <cd:constant type="righttop"/> + <cd:constant type="leftbottom"/> + <cd:constant type="rightbottom"/> + <cd:constant type="middle"/> + <cd:constant type="middletop"/> + <cd:constant type="middlebottom"/> + <cd:constant type="middleleft"/> + <cd:constant type="middleright"/> + <cd:constant type="lefttopleft"/> + <cd:constant type="lefttopright"/> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-lyr.mkiv" name="resetlayer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-lyr.mkiv" name="flushlayer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-lyr.mkiv" name="tightlayer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-lyr.mkiv" name="placelayer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-lyr.mkiv" name="composedlayer"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-lyr.mkiv" name="setlayer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="even"/> + <cd:constant type="odd"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayer"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-lyr.mkiv" name="definelayerpreset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setuplayer"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-lyr.mkiv" name="definelayerpreset" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-lyr.mkiv" name="doifelselayerdata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-lyr.mkiv" name="doiflayerdataelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-lyr.mkiv" name="layerwidth"/> + <cd:command file="pack-lyr.mkiv" name="layerheight"/> + <cd:command file="pack-lyr.mkiv" name="setMPlayer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayer"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-lyr.mkiv" name="getMPlayer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-layout.xml"> + <cd:command file="page-lay.mkiv" name="definelayout"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayout"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="setuplayout"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + <cd:constant type="normal"/> + <cd:constant type="repeat"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="edge"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="margindistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="edgedistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="leftedgedistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightedgedistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="leftmargindistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightmargindistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="topdistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="headerdistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="footerdistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bottomdistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="preset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="leftmargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightmargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="leftedge"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightedge"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="header"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="footer"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="top"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bottom"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="backspace"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="topspace"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="setups"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="cutspace"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + <cd:constant type="middle"/> + <cd:constant type="fit"/> + </cd:parameter> + <cd:parameter name="bottomspace"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="lines"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + <cd:constant type="middle"/> + <cd:constant type="fit"/> + </cd:parameter> + <cd:parameter name="horoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="veroffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="columns"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="columndistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="default"/> + <cd:constant default="name" type="normal"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="singlesided"/> + <cd:constant type="doublesided"/> + </cd:parameter> + <cd:parameter name="textwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="textheight"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="nx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="ny"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="dx"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="dy"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="scale"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="sx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="sy"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="marking"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + <cd:constant type="page"/> + <cd:constant type="empty"/> + <cd:constant type="color"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="four"/> + </cd:parameter> + <cd:parameter name="grid"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="off"/> + </cd:parameter> + <cd:parameter name="textdistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant default="yes" type="normal"/> + <cd:constant type="makeup"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="clipoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="cropoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="trimoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bleedoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="artoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="setuplayout" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="reset"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="doifelselayoutdefined"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="doiflayoutdefinedelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="adaptlayout"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="height"> + <cd:constant type="max"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="lines"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="layout" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="doifelseoddpage"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="doifoddpageelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="doifbothsidesoverruled"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="doifbothsides"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="rightorleftpageaction"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-run.mkiv" name="showprint"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="setuppapersize"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="setuppapersize"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayout"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-run.mkiv" name="showframe"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="top"/> + <cd:constant type="header"/> + <cd:constant type="text"/> + <cd:constant type="footer"/> + <cd:constant type="bottom"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="leftedge"/> + <cd:constant type="leftmargin"/> + <cd:constant type="text"/> + <cd:constant type="rightmargin"/> + <cd:constant type="rightedge"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-run.mkiv" name="showsetups"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant default="yes" type="pt"/> + <cd:constant type="bp"/> + <cd:constant default="yes" type="cm"/> + <cd:constant type="mm"/> + <cd:constant type="dd"/> + <cd:constant type="cc"/> + <cd:constant type="pc"/> + <cd:constant type="nd"/> + <cd:constant type="nc"/> + <cd:constant type="sp"/> + <cd:constant type="in"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-run.mkiv" name="showlayout"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant default="yes" type="pt"/> + <cd:constant type="bp"/> + <cd:constant default="yes" type="cm"/> + <cd:constant type="mm"/> + <cd:constant type="dd"/> + <cd:constant type="cc"/> + <cd:constant type="pc"/> + <cd:constant type="nd"/> + <cd:constant type="nc"/> + <cd:constant type="sp"/> + <cd:constant type="in"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-run.mkiv" name="showmargins"/> + <cd:command file="page-spr.mkiv" name="spread" type="environment"/> + </cd:interface> + <cd:interface file="i-linenumber.xml"> + <cd:command file="page-lin.mkvi" name="definelinenumbering"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplinenumbering"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-lin.mkvi" name="setuplinenumbering"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="start"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="step"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="page"/> + <cd:constant default="yes" type="first"/> + <cd:constant type="next"/> + </cd:parameter> + <cd:parameter name="conversion"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="continue"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="text"/> + <cd:constant type="begin"/> + <cd:constant type="end"/> + <cd:constant default="yes" type="default"/> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + <cd:constant type="inleft"/> + <cd:constant type="inright"/> + <cd:constant type="margin"/> + <cd:constant type="inmargin"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + <cd:constant type="flushleft"/> + <cd:constant type="flushright"/> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="middle"/> + <cd:constant default="yes" type="auto"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="margin"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-lin.mkvi" name="linenumbering" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="continue"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="start"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="step"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="page"/> + <cd:constant default="yes" type="first"/> + <cd:constant type="next"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-lin.mkvi" name="linenumbering" type="environment" variant="argument"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="continue"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lin.mkvi" name="someline"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lin.mkvi" name="startline"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lin.mkvi" name="stopline"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lin.mkvi" name="doifelsesamelinereference"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lin.mkvi" name="doifsamelinereferenceelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lin.mkvi" name="inline"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lin.mkvi" name="inlinerange"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-lines.xml"> + <cd:command file="supp-box.mkiv" name="noflines"/> + <cd:command file="supp-box.mkiv" name="getnoflines"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="getroundednoflines"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="getrawnoflines"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="determinenoflines"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-lin.mkiv" name="definelines"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplines"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-lin.mkiv" name="setuplines"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="option"> + <cd:constant type="packed"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="indenting"> + <cd:inherit name="setupindenting"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="space"> + <cd:constant type="yes"/> + <cd:constant type="on"/> + <cd:constant type="off"/> + <cd:constant type="fixed"/> + <cd:constant default="yes" type="default"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-lin.mkiv" generated="yes" name="lines" type="environment" variant="instance"> + <cd:sequence> + <cd:instance value="lines"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplines"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="spac-lin.mkiv" name="emptylines"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-linetable.xml"> + <cd:command file="tabl-ltb.mkiv" name="setuplinetable"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="r"/> + <cd:constant type="c"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="odd"/> + <cd:constant type="even"/> + <cd:constant type="header"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="lines"> + <cd:constant type="fit"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="stretch"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="fit"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="nleft"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="repeat"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="nx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant default="yes" type="fit"/> + <cd:constant type="line"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="leftoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="background"> + <cd:constant type="color"/> + </cd:parameter> + <cd:parameter name="backgroundcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="xheight"> + <cd:constant type="max"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="xdepth"> + <cd:constant type="max"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-ltb.mkiv" name="linetablecell" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplinetable"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-ltb.mkiv" name="linetable" type="environment"/> + <cd:command file="tabl-ltb.mkiv" name="linetablehead" type="environment"/> + <cd:command file="tabl-ltb.mkiv" name="linetablebody" type="environment"/> + <cd:command file="tabl-ltb.mkiv" name="processlinetablebuffer"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-ltb.mkiv" name="processlinetablefile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-linewidth.xml"> + <cd:command file="pack-rul.mkiv" name="setuplinewidth"> + <cd:arguments> + <cd:keywords> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="linewidth"/> + </cd:interface> + <cd:interface file="i-list.xml"> + <cd:command file="strc-lst.mkvi" name="definelist"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="setuplist"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="none"/> + <cd:constant type="here"/> + </cd:parameter> + <cd:parameter name="type"> + <cd:constant type="simple"/> + <cd:constant type="command"/> + <cd:constant type="userdata"/> + </cd:parameter> + <cd:parameter name="criterium"> + <cd:constant default="yes" type="local"/> + <cd:constant type="intro"/> + <cd:constant type="reference"/> + <cd:constant method="range" prefix="cd:sectionblock" type="reference"/> + <cd:constant type="all"/> + <cd:constant method="range" prefix="cd:sectionblock" type="all"/> + <cd:constant type="text"/> + <cd:constant method="range" prefix="cd:sectionblock" type="text"/> + <cd:constant type="current"/> + <cd:constant method="range" prefix="cd:sectionblock" type="current"/> + <cd:constant type="here"/> + <cd:constant type="previous"/> + <cd:constant method="range" prefix="cd:sectionblock" type="previous"/> + <cd:constant type="component"/> + <cd:constant type="cd:section"/> + <cd:constant method="range" prefix="cd:sectionblock" type="cd:section"/> + </cd:parameter> + <cd:parameter name="list"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="auto"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="fit"/> + <cd:constant default="yes" type="broad"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="fit"/> + <cd:constant default="yes" type="broad"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="symbol"> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="three"/> + <cd:constant type="none"/> + <cd:constant default="yes" type="default"/> + </cd:parameter> + <cd:parameter name="label"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="none"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="starter"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="stopper"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:threearguments"/> + </cd:parameter> + <cd:parameter name="numbercommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="textcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="pagecommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="pagenumber"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + <cd:constant type="always"/> + </cd:parameter> + <cd:parameter name="headnumber"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + <cd:constant type="always"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="none"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="none"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="aligntitle"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="numberalign"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="middle"/> + <cd:constant type="flushleft"/> + <cd:constant type="flushright"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="hang"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="interaction"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant default="yes" type="all"/> + <cd:constant type="number"/> + <cd:constant type="text"/> + <cd:constant type="title"/> + <cd:constant type="page"/> + <cd:constant type="sectionnumber"/> + <cd:constant type="pagenumber"/> + </cd:parameter> + <cd:parameter name="limittext"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="numberstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="numbercolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="textstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="textcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="pagestyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="pagecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="extras"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="order"> + <cd:constant type="command"/> + <cd:constant type="all"/> + <cd:constant type="title"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="a"/> + <cd:constant default="yes" type="b"/> + <cd:constant type="c"/> + <cd:constant type="d"/> + <cd:constant type="e"/> + <cd:constant type="f"/> + <cd:constant type="g"/> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="command"/> + <cd:constant type="none"/> + <cd:constant type="interactive"/> + <cd:constant type="paragraph"/> + <cd:constant type="horizontal"/> + <cd:constant type="vertical"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="pageprefix"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="pageprefixseparatorset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="pageprefixconversionset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="pageprefixset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="pageprefixsegments"> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="*"/> + <cd:constant method="range" prefix="cd:number" type="all"/> + <cd:constant type="cd:section"/> + <cd:constant method="range" prefix="cd:section" type="cd:section"/> + <cd:constant method="range" prefix="cd:section" type="*"/> + <cd:constant method="range" prefix="cd:section" type="all"/> + </cd:parameter> + <cd:parameter name="pageprefixconnector"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="pageconversionset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="pagestarter"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="pagestopper"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupcounter"/> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="doifelselist"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="doiflistelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="writebetweenlist"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="writedatatolist"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="writetolist"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="placelist"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="placerawlist"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="completelist"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="definecombinedlist"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="setupcombinedlist"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="placecombinedlist"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" generated="yes" name="setupcombinedlist" variant="instance"> + <cd:sequence> + <cd:string value="setup"/> + <cd:instance value="combinedlist"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-lst.mkvi" generated="yes" name="placecombinedlist" variant="instance"> + <cd:sequence> + <cd:string value="place"/> + <cd:instance value="combinedlist"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-lst.mkvi" generated="yes" name="completecombinedlist" variant="instance"> + <cd:sequence> + <cd:string value="complete"/> + <cd:instance value="combinedlist"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-lst.mkvi" name="structurelistuservariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="rawstructurelistuservariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="doifelsestructurelisthaspage"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="doifstructurelisthaspageelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="doifelsestructurelisthasnumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="doifstructurelisthasnumberelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="definelistextra"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplistextra"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="setuplistextra"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="definelistalternative"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplistalternative"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="setuplistalternative"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:threearguments"/> + </cd:parameter> + <cd:parameter name="renderingsetup"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="stretch"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="filler"> + <cd:constant type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="determinelistcharacteristics"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:list"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="currentlistentrynumber"/> + <cd:command file="strc-lst.mkvi" name="currentlistentrytitle"/> + <cd:command file="strc-lst.mkvi" name="currentlistentrytitlerendered"/> + <cd:command file="strc-lst.mkvi" name="currentlistentrypagenumber"/> + <cd:command file="strc-lst.mkvi" name="currentlistsymbol"/> + <cd:command file="strc-lst.mkvi" name="listlength"/> + <cd:command file="strc-lst.mkvi" name="currentlistentrywrapper" type="environment"/> + <cd:command file="strc-lst.mkvi" name="currentlistentryreferenceattribute"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="number"/> + <cd:constant type="text"/> + <cd:constant type="pagenumber"/> + <cd:constant type="all"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-lst.mkvi" name="currentlistentrydestinationattribute"/> + <cd:command file="strc-lst.mkvi" name="currentlistentrylimitedtext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-logo.xml"> + <cd:command file="cont-log.mkiv" name="TeX"/> + <cd:command file="cont-log.mkiv" name="ConTeXt"/> + <cd:command file="cont-log.mkiv" name="PPCHTeX"/> + <cd:command file="cont-log.mkiv" name="PRAGMA"/> + <cd:command file="cont-log.mkiv" name="LaTeX"/> + <cd:command file="cont-log.mkiv" name="TaBlE"/> + <cd:command file="cont-log.mkiv" name="PiCTeX"/> + <cd:command file="cont-log.mkiv" name="AmSTeX"/> + <cd:command file="cont-log.mkiv" name="LamSTeX"/> + <cd:command file="cont-log.mkiv" name="Context"/> + <cd:command file="cont-log.mkiv" name="MetaFont"/> + <cd:command file="cont-log.mkiv" name="MetaPost"/> + <cd:command file="cont-log.mkiv" name="MetaFun"/> + <cd:command file="cont-log.mkiv" name="eTeX"/> + <cd:command file="cont-log.mkiv" name="pdfTeX"/> + <cd:command file="cont-log.mkiv" name="pdfeTeX"/> + <cd:command file="cont-log.mkiv" name="Lua"/> + <cd:command file="cont-log.mkiv" name="luaTeX"/> + <cd:command file="cont-log.mkiv" name="luajitTeX"/> + <cd:command file="cont-log.mkiv" name="metaTeX"/> + <cd:command file="cont-log.mkiv" name="XeTeX"/> + <cd:command file="cont-log.mkiv" name="LuaTeX"/> + <cd:command file="cont-log.mkiv" name="LuajitTeX"/> + <cd:command file="cont-log.mkiv" name="MKII"/> + <cd:command file="cont-log.mkiv" name="MKIV"/> + <cd:command file="cont-log.mkiv" name="MKVI"/> + <cd:command file="cont-log.mkiv" name="MKIX"/> + <cd:command file="cont-log.mkiv" name="MKXI"/> + <cd:command file="cont-log.mkiv" name="MPII"/> + <cd:command file="cont-log.mkiv" name="MPIV"/> + <cd:command file="cont-log.mkiv" name="MPVI"/> + <cd:command file="cont-log.mkiv" name="METAFONT"/> + <cd:command file="cont-log.mkiv" name="METAPOST"/> + <cd:command file="cont-log.mkiv" name="PPCHTEX"/> + <cd:command file="cont-log.mkiv" name="CONTEXT"/> + <cd:command file="cont-log.mkiv" name="METAFUN"/> + <cd:command file="cont-log.mkiv" name="TEX"/> + <cd:command file="cont-log.mkiv" name="LATEX"/> + <cd:command file="cont-log.mkiv" name="PICTEX"/> + <cd:command file="cont-log.mkiv" name="TABLE"/> + <cd:command file="cont-log.mkiv" name="AMSTEX"/> + <cd:command file="cont-log.mkiv" name="LAMSTEX"/> + <cd:command file="cont-log.mkiv" name="INRSTEX"/> + <cd:command file="cont-log.mkiv" name="ETEX"/> + <cd:command file="cont-log.mkiv" name="PDFTEX"/> + <cd:command file="cont-log.mkiv" name="PDFETEX"/> + <cd:command file="cont-log.mkiv" name="LUATEX"/> + <cd:command file="cont-log.mkiv" name="LUAJITTEX"/> + <cd:command file="cont-log.mkiv" name="XETEX"/> + </cd:interface> + <cd:interface file="i-lohi.xml"> + <cd:command file="typo-scr.mkiv" name="definelow"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplow"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-scr.mkiv" name="setuplow"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="down"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-scr.mkiv" generated="yes" name="low" variant="instance"> + <cd:sequence> + <cd:instance value="low"/> + </cd:sequence> + <cd:arguments> + <cd:content/> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="typo-scr.mkiv" name="low"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-scr.mkiv" name="definehigh"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuphigh"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-scr.mkiv" name="setuphigh"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="up"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-scr.mkiv" generated="yes" name="high" variant="instance"> + <cd:sequence> + <cd:instance value="high"/> + </cd:sequence> + <cd:arguments> + <cd:content/> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="typo-scr.mkiv" name="high"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-scr.mkiv" name="definelowhigh"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplowhigh"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-scr.mkiv" name="setuplowhigh"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="up"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="down"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-scr.mkiv" generated="yes" name="lowhigh" variant="instance"> + <cd:sequence> + <cd:instance value="lowhigh"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="left"/> + <cd:constant default="yes" type="right"/> + </cd:keywords> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-scr.mkiv" name="lohi"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="left"/> + <cd:constant default="yes" type="right"/> + </cd:keywords> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-scr.mkiv" name="hilo"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="left"/> + <cd:constant default="yes" type="right"/> + </cd:keywords> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-scr.mkiv" name="definelowmidhigh"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplowmidhigh"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-scr.mkiv" name="setuplowmidhigh"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="up"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="down"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-scr.mkiv" generated="yes" name="lowmidhigh" variant="instance"> + <cd:sequence> + <cd:instance value="lowmidhigh"/> + </cd:sequence> + <cd:arguments> + <cd:content/> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-scr.mkiv" name="lomihi"> + <cd:arguments> + <cd:content/> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="typo-scr.mkiv" name="himilo"> + <cd:arguments> + <cd:content/> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-lua.xml"> + <cd:command file="back-exp.mkiv" name="taggedctxcommand"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="cldf-ini.mkiv" name="luafunction"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="cldf-ini.mkiv" name="cldprocessfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="cldf-ini.mkiv" name="cldloadfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="cldf-ini.mkiv" name="cldcontext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="cldf-ini.mkiv" name="cldcommand"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-cod.mkiv" name="ctxdirectlua"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-cod.mkiv" name="ctxlatelua"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-cod.mkiv" name="ctxsprint"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-cod.mkiv" name="ctxcommand"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-cod.mkiv" name="ctxdirectcommand"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-cod.mkiv" name="ctxlatecommand"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-cod.mkiv" name="ctxreport"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-cod.mkiv" name="ctxlua"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-cod.mkiv" name="luacode"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-cod.mkiv" name="lateluacode"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-cod.mkiv" name="directluacode"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-cod.mkiv" name="luaversion"/> + <cd:command file="luat-cod.mkiv" name="registerctxluafile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-cod.mkiv" name="ctxloadluafile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="lua" type="environment"/> + <cd:command file="luat-ini.mkiv" name="luacode" type="environment"/> + <cd:command file="luat-ini.mkiv" name="luamajorversion"/> + <cd:command file="luat-ini.mkiv" name="luaminorversion"/> + <cd:command file="luat-ini.mkiv" name="luaexpanded"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="luaparameterset" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="luaparameterset"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="luaconditional"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="ctxluacode"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="ctxfunctiondefinition" type="environment"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" generated="yes" name="ctxfunctiondefinition" variant="example"> + <cd:sequence> + <cd:variable value="ctxfunctiondefinition"/> + </cd:sequence> + </cd:command> + <cd:command file="luat-ini.mkiv" name="ctxfunction" type="environment"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="ctxfunction"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" generated="yes" name="ctxfunction" variant="example"> + <cd:sequence> + <cd:variable value="ctxfunction"/> + </cd:sequence> + </cd:command> + </cd:interface> + <cd:interface file="i-makeup.xml"> + <cd:command file="page-mak.mkvi" name="definemakeup"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmakeup"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-mak.mkvi" name="setupmakeup"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="page"> + <cd:inherit name="page"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="setups"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="top"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="bottom"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="top"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="pagestate"> + <cd:constant type="start"/> + <cd:constant default="yes" type="stop"/> + </cd:parameter> + <cd:parameter name="headerstate"> + <cd:constant type="start"/> + <cd:constant default="yes" type="stop"/> + <cd:constant type="high"/> + <cd:constant type="empty"/> + <cd:constant type="none"/> + <cd:constant type="normal"/> + </cd:parameter> + <cd:parameter name="footerstate"> + <cd:constant type="start"/> + <cd:constant default="yes" type="stop"/> + <cd:constant type="high"/> + <cd:constant type="empty"/> + <cd:constant type="none"/> + <cd:constant type="normal"/> + </cd:parameter> + <cd:parameter name="topstate"> + <cd:constant type="start"/> + <cd:constant type="stop"/> + <cd:constant type="high"/> + <cd:constant type="empty"/> + <cd:constant type="none"/> + <cd:constant default="yes" type="normal"/> + </cd:parameter> + <cd:parameter name="bottomstate"> + <cd:constant type="start"/> + <cd:constant type="stop"/> + <cd:constant type="high"/> + <cd:constant type="empty"/> + <cd:constant type="none"/> + <cd:constant default="yes" type="normal"/> + </cd:parameter> + <cd:parameter name="textstate"> + <cd:constant type="start"/> + <cd:constant type="stop"/> + <cd:constant type="high"/> + <cd:constant type="empty"/> + <cd:constant type="none"/> + <cd:constant default="yes" type="normal"/> + </cd:parameter> + <cd:parameter name="doublesided"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant default="yes" type="empty"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:inherit name="value-style"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-mak.mkvi" name="makeup" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmakeup"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-mak.mkvi" generated="yes" name="makeup" type="environment" variant="instance"> + <cd:sequence> + <cd:instance value="makeup"/> + <cd:string value="makeup"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmakeup"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + </cd:interface> + <cd:interface file="i-marginblock.xml"> + <cd:command file="page-mbk.mkvi" name="definemarginblock"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmarginblock"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-mbk.mkvi" name="setupmarginblock"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="top"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="bottom"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="middle"/> + <cd:constant default="yes" type="inmargin"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-mbk.mkvi" name="marginblock" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-margindata.xml"> + <cd:command file="typo-mar.mkiv" name="definemargindata"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-mar.mkiv" name="setupmargindata"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="strut"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + <cd:constant type="cap"/> + <cd:constant type="fit"/> + <cd:constant type="line"/> + <cd:constant type="default"/> + <cd:constant type="cd:character"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="anchor"> + <cd:constant type="region"/> + <cd:constant default="yes" type="text"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant default="yes" type="left"/> + <cd:constant type="right"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="top"/> + <cd:constant type="line"/> + <cd:constant type="first"/> + <cd:constant type="depth"/> + <cd:constant type="height"/> + </cd:parameter> + <cd:parameter name="category"> + <cd:constant type="default"/> + <cd:constant type="edge"/> + </cd:parameter> + <cd:parameter name="scope"> + <cd:constant type="local"/> + <cd:constant type="global"/> + </cd:parameter> + <cd:parameter name="option"> + <cd:constant type="text"/> + <cd:constant type="paragraph"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="local"/> + <cd:constant default="yes" type="normal"/> + <cd:constant type="margin"/> + <cd:constant type="edge"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="hoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="voffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="dy"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bottomspace"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="threshold"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="line"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="stack"> + <cd:constant type="yes"/> + <cd:constant type="continue"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-mar.mkiv" name="setupmarginframed"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-mar.mkiv" generated="yes" name="margindata" variant="instance"> + <cd:sequence> + <cd:instance value="margindata"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmarginframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="typo-mar.mkiv" name="margindata"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmarginframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-marker.xml"> + <cd:command file="attr-mkr.mkiv" name="definemarker"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="attr-mkr.mkiv" name="setmarker"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="attr-mkr.mkiv" name="resetmarker"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="attr-mkr.mkiv" name="boxmarker"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-marking.xml"> + <cd:command file="strc-mar.mkiv" name="definemarking"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:mark"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmarking"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="setupmarking"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:mark"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="expansion"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="separator"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="filtercommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="relatemarking"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:mark"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:mark"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="setmarking"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:mark"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="resetmarking"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:mark"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="synchronizemarking"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:mark"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="keep"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="doifelsemarking"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:mark"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="doifmarkingelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:mark"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="getmarking"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:mark"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant default="yes" type="page"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="current"/> + <cd:constant type="previous"/> + <cd:constant type="next"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="default"/> + <cd:constant type="both"/> + <cd:constant type="all"/> + <cd:constant method="range" prefix="first" type="nocheck"/> + <cd:constant method="range" prefix="last" type="nocheck"/> + <cd:constant method="range" prefix="previous" type="nocheck"/> + <cd:constant method="range" prefix="next" type="nocheck"/> + <cd:constant method="range" prefix="top" type="nocheck"/> + <cd:constant method="range" prefix="bottom" type="nocheck"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="fetchonemark"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:mark"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="current"/> + <cd:constant type="previous"/> + <cd:constant type="next"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="default"/> + <cd:constant type="both"/> + <cd:constant type="all"/> + <cd:constant method="range" prefix="first" type="nocheck"/> + <cd:constant method="range" prefix="last" type="nocheck"/> + <cd:constant method="range" prefix="previous" type="nocheck"/> + <cd:constant method="range" prefix="next" type="nocheck"/> + <cd:constant method="range" prefix="top" type="nocheck"/> + <cd:constant method="range" prefix="bottom" type="nocheck"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="fetchtwomarks"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:mark"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="fetchallmarks"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:mark"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="fetchmark"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:mark"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="current"/> + <cd:constant type="previous"/> + <cd:constant type="next"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="default"/> + <cd:constant type="both"/> + <cd:constant type="all"/> + <cd:constant method="range" prefix="first" type="nocheck"/> + <cd:constant method="range" prefix="last" type="nocheck"/> + <cd:constant method="range" prefix="previous" type="nocheck"/> + <cd:constant method="range" prefix="next" type="nocheck"/> + <cd:constant method="range" prefix="top" type="nocheck"/> + <cd:constant method="range" prefix="bottom" type="nocheck"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="fetchmarking"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:mark"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="page"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="current"/> + <cd:constant type="previous"/> + <cd:constant type="next"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="default"/> + <cd:constant type="both"/> + <cd:constant type="all"/> + <cd:constant method="range" prefix="first" type="nocheck"/> + <cd:constant method="range" prefix="last" type="nocheck"/> + <cd:constant method="range" prefix="previous" type="nocheck"/> + <cd:constant method="range" prefix="next" type="nocheck"/> + <cd:constant method="range" prefix="top" type="nocheck"/> + <cd:constant method="range" prefix="bottom" type="nocheck"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="fetchonemarking"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:mark"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="page"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="current"/> + <cd:constant type="previous"/> + <cd:constant type="next"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="default"/> + <cd:constant type="both"/> + <cd:constant type="all"/> + <cd:constant method="range" prefix="first" type="nocheck"/> + <cd:constant method="range" prefix="last" type="nocheck"/> + <cd:constant method="range" prefix="previous" type="nocheck"/> + <cd:constant method="range" prefix="next" type="nocheck"/> + <cd:constant method="range" prefix="top" type="nocheck"/> + <cd:constant method="range" prefix="bottom" type="nocheck"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="fetchtwomarkings"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:mark"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="page"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-mar.mkiv" name="fetchallmarkings"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:mark"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="page"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-math.xml"> + <cd:command category="mathematics" file="math-ini.mkiv" name="definemathematics"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathematics"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command category="mathematics" file="math-ini.mkiv" name="setupmathematics"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="openup"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="symbolset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="functionstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="compact"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:constant default="yes" type="l2r"/> + <cd:constant type="r2l"/> + </cd:parameter> + <cd:parameter name="bidi"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="sygreek"> + <cd:constant type="normal"/> + <cd:constant default="yes" type="italic"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="lcgreek"> + <cd:constant type="normal"/> + <cd:constant default="yes" type="italic"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="ucgreek"> + <cd:constant default="yes" type="normal"/> + <cd:constant type="italic"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="italics"> + <cd:constant type="1"/> + <cd:constant type="2"/> + <cd:constant default="yes" type="3"/> + <cd:constant type="4"/> + <cd:constant type="none"/> + <cd:constant type="reset"/> + </cd:parameter> + <cd:parameter name="autopunctuation"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="all"/> + </cd:parameter> + <cd:parameter name="setups"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="domain"> + <cd:constant type="cd:name"/> + <cd:constant type="reset"/> + </cd:parameter> + <cd:parameter name="textstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="textcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="functioncolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="integral"> + <cd:constant type="limits"/> + <cd:constant type="nolimits"/> + <cd:constant default="yes" type="autolimits"/> + <cd:constant type="displaylimits"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="stylealternative"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="default"> + <cd:constant type="normal"/> + <cd:constant default="yes" type="italic"/> + </cd:parameter> + <cd:parameter name="fraction"> + <cd:constant type="ams"/> + <cd:constant default="yes" type="ctx"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command category="mathematics" file="math-ini.mkiv" name="inlineordisplaymath"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command category="mathematics" file="math-ini.mkiv" name="mathematics"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command category="mathematics" file="math-ini.mkiv" name="math"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command category="mathematics" file="math-ini.mkiv" name="m"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command category="mathematics" file="math-ini.mkiv" name="definemathcommand"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="ord"/> + <cd:constant type="op"/> + <cd:constant type="bin"/> + <cd:constant type="rel"/> + <cd:constant type="open"/> + <cd:constant type="close"/> + <cd:constant type="punct"/> + <cd:constant type="alpha"/> + <cd:constant type="inner"/> + <cd:constant default="yes" type="nothing"/> + <cd:constant type="limop"/> + <cd:constant type="nolop"/> + <cd:constant type="box"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="one"/> + <cd:constant type="two"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:command"/> + <cd:constant type="cd:oneargument"/> + <cd:constant type="cd:twoarguments"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" generated="yes" name="mathcommand" variant="example"> + <cd:sequence> + <cd:variable value="mathcommand"/> + </cd:sequence> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathcommand"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathop"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mtext"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command category="mathematics" file="math-ini.mkiv" name="mathfunction"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command category="mathematics" file="math-ini.mkiv" name="mfunction"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mfunctionlabeltext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="stackrel"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="apply"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="definemathstyle"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="display"/> + <cd:constant type="text"/> + <cd:constant type="script"/> + <cd:constant type="scriptscript"/> + <cd:constant type="cramped"/> + <cd:constant type="uncramped"/> + <cd:constant type="normal"/> + <cd:constant type="packed"/> + <cd:constant type="small"/> + <cd:constant type="big"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="setupmathstyle"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="display"/> + <cd:constant type="text"/> + <cd:constant type="script"/> + <cd:constant type="scriptscript"/> + <cd:constant type="cramped"/> + <cd:constant type="uncramped"/> + <cd:constant type="normal"/> + <cd:constant type="packed"/> + <cd:constant type="small"/> + <cd:constant type="big"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="setmathstyle"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="display"/> + <cd:constant type="text"/> + <cd:constant type="script"/> + <cd:constant type="scriptscript"/> + <cd:constant type="cramped"/> + <cd:constant type="uncramped"/> + <cd:constant type="normal"/> + <cd:constant type="packed"/> + <cd:constant type="small"/> + <cd:constant type="big"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathstyle" type="environment"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="display"/> + <cd:constant type="text"/> + <cd:constant type="script"/> + <cd:constant type="scriptscript"/> + <cd:constant type="cramped"/> + <cd:constant type="uncramped"/> + <cd:constant type="normal"/> + <cd:constant type="packed"/> + <cd:constant type="small"/> + <cd:constant type="big"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command begin="push" end="pop" file="math-ini.mkiv" name="mathstyle" type="environment"/> + <cd:command file="math-ini.mkiv" name="usemathstyleparameter"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="usemathstyleparameter" type="environment"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathtext"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathtexttf"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathtextit"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathtextsl"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathtextbf"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathtextbi"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathtextbs"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathword"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathwordtf"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathwordit"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathwordsl"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathwordbf"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathwordbi"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathwordbs"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ini.mkiv" name="mathrm"/> + <cd:command file="math-ini.mkiv" name="mathss"/> + <cd:command file="math-ini.mkiv" name="mathtt"/> + <cd:command file="math-ini.mkiv" name="mathtf"/> + <cd:command file="math-ini.mkiv" name="mathsl"/> + <cd:command file="math-ini.mkiv" name="mathit"/> + <cd:command file="math-ini.mkiv" name="mathbf"/> + <cd:command file="math-ini.mkiv" name="mathbi"/> + <cd:command file="math-ini.mkiv" name="mathbs"/> + <cd:command file="math-ini.mkiv" name="mathitalic"/> + <cd:command file="math-ini.mkiv" name="mathupright"/> + <cd:command file="math-ini.mkiv" name="mathdefault"/> + <cd:command file="math-ini.mkiv" name="mathscript"/> + <cd:command file="math-ini.mkiv" name="mathfraktur"/> + <cd:command file="math-ini.mkiv" name="mathblackboard"/> + <cd:command file="supp-mat.mkiv" name="displaymath"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-mat.mkiv" name="inlinemath"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-mat.mkiv" name="textmath"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-mat.mkiv" name="imath" type="environment"/> + <cd:command file="supp-mat.mkiv" name="dmath" type="environment"/> + <cd:command file="supp-mat.mkiv" name="mathmode" type="environment"/> + <cd:command file="supp-mat.mkiv" name="nonmathematics"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-mat.mkiv" name="displaymathematics"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-mat.mkiv" name="inlinemathematics"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-mat.mkiv" name="automathematics"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-mat.mkiv" name="cramped"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-mat.mkiv" name="crampedllap"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-mat.mkiv" name="crampedrlap"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-mat.mkiv" name="crampedclap"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-mathalignment.xml"> + <cd:command file="math-ali.mkiv" name="definemathalignment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathalignment"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-ali.mkiv" name="setupmathalignment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="m"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant default="yes" type="normal"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-ali.mkiv" generated="yes" name="mathalignment" type="environment" variant="instance"> + <cd:sequence> + <cd:instance value="mathalignment"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathalignment"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + </cd:interface> + <cd:interface file="i-mathcases.xml"> + <cd:command file="math-ali.mkiv" name="definemathcases"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathcases"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-ali.mkiv" name="setupmathcases"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="strut"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="numberdistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-ali.mkiv" generated="yes" name="mathcases" type="environment" variant="instance"> + <cd:sequence> + <cd:instance value="mathcases"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathcases"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + </cd:interface> + <cd:interface file="i-mathfence.xml"> + <cd:command file="math-fen.mkiv" name="definemathfence"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathfence"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="setupmathfence"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="command"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="middle"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="mathstyle"> + <cd:constant type="display"/> + <cd:constant type="text"/> + <cd:constant type="script"/> + <cd:constant type="scriptscript"/> + <cd:constant type="cramped"/> + <cd:constant type="uncramped"/> + <cd:constant type="normal"/> + <cd:constant type="packed"/> + <cd:constant type="small"/> + <cd:constant type="big"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="state"> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="factor"> + <cd:constant default="yes" type="auto"/> + <cd:constant type="none"/> + <cd:constant type="number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" generated="yes" name="fence" variant="example"> + <cd:sequence> + <cd:variable value="fence"/> + </cd:sequence> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="fenced"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="fence"/> + <cd:command file="math-fen.mkiv" name="left"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="middle"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="right"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="big"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="Big"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="bigg"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="Bigg"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="bigl"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="bigm"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="bigr"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="Bigl"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="Bigm"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="Bigr"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="biggl"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="biggm"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="biggr"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="Biggl"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="Biggm"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="Biggr"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="lfence"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="mfence"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="rfence"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-fen.mkiv" name="checkedfences" type="environment"/> + </cd:interface> + <cd:interface file="i-mathmatrix.xml"> + <cd:command file="math-ali.mkiv" name="definemathmatrix"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathmatrix"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-ali.mkiv" name="setupmathmatrix"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="strut"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:constant type="left"/> + <cd:constant default="yes" type="middle"/> + <cd:constant type="right"/> + <cd:constant type="normal"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="high"/> + <cd:constant type="low"/> + <cd:constant type="lohi"/> + <cd:constant default="yes" type="normal"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-ali.mkiv" generated="yes" name="mathmatrix" type="environment" variant="instance"> + <cd:sequence> + <cd:instance value="mathmatrix"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathmatrix"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="math-ali.mkiv" name="matrices" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathmatrix"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-ali.mkiv" name="intertext" type="environment"/> + <cd:command file="math-ali.mkiv" name="intertext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ali.mkiv" name="substack" type="environment"/> + <cd:command file="math-ali.mkiv" name="overset"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-ali.mkiv" name="underset"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-mathornament.xml"> + <cd:command file="math-rad.mkvi" name="definemathornament"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathornament"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-rad.mkvi" name="setupmathornament"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="alternative"> + <cd:constant type="mp"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="mpoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="mp"> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-rad.mkvi" generated="yes" name="mathornament" variant="example"> + <cd:sequence> + <cd:variable value="mathornament"/> + </cd:sequence> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-mathradical.xml"> + <cd:command file="math-rad.mkvi" name="definemathradical"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathradical"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-rad.mkvi" name="setupmathradical"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant default="yes" type="normal"/> + <cd:constant type="mp"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="mpoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="mp"> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-rad.mkvi" generated="yes" name="mathradical" variant="example"> + <cd:sequence> + <cd:variable value="mathradical"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="math-rad.mkvi" name="sqrt"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-mathstackers.xml"> + <cd:command file="math-stc.mkvi" name="definemathstackers"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathstackers"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="setupmathstackers"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="topcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="bottomcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="middlecommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="mp"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="mpheight"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="mpdepth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="mpoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="hoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="voffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="minheight"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="mindepth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="mathclass"> + <cd:constant default="yes" type="rel"/> + <cd:constant type="ord"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="min"/> + <cd:constant type="max"/> + <cd:constant default="yes" type="normal"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant default="yes" type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="high"/> + <cd:constant type="low"/> + <cd:constant type="middle"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="strut"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="normal"/> + <cd:constant type="default"/> + <cd:constant type="mp"/> + </cd:parameter> + <cd:parameter name="minwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="moffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="order"> + <cd:constant default="yes" type="normal"/> + <cd:constant type="reverse"/> + </cd:parameter> + <cd:parameter name="mathlimits"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="math-sty.mkvi" name="definemathextensible"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="reverse"/> + <cd:constant type="mathematics"/> + <cd:constant type="text"/> + <cd:constant type="chemistry"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" generated="yes" name="mathextensible" variant="example"> + <cd:sequence> + <cd:variable value="mathextensible"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="reverse"/> + <cd:constant type="mathematics"/> + <cd:constant type="text"/> + <cd:constant type="chemistry"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-sty.mkvi" name="definemathoverextensible"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="top"/> + <cd:constant type="vfenced"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" generated="yes" name="mathoverextensible" variant="example"> + <cd:sequence> + <cd:variable value="mathoverextensible"/> + </cd:sequence> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-sty.mkvi" name="definemathunderextensible"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="bottom"/> + <cd:constant type="vfenced"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" generated="yes" name="mathunderextensible" variant="example"> + <cd:sequence> + <cd:variable value="mathunderextensible"/> + </cd:sequence> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-sty.mkvi" name="definemathdoubleextensible"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="both"/> + <cd:constant type="vfenced"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" generated="yes" name="mathdoubleextensible" variant="example"> + <cd:sequence> + <cd:variable value="mathdoubleextensible"/> + </cd:sequence> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-sty.mkvi" name="definemathovertextextensible"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="bothtext"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" generated="yes" name="mathovertextextensible" variant="example"> + <cd:sequence> + <cd:variable value="mathovertextextensible"/> + </cd:sequence> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-sty.mkvi" name="definemathundertextextensible"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="bothtext"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" generated="yes" name="mathundertextextensible" variant="example"> + <cd:sequence> + <cd:variable value="mathundertextextensible"/> + </cd:sequence> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-sty.mkvi" name="definemathtriplet"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" generated="yes" name="mathtriplet" variant="example"> + <cd:sequence> + <cd:variable value="mathtriplet"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mathtriplet"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xrel"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xequal"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xleftrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xLeftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xRightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xLeftrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xtwoheadleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xtwoheadrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xmapsto"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xhookleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xhookrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xleftharpoondown"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xleftharpoonup"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xrightharpoondown"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xrightharpoonup"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xrightoverleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xleftrightharpoons"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xrightleftharpoons"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="xtriplerel"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mrel"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mequal"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mleftrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mLeftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mRightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mLeftrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mtwoheadleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mtwoheadrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mmapsto"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mhookleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mhookrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mleftharpoondown"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mleftharpoonup"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mrightharpoondown"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mrightharpoonup"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mrightoverleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mleftrightharpoons"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mrightleftharpoons"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="mtriplerel"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="eleftarrowfill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="erightarrowfill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="eleftrightarrowfill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="etwoheadrightarrowfill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="eleftharpoondownfill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="eleftharpoonupfill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="erightharpoondownfill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="erightharpoonupfill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="eoverbarfill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="eunderbarfill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="eoverbracefill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="eunderbracefill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="eoverparentfill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="eunderparentfill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="eoverbracketfill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="eunderbracketfill"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="trel"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="tequal"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="tmapsto"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="tleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="trightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="tleftrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="tLeftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="tRightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="tLeftrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="ttwoheadleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="ttwoheadrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="thookleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="thookrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="tleftharpoondown"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="tleftharpoonup"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="trightharpoondown"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="trightharpoonup"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="trightoverleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="tleftrightharpoons"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="trightleftharpoons"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="ttriplerel"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="cleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="crightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="crightoverleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="underleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="underrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="underleftrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="undertwoheadleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="undertwoheadrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="underleftharpoondown"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="underleftharpoonup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="underrightharpoondown"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="underrightharpoonup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="underbar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="underbrace"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="underparent"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="underbracket"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overleftrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overtwoheadleftarrow"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overtwoheadrightarrow"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overleftharpoondown"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overleftharpoonup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overrightharpoondown"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overrightharpoonup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overbar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overbrace"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overparent"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overbracket"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="doublebar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="doublebrace"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="doubleparent"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="doublebracket"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overbarunderbar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overbraceunderbrace"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overparentunderparent"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overbracketunderbracket"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overbartext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overbracetext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overparenttext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="overbrackettext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="underbartext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="underbracetext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="underparenttext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="underbrackettext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" name="singlebond"/> + <cd:command file="math-stc.mkvi" name="doublebond"/> + <cd:command file="math-stc.mkvi" name="triplebond"/> + <cd:command file="math-stc.mkvi" name="definemathunstacked"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="wide"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="math-stc.mkvi" generated="yes" name="mathunstacked" variant="example"> + <cd:sequence> + <cd:variable value="mathunstacked"/> + </cd:sequence> + </cd:command> + <cd:command file="math-stc.mkvi" name="And"/> + <cd:command file="math-stc.mkvi" name="impliedby"/> + <cd:command file="math-stc.mkvi" name="implies"/> + <cd:command file="math-stc.mkvi" name="iff"/> + </cd:interface> + <cd:interface file="i-metapost.xml"> + <cd:command file="meta-ini.mkiv" name="MPdefinitions" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPextensions" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPinitializations" type="environment"/> + <cd:command file="meta-ini.mkiv" name="MPinclusions" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="+"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPinclusions"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="+"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="defineMPinstance"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupMPinstance"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="setupMPinstance"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="format"> + <cd:constant default="yes" type="metafun"/> + <cd:constant type="mpost"/> + </cd:parameter> + <cd:parameter name="initializations"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="setups"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="textstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="textcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="extensions"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="binary"/> + <cd:constant type="decimal"/> + <cd:constant type="double"/> + <cd:constant type="scaled"/> + <cd:constant default="yes" type="default"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="resetMPinstance"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="processMPfigurefile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPdrawing" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="-"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="resetMPdrawing"/> + <cd:command file="meta-ini.mkiv" name="getMPdrawing"/> + <cd:command begin="push" end="pop" file="meta-ini.mkiv" name="MPdrawing" type="environment"/> + <cd:command file="meta-ini.mkiv" name="MPdrawing"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPclip" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPfontsizehskip"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="setupMPvariables"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="setMPvariables"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="setMPvariable"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPrawvar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPvariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPvar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="useMPvariables"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="uniqueMPgraphic" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes" optional="yes"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="uniqueMPgraphic"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments delimiters="braces" list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="useMPgraphic" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes" optional="yes"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="useMPgraphic"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments delimiters="braces" list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="usableMPgraphic" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes" optional="yes"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="reuseMPgraphic"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments delimiters="braces" list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="reusableMPgraphic" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes" optional="yes"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="reusableMPgraphic"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments delimiters="braces" list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="uniqueMPpagegraphic" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes" optional="yes"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="uniqueMPpagegraphic"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments delimiters="braces" list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="processMPbuffer"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="runMPbuffer"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPenvironment" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="reset"/> + <cd:constant type="global"/> + <cd:constant type="+"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="resetMPenvironment"/> + <cd:command file="meta-ini.mkiv" name="useMPenvironmentbuffer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPcode" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPcode"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPrun" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="useMPrun"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="useMPlibrary"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="setMPtext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPtext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="MPbetex"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="doifelseMPgraphic"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="doifMPgraphicelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="staticMPfigure" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="staticMPgraphic" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes" optional="yes"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="usestaticMPfigure"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupscale"/> + </cd:assignments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="meta-ini.mkiv" name="setupMPgraphics"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="color"> + <cd:constant default="yes" type="local"/> + <cd:constant type="global"/> + </cd:parameter> + <cd:parameter name="mpy"> + <cd:constant type="cd:file"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-mixedcolumns.xml"> + <cd:command file="page-mix.mkiv" name="definemixedcolumns"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmixedcolumns"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-mix.mkiv" name="setupmixedcolumns"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="grid"> + <cd:inherit name="definegridsnapping"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="otr"/> + <cd:constant type="box"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="maxheight"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="step"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="profile"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="setups"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="balance"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="splitmethod"> + <cd:constant type="none"/> + <cd:constant type="fixed"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant default="yes" type="local"/> + <cd:constant type="global"/> + </cd:parameter> + <cd:parameter name="internalgrid"> + <cd:constant default="yes" type="line"/> + <cd:constant type="halfline"/> + </cd:parameter> + <cd:parameter name="separator"> + <cd:constant type="rule"/> + </cd:parameter> + <cd:parameter name="strut"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="rulecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="direction"> + <cd:constant default="yes" type="normal"/> + <cd:constant type="reverse"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-mix.mkiv" name="mixedcolumns" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmixedcolumns"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-mix.mkiv" generated="yes" name="mixedcolumns" type="environment" variant="instance"> + <cd:sequence> + <cd:instance value="mixedcolumns"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmixedcolumns"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + </cd:interface> + <cd:interface file="i-modes.xml"> + <cd:command file="core-env.mkiv" name="newmode"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setmode"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="resetmode"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="newsystemmode"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setsystemmode"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="resetsystemmode"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="preventmode"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="enablemode"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="disablemode"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="globalpreventmode"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="globalenablemode"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="globaldisablemode"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="definemode"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="keep"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="booleanmodevalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifelsemode"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifmodeelse"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifmode"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifnotmode"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="mode" type="environment"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="notmode" type="environment"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifelseallmodes"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifallmodeselse"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifallmodes"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifnotallmodes"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="allmodes" type="environment"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="notallmodes" type="environment"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="modeset" type="environment"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + <cd:constant type="default"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="pushmode"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="popmode"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="pushsystemmode"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="popsystemmode"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-modules.xml"> + <cd:command file="file-mod.mkvi" name="usemodule"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="m"/> + <cd:constant type="p"/> + <cd:constant type="s"/> + <cd:constant type="x"/> + <cd:constant type="t"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="file-mod.mkvi" name="usetexmodule"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="m"/> + <cd:constant type="p"/> + <cd:constant type="s"/> + <cd:constant type="x"/> + <cd:constant type="t"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="file-mod.mkvi" name="module" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-mod.mkvi" name="module" type="environment" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-mod.mkvi" name="setupmodule"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="test"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="file-mod.mkvi" name="moduleparameter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-mod.mkvi" name="currentmoduleparameter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-mod.mkvi" name="moduletestsection" type="environment"/> + <cd:command file="file-mod.mkvi" name="fetchruntinecommand"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-mod.mkvi" name="luaenvironment"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-mod.mkvi" name="useluamodule"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-narrow.xml"> + <cd:command file="spac-hor.mkiv" name="definenarrower"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupnarrower"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="setupnarrower"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="left"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="middle"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="default"> + <cd:constant method="none" prefix="cd:sign" type="left"/> + <cd:constant default="yes" method="none" prefix="cd:sign" type="middle"/> + <cd:constant method="none" prefix="cd:sign" type="right"/> + <cd:constant method="factor" prefix="cd:number" type="left"/> + <cd:constant method="factor" prefix="cd:number" type="middle"/> + <cd:constant method="factor" prefix="cd:number" type="right"/> + <cd:constant type="reset"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="narrower" type="environment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant method="none" prefix="cd:sign" type="left"/> + <cd:constant method="none" prefix="cd:sign" type="middle"/> + <cd:constant method="none" prefix="cd:sign" type="right"/> + <cd:constant method="factor" prefix="cd:number" type="left"/> + <cd:constant method="factor" prefix="cd:number" type="middle"/> + <cd:constant method="factor" prefix="cd:number" type="right"/> + <cd:constant type="reset"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" generated="yes" name="narrower" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="narrower"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant method="none" prefix="cd:sign" type="left"/> + <cd:constant method="none" prefix="cd:sign" type="middle"/> + <cd:constant method="none" prefix="cd:sign" type="right"/> + <cd:constant method="factor" prefix="cd:number" type="left"/> + <cd:constant method="factor" prefix="cd:number" type="middle"/> + <cd:constant method="factor" prefix="cd:number" type="right"/> + <cd:constant type="reset"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="narrow" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupnarrower"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="narrow" type="environment" variant="name"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant method="none" prefix="cd:sign" type="left"/> + <cd:constant method="none" prefix="cd:sign" type="middle"/> + <cd:constant method="none" prefix="cd:sign" type="right"/> + <cd:constant method="factor" prefix="cd:number" type="left"/> + <cd:constant method="factor" prefix="cd:number" type="middle"/> + <cd:constant method="factor" prefix="cd:number" type="right"/> + <cd:constant type="reset"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-hor.mkiv" name="narrow" type="environment" variant="assignment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupnarrower"/> + </cd:assignments> + <cd:keywords list="yes" optional="yes"> + <cd:constant method="none" prefix="cd:sign" type="left"/> + <cd:constant method="none" prefix="cd:sign" type="middle"/> + <cd:constant method="none" prefix="cd:sign" type="right"/> + <cd:constant method="factor" prefix="cd:number" type="left"/> + <cd:constant method="factor" prefix="cd:number" type="middle"/> + <cd:constant method="factor" prefix="cd:number" type="right"/> + <cd:constant type="reset"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-naturaltable.xml"> + <cd:command file="tabl-ntb.mkiv" name="setupTABLE"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="r"/> + <cd:constant type="c"/> + <cd:constant type="x"/> + <cd:constant type="y"/> + <cd:constant type="row"/> + <cd:constant type="column"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="start"/> + <cd:constant type="header"/> + <cd:constant type="each"/> + <cd:constant type="odd"/> + <cd:constant type="even"/> + <cd:constant type="one"/> + <cd:constant type="cd:number"/> + <cd:constant method="none" prefix="-" type="cd:number"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="first"/> + <cd:constant type="least"/> + <cd:constant type="each"/> + <cd:constant type="two"/> + <cd:constant type="odd"/> + <cd:constant type="even"/> + <cd:constant type="cd:number"/> + <cd:constant method="none" prefix="-" type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="extras"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="headcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="headstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="leftmargindistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightmargindistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="columndistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="setups"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="textwidth"> + <cd:constant type="cd:dimension"/> + <cd:constant default="yes" type="local"/> + </cd:parameter> + <cd:parameter name="split"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="repeat"/> + <cd:constant default="yes" type="auto"/> + </cd:parameter> + <cd:parameter name="header"> + <cd:constant type="repeat"/> + </cd:parameter> + <cd:parameter name="option"> + <cd:constant type="stretch"/> + <cd:constant type="tight"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="samepage"> + <cd:constant type="before"/> + <cd:constant type="after"/> + <cd:constant type="both"/> + </cd:parameter> + <cd:parameter name="spaceinbetween"> + <cd:inherit name="blank"/> + </cd:parameter> + <cd:parameter name="splitoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="aligncharacter"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="alignmentcharacter"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="number" type="cd:text"/> + <cd:constant method="apply" prefix="text" type="cd:text"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="math"/> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="b" end="e" file="tabl-ntb.mkiv" name="TABLE" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupTABLE"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="b" end="e" file="tabl-ntb.mkiv" name="TD" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="nx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="ny"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="nc"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="nr"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="m"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="action"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupTABLE"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="b" end="e" file="tabl-ntb.mkiv" name="TR" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupTABLE"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="b" end="e" file="tabl-ntb.mkiv" name="TC" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="bTD"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="b" end="e" file="tabl-ntb.mkiv" name="TX" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="bTD"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="b" end="e" file="tabl-ntb.mkiv" name="TY" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupTABLE"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="b" end="e" file="tabl-ntb.mkiv" name="TH" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="bTD"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="b" end="e" file="tabl-ntb.mkiv" name="TN" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="bTD"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="b" end="e" file="tabl-ntb.mkiv" name="TABLEhead" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupTABLE"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="b" end="e" file="tabl-ntb.mkiv" name="TABLEnext" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupTABLE"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="b" end="e" file="tabl-ntb.mkiv" name="TABLEbody" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupTABLE"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="b" end="e" file="tabl-ntb.mkiv" name="TABLEfoot" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupTABLE"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-ntb.mkiv" name="defineTABLEsetup"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupTABLE"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="b" end="e" file="tabl-ntb.mkiv" name="TDs" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command begin="b" end="e" file="tabl-ntb.mkiv" name="TRs" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-ntb.mkiv" name="TABLE" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupTABLE"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-ntb.mkiv" name="TABLEhead" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupTABLE"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-ntb.mkiv" name="TABLEnext" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupTABLE"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-ntb.mkiv" name="TABLEbody" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupTABLE"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-ntb.mkiv" name="TABLEfoot" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupTABLE"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-note.xml"> + <cd:command file="strc-not.mkvi" name="setupnotation"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="title"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="number"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="type"> + <cd:constant type="note"/> + </cd:parameter> + <cd:parameter name="numbercommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="titledistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="titlestyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="titlecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="titlecommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="titleleft"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="titleright"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="symbol"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="starter"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="stopper"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="coupling"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="counter"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="level"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="text"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="headcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="inmargin"/> + <cd:constant type="inleft"/> + <cd:constant type="inright"/> + <cd:constant type="margin"/> + <cd:constant type="leftmargin"/> + <cd:constant type="rightmargin"/> + <cd:constant type="innermargin"/> + <cd:constant type="outermargin"/> + <cd:constant type="serried"/> + <cd:constant type="hanging"/> + <cd:constant type="top"/> + <cd:constant type="command"/> + <cd:constant default="yes" type="note"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="headalign"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="indenting"> + <cd:inherit name="setupindenting"/> + </cd:parameter> + <cd:parameter name="display"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="indentnext"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="line"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="none"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="hang"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="none"/> + <cd:constant type="margin"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="closesymbol"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="closecommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="expansion"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="xml"/> + </cd:parameter> + <cd:parameter name="referenceprefix"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="sample"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="headstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="headcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:inherit name="setupcounter"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="setupnotations"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupnotation"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" generated="yes" name="note" type="environment" variant="instance:assignment"> + <cd:sequence> + <cd:instance value="note"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="list"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-not.mkvi" generated="yes" name="note" type="environment" variant="instance"> + <cd:sequence> + <cd:instance value="note"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-not.mkvi" generated="yes" name="note" variant="instance"> + <cd:sequence> + <cd:instance value="note"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-not.mkvi" generated="yes" name="note" variant="instance:assignment"> + <cd:sequence> + <cd:instance value="note"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="list"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-not.mkvi" name="definenote"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupnote"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="setupnote"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="interaction"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + <cd:constant type="number"/> + <cd:constant type="text"/> + <cd:constant type="all"/> + </cd:parameter> + <cd:parameter name="symbolcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="textcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="indicator"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="textseparator"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rulecommand"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="rule"> + <cd:constant default="yes" type="on"/> + <cd:constant type="off"/> + <cd:constant type="normal"/> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="command"/> + <cd:constant type="paragraph"/> + </cd:parameter> + <cd:parameter name="split"> + <cd:constant default="yes" type="tolerant"/> + <cd:constant type="strict"/> + <cd:constant type="verystrict"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="factor"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="text"/> + <cd:constant type="page"/> + <cd:constant type="high"/> + <cd:constant type="bottom"/> + <cd:constant type="none"/> + <cd:constant type="columns"/> + <cd:constant type="firstcolumn"/> + <cd:constant type="lastcolumn"/> + </cd:parameter> + <cd:parameter name="next"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="rulecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="setups"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="interlinespace"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="paragraph"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="scope"> + <cd:constant type="page"/> + </cd:parameter> + <cd:parameter name="columndistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="continue"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="grid"/> + <cd:constant type="fixed"/> + <cd:constant type="columns"/> + <cd:constant default="yes" type="note"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="criterium"> + <cd:constant type="page"/> + </cd:parameter> + <cd:parameter name="bodyfont"> + <cd:inherit name="setupbodyfont"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="textstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="textcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="anchor"> + <cd:constant type="next"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="setupnotes"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupnote"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="setnote"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="setnote" variant="assignment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="list"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="setnotetext"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="setnotetext" variant="assignment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="list"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="placenotes"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupnote"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="localnotes" type="environment"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="placelocalnotes"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupnote"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="postponenotes"/> + <cd:command file="strc-not.mkvi" name="flushnotes"/> + <cd:command file="strc-not.mkvi" name="doifelsenoteonsamepage"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="doifnoteonsamepageelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="doifnotescollected"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="notesymbol"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="note"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="footnotetext"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="footnotetext" variant="assignment"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="list"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="placefootnotes"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupnote"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-not.mkvi" name="localfootnotes" type="environment"/> + <cd:command file="strc-not.mkvi" name="placelocalfootnotes"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupnote"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lnt.mkvi" name="definelinenote"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplinenote"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lnt.mkvi" name="setuplinenote"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="compress"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="compressmethod"> + <cd:constant type="separator"/> + <cd:constant type="stopper"/> + <cd:constant type="space"/> + </cd:parameter> + <cd:parameter name="compressseparator"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="compressdistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:inherit name="setupnote"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lnt.mkvi" generated="yes" name="linenote" variant="instance"> + <cd:sequence> + <cd:instance value="linenote"/> + </cd:sequence> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-lnt.mkvi" generated="yes" name="startlinenote" variant="instance"> + <cd:sequence> + <cd:string value="start"/> + <cd:instance value="linenote"/> + </cd:sequence> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-lnt.mkvi" generated="yes" name="stoplinenote" variant="instance"> + <cd:sequence> + <cd:string value="stop"/> + <cd:instance value="linenote"/> + </cd:sequence> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-lnt.mkvi" name="fromlinenote"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-lnt.mkvi" name="tolinenote"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-object.xml"> + <cd:command file="pack-obj.mkiv" name="ifinobject"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:delimiter name="else"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:false"/> + </cd:keywords> + <cd:delimiter name="fi"/> + </cd:arguments> + </cd:command> + <cd:command file="pack-obj.mkiv" name="objectmargin"/> + <cd:command file="pack-obj.mkiv" name="objectwidth"/> + <cd:command file="pack-obj.mkiv" name="objectheight"/> + <cd:command file="pack-obj.mkiv" name="objectdepth"/> + <cd:command file="pack-obj.mkiv" name="setreferencedobject"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-obj.mkiv" name="settightreferencedobject"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-obj.mkiv" name="setunreferencedobject"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-obj.mkiv" name="settightunreferencedobject"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-obj.mkiv" name="setobject"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-obj.mkiv" name="settightobject"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-obj.mkiv" name="getobject"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-obj.mkiv" name="getobjectdimensions"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-obj.mkiv" name="defaultobjectreference"/> + <cd:command file="pack-obj.mkiv" name="defaultobjectpage"/> + <cd:command file="pack-obj.mkiv" name="doifelseobjectfound"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-obj.mkiv" name="doifobjectfoundelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-obj.mkiv" name="doifelseobjectreferencefound"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-obj.mkiv" name="doifobjectreferencefoundelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-offset.xml"> + <cd:command file="pack-box.mkiv" name="setupoffsetbox"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="x"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="y"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="leftoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="topoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bottomoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="fixed"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="line"/> + <cd:constant type="l"/> + <cd:constant type="c"/> + <cd:constant type="r"/> + <cd:constant type="m"/> + <cd:constant type="t"/> + <cd:constant type="b"/> + <cd:constant type="g"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="setupoffset"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupoffsetbox"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="offsetbox"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupoffsetbox"/> + </cd:assignments> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="offset"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupoffset"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-opposite.xml"> + <cd:command file="page-fac.mkiv" name="setupoppositeplacing"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-fac.mkiv" name="opposite" type="environment"/> + </cd:interface> + <cd:interface file="i-ornament.xml"> + <cd:command file="pack-box.mkiv" name="ornamenttext" variant="collector"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="alternative"> + <cd:constant default="yes" type="a"/> + <cd:constant type="b"/> + </cd:parameter> + <cd:inherit name="setupcollector"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="ornamenttext" variant="layer"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="alternative"> + <cd:constant type="a"/> + <cd:constant default="yes" type="b"/> + </cd:parameter> + <cd:inherit name="setuplayer"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayeredtext"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="ornamenttext" variant="direct"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="defineornament" variant="collector"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="alternative"> + <cd:constant default="yes" type="a"/> + <cd:constant type="b"/> + </cd:parameter> + <cd:inherit name="setupcollector"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="defineornament" variant="layer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="alternative"> + <cd:constant type="a"/> + <cd:constant default="yes" type="b"/> + </cd:parameter> + <cd:inherit name="setuplayer"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplayeredtext"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" generated="yes" name="ornament" variant="example"> + <cd:sequence> + <cd:variable value="ornament"/> + </cd:sequence> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-output.xml"> + <cd:command file="page-otr.mkvi" name="defineoutputroutine"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupoutputroutine"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-otr.mkvi" name="setupoutputroutine"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:csname"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-otr.mkvi" name="setupoutputroutine" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-otr.mkvi" name="defineoutputroutinecommand"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-otr.mkvi" name="traceoutputroutines"/> + <cd:command file="page-otr.mkvi" name="installoutputroutine"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-overlay.xml"> + <cd:command file="pack-lyr.mkiv" name="defineoverlay"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="overlaycolor"/> + <cd:command file="pack-rul.mkiv" name="overlaylinecolor"/> + <cd:command file="pack-rul.mkiv" name="overlaywidth"/> + <cd:command file="pack-rul.mkiv" name="overlayheight"/> + <cd:command file="pack-rul.mkiv" name="overlaydepth"/> + <cd:command file="pack-rul.mkiv" name="overlayoffset"/> + <cd:command file="pack-rul.mkiv" name="overlaylinewidth"/> + <cd:command file="pack-rul.mkiv" name="doifelseoverlay"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-rul.mkiv" name="doifoverlayelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-pagebreak.xml"> + <cd:command file="page-brk.mkiv" name="definepagebreak"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="empty"/> + <cd:constant type="header"/> + <cd:constant type="footer"/> + <cd:constant type="dummy"/> + <cd:constant type="frame"/> + <cd:constant type="cd:number"/> + <cd:constant method="none" prefix="+" type="cd:number"/> + <cd:constant type="default"/> + <cd:constant type="reset"/> + <cd:constant type="disable"/> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="makeup"/> + <cd:constant type="blank"/> + <cd:constant type="preference"/> + <cd:constant type="bigpreference"/> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="even"/> + <cd:constant type="odd"/> + <cd:constant type="quadruple"/> + <cd:constant type="last"/> + <cd:constant type="lastpage"/> + <cd:constant type="start"/> + <cd:constant type="stop"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-brk.mkiv" name="pagebreak"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="empty"/> + <cd:constant type="header"/> + <cd:constant type="footer"/> + <cd:constant type="dummy"/> + <cd:constant type="frame"/> + <cd:constant type="cd:number"/> + <cd:constant method="none" prefix="+" type="cd:number"/> + <cd:constant type="default"/> + <cd:constant type="reset"/> + <cd:constant type="disable"/> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="makeup"/> + <cd:constant type="blank"/> + <cd:constant type="preference"/> + <cd:constant type="bigpreference"/> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="even"/> + <cd:constant type="odd"/> + <cd:constant type="quadruple"/> + <cd:constant type="last"/> + <cd:constant type="lastpage"/> + <cd:constant type="start"/> + <cd:constant type="stop"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-brk.mkiv" name="page"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="pagebreak"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-brk.mkiv" name="definecolumnbreak"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="preference"/> + <cd:constant type="local"/> + <cd:constant type="force"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-brk.mkiv" name="columnbreak"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="preference"/> + <cd:constant type="local"/> + <cd:constant type="force"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="cd:number"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-brk.mkiv" name="column"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="columnbreak"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-brk.mkiv" name="definepagechecker"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppagechecker"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-brk.mkiv" name="setuppagechecker"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="lines"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="0"/> + <cd:constant type="1"/> + <cd:constant type="2"/> + <cd:constant type="3"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-brk.mkiv" name="checkpage"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppagechecker"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-brk.mkiv" name="testpage"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-brk.mkiv" name="testpageonly"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-brk.mkiv" name="testpagesync"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-brk.mkiv" name="testcolumn"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-pagecomment.xml"> + <cd:command file="page-com.mkiv" name="setuppagecomment"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="location"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="top"/> + <cd:constant default="yes" type="bottom"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="state"> + <cd:constant type="start"/> + <cd:constant type="stop"/> + <cd:constant default="yes" type="none"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-com.mkiv" name="pagecomment" type="environment"/> + </cd:interface> + <cd:interface file="i-pagefigure.xml"> + <cd:command file="page-app.mkiv" name="pagefigure"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupexternalfigure"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-app.mkiv" name="pagefigure" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupexternalfigure"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-pagegrid.xml"> + <cd:command file="page-cst.mkiv" name="definepagegrid"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppagegrid"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-cst.mkiv" name="setuppagegrid"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="nleft"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="nright"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="lines"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="maxheight"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="direction"> + <cd:constant default="yes" type="normal"/> + <cd:constant type="reverse"/> + </cd:parameter> + <cd:parameter name="page"> + <cd:inherit name="page"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-cst.mkiv" generated="yes" name="pagegrid" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="pagegrid"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppagegrid"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-cst.mkiv" name="pagegrid" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppagegrid"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-cst.mkiv" name="setpagegrid"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="c"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="r"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="option"> + <cd:constant default="yes" type="none"/> + </cd:parameter> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="page-cst.mkiv" name="definepagegridspan"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppagegridspan"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-cst.mkiv" name="setuppagegridspan"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-cst.mkiv" name="pagegridspan" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppagegridspan"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-cst.mkiv" name="pagegridspanwidth"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-cst.mkiv" name="definepagegridarea"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppagegridarea"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-cst.mkiv" name="setuppagegridarea"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant type="start"/> + <cd:constant default="yes" type="stop"/> + <cd:constant type="repeat"/> + </cd:parameter> + <cd:parameter name="x"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="y"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="nx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="ny"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="clipoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-cst.mkiv" name="setuppagegridareatext"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-cst.mkiv" name="setuppagegridlines"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-cst.mkiv" name="setuppagegridstart"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-pageinjection.xml"> + <cd:command file="page-inj.mkvi" name="definepageinjection"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppageinjection"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-inj.mkvi" name="setuppageinjection"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant type="previous"/> + <cd:constant default="yes" type="next"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="delay"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant default="yes" type="figure"/> + <cd:constant type="buffer"/> + <cd:constant type="setups"/> + <cd:constant type="none"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="page"> + <cd:inherit name="page"/> + </cd:parameter> + <cd:parameter name="pagestate"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-inj.mkvi" name="pageinjection"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-inj.mkvi" name="pageinjection" variant="assignment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppageinjection"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-inj.mkvi" name="definepageinjectionalternative"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppageinjectionalternative"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-inj.mkvi" name="setuppageinjectionalternative"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="renderingsetup"> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-pagelayout.xml"> + <cd:command file="page-plg.mkiv" name="pagearea"> + <cd:arguments> + <cd:keywords> + <cd:constant type="top"/> + <cd:constant type="header"/> + <cd:constant type="text"/> + <cd:constant type="footer"/> + <cd:constant type="bottom"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="text"/> + <cd:constant type="margin"/> + <cd:constant type="edge"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="lefttext"/> + <cd:constant default="yes" type="middletext"/> + <cd:constant type="righttext"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-plg.mkiv" name="pagelayout" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="page"/> + <cd:constant type="leftpage"/> + <cd:constant type="rightpage"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-pagenumber.xml"> + <cd:command file="strc-pag.mkiv" name="setuprealpagenumber"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupcounter"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-pag.mkiv" name="setupuserpagenumber"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="viewerprefix"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="state"> + <cd:constant type="start"/> + <cd:constant type="stop"/> + <cd:constant type="none"/> + <cd:constant type="keep"/> + <cd:constant type="empty"/> + </cd:parameter> + <cd:inherit name="setupcounter"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-pag.mkiv" name="setupsubpagenumber"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupcounter"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-pag.mkiv" name="setuppagenumber"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setupuserpagenumber"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-pag.mkiv" name="resetuserpagenumber"/> + <cd:command file="strc-pag.mkiv" name="resetsubpagenumber"/> + <cd:command file="strc-pag.mkiv" name="resetpagenumber"/> + <cd:command file="strc-pag.mkiv" name="setuppagenumbering"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="alternative"> + <cd:constant default="yes" type="singlesided"/> + <cd:constant type="doublesided"/> + </cd:parameter> + <cd:parameter name="page"> + <cd:inherit name="page"/> + </cd:parameter> + <cd:parameter name="strut"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant default="yes" type="header"/> + <cd:constant type="footer"/> + <cd:constant type="left"/> + <cd:constant default="yes" type="middle"/> + <cd:constant type="right"/> + <cd:constant type="inleft"/> + <cd:constant type="inright"/> + <cd:constant type="margin"/> + <cd:constant type="inmargin"/> + <cd:constant type="atmargin"/> + <cd:constant type="marginedge"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-pag.mkiv" name="firstrealpagenumber"/> + <cd:command file="strc-pag.mkiv" name="firstuserpagenumber"/> + <cd:command file="strc-pag.mkiv" name="firstsubpagenumber"/> + <cd:command file="strc-pag.mkiv" name="lastrealpagenumber"/> + <cd:command file="strc-pag.mkiv" name="lastuserpagenumber"/> + <cd:command file="strc-pag.mkiv" name="lastsubpagenumber"/> + <cd:command file="strc-pag.mkiv" name="prevrealpagenumber"/> + <cd:command file="strc-pag.mkiv" name="prevuserpagenumber"/> + <cd:command file="strc-pag.mkiv" name="prevsubpagenumber"/> + <cd:command file="strc-pag.mkiv" name="nextrealpagenumber"/> + <cd:command file="strc-pag.mkiv" name="nextuserpagenumber"/> + <cd:command file="strc-pag.mkiv" name="nextsubpagenumber"/> + <cd:command file="strc-pag.mkiv" name="firstrealpage"/> + <cd:command file="strc-pag.mkiv" name="firstuserpage"/> + <cd:command file="strc-pag.mkiv" name="firstsubpage"/> + <cd:command file="strc-pag.mkiv" name="prevrealpage"/> + <cd:command file="strc-pag.mkiv" name="prevuserpage"/> + <cd:command file="strc-pag.mkiv" name="prevsubpage"/> + <cd:command file="strc-pag.mkiv" name="nextrealpage"/> + <cd:command file="strc-pag.mkiv" name="nextuserpage"/> + <cd:command file="strc-pag.mkiv" name="nextsubpage"/> + <cd:command file="strc-pag.mkiv" name="lastrealpage"/> + <cd:command file="strc-pag.mkiv" name="lastuserpage"/> + <cd:command file="strc-pag.mkiv" name="lastsubpage"/> + <cd:command file="strc-pag.mkiv" name="realpagenumber"/> + <cd:command file="strc-pag.mkiv" name="userpagenumber"/> + <cd:command file="strc-pag.mkiv" name="subpagenumber"/> + <cd:command file="strc-pag.mkiv" name="pagenumber"/> + <cd:command file="strc-pag.mkiv" name="prefixedpagenumber"/> + <cd:command file="strc-pag.mkiv" name="incrementpagenumber"/> + <cd:command file="strc-pag.mkiv" name="incrementsubpagenumber"/> + <cd:command file="strc-pag.mkiv" name="decrementpagenumber"/> + <cd:command file="strc-pag.mkiv" name="decrementsubpagenumber"/> + <cd:command file="strc-pag.mkiv" name="completepagenumber"/> + <cd:command file="strc-pag.mkiv" name="placepagenumber"/> + </cd:interface> + <cd:interface file="i-pageselection.xml"> + <cd:command file="page-sel.mkvi" name="insertpages"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="category"> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-sel.mkvi" name="filterpages"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="even"/> + <cd:constant type="odd"/> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="category"> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-sel.mkvi" name="copypages"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="marking"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupexternalfigure"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-sel.mkvi" name="combinepages"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="alternative"> + <cd:constant default="yes" type="a"/> + <cd:constant type="b"/> + <cd:constant type="c"/> + <cd:constant type="horizontal"/> + <cd:constant type="vertical"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="nx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="ny"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="start"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="stop"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="top"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="bottom"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="frame"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + </cd:parameter> + <cd:parameter name="background"> + <cd:constant type="foreground"/> + <cd:constant type="color"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="backgroundcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-sel.mkvi" name="slicepages"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="hoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="voffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="hoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="voffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-pageshift.xml"> + <cd:command file="page-imp.mkiv" name="definepageshift"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="horizontal"/> + <cd:constant type="vertical"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-imp.mkiv" name="setuppageshift"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant default="yes" type="page"/> + <cd:constant type="paper"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-pagestate.xml"> + <cd:command file="core-dat.mkiv" name="definepagestate"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppagestate"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-dat.mkiv" name="setuppagestate"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="delay"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-dat.mkiv" name="setpagestate"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-dat.mkiv" name="pagestaterealpage"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-dat.mkiv" name="setpagestaterealpageno"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-pairedbox.xml"> + <cd:command file="pack-com.mkiv" name="definepairedbox"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppairedbox"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-com.mkiv" name="setuppairedbox"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="high"/> + <cd:constant type="low"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bodyfont"> + <cd:inherit name="setupbodyfont"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="maxheight"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-com.mkiv" name="placepairedbox"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppairedbox"/> + </cd:assignments> + <cd:content/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-com.mkiv" name="placepairedbox" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppairedbox"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-com.mkiv" generated="yes" name="setuppairedbox" variant="instance"> + <cd:sequence> + <cd:string value="setup"/> + <cd:instance value="pairedbox"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setuppairedbox"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="pack-com.mkiv" generated="yes" name="placepairedbox" variant="instance"> + <cd:sequence> + <cd:string value="place"/> + <cd:instance value="pairedbox"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppairedbox"/> + </cd:assignments> + <cd:content/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="pack-com.mkiv" generated="yes" name="placepairedbox" type="environment" variant="instance"> + <cd:sequence> + <cd:string value="place"/> + <cd:instance value="pairedbox"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppairedbox"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="pack-com.mkiv" name="placeontopofeachother"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-com.mkiv" name="placesidebyside"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-papersize.xml"> + <cd:command file="page-lay.mkiv" name="definepapersize"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="top"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="bottom"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="page"> + <cd:inherit name="setuppapersize"/> + </cd:parameter> + <cd:parameter name="paper"> + <cd:inherit name="setuppapersize"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="definepapersize" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:inherit name="setuppapersize"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="setuppapersize"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="setuppapersize" variant="name"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="reset"/> + <cd:constant type="landscape"/> + <cd:constant type="mirrored"/> + <cd:constant type="negative"/> + <cd:constant type="rotated"/> + <cd:constant type="90"/> + <cd:constant type="180"/> + <cd:constant type="270"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="reset"/> + <cd:constant type="landscape"/> + <cd:constant type="mirrored"/> + <cd:constant type="negative"/> + <cd:constant type="rotated"/> + <cd:constant type="90"/> + <cd:constant type="180"/> + <cd:constant type="270"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="setuppapersize"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="top"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="bottom"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant default="yes" type="normal"/> + <cd:constant type="none"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="scale"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="nx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="ny"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="dx"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="dy"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="topspace"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="backspace"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="page"> + <cd:constant type="reset"/> + <cd:constant type="landscape"/> + <cd:constant type="mirrored"/> + <cd:constant type="negative"/> + <cd:constant type="rotated"/> + <cd:constant type="90"/> + <cd:constant type="180"/> + <cd:constant type="270"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="paper"> + <cd:constant type="reset"/> + <cd:constant type="landscape"/> + <cd:constant type="mirrored"/> + <cd:constant type="negative"/> + <cd:constant type="rotated"/> + <cd:constant type="90"/> + <cd:constant type="180"/> + <cd:constant type="270"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="option"> + <cd:constant type="fit"/> + <cd:constant default="yes" type="max"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="setuppaper"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setuppapersize"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-lay.mkiv" name="adaptpapersize"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:inherit name="setuppapersize"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="setuppapersize"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-paragraph.xml"> + <cd:command file="strc-tag.mkiv" name="defineparagraph"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupparagraph"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-tag.mkiv" name="setupparagraph"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="setups"> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-tag.mkiv" name="paragraph" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupparagraph"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-tag.mkiv" name="par" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupparagraph"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="b" end="e" file="strc-tag.mkiv" name="par" type="environment"/> + <cd:command file="spac-par.mkiv" name="setupparagraphintro"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="reset"/> + <cd:constant type="each"/> + <cd:constant type="first"/> + <cd:constant type="next"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-paragraphnumber.xml"> + <cd:command file="page-par.mkiv" name="setupparagraphnumbering"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant type="start"/> + <cd:constant default="yes" type="stop"/> + <cd:constant type="line"/> + <cd:constant type="reset"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-paragraphs.xml"> + <cd:command file="tabl-mis.mkiv" name="defineparagraphs"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupparagraphs"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-mis.mkiv" name="setupparagraphs"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="each"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + <cd:constant default="yes" type="fit"/> + </cd:parameter> + <cd:parameter name="top"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="bottom"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="inner"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="rule"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rulecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-mis.mkiv" name="setupparagraphs" variant="assignment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant method="range" prefix="cd:name" type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + <cd:constant default="yes" type="fit"/> + </cd:parameter> + <cd:parameter name="top"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="bottom"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="inner"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="rule"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rulecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-mis.mkiv" name="paragraphs" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-mis.mkiv" name="nextparagraphs"/> + <cd:command file="tabl-mis.mkiv" generated="yes" name="paragraphs" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="paragraphs"/> + </cd:sequence> + </cd:command> + <cd:command file="tabl-mis.mkiv" generated="yes" name="paragraphs" variant="example"> + <cd:sequence> + <cd:variable value="paragraphs"/> + </cd:sequence> + </cd:command> + <cd:command file="tabl-mis.mkiv" generated="yes" name="nextparagraphs" variant="example"> + <cd:sequence> + <cd:string value="next"/> + <cd:variable value="paragraphs"/> + </cd:sequence> + </cd:command> + <cd:command file="tabl-mis.mkiv" name="paragraphscell" type="environment"/> + </cd:interface> + <cd:interface file="i-parallel.xml"> + <cd:command file="buff-par.mkvi" name="defineparallel"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-par.mkvi" name="setupparallel"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="setups"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="start"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="criterium"> + <cd:constant type="all"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="buff-par.mkvi" name="placeparallel"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupparallel"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="buff-par.mkvi" name="doifelseparallel"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + <cd:constant default="yes" type="all"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-par.mkvi" name="doifparallelelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + <cd:constant default="yes" type="all"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-par.mkvi" name="resetparallel"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + <cd:constant default="yes" type="all"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-par.mkvi" generated="yes" name="parallel" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="parallel"/> + </cd:sequence> + </cd:command> + </cd:interface> + <cd:interface file="i-parbuilder.xml"> + <cd:command file="typo-bld.mkiv" name="defineparbuilder"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-bld.mkiv" name="parbuilder" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="default"/> + <cd:constant type="oneline"/> + <cd:constant type="basic"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-bld.mkiv" name="setmainparbuilder"> + <cd:arguments> + <cd:keywords> + <cd:constant type="default"/> + <cd:constant type="oneline"/> + <cd:constant type="basic"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-pdf.xml"> + <cd:command file="back-pdf.mkiv" name="pdfbackendsetcatalog"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="back-pdf.mkiv" name="pdfbackendsetinfo"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="back-pdf.mkiv" name="pdfbackendsetname"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="back-pdf.mkiv" name="pdfbackendsetpageattribute"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="back-pdf.mkiv" name="pdfbackendsetpagesattribute"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="back-pdf.mkiv" name="pdfbackendsetpageresource"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="back-pdf.mkiv" name="pdfbackendsetextgstate"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="back-pdf.mkiv" name="pdfbackendsetcolorspace"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="back-pdf.mkiv" name="pdfbackendsetpattern"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="back-pdf.mkiv" name="pdfbackendsetshade"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="back-pdf.mkiv" name="pdfbackendcurrentresources"/> + <cd:command file="back-pdf.mkiv" name="pdfcolor"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="back-pdf.mkiv" name="PDFcolor"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="back-pdf.mkiv" name="TransparencyHack"/> + <cd:command file="pack-obj.mkiv" name="lastpredefinedsymbol"/> + <cd:command file="pack-obj.mkiv" name="predefinesymbol"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="back-pdf.mkiv" name="pdfbackendactualtext"> + <cd:arguments> + <cd:content/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="back-pdf.mkiv" name="pdfactualtext"> + <cd:arguments> + <cd:content/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="attr-neg.mkiv" name="negative" type="environment"/> + <cd:command file="attr-neg.mkiv" name="positive" type="environment"/> + <cd:command file="scrn-pag.mkvi" name="setuppagetransitions"> + <cd:arguments> + <cd:keywords> + <cd:constant default="yes" type="reset"/> + <cd:constant type="auto"/> + <cd:constant type="start"/> + <cd:constant type="random"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-penalty.xml"> + <cd:command file="spac-ver.mkiv" name="resetpenalties"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setpenalties"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="keeplinestogether"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setdefaultpenalties"/> + </cd:interface> + <cd:interface file="i-periods.xml"> + <cd:command file="enco-ini.mkiv" name="setupperiods"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + <cd:constant type="fit"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="symbol"> + <cd:constant type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="enco-ini.mkiv" name="periods"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="enco-ini.mkiv" name="periods" variant="assignment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupperiods"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="enco-ini.mkiv" name="unknown"/> + </cd:interface> + <cd:interface file="i-phantom.xml"> + <cd:command file="supp-box.mkiv" name="phantom"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="hphantom"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="vphantom"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-box.mkiv" name="phantombox"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-placement.xml"> + <cd:command file="pack-mis.mkiv" name="defineplacement"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupplacement"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-mis.mkiv" name="setupplacement"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="grid"> + <cd:inherit name="snaptogrid"/> + </cd:parameter> + <cd:parameter name="linecorrection"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + </cd:parameter> + <cd:parameter name="depthcorrection"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant default="yes" type="standard"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-mis.mkiv" name="placement"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupplacement"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="pack-mis.mkiv" generated="yes" name="placement" variant="example"> + <cd:sequence> + <cd:variable value="placement"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupplacement"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-position.xml"> + <cd:command file="anch-pgr.mkiv" name="doifpositionaction"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pgr.mkiv" name="doifelsepositionaction"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pgr.mkiv" name="doifpositionactionelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pgr.mkiv" name="dopositionaction"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pgr.mkiv" name="positionoverlay"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pgr.mkiv" name="MPoverlayanchor"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pgr.mkiv" name="positionregionoverlay"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pgr.mkiv" name="positionoverlay" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pgr.mkiv" name="MPpositiongraphic" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes" optional="yes"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pgr.mkiv" name="MPpositiongraphic"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments delimiters="braces" list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="anch-pgr.mkiv" name="MPpositionmethod" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pgr.mkiv" name="setMPpositiongraphic"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments delimiters="braces" list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="anch-pgr.mkiv" name="setMPpositiongraphicrange"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments delimiters="braces" list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="anch-pgr.mkiv" name="MPgetposboxes"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pgr.mkiv" name="MPgetmultipars"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pgr.mkiv" name="MPgetmultishape"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPp"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPr"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPc"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPn"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPx"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPy"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPw"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPh"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPd"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPwhd"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPxy"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPll"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPlr"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPur"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPul"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPpos"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPls"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPrs"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPpardata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPxywhd"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPposset"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPpage"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPregion"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPcolumn"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPanchor"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPleftskip"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPrightskip"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPplus"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPv"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPrest"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="MPvv"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="setpositiononly"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="setposition"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="setpositiondata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="setpositionbox"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="setpositionstrut"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="setpositiondataplus"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="setpositionplus"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="copyposition"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="doifposition"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="doifelseposition"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="doifpositionelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="doifelsepositiononpage"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="doifpositiononpageelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="xypos"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="hpos"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="vpos"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="bpos"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="epos"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="tracepositions"/> + <cd:command file="anch-pos.mkiv" name="enableparpositions"/> + <cd:command file="anch-pos.mkiv" name="disableparpositions"/> + <cd:command file="anch-pos.mkiv" name="doifelseoverlapping"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="doifoverlappingelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="doifelsepositionsonsamepage"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="doifpositionsonsamepageelse"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="doifelsepositionsonthispage"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="doifpositionsonthispageelse"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="doifelsepositionsused"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-pos.mkiv" name="doifpositionsusedelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-positionbar.xml"> + <cd:command file="pack-bar.mkiv" name="setuppositionbar"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="min"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="max"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="text"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-bar.mkiv" name="horizontalpositionbar"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setuppositionbar"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-bar.mkiv" name="verticalpositionbar"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setuppositionbar"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-bar.mkiv" name="horizontalgrowingbar"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setuppositionbar"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-bar.mkiv" name="verticalgrowingbar"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setuppositionbar"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-positioning.xml"> + <cd:command file="pack-pos.mkiv" name="definepositioning"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppositioning"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-pos.mkiv" name="setuppositioning"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="offset"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="unit"> + <cd:constant type="ex"/> + <cd:constant type="em"/> + <cd:constant type="pt"/> + <cd:constant type="in"/> + <cd:constant default="yes" type="cm"/> + <cd:constant type="mm"/> + <cd:constant type="sp"/> + <cd:constant type="bp"/> + <cd:constant type="pc"/> + <cd:constant type="dd"/> + <cd:constant type="cc"/> + <cd:constant type="nc"/> + </cd:parameter> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="overlay"/> + </cd:parameter> + <cd:parameter name="xoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="yoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="xstep"> + <cd:constant default="yes" type="absolute"/> + <cd:constant type="relative"/> + </cd:parameter> + <cd:parameter name="ystep"> + <cd:constant default="yes" type="absolute"/> + <cd:constant type="relative"/> + </cd:parameter> + <cd:parameter name="xscale"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="yscale"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="xfactor"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="yfactor"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="factor"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="scale"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-pos.mkiv" name="positioning" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppositioning"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-pos.mkiv" name="position"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppositioning"/> + </cd:assignments> + <cd:position list="yes"/> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-postponing.xml"> + <cd:command file="page-pst.mkiv" name="postponing" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant method="none" prefix="cd:sign" type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-processor.xml"> + <cd:command file="typo-prc.mkvi" name="defineprocessor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupprocessor"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-prc.mkvi" name="setupprocessor"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="typo-prc.mkvi" name="applyprocessor"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-profile.xml"> + <cd:command file="spac-prf.mkvi" name="defineprofile"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupprofile"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-prf.mkvi" name="setupprofile"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="factor"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="lines"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant default="yes" type="strict"/> + <cd:constant type="fixed"/> + <cd:constant type="none"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="spac-prf.mkvi" name="setprofile"> + <cd:arguments> + <cd:keywords> + <cd:constant type="none"/> + <cd:constant type="fixed"/> + <cd:constant type="strict"/> + <cd:constant type="halffixed"/> + <cd:constant type="quarterfixed"/> + <cd:constant type="eightsfixed"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-prf.mkvi" name="resetprofile"/> + <cd:command file="spac-prf.mkvi" name="useprofileparameter"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="spac-prf.mkvi" name="profiledbox"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="none"/> + <cd:constant type="fixed"/> + <cd:constant type="strict"/> + <cd:constant type="halffixed"/> + <cd:constant type="quarterfixed"/> + <cd:constant type="eightsfixed"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupprofile"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-prf.mkvi" name="profilegivenbox"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="none"/> + <cd:constant type="fixed"/> + <cd:constant type="strict"/> + <cd:constant type="halffixed"/> + <cd:constant type="quarterfixed"/> + <cd:constant type="eightsfixed"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-publication.xml"> + <cd:command file="publ-ini.mkiv" name="btxrenderingdefinitions" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="loadbtxdefinitionfile"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="loadbtxreplacementfile"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="definebtx"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbtx"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="setupbtx"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="specification"> + <cd:constant type="default"/> + <cd:constant type="apa"/> + <cd:constant type="aps"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="dataset"> + <cd:constant type="default"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="authorconversion"> + <cd:constant type="normal"/> + <cd:constant type="normalshort"/> + <cd:constant type="normalinverted"/> + <cd:constant type="invertedshort"/> + <cd:constant type="short"/> + </cd:parameter> + <cd:parameter name="etallimit"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="etaldisplay"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="etaloption"> + <cd:constant type="last"/> + </cd:parameter> + <cd:parameter name="stopper"> + <cd:constant type="initials"/> + </cd:parameter> + <cd:parameter name="interaction"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + <cd:constant type="all"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="sorttype"> + <cd:constant default="yes" type="normal"/> + <cd:constant type="reverse"/> + </cd:parameter> + <cd:parameter name="compress"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="default"> + <cd:constant type="default"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="setupbtx" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="usingbtxspecification" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="definebtxdataset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbtxdataset"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="setupbtxdataset"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="language"> + <cd:constant type="cd:language"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="definebtxregister"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbtxregister"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="setupbtxregister"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="dataset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="field"> + <cd:constant type="keyword"/> + <cd:constant type="range"/> + <cd:constant type="pagenumber"/> + <cd:constant type="author"/> + </cd:parameter> + <cd:parameter name="register"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="once"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="normalshort"/> + <cd:constant type="invertedshort"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="definebtxrendering"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbtxrendering"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="setupbtxrendering"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="textstate"> + <cd:constant type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="pagestate"> + <cd:constant type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="separator"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="criterium"> + <cd:constant type="previous"/> + <cd:constant type="cite"/> + <cd:constant type="here"/> + <cd:constant type="all"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="specification"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="dataset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="dataset"/> + <cd:constant type="force"/> + <cd:constant type="local"/> + <cd:constant type="global"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="sorttype"> + <cd:constant type="short"/> + <cd:constant type="dataset"/> + <cd:constant type="list"/> + <cd:constant type="reference"/> + <cd:constant type="used"/> + <cd:constant type="default"/> + <cd:constant type="cite"/> + <cd:constant type="index"/> + </cd:parameter> + <cd:parameter name="repeat"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="group"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="numbering"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="num"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="usebtxdataset"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="specification"> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="publication" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="tag"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="category"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="k"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="t"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="setupbtxlist"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="completebtxrendering"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbtxrendering"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="placebtxrendering"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbtxrendering"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="completelistofpublications"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbtxrendering"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="placelistofpublications"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupbtxrendering"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxhybridcite"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxhybridcite" variant="userdata"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxhybridcite" variant="alternative"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxhybridcite" variant="direct"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxlistcitation"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxlistcitation" variant="userdata"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxlistcitation" variant="alternative"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxtextcitation"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxtextcitation" variant="userdata"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxtextcitation" variant="alternative"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxalwayscitation"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxalwayscitation" variant="userdata"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxalwayscitation" variant="alternative"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="bthiddencitation"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="listcitation"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="listcitation" variant="userdata"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="listcitation" variant="alternative"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="listcite"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="listcite" variant="userdata"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="listcite" variant="alternative"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="textcitation"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="textcitation" variant="userdata"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="textcitation" variant="alternative"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="textcite"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="textcite" variant="userdata"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="textcite" variant="alternative"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="alwayscitation"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="alwayscitation" variant="userdata"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="alwayscitation" variant="alternative"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="alwayscite"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="alwayscite" variant="userdata"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="alwayscite" variant="alternative"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="hiddencitation"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="hiddencite"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="citation"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="citation" variant="userdata"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="citation" variant="alternative"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="citation" variant="direct"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="cite"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="cite" variant="userdata"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:inherit name="setupbtx"/> + </cd:assignments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="cite" variant="alternative"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="default"/> + <cd:constant type="category"/> + <cd:constant type="entry"/> + <cd:constant type="short"/> + <cd:constant type="page"/> + <cd:constant type="num"/> + <cd:constant type="textnum"/> + <cd:constant type="year"/> + <cd:constant type="index"/> + <cd:constant type="tag"/> + <cd:constant type="keywords"/> + <cd:constant type="author"/> + <cd:constant type="authoryears"/> + <cd:constant type="authornum"/> + <cd:constant type="authoryear"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="cite" variant="direct"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="nocitation"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="nocitation" variant="direct"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="nocite"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="nocite" variant="direct"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="savebtxdataset"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="dataset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="type"> + <cd:constant type="bib"/> + <cd:constant type="lua"/> + <cd:constant type="xml"/> + </cd:parameter> + <cd:parameter name="file"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="criterium"> + <cd:constant type="all"/> + <cd:constant type="text"/> + <cd:constant type="intro"/> + <cd:constant type="reference"/> + <cd:constant type="current"/> + <cd:constant type="here"/> + <cd:constant type="previous"/> + <cd:constant type="local"/> + <cd:constant type="component"/> + <cd:constant method="range" prefix="cd:sectionblock" type="all"/> + <cd:constant method="range" prefix="cd:sectionblock" type="reference"/> + <cd:constant method="range" prefix="cd:sectionblock" type="current"/> + <cd:constant method="range" prefix="cd:sectionblock" type="previous"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="placecitation"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="usebtxdefinitions"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxfield"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxdetail"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxflush"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxdirect"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxfieldname"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxfieldtype"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxfoundname"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxfoundtype"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxauthorfield"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="initials"/> + <cd:constant type="firstnames"/> + <cd:constant type="vons"/> + <cd:constant type="surnames"/> + <cd:constant type="juniors"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxdoifelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxdoif"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxdoifnot"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxsetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxdoifelsesameaspreviouschecked"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="always"/> + <cd:constant type="doublesided"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxdoifelsesameasprevious"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxdoifelsecombiinlist"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxdoifsameaspreviouscheckedelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="always"/> + <cd:constant type="doublesided"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxdoifsameaspreviouselse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxdoifcombiinlistelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="currentbtxuservariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxdoifelseuservariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxdoifuservariableelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxremapauthor"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxflushauthor"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="num"/> + <cd:constant type="normal"/> + <cd:constant type="normalshort"/> + <cd:constant type="inverted"/> + <cd:constant type="invertedshort"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="author"/> + <cd:constant type="editor"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxflushsuffix"/> + <cd:command file="publ-ini.mkiv" name="btxflushauthorname"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="author"/> + <cd:constant type="editor"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxflushauthornormal"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="author"/> + <cd:constant type="editor"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxflushauthornormalshort"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="author"/> + <cd:constant type="editor"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxflushauthorinverted"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="author"/> + <cd:constant type="editor"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxflushauthorinvertedshort"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="author"/> + <cd:constant type="editor"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxsingularplural"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="editor"/> + <cd:constant type="producer"/> + <cd:constant type="director"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxsingularorplural"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="editor"/> + <cd:constant type="producer"/> + <cd:constant type="director"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxoneorrange"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="volume"/> + <cd:constant type="pages"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxfirstofrange"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="volume"/> + <cd:constant type="pages"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxloadjournalist"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxsavejournalist"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxaddjournal"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxexpandedjournal"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-ini.mkiv" name="btxabbreviatedjournal"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-tra.mkiv" name="showbtxdatasetfields"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="specification"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="dataset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="field"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-tra.mkiv" name="showbtxdatasetfields" variant="argument"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-tra.mkiv" name="showbtxdatasetcompleteness"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="specification"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="dataset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="field"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-tra.mkiv" name="showbtxdatasetcompleteness" variant="argument"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-tra.mkiv" name="showbtxdatasetauthors"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="specification"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="dataset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="field"> + <cd:constant type="address"/> + <cd:constant type="assignee"/> + <cd:constant type="author"/> + <cd:constant type="booktitle"/> + <cd:constant type="chapter"/> + <cd:constant type="day"/> + <cd:constant type="dayfiled"/> + <cd:constant type="edition"/> + <cd:constant type="editor"/> + <cd:constant type="howpublished"/> + <cd:constant type="institution"/> + <cd:constant type="journal"/> + <cd:constant type="language"/> + <cd:constant type="month"/> + <cd:constant type="monthfiled"/> + <cd:constant type="nationality"/> + <cd:constant type="note"/> + <cd:constant type="number"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="organization"/> + <cd:constant type="pages"/> + <cd:constant type="publisher"/> + <cd:constant type="school"/> + <cd:constant type="series"/> + <cd:constant type="title"/> + <cd:constant type="type"/> + <cd:constant type="volume"/> + <cd:constant type="year"/> + <cd:constant type="yearfiled"/> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-tra.mkiv" name="showbtxdatasetauthors" variant="argument"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-tra.mkiv" name="showbtxhashedauthors"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-tra.mkiv" name="showbtxfields"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="rotation"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="specification"> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="publ-tra.mkiv" name="showbtxfields" variant="argument"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="publ-tra.mkiv" name="showbtxtables"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-random.xml"> + <cd:command file="supp-ran.mkiv" name="getrandomcount"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-ran.mkiv" name="getrandomdimen"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-ran.mkiv" name="getrandomnumber"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-ran.mkiv" name="getrandomfloat"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-ran.mkiv" name="setrandomseed"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-ran.mkiv" name="getrandomseed"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command begin="push" end="pop" file="supp-ran.mkiv" name="randomseed" type="environment"/> + <cd:command file="supp-ran.mkiv" name="reuserandomseed"/> + <cd:command file="supp-ran.mkiv" name="randomnumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-ran.mkiv" name="mprandomnumber"/> + </cd:interface> + <cd:interface file="i-references.xml"> + <cd:command file="strc-ref.mkvi" name="setupreferencing"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="expansion"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="xml"/> + </cd:parameter> + <cd:parameter name="autofile"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="export"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="doublesided"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="interaction"> + <cd:constant type="label"/> + <cd:constant type="text"/> + <cd:constant type="symbol"/> + <cd:constant default="yes" type="all"/> + </cd:parameter> + <cd:parameter name="separator"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="prefix"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="textreference"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="pagereference"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="reference"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="setreference"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="usereferenceparameter"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="boxreference"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="hboxreference"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="vboxreference"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="contentreference"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="definereference"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="resetreference"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="setpagereference"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="doifelsereferencefound"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="doifreferencefoundelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="setupreferenceprefix"> + <cd:arguments> + <cd:keywords> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="setupglobalreferenceprefix"> + <cd:arguments> + <cd:keywords> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command begin="push" end="pop" file="strc-ref.mkvi" name="referenceprefix" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command begin="globalpush" end="globalpop" file="strc-ref.mkvi" name="referenceprefix" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="referenceprefix"/> + <cd:command file="strc-ref.mkvi" name="in"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="at"> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="about"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="from"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="over"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="filterreference"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="default"/> + <cd:constant type="text"/> + <cd:constant type="title"/> + <cd:constant type="number"/> + <cd:constant type="page"/> + <cd:constant type="realpage"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="getreferenceentry"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="default"/> + <cd:constant type="text"/> + <cd:constant type="title"/> + <cd:constant type="number"/> + <cd:constant type="page"/> + <cd:constant type="realpage"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="getreference"> + <cd:arguments> + <cd:keywords> + <cd:constant type="default"/> + <cd:constant type="text"/> + <cd:constant type="title"/> + <cd:constant type="number"/> + <cd:constant type="page"/> + <cd:constant type="realpage"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="ref"> + <cd:arguments> + <cd:keywords> + <cd:constant type="default"/> + <cd:constant type="text"/> + <cd:constant type="title"/> + <cd:constant type="number"/> + <cd:constant type="page"/> + <cd:constant type="realpage"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="somewhere"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="docheckedpagestate"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="someplace"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="atpage"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="symbolreference"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="definereferenceformat"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupreferenceformat"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="setupreferenceformat"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="label"> + <cd:constant type="*"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="type"> + <cd:constant type="default"/> + <cd:constant type="text"/> + <cd:constant type="title"/> + <cd:constant type="number"/> + <cd:constant type="page"/> + <cd:constant type="realpage"/> + </cd:parameter> + <cd:parameter name="setups"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="autocase"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="text"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" generated="yes" name="referenceformat" variant="example"> + <cd:sequence> + <cd:variable value="referenceformat"/> + </cd:sequence> + <cd:arguments> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="goto"> + <cd:arguments> + <cd:content/> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="goto" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="gotobox"> + <cd:arguments> + <cd:content/> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="useurl"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:url"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="useURL"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:url"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="usefile"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="useexternaldocument"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="doifelseurldefined"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="doifurldefinedelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="doifelsefiledefined"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="doiffiledefinedelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="setupurl"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="url"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="defineprogram"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="setupprograms"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="program"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="definepage"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="gotopage"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:reference"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-ref.mkvi" name="setupreferencestructureprefix"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:section"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="default"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="prefix"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="prefixseparatorset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="prefixconversion"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="prefixconversionset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="prefixstarter"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="prefixstopper"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="prefixset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="prefixsegments"> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="*"/> + <cd:constant method="range" prefix="cd:number" type="all"/> + <cd:constant type="cd:section"/> + <cd:constant method="range" prefix="cd:section" type="cd:section"/> + <cd:constant method="range" prefix="cd:section" type="*"/> + <cd:constant method="range" prefix="cd:section" type="all"/> + </cd:parameter> + <cd:parameter name="numberconversion"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="numberconversionset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="numberstarter"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="numberstopper"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="numbersegments"> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="*"/> + <cd:constant method="range" prefix="cd:number" type="all"/> + </cd:parameter> + <cd:parameter name="numberseparatorset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="prefixconnector"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-regime.xml"> + <cd:command file="regi-ini.mkiv" name="currentregime"/> + <cd:command file="regi-ini.mkiv" name="disableregime"/> + <cd:command file="regi-ini.mkiv" name="enableregime"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cp1250"/> + <cd:constant type="cp1251"/> + <cd:constant type="cp1252"/> + <cd:constant type="cp1253"/> + <cd:constant type="cp1254"/> + <cd:constant type="cp1255"/> + <cd:constant type="cp1256"/> + <cd:constant type="cp1257"/> + <cd:constant type="cp1258"/> + <cd:constant type="8859-1"/> + <cd:constant type="8859-2"/> + <cd:constant type="8859-3"/> + <cd:constant type="8859-4"/> + <cd:constant type="8859-9"/> + <cd:constant type="8859-10"/> + <cd:constant type="8859-13"/> + <cd:constant type="8859-14"/> + <cd:constant type="8859-15"/> + <cd:constant type="8859-16"/> + <cd:constant type="utf"/> + <cd:constant type="windows-1250"/> + <cd:constant type="windows-1251"/> + <cd:constant type="windows-1252"/> + <cd:constant type="windows-1253"/> + <cd:constant type="windows-1254"/> + <cd:constant type="windows-1255"/> + <cd:constant type="windows-1256"/> + <cd:constant type="windows-1257"/> + <cd:constant type="windows-1258"/> + <cd:constant type="il1"/> + <cd:constant type="il2"/> + <cd:constant type="il3"/> + <cd:constant type="il4"/> + <cd:constant type="il5"/> + <cd:constant type="il6"/> + <cd:constant type="il7"/> + <cd:constant type="il8"/> + <cd:constant type="il9"/> + <cd:constant type="il10"/> + <cd:constant type="iso-8859-1"/> + <cd:constant type="iso-8859-2"/> + <cd:constant type="iso-8859-3"/> + <cd:constant type="iso-8859-4"/> + <cd:constant type="iso-8859-9"/> + <cd:constant type="iso-8859-10"/> + <cd:constant type="iso-8859-13"/> + <cd:constant type="iso-8859-14"/> + <cd:constant type="iso-8859-15"/> + <cd:constant type="iso-8859-16"/> + <cd:constant type="latin1"/> + <cd:constant type="latin2"/> + <cd:constant type="latin3"/> + <cd:constant type="latin4"/> + <cd:constant type="latin5"/> + <cd:constant type="latin6"/> + <cd:constant type="latin7"/> + <cd:constant type="latin8"/> + <cd:constant type="latin9"/> + <cd:constant type="latin10"/> + <cd:constant type="utf-8"/> + <cd:constant type="utf8"/> + <cd:constant type="windows"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="regi-ini.mkiv" name="regime" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:inherit name="enableregime"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-register.xml"> + <cd:command file="strc-reg.mkiv" name="defineregister"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupregister"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-reg.mkiv" name="setupregister" variant="argument"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="referencemethod"> + <cd:constant type="forward"/> + </cd:parameter> + <cd:parameter name="expansion"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="xml"/> + </cd:parameter> + <cd:parameter name="ownnumber"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="xmlsetup"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="a"/> + <cd:constant type="b"/> + <cd:constant type="A"/> + <cd:constant type="B"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="default"/> + <cd:constant type="before"/> + <cd:constant type="after"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="ch"/> + <cd:constant type="mm"/> + <cd:constant type="zm"/> + <cd:constant type="pm"/> + <cd:constant type="mc"/> + <cd:constant type="zc"/> + <cd:constant type="pc"/> + <cd:constant type="uc"/> + </cd:parameter> + <cd:parameter name="compress"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="all"/> + </cd:parameter> + <cd:parameter name="criterium"> + <cd:constant type="local"/> + <cd:constant type="text"/> + <cd:constant type="current"/> + <cd:constant type="previous"/> + <cd:constant default="yes" type="all"/> + <cd:constant type="cd:section"/> + </cd:parameter> + <cd:parameter name="pageprefixseparatorset"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="pageprefixconversionset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="pageprefixstarter"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="pageprefixstopper"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="pageprefixset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="pageprefixsegments"> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="*"/> + <cd:constant method="range" prefix="cd:number" type="all"/> + <cd:constant type="cd:section"/> + <cd:constant method="range" prefix="cd:section" type="cd:section"/> + <cd:constant method="range" prefix="cd:section" type="*"/> + <cd:constant method="range" prefix="cd:section" type="all"/> + </cd:parameter> + <cd:parameter name="pageprefixconnector"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="pageprefix"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="pageseparatorset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="pageconversionset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="pagestarter"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="pagestopper"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="pagesegments"> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="*"/> + <cd:constant method="range" prefix="cd:number" type="all"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="indicator"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="textcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="deeptextcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="pagecommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="interaction"> + <cd:constant type="text"/> + <cd:constant default="yes" type="pagenumber"/> + </cd:parameter> + <cd:parameter name="pagenumber"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="symbol"> + <cd:constant type="a"/> + <cd:constant default="yes" type="n"/> + <cd:constant type="none"/> + <cd:constant type="1"/> + <cd:constant type="2"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="language"> + <cd:constant type="default"/> + <cd:constant type="DIN␣5007-1"/> + <cd:constant type="DIN␣5007-2"/> + <cd:constant type="Duden"/> + <cd:constant type="de-DE"/> + <cd:constant type="de-CH"/> + <cd:constant type="de-AT"/> + <cd:constant type="ru-iso9"/> + <cd:constant type="ocs-scn"/> + <cd:constant type="cd:language"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="textstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="textcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="pagestyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="pagecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="balance"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="numberorder"> + <cd:constant default="yes" type="numbers"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-reg.mkiv" name="setupregister"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + <cd:constant method="range" prefix="cd:name" type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="referencemethod"> + <cd:constant type="forward"/> + </cd:parameter> + <cd:parameter name="expansion"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="xml"/> + </cd:parameter> + <cd:parameter name="ownnumber"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="xmlsetup"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="a"/> + <cd:constant type="b"/> + <cd:constant type="A"/> + <cd:constant type="B"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="default"/> + <cd:constant type="before"/> + <cd:constant type="after"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="ch"/> + <cd:constant type="mm"/> + <cd:constant type="zm"/> + <cd:constant type="pm"/> + <cd:constant type="mc"/> + <cd:constant type="zc"/> + <cd:constant type="pc"/> + <cd:constant type="uc"/> + </cd:parameter> + <cd:parameter name="compress"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="all"/> + </cd:parameter> + <cd:parameter name="criterium"> + <cd:constant type="local"/> + <cd:constant type="text"/> + <cd:constant type="current"/> + <cd:constant type="previous"/> + <cd:constant default="yes" type="all"/> + <cd:constant type="cd:section"/> + </cd:parameter> + <cd:parameter name="pageprefixseparatorset"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="pageprefixconversionset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="pageprefixstarter"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="pageprefixstopper"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="pageprefixset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="pageprefixsegments"> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="*"/> + <cd:constant method="range" prefix="cd:number" type="all"/> + <cd:constant type="cd:section"/> + <cd:constant method="range" prefix="cd:section" type="cd:section"/> + <cd:constant method="range" prefix="cd:section" type="*"/> + <cd:constant method="range" prefix="cd:section" type="all"/> + </cd:parameter> + <cd:parameter name="pageprefixconnector"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="pageprefix"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="pageseparatorset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="pageconversionset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="pagestarter"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="pagestopper"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="pagesegments"> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="*"/> + <cd:constant method="range" prefix="cd:number" type="all"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="indicator"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="textcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="deeptextcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="pagecommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="interaction"> + <cd:constant type="text"/> + <cd:constant default="yes" type="pagenumber"/> + </cd:parameter> + <cd:parameter name="pagenumber"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="symbol"> + <cd:constant type="a"/> + <cd:constant default="yes" type="n"/> + <cd:constant type="none"/> + <cd:constant type="1"/> + <cd:constant type="2"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="language"> + <cd:constant type="default"/> + <cd:constant type="DIN␣5007-1"/> + <cd:constant type="DIN␣5007-2"/> + <cd:constant type="Duden"/> + <cd:constant type="de-DE"/> + <cd:constant type="de-CH"/> + <cd:constant type="de-AT"/> + <cd:constant type="ru-iso9"/> + <cd:constant type="ocs-scn"/> + <cd:constant type="cd:language"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="textstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="textcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="pagestyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="pagecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="balance"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="numberorder"> + <cd:constant default="yes" type="numbers"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-reg.mkiv" name="setupregisters" variant="argument"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupregister"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-reg.mkiv" name="setupregisters"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + <cd:constant method="range" prefix="cd:name" type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupregister"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-reg.mkiv" generated="yes" name="register" variant="instance"> + <cd:sequence> + <cd:instance value="register"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:text"/> + </cd:keywords> + <cd:index list="yes"/> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-reg.mkiv" generated="yes" name="register" variant="instance:ownnumber"> + <cd:sequence> + <cd:instance value="register"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:index list="yes"/> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-reg.mkiv" generated="yes" name="seeregister" variant="instance"> + <cd:sequence> + <cd:string value="see"/> + <cd:instance value="register"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:text"/> + </cd:keywords> + <cd:index list="yes"/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:text"/> + </cd:keywords> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-reg.mkiv" generated="yes" name="placeregister" variant="instance"> + <cd:sequence> + <cd:string value="place"/> + <cd:instance value="register"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupregister"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-reg.mkiv" generated="yes" name="completeregister" variant="instance"> + <cd:sequence> + <cd:string value="complete"/> + <cd:instance value="register"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupregister"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-reg.mkiv" generated="yes" name="setupregister" variant="instance"> + <cd:sequence> + <cd:string value="setup"/> + <cd:instance value="register"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupregister"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-reg.mkiv" name="startregister"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:text"/> + </cd:keywords> + <cd:index list="yes"/> + </cd:arguments> + </cd:command> + <cd:command file="strc-reg.mkiv" name="stopregister"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-reg.mkiv" name="setregisterentry"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="label"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="keys"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:text"/> + </cd:parameter> + <cd:parameter name="entries"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:text"/> + </cd:parameter> + <cd:parameter name="keys:1"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="keys:2"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="keys:3"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="entries:1"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="entries:2"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="entries:3"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-reg.mkiv" name="finishregisterentry"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="label"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="keys"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:text"/> + </cd:parameter> + <cd:parameter name="entries"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:text"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-reg.mkiv" name="setstructurepageregister"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="label"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="keys"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:text"/> + </cd:parameter> + <cd:parameter name="entries"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:text"/> + </cd:parameter> + <cd:parameter name="keys:1"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="keys:2"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="keys:3"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="entries:1"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="entries:2"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="entries:3"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-reg.mkiv" name="startstructurepageregister"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="label"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="keys"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:text"/> + </cd:parameter> + <cd:parameter name="entries"> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:text"/> + </cd:parameter> + <cd:parameter name="keys:1"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="keys:2"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="keys:3"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="entries:1"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="entries:2"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="entries:3"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-reg.mkiv" name="stopstructurepageregister"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-reg.mkiv" name="determineregistercharacteristics"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="language"> + <cd:constant type="default"/> + <cd:constant type="DIN␣5007-1"/> + <cd:constant type="DIN␣5007-2"/> + <cd:constant type="Duden"/> + <cd:constant type="de-DE"/> + <cd:constant type="de-CH"/> + <cd:constant type="de-AT"/> + <cd:constant type="ru-iso9"/> + <cd:constant type="ocs-scn"/> + <cd:constant type="cd:language"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="default"/> + <cd:constant type="before"/> + <cd:constant type="after"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="ch"/> + <cd:constant type="mm"/> + <cd:constant type="zm"/> + <cd:constant type="pm"/> + <cd:constant type="mc"/> + <cd:constant type="zc"/> + <cd:constant type="pc"/> + <cd:constant type="uc"/> + </cd:parameter> + <cd:parameter name="numberorder"> + <cd:constant default="yes" type="numbers"/> + </cd:parameter> + <cd:parameter name="compress"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="all"/> + </cd:parameter> + <cd:parameter name="criterium"> + <cd:constant type="local"/> + <cd:constant type="text"/> + <cd:constant type="current"/> + <cd:constant type="previous"/> + <cd:constant default="yes" type="all"/> + <cd:constant type="cd:section"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-reg.mkiv" name="utilityregisterlength"/> + <cd:command file="strc-reg.mkiv" name="placeregister"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupregister"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-reg.mkiv" name="completeregister"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupregister"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-reg.mkiv" name="currentregisterpageuserdata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-renderingwindow.xml"> + <cd:command file="scrn-wid.mkvi" name="useexternalrendering"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="auto"/> + <cd:constant type="embed"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-wid.mkvi" name="setinternalrendering"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="auto"/> + <cd:constant type="embed"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="scrn-wid.mkvi" name="definerenderingwindow"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuprenderingwindow"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-wid.mkvi" name="setuprenderingwindow"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="openpageaction"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="closepageaction"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-wid.mkvi" name="placerenderingwindow"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-replacement.xml"> + <cd:command file="lang-rep.mkiv" name="replaceword"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-rep.mkiv" name="setreplacement"> + <cd:arguments> + <cd:keywords> + <cd:constant type="reset"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="lang-rep.mkiv" name="resetreplacement"/> + </cd:interface> + <cd:interface file="i-rotatation.xml"> + <cd:command file="grph-trf.mkiv" name="mirror"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="grph-trf.mkiv" name="setuprotate"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="location"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="depth"/> + <cd:constant type="high"/> + <cd:constant type="middle"/> + <cd:constant type="default"/> + <cd:constant type="normal"/> + </cd:parameter> + <cd:parameter name="rotation"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="inner"/> + <cd:constant type="outer"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="grph-trf.mkiv" name="rotate"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuprotate"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="grph-trf.mkiv" name="dorotatebox"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-scale.xml"> + <cd:command file="grph-trf.mkiv" name="definescale"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupscale"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="grph-trf.mkiv" name="setupscale"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="scale"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="xscale"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="yscale"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="lines"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="factor"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="max"/> + <cd:constant type="auto"/> + <cd:constant type="default"/> + </cd:parameter> + <cd:parameter name="hfactor"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="max"/> + <cd:constant type="auto"/> + <cd:constant type="default"/> + </cd:parameter> + <cd:parameter name="wfactor"> + <cd:constant type="fit"/> + <cd:constant type="broad"/> + <cd:constant type="max"/> + <cd:constant type="auto"/> + <cd:constant type="default"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="maxheight"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="s"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="sx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="sy"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="equalwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="equalheight"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="grid"> + <cd:constant type="yes"/> + <cd:constant type="fit"/> + <cd:constant type="height"/> + <cd:constant type="depth"/> + <cd:constant type="halfline"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="grph-trf.mkiv" name="scale"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupscale"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="grph-trf.mkiv" name="fastscale"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="grph-trf.mkiv" name="fastsxsy"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-script.xml"> + <cd:command file="scrp-ini.mkvi" name="definescript"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupscript"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrp-ini.mkvi" name="setupscript"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="method"> + <cd:constant type="hangul"/> + <cd:constant type="hanzi"/> + <cd:constant type="nihongo"/> + <cd:constant type="ethiopic"/> + <cd:constant type="thai"/> + <cd:constant type="test"/> + </cd:parameter> + <cd:parameter name="preset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="features"> + <cd:constant type="auto"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrp-ini.mkvi" name="setupscripts"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupscript"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrp-ini.mkvi" name="setscript"> + <cd:arguments> + <cd:keywords> + <cd:constant type="hangul"/> + <cd:constant type="hanzi"/> + <cd:constant type="nihongo"/> + <cd:constant type="ethiopic"/> + <cd:constant type="thai"/> + <cd:constant type="test"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrp-ini.mkvi" name="resetscript"/> + <cd:command file="scrp-ini.mkvi" name="script" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="hangul"/> + <cd:constant type="hanzi"/> + <cd:constant type="nihongo"/> + <cd:constant type="ethiopic"/> + <cd:constant type="thai"/> + <cd:constant type="test"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrp-ini.mkvi" generated="yes" name="script" varianet="instance"> + <cd:sequence> + <cd:instance value="script"/> + </cd:sequence> + <cd:instances/> + </cd:command> + </cd:interface> + <cd:interface file="i-section.xml"> + <cd:command file="strc-sec.mkiv" name="definehead"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:section"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuphead"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="setuphead"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:section"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="frontpartlabel"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="bodypartlabel"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="appendixlabel"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="backpartlabel"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="expansion"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="xml"/> + </cd:parameter> + <cd:parameter name="catcodes"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="sectionresetset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="sectionseparatorset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="sectionconversionset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="conversion"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="sectionstarter"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="sectionstopper"> + <cd:constant type="cd:command"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:command"/> + </cd:parameter> + <cd:parameter name="sectionset"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="sectionsegments"> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="*"/> + <cd:constant method="range" prefix="cd:number" type="all"/> + <cd:constant type="cd:section"/> + <cd:constant method="range" prefix="cd:section" type="cd:section"/> + <cd:constant method="range" prefix="cd:section" type="*"/> + <cd:constant method="range" prefix="cd:section" type="all"/> + </cd:parameter> + <cd:parameter name="referenceprefix"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="textstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="textcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="numberstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="numbercolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="coupling"> + <cd:constant type="cd:section"/> + </cd:parameter> + <cd:parameter name="ownnumber"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="beforesection"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="aftersection"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="insidesection"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="incrementnumber"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + <cd:constant type="list"/> + <cd:constant type="empty"/> + </cd:parameter> + <cd:parameter name="placehead"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + <cd:constant type="hidden"/> + <cd:constant type="empty"/> + </cd:parameter> + <cd:parameter name="number"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="page"> + <cd:inherit name="page"/> + </cd:parameter> + <cd:parameter name="marking"> + <cd:constant type="page"/> + <cd:constant type="reset"/> + </cd:parameter> + <cd:parameter name="header"> + <cd:constant type="start"/> + <cd:constant type="stop"/> + <cd:constant type="high"/> + <cd:constant type="none"/> + <cd:constant type="normal"/> + <cd:constant type="empty"/> + <cd:constant type="nomarking"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="text"> + <cd:constant type="start"/> + <cd:constant type="stop"/> + <cd:constant type="high"/> + <cd:constant type="none"/> + <cd:constant type="normal"/> + <cd:constant type="empty"/> + <cd:constant type="nomarking"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="footer"> + <cd:constant type="start"/> + <cd:constant type="stop"/> + <cd:constant type="high"/> + <cd:constant type="none"/> + <cd:constant type="normal"/> + <cd:constant type="empty"/> + <cd:constant type="nomarking"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="continue"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="aligntitle"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="float"/> + </cd:parameter> + <cd:parameter name="interlinespace"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="interaction"> + <cd:constant type="list"/> + <cd:constant type="reference"/> + </cd:parameter> + <cd:parameter name="internalgrid"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="grid"> + <cd:constant type="normal"/> + <cd:constant type="standard"/> + <cd:constant type="yes"/> + <cd:constant type="strict"/> + <cd:constant type="tolerant"/> + <cd:constant type="top"/> + <cd:constant type="bottom"/> + <cd:constant type="both"/> + <cd:constant type="broad"/> + <cd:constant type="fit"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="high"/> + <cd:constant type="one"/> + <cd:constant type="low"/> + <cd:constant type="none"/> + <cd:constant type="line"/> + <cd:constant type="strut"/> + <cd:constant type="box"/> + <cd:constant type="min"/> + <cd:constant type="max"/> + <cd:constant type="middle"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="tolerance"> + <cd:inherit name="setuptolerance"/> + </cd:parameter> + <cd:parameter name="strut"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="hang"> + <cd:constant type="line"/> + <cd:constant type="broad"/> + <cd:constant type="fit"/> + <cd:constant default="yes" type="none"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="indentnext"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="text"/> + <cd:constant type="paragraph"/> + <cd:constant default="yes" type="normal"/> + <cd:constant type="margin"/> + <cd:constant type="inmargin"/> + <cd:constant type="top"/> + <cd:constant type="middle"/> + <cd:constant type="bottom"/> + <cd:constant type="reverse"/> + <cd:constant type="margintext"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="numberwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="textwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="textdistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="commandbefore"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="commandafter"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:twoarguments"/> + </cd:parameter> + <cd:parameter name="textcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="deeptextcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="numbercommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="deepnumbercommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="setupheads"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:section"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setuphead"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" generated="yes" name="section" variant="instance"> + <cd:sequence> + <cd:instance value="section"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + <cd:instances> + <cd:constant value="chapter"/> + <cd:constant value="section"/> + <cd:constant value="subsection"/> + <cd:constant value="subsubsection"/> + <cd:constant value="subsubsubsection"/> + <cd:constant value="subsubsubsubsection"/> + <cd:constant value="title"/> + <cd:constant value="subject"/> + <cd:constant value="subsubject"/> + <cd:constant value="subsubsubject"/> + <cd:constant value="subsubsubsubject"/> + <cd:constant value="subsubsubsubsubject"/> + </cd:instances> + </cd:command> + <cd:command file="strc-sec.mkiv" generated="yes" name="section" variant="instance:ownnumber"> + <cd:sequence> + <cd:instance value="section"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:reference"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + <cd:instances> + <cd:constant value="chapter"/> + <cd:constant value="section"/> + <cd:constant value="subsection"/> + <cd:constant value="subsubsection"/> + <cd:constant value="subsubsubsection"/> + <cd:constant value="subsubsubsubsection"/> + <cd:constant value="title"/> + <cd:constant value="subject"/> + <cd:constant value="subsubject"/> + <cd:constant value="subsubsubject"/> + <cd:constant value="subsubsubsubject"/> + <cd:constant value="subsubsubsubsubject"/> + </cd:instances> + </cd:command> + <cd:command file="strc-sec.mkiv" generated="yes" name="section" variant="instance:assignment"> + <cd:sequence> + <cd:instance value="section"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="marking"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="list"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="ownnumber"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + <cd:instances> + <cd:constant value="chapter"/> + <cd:constant value="section"/> + <cd:constant value="subsection"/> + <cd:constant value="subsubsection"/> + <cd:constant value="subsubsubsection"/> + <cd:constant value="subsubsubsubsection"/> + <cd:constant value="title"/> + <cd:constant value="subject"/> + <cd:constant value="subsubject"/> + <cd:constant value="subsubsubject"/> + <cd:constant value="subsubsubsubject"/> + <cd:constant value="subsubsubsubsubject"/> + </cd:instances> + </cd:command> + <cd:command file="strc-sec.mkiv" generated="yes" name="section" type="environment" variant="instance"> + <cd:sequence> + <cd:instance value="section"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="marking"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="list"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="ownnumber"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + <cd:instances> + <cd:constant value="chapter"/> + <cd:constant value="section"/> + <cd:constant value="subsection"/> + <cd:constant value="subsubsection"/> + <cd:constant value="subsubsubsection"/> + <cd:constant value="subsubsubsubsection"/> + <cd:constant value="title"/> + <cd:constant value="subject"/> + <cd:constant value="subsubject"/> + <cd:constant value="subsubsubject"/> + <cd:constant value="subsubsubsubject"/> + <cd:constant value="subsubsubsubsubject"/> + </cd:instances> + </cd:command> + <cd:command file="strc-sec.mkiv" name="namedsection" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:section"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="marking"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="list"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="ownnumber"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="definesection"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="placeheadtext"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:section"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="placeheadnumber"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:section"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="setupheadnumber"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:section"/> + </cd:keywords> + <cd:keywords> + <cd:constant method="none" prefix="cd:sign" type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="determineheadnumber"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:section"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="currentheadnumber"/> + <cd:command file="strc-sec.mkiv" name="namedheadnumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:section"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="somenamedheadnumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:section"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="previous"/> + <cd:constant type="current"/> + <cd:constant type="next"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="headnumber"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:section"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="previous"/> + <cd:constant default="yes" type="current"/> + <cd:constant type="next"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="someheadnumber"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:section"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="previous"/> + <cd:constant type="current"/> + <cd:constant type="next"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="namedstructureheadlocation"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:section"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="structurenumber"/> + <cd:command file="strc-sec.mkiv" name="structuretitle"/> + <cd:command file="strc-sec.mkiv" name="structurevariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="structureuservariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="namedstructurevariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:section"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-sec.mkiv" name="namedstructureuservariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:section"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-lev.mkvi" name="definesectionlevels"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:section"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-lev.mkvi" name="sectionlevel" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="marking"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="list"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="ownnumber"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-lev.mkvi" name="subjectlevel" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="marking"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="list"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:parameter name="ownnumber"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-ren.mkiv" name="defineheadalternative"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupheadalternative"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-ren.mkiv" name="setupheadalternative"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="alternative"> + <cd:constant type="horizontal"/> + <cd:constant default="yes" type="vertical"/> + <cd:constant type="somewhere"/> + </cd:parameter> + <cd:parameter name="renderingsetup"> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-ren.mkiv" name="localheadsetup" type="environment"/> + <cd:command file="strc-ren.mkiv" name="headhbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="strc-ren.mkiv" name="headvbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="strc-ren.mkiv" name="headreferenceattributes"/> + <cd:command file="strc-ren.mkiv" name="headnumbercontent"/> + <cd:command file="strc-ren.mkiv" name="headtextcontent"/> + <cd:command file="strc-ren.mkiv" name="headwidth"/> + <cd:command file="strc-ren.mkiv" name="headtextwidth"/> + <cd:command file="strc-ren.mkiv" name="headnumberwidth"/> + <cd:command file="strc-ren.mkiv" name="headnumberdistance"/> + <cd:command file="strc-ren.mkiv" name="headtextdistance"/> + <cd:command file="strc-ren.mkiv" name="headsetupspacing"/> + </cd:interface> + <cd:interface file="i-sectionblock.xml"> + <cd:command file="strc-sbe.mkiv" name="definesectionblock"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsectionblock"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-sbe.mkiv" name="setupsectionblock"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="page"> + <cd:inherit name="page"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="number"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-sbe.mkiv" name="setsectionblock"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-sbe.mkiv" name="sectionblock" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:inherit name="setupsectionblock"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-sbe.mkiv" generated="yes" name="sectionblock" type="environment" variant="instance"> + <cd:sequence> + <cd:instance value="sectionblock"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:inherit name="setupsectionblock"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-sbe.mkiv" name="sectionblockenvironment" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-selector.xml"> + <cd:command file="core-env.mkiv" name="defineselector"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupselector"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setupselector"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="m"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="select"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content optional="yes"/> + <cd:content optional="yes"/> + <cd:content optional="yes"/> + <cd:content optional="yes"/> + <cd:content optional="yes"/> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="directselect"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content optional="yes"/> + <cd:content optional="yes"/> + <cd:content optional="yes"/> + <cd:content optional="yes"/> + <cd:content optional="yes"/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-setups.xml"> + <cd:command file="core-env.mkiv" name="setups"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setups" variant="direct"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setup"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setup" variant="direct"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="directsetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="fastsetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="texsetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="luasetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="systemsetups"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="resetsetups"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="showsetupsdefinition"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setupwithargument"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="fastsetupwithargument"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setupwithargumentswapped"> + <cd:arguments> + <cd:content/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="fastsetupwithargumentswapped"> + <cd:arguments> + <cd:content/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="usesetupsparameter"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="autosetups"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doprocesslocalsetups"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifelsesetups"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifsetupselse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifsetups"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifnotsetups"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="luasetups" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="grid"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="luasetups" type="environment" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="xmlsetups" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="grid"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="xmlsetups" type="environment" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="rawsetups" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="grid"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="rawsetups" type="environment" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="localsetups" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="grid"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="localsetups" type="environment" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setups" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="grid"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setups" type="environment" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-shift.xml"> + <cd:command file="node.rul.mkiv" name="defineshift"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupshift"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" name="setupshift"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="continue"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="unit"> + <cd:constant default="yes" type="ex"/> + <cd:constant type="em"/> + <cd:constant type="pt"/> + <cd:constant type="in"/> + <cd:constant type="cm"/> + <cd:constant type="mm"/> + <cd:constant type="sp"/> + <cd:constant type="bp"/> + <cd:constant type="pc"/> + <cd:constant type="dd"/> + <cd:constant type="cc"/> + <cd:constant type="nc"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="dy"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="node-rul.mkiv" generated="yes" name="shift" variant="instance"> + <cd:sequence> + <cd:instance value="shift"/> + </cd:sequence> + <cd:arguments> + <cd:content/> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="node-rul.mkiv" name="shift" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-sidebar.xml"> + <cd:command file="anch-bar.mkiv" name="definesidebar"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsidebar"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="anch-bar.mkiv" name="setupsidebar"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rulecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="topoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bottomoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="leftmargindistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="level"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="anch-bar.mkiv" name="sidebar" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsidebar"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="anch-bar.mkiv" name="setupmarginrule"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupsidebar"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="anch-bar.mkiv" name="setupmarginrules"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupmarginrule"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="anch-bar.mkiv" name="marginrule" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="anch-bar.mkiv" name="marginrule" type="environment" variant="assignment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmarginrule"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-smash.xml"> + <cd:command file="supp-box.mkiv" name="smashbox"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="smashboxed"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="hsmashbox"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="vsmashbox"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="hsmash"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="vsmash"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="hsmashed"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="vsmashed"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="smashedhbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="smashedvbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="supp-box.mkiv" name="smash"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="w"/> + <cd:constant default="yes" type="h"/> + <cd:constant default="yes" type="d"/> + <cd:constant type="t"/> + <cd:constant type="b"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-sort.xml"> + <cd:command file="strc-syn.mkiv" name="definesorting"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:plural"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="none"/> + <cd:constant type="cd:csname"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" name="setupsorting"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="expansion"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="xml"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="normal"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="next"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:threearguments"/> + </cd:parameter> + <cd:parameter name="textcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="synonymcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="language"> + <cd:constant type="default"/> + <cd:constant type="DIN␣5007-1"/> + <cd:constant type="DIN␣5007-2"/> + <cd:constant type="Duden"/> + <cd:constant type="de-DE"/> + <cd:constant type="de-CH"/> + <cd:constant type="de-AT"/> + <cd:constant type="ru-iso9"/> + <cd:constant type="ocs-scn"/> + <cd:constant type="cd:language"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="default"/> + <cd:constant type="before"/> + <cd:constant type="after"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="ch"/> + <cd:constant type="mm"/> + <cd:constant type="zm"/> + <cd:constant type="pm"/> + <cd:constant type="mc"/> + <cd:constant type="zc"/> + <cd:constant type="pc"/> + <cd:constant type="uc"/> + </cd:parameter> + <cd:parameter name="criterium"> + <cd:constant type="current"/> + <cd:constant type="previous"/> + <cd:constant type="local"/> + <cd:constant type="text"/> + <cd:constant default="yes" type="all"/> + <cd:constant type="cd:section"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="textstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="textcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="synonymstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="synonymcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" generated="yes" name="sorting" variant="instance"> + <cd:sequence> + <cd:instance value="sorting"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-syn.mkiv" name="definesort"> + <cd:arguments> + <cd:keywords> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" generated="yes" name="placelistofsorts" variant="instance"> + <cd:sequence> + <cd:string value="placelistof"/> + <cd:instance value="sorts"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsorting"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-syn.mkiv" generated="yes" name="completelistofsorts" variant="instance"> + <cd:sequence> + <cd:string value="completelistof"/> + <cd:instance value="sorts"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsorting"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-syn.mkiv" name="doifelsecurrentsortingused"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" name="resetusedsortings"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" name="registersort"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" name="placelistofsorts"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsorting"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" name="completelistofsorts"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsorting"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-soundtrack.xml"> + <cd:command file="scrn-wid.mkvi" name="setupexternalsoundtracks"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="option"> + <cd:constant type="repeat"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-wid.mkvi" name="useexternalsoundtrack"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="scrn-wid.mkvi" name="checksoundtrack"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-spellchecking.xml"> + <cd:command file="lang-wrd.mkiv" name="setupspellchecking"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant type="start"/> + <cd:constant defult="yes" type="stop"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="1"/> + <cd:constant type="2"/> + <cd:constant type="3"/> + </cd:parameter> + <cd:parameter name="list"> + <cd:constant type="cd:name"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="lang-wrd.mkiv" name="loadspellchecklist"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-startstop.xml"> + <cd:command file="core-sys.mkiv" name="definestartstop"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupstartstop"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-sys.mkiv" name="setupstartstop"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="setups"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-sys.mkiv" generated="yes" name="startstop" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="startstop"/> + </cd:sequence> + </cd:command> + <cd:command file="core-sys.mkiv" name="startstop" type="environment"> + <cd:sequence> + <cd:string value=""/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-sys.mkiv" generated="yes" name="startstop" variant="example"> + <cd:sequence> + <cd:variable value="startstop"/> + </cd:sequence> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-stream.xml"> + <cd:command file="page-str.mkiv" name="currentoutputstream"/> + <cd:command file="page-str.mkiv" name="ifinoutputstream"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:delimiter name="else"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:false"/> + </cd:keywords> + <cd:delimiter name="fi"/> + </cd:arguments> + </cd:command> + <cd:command file="page-str.mkiv" name="enableoutputstream"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-str.mkiv" name="disableoutputstream"/> + <cd:command file="page-str.mkiv" name="outputstream" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-str.mkiv" name="flushoutputstream"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-str.mkiv" name="outputstreambox"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-str.mkiv" name="outputstreamcopy"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-str.mkiv" name="outputstreamunvbox"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-str.mkiv" name="outputstreamunvcopy"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-str.mkiv" name="synchronizeoutputstreams"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-str.mkiv" name="pushoutputstream"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-string.xml"> + <cd:command file="blob-ini.mkiv" name="wdofstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="blob-ini.mkiv" name="htofstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="blob-ini.mkiv" name="dpofstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="blob-ini.mkiv" name="hdofstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="blob-ini.mkiv" name="htdpofstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="blob-ini.mkiv" name="widthofstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="blob-ini.mkiv" name="heightofstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="blob-ini.mkiv" name="depthofstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="blob-ini.mkiv" name="heightanddepthofstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="blob-ini.mkiv" name="setwidthof"> + <cd:arguments> + <cd:text/> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-strut.xml"> + <cd:command file="supp-box.mkiv" name="strutdp"/> + <cd:command file="supp-box.mkiv" name="strutht"/> + <cd:command file="supp-box.mkiv" name="strutwd"/> + <cd:command file="supp-box.mkiv" name="struthtdp"/> + <cd:command file="spac-ver.mkiv" name="setupstruts"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + <cd:constant type="cap"/> + <cd:constant type="fit"/> + <cd:constant type="line"/> + <cd:constant type="default"/> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="synchronizestrut"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + <cd:constant type="cap"/> + <cd:constant type="fit"/> + <cd:constant type="line"/> + <cd:constant type="default"/> + <cd:constant type="cd:character"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="strut"/> + <cd:command file="spac-ver.mkiv" name="setstrut"/> + <cd:command file="spac-ver.mkiv" name="setcharstrut"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setfontstrut"/> + <cd:command file="spac-ver.mkiv" name="setcapstrut"/> + <cd:command file="spac-ver.mkiv" name="setnostrut"/> + <cd:command file="spac-ver.mkiv" name="showstruts"/> + <cd:command file="spac-ver.mkiv" name="showcolorstruts"/> + <cd:command begin="beg" end="end" file="spac-ver.mkiv" name="strut" type="environment"/> + </cd:interface> + <cd:interface file="i-symbol.xml"> + <cd:command file="symb-ini.mkiv" name="definesymbol"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="symb-ini.mkiv" name="doifelseinsymbolset"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="symb-ini.mkiv" name="doifinsymbolsetelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="symb-ini.mkiv" name="doifinsymbolset"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="symb-ini.mkiv" name="doifelsesymbolset"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="symb-ini.mkiv" name="doifsymbolsetelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="symb-ini.mkiv" name="symbol"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="symb-ini.mkiv" name="symbol" variant="direct"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="symb-ini.mkiv" name="directsymbol"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="symb-ini.mkiv" name="definefiguresymbol"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:file"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="externalfigure"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="symb-ini.mkiv" name="figuresymbol"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="externalfigure"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="symb-ini.mkiv" name="doifelsesymboldefined"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="symb-ini.mkiv" name="doifsymboldefinedelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="symb-ini.mkiv" name="symbolset" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="symb-ini.mkiv" name="setupsymbolset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="symb-ini.mkiv" name="resetsymbolset"/> + <cd:command file="symb-ini.mkiv" name="usesymbols"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="symb-run.mkiv" name="showsymbolset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-synonym.xml"> + <cd:command file="strc-syn.mkiv" name="definesynonyms"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:plural"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:csname"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:csname"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" name="setupsynonyms"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="expansion"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="xml"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="normal"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="next"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:threearguments"/> + </cd:parameter> + <cd:parameter name="textcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="synonymcommand"> + <cd:constant type="cd:oneargument"/> + </cd:parameter> + <cd:parameter name="language"> + <cd:constant type="default"/> + <cd:constant type="DIN␣5007-1"/> + <cd:constant type="DIN␣5007-2"/> + <cd:constant type="Duden"/> + <cd:constant type="de-DE"/> + <cd:constant type="de-CH"/> + <cd:constant type="de-AT"/> + <cd:constant type="ru-iso9"/> + <cd:constant type="ocs-scn"/> + <cd:constant type="cd:language"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="default"/> + <cd:constant type="before"/> + <cd:constant type="after"/> + <cd:constant type="first"/> + <cd:constant type="last"/> + <cd:constant type="ch"/> + <cd:constant type="mm"/> + <cd:constant type="zm"/> + <cd:constant type="pm"/> + <cd:constant type="mc"/> + <cd:constant type="zc"/> + <cd:constant type="pc"/> + <cd:constant type="uc"/> + </cd:parameter> + <cd:parameter name="criterium"> + <cd:constant type="current"/> + <cd:constant type="previous"/> + <cd:constant type="local"/> + <cd:constant type="text"/> + <cd:constant default="yes" type="all"/> + <cd:constant type="cd:section"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="textstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="textcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="synonymstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="synonymcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" generated="yes" name="synonym" variant="instance"> + <cd:sequence> + <cd:instance value="synonym"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-syn.mkiv" name="definesynonym"> + <cd:arguments> + <cd:keywords> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" generated="yes" name="placelistofsynonyms" variant="instance"> + <cd:sequence> + <cd:string value="placelistof"/> + <cd:instance value="synonyms"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsynonyms"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-syn.mkiv" generated="yes" name="completelistofsynonyms" variant="instance"> + <cd:sequence> + <cd:string value="completelistof"/> + <cd:instance value="synonyms"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsynonyms"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="strc-syn.mkiv" name="registersynonym"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" name="doifelsecurrentsynonymused"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" name="doifelsecurrentsynonymshown"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" name="resetusedsynonyms"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" name="resetshownsynonyms"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" name="placelistofsynonyms"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsynonyms"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" name="completelistofsynonyms"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:singular"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsynonyms"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-syn.mkiv" name="infull"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-system.xml"> + <cd:command file="syst-aux.mkiv" name="expanded"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="expanded" type="environment"/> + <cd:command file="syst-aux.mkiv" name="gobbleoneargument"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobbletwoarguments"> + <cd:arguments> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobblethreearguments"> + <cd:arguments> + <cd:content/> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobblefourarguments"> + <cd:arguments> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobblefivearguments"> + <cd:arguments> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobblesixarguments"> + <cd:arguments> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobblesevenarguments"> + <cd:arguments> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobbleeightarguments"> + <cd:arguments> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobbleninearguments"> + <cd:arguments> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobbletenarguments"> + <cd:arguments> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobbleoneoptional"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobbletwooptionals"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobblethreeoptionals"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobblefouroptionals"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobblefiveoptionals"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="donothing"/> + <cd:command file="syst-aux.mkiv" name="doifelsenextchar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:character"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnextcharelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:character"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsenextoptional"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnextoptionalelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsenextoptionalcs"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnextoptionalcselse"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsenextbgroup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnextbgroupelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsenextbgroupcs"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnextbgroupcselse"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsenextparenthesis"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnextparenthesiselse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsefastoptionalcheck"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doiffastoptionalcheckelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsefastoptionalcheckcs"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doiffastoptionalcheckcselse"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="assumelongusagecs"> + <cd:arguments> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="setvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="setgvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="setevalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="setxvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="getvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="letvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="letgvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="resetvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="undefinevalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="ignorevalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="setuvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="setuevalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="setugvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="setuxvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="getuvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelseundefined"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifundefinedelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsedefined"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifdefinedelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifundefined"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifdefined"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="letbeundefined"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="localundefine"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="globalundefine"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsealldefined"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifalldefinedelse"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doif"> + <cd:arguments> + <cd:content/> + <cd:content/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnot"> + <cd:arguments> + <cd:content/> + <cd:content/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelse"> + <cd:arguments> + <cd:content/> + <cd:content/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelseempty"> + <cd:arguments> + <cd:content/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifemptyelse"> + <cd:arguments> + <cd:content/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifempty"> + <cd:arguments> + <cd:content/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnotempty"> + <cd:arguments> + <cd:content/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelseinset"> + <cd:arguments> + <cd:content/> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifinsetelse"> + <cd:arguments> + <cd:content/> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifinset"> + <cd:arguments> + <cd:content/> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnotinset"> + <cd:arguments> + <cd:content/> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsecommon"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifcommonelse"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifcommon"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnotcommon"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processcommalist"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="quitcommalist"/> + <cd:command file="syst-aux.mkiv" name="quitprevcommalist"/> + <cd:command file="syst-aux.mkiv" name="processcommacommand"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processcommalistwithparameters"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processcommalist" type="environment"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processcommacommand" type="environment"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="currentcommalistitem"/> + <cd:command file="syst-aux.mkiv" name="processaction"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:apply list="yes"/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processfirstactioninset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:apply list="yes"/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processallactionsinset"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:apply list="yes"/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="commalistelement"/> + <cd:command file="syst-aux.mkiv" name="firstcharacter"/> + <cd:command file="syst-aux.mkiv" name="remainingcharacters"/> + <cd:command file="syst-aux.mkiv" name="getfirstcharacter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsefirstchar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doiffirstcharelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="thefirstcharacter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="theremainingcharacters"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelseinstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifinstringelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifinstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnotinstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelseincsname"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:csname"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifincsnameelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:csname"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsenumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnumberelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnotnumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="percentdimen"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:csname"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + <cd:constant method="none" prefix="cd:number" type="%"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="setpercentdimen"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:csname"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + <cd:constant method="none" prefix="cd:number" type="%"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="makerawcommalist"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="rawprocesscommalist"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="rawprocesscommacommand"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="rawdoifelseinset"> + <cd:arguments> + <cd:content/> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="rawdoifinsetelse"> + <cd:arguments> + <cd:content/> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="rawdoifinset"> + <cd:arguments> + <cd:content/> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="rawprocessaction"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:apply list="yes"/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="currentvalue"/> + <cd:command file="syst-aux.mkiv" name="getparameters"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="geteparameters"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="getgparameters"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="getxparameters"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="forgetparameters"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="getexpandedparameters"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doassign"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doeassign"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="undoassign"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doassignempty"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processassignmentlist"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processassignmentcommand"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processassignmentlist" type="environment"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processassignmentcommand" type="environment"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="currentassignmentlistkey"/> + <cd:command file="syst-aux.mkiv" name="currentassignmentlistvalue"/> + <cd:command file="syst-aux.mkiv" name="getemptyparameters"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="copyparameters"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords list="yes"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="checkparameters"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="ifparameters"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:delimiter name="else"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:false"/> + </cd:keywords> + <cd:delimiter name="fi"/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="commalistsize"/> + <cd:command file="syst-aux.mkiv" name="getcommalistsize"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="getcommacommandsize"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="getfromcommalist"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="getfromcommacommand"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dogetcommacommandelement"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:delimiter name="from"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dosingleempty"> + <cd:arguments> + <cd:csname/> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dodoubleempty"> + <cd:arguments> + <cd:csname/> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dotripleempty"> + <cd:arguments> + <cd:csname/> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doquadrupleempty"> + <cd:arguments> + <cd:csname/> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doquintupleempty"> + <cd:arguments> + <cd:csname/> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dosixtupleempty"> + <cd:arguments> + <cd:csname/> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doseventupleempty"> + <cd:arguments> + <cd:csname/> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dosingleargument"> + <cd:arguments> + <cd:csname/> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dodoubleargument"> + <cd:arguments> + <cd:csname/> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dotripleargument"> + <cd:arguments> + <cd:csname/> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doquadrupleargument"> + <cd:arguments> + <cd:csname/> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doquintupleargument"> + <cd:arguments> + <cd:csname/> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dosixtupleargument"> + <cd:arguments> + <cd:csname/> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doseventupleargument"> + <cd:arguments> + <cd:csname/> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="strippedcsname"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="strippedcsname" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="complexorsimple"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="complexorsimple" variant="argument"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + <cd:constant type="cd:csname"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="complexorsimpleempty"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="complexorsimpleempty" variant="argument"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + <cd:constant type="cd:csname"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="definecomplexorsimple"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="definecomplexorsimple" variant="argument"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + <cd:constant type="cd:csname"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="definecomplexorsimpleempty"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="definecomplexorsimpleempty" variant="argument"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + <cd:constant type="cd:csname"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="permitspacesbetweengroups"/> + <cd:command file="syst-aux.mkiv" name="dontpermitspacesbetweengroups"/> + <cd:command file="syst-aux.mkiv" name="dosinglegroupempty"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dodoublegroupempty"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dotriplegroupempty"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doquadruplegroupempty"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doquintuplegroupempty"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="firstofoneargument"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="firstoftwoarguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="secondoftwoarguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="firstofthreearguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="secondofthreearguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="thirdofthreearguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="firstoffourarguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="secondoffourarguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="thirdoffourarguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="fourthoffourarguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="firstoffivearguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="secondoffivearguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="thirdoffivearguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="fourthoffivearguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="fifthoffivearguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="firstofsixarguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="secondofsixarguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="thirdofsixarguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="fourthofsixarguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="fifthofsixarguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="sixthofsixarguments"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="firstofoneunexpanded"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="firstoftwounexpanded"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="secondoftwounexpanded"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="firstofthreeunexpanded"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="secondofthreeunexpanded"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="thirdofthreeunexpanded"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="letempty"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="globalletempty"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="letvalueempty"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="letgvalueempty"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="letvaluerelax"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="letgvalurelax"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="relaxvalueifundefined"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="rawgetparameters"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="texdefinition" type="environment"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="spaces"/> + <cd:constant type="nospaces"/> + </cd:keywords> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="global"/> + </cd:keywords> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="unexpanded"/> + </cd:keywords> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="expanded"/> + </cd:keywords> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:template"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="texdefinition"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="texcode" type="environment"/> + <cd:command file="syst-aux.mkiv" name="newcounter"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="fastincrement"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="fastdecrement"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="increment"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="increment" variant="argument"> + <cd:arguments> + <cd:keywords delimiters="parentheses" list="yes"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="decrement"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="decrement" variant="argument"> + <cd:arguments> + <cd:keywords delimiters="parentheses" list="yes"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="incrementvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="decrementvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="newsignal"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="checkedstrippedcsname"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="checkedstrippedcsname" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="savenormalmeaning"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="recursedepth"/> + <cd:command file="syst-aux.mkiv" name="recurselevel"/> + <cd:command file="syst-aux.mkiv" name="dostepwiserecurse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant method="none" prefix="cd:sign" type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dorecurse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doexpandedrecurse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dowith"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doloop"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="exitloop"/> + <cd:command file="syst-aux.mkiv" name="exitloopnow"/> + <cd:command file="syst-aux.mkiv" name="dorecurse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doloopoverlist"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="recursestring"/> + <cd:command file="syst-aux.mkiv" name="newevery"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="EveryPar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="EveryLine"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="forgeteverypar"/> + <cd:command file="syst-aux.mkiv" name="convertvalue"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="defconvertedvalue"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelseassignment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifassignmentelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="docheckassignment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="ifassignment"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:delimiter name="else"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:false"/> + </cd:keywords> + <cd:delimiter name="fi"/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="convertargument"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="convertcommand"> + <cd:arguments> + <cd:csname/> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="defconvertedargument"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="defconvertedcommand"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="edefconvertedargument"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gdefconvertedargument"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gdefconvertedcommand"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="xdefconvertedargument"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="showvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsemeaning"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifmeaningelse"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsesamestring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifsamestringelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifsamestring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnotsamestring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="ConvertToConstant"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="ConvertConstantAfter"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="assignifempty"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="grabuntil"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processbetween"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobbleuntil"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobbleuntilrelax"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:content"/> + </cd:keywords> + <cd:delimiter name="relax"/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processuntil"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="groupedcommand"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="simplegroupedcommand"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="pickupgroupedcommand"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="BeforePar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="AfterPar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="GetPar"/> + <cd:command file="syst-aux.mkiv" name="GotoPar"/> + <cd:command file="syst-aux.mkiv" name="dowithpargument"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dowithwargument"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dorepeatwithcommand"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + <cd:constant method="factor" prefix="cd:number" type="cd:text"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsestringinstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifstringinstringelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="appendtoks"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="prependtoks"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="appendtoksonce"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="prependtoksonce"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelseintoks"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifintokselse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="collecting" type="environment"/> + <cd:command file="syst-aux.mkiv" name="collect" type="environment"/> + <cd:command file="syst-aux.mkiv" name="expandedcollect" type="environment"/> + <cd:command file="syst-aux.mkiv" name="collect"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="collectexpanded"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="removetoks"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:delimiter name="from"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="appendetoks"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="prependetoks"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="flushtoks"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dotoks"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="beforesplitstring"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="at"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="aftersplitstring"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="at"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="splitstring"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="at"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + <cd:delimiter name="and"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="greedysplitstring"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="at"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + <cd:delimiter name="and"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="beforetestandsplitstring"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="at"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="aftertestandsplitstring"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="at"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="testandsplitstring"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="at"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + <cd:delimiter name="and"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="splitatcolon"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="splitatcomma"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="splitatasterisk"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="splitatcolon"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="splitatcolons"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="removesubstring"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="from"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="appendtocommalist"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="prependtocommalist"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="addtocommalist"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="pretocommalist"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="robustdoifelseinset"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="robustdoifinsetelse"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="robustaddtocommalist"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="robustpretocommalist"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="xsplitstring"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="removefromcommalist"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="substituteincommalist"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="replaceincommalist"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="globalprocesscommalist"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="withoutpt"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="PtToCm"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dimensiontocount"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="numberofpoints"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="swapdimens"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="swapcounts"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="swapmacros"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="globalswapdimens"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="globalswapcounts"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="globalswapmacros"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="globalpushmacro"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="localpushmacro"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="globalpopmacro"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="localpopmacro"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="pushmacro"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="popmacro"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="localhsize"/> + <cd:command file="syst-aux.mkiv" name="setlocalhsize"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant method="none" prefix="cd:sign" type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="availablehsize"/> + <cd:command file="syst-aux.mkiv" name="distributedhsize"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="hsizefraction"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnotvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsevalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifvalueelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnothing"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifsomething"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsenothing"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnothingelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsesomething"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifsomethingelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifvaluenothing"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifvaluesomething"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsevaluenothing"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifvaluenothingelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelseemptyvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifemptyvalueelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifemptyvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnotemptyvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelseallcommon"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifallcommonelse"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifallcommon"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnotallcommon"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dodoubleemptywithset"> + <cd:arguments> + <cd:csname/> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dotripleemptywithset"> + <cd:arguments> + <cd:csname/> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dodoubleargumentwithset"> + <cd:arguments> + <cd:csname/> + <cd:keywords list="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dotripleargumentwithset"> + <cd:arguments> + <cd:csname/> + <cd:keywords list="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="stripcharacter"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:character"/> + </cd:keywords> + <cd:delimiter name="from"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="stripspaces"> + <cd:arguments> + <cd:delimiter name="from"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="unspacestring"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="executeifdefined"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsesomespace"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifsomespaceelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processseparatedlist"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:csname"/> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processlist"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:character"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:character"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processassignlist"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="untexargument"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="untexcommand"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:csname"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="PointsToBigPoints"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="PointsToWholeBigPoints"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="ScaledPointsToBigPoints"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="ScaledPointsToWholeBigPoints"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="PointsToReal"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dontleavehmode"/> + <cd:command file="syst-aux.mkiv" name="utfupper"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="utflower"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="uppercasestring"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="lowercasestring"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="counttoken"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="in"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="counttokens"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="splitofftokens"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="from"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="handletokens"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="with"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="settrialtypesetting"/> + <cd:command file="syst-aux.mkiv" name="resettrialtypesetting"/> + <cd:command file="syst-aux.mkiv" name="iftrialtypesetting"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:delimiter name="else"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:false"/> + </cd:keywords> + <cd:delimiter name="fi"/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="integerrounding"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="onedigitrounding"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="twodigitrounding"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="threedigitrounding"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processcontent"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dogobblesingleempty"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dogobbledoubleempty"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobblesingleempty"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobbledoubleempty"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsesometoks"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifsometokselse"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifsometoks"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifemptytoks"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="strictinspectnextcharacter" type="environment"/> + <cd:command file="syst-aux.mkiv" name="strictdoifelsenextoptional"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="strictdoifnextoptionalelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="gobblespacetokens"/> + <cd:command file="syst-aux.mkiv" name="verbatimstring"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="lastdigit"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="lasttwodigits"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="serializedcommalist"/> + <cd:command file="syst-aux.mkiv" name="serializecommalist"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="purenumber"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="filterfromvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="filterfromnext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:content/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:content/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="definemeasure"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="freezemeasure"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="setmeasure"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="setgmeasure"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="setemeasure"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="setxmeasure"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="measure"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="measured"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dividedsize"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsedimension"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifdimensionelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsedimenstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifdimenstringelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="compresult"/> + <cd:command file="syst-aux.mkiv" name="comparedimension"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="comparedimensioneps"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="letcscsname"> + <cd:arguments> + <cd:csname/> + <cd:delimiter name="csname"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:delimiter name="endcsname"/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="letcsnamecs"> + <cd:arguments> + <cd:delimiter name="csname"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:delimiter name="endcsname"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="letcsnamecsname"> + <cd:arguments> + <cd:delimiter name="csname"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:delimiter name="endcsname"/> + <cd:delimiter name="csname"/> + <cd:keywords delimiters="none"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:delimiter name="endcsname"/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="addvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="unspaced"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="unspaceargument"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="unspaceafter"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsehasspace"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifhasspaceelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="setflag"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="resetflag"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="flag"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelseflagged"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifflaggedelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnotflagged"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="inheritparameter"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifelsenonzeropositive"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="doifnonzeropositiveelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="getrawparameters"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="getraweparameters"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="getrawgparameters"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="getrawxparameters"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="unprotected"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:content"/> + </cd:keywords> + <cd:delimiter name="par"/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="resettimer"/> + <cd:command file="syst-aux.mkiv" name="elapsedtime"/> + <cd:command file="syst-aux.mkiv" name="elapsedseconds"/> + <cd:command file="syst-aux.mkiv" name="currentfeaturetest"/> + <cd:command file="syst-aux.mkiv" name="testfeature"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="showtimer"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="testfeatureonce"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="freezedimenmacro"> + <cd:arguments> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="negated"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="assigndimen"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="appendvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="appendgvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="prependvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="prependgvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="processranges"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="cd:number"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="dowithrange"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:number"/> + <cd:constant method="range" prefix="cd:number" type="cd:number"/> + </cd:keywords> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="ignoreimplicitspaces"/> + <cd:command file="syst-aux.mkiv" name="nointerference" type="environment"/> + <cd:command file="syst-aux.mkiv" name="expandcheckedcsname"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="docheckedpair"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="constantnumber"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="constantnumberargument"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="constantdimen"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="constantdimenargument"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="constantemptyargument"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="getsubstring"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="converteddimen"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="ex"/> + <cd:constant type="em"/> + <cd:constant type="pt"/> + <cd:constant type="in"/> + <cd:constant type="cm"/> + <cd:constant type="mm"/> + <cd:constant type="sp"/> + <cd:constant type="bp"/> + <cd:constant type="pc"/> + <cd:constant type="dd"/> + <cd:constant type="cc"/> + <cd:constant type="nc"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="syst-aux.mkiv" name="ntimes"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-systemlog.xml"> + <cd:command file="core-sys.mkiv" name="systemlog"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-sys.mkiv" name="systemlogfirst"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-sys.mkiv" name="systemloglast"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-table.xml"> + <cd:command file="tabl-tab.mkiv" name="table" type="environment"> + <cd:arguments> + <cd:template/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptables"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tab.mkiv" name="table" type="environment" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptables"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tab.mkiv" name="definetabletemplate"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:template/> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tab.mkiv" name="tables" type="environment"> + <cd:arguments> + <cd:template/> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tab.mkiv" name="tables" type="environment" variant="name"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tab.mkiv" name="tablehead" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tab.mkiv" name="tabletail" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tab.mkiv" name="setuptables"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="text"> + <cd:constant type="cd:dimension"/> + <cd:constant type="max"/> + </cd:parameter> + <cd:parameter name="split"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="repeat"/> + <cd:constant default="yes" type="auto"/> + </cd:parameter> + <cd:parameter name="frame"> + <cd:constant type="on"/> + <cd:constant type="off"/> + </cd:parameter> + <cd:parameter name="NL"> + <cd:inherit name="blank"/> + </cd:parameter> + <cd:parameter name="VL"> + <cd:constant type="small"/> + <cd:constant default="yes" type="medium"/> + <cd:constant type="big"/> + <cd:constant type="none"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="HL"> + <cd:constant type="small"/> + <cd:constant default="yes" type="medium"/> + <cd:constant type="big"/> + <cd:constant type="none"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="small"/> + <cd:constant default="yes" type="medium"/> + <cd:constant type="big"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant default="yes" type="right"/> + </cd:parameter> + <cd:parameter name="commands"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="bodyfont"> + <cd:inherit name="setupbodyfont"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="strut"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="strut"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="openup"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-tabulation.xml"> + <cd:command file="tabl-tbl.mkiv" name="definetabulation"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptabulation"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tbl.mkiv" name="setuptabulation"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="format"> + <cd:constant type="cd:template"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="small"/> + <cd:constant default="yes" type="medium"/> + <cd:constant type="big"/> + <cd:constant type="none"/> + <cd:constant type="blank"/> + <cd:constant default="yes" type="depth"/> + <cd:constant type="grid"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + <cd:constant type="dimension"/> + </cd:parameter> + <cd:parameter name="rule"> + <cd:constant type="line"/> + <cd:constant default="yes" type="normal"/> + </cd:parameter> + <cd:parameter name="rulecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bodyfont"> + <cd:inherit name="setupbodyfont"/> + </cd:parameter> + <cd:parameter name="indenting"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + </cd:parameter> + <cd:parameter name="split"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="repeat"/> + <cd:constant default="yes" type="auto"/> + </cd:parameter> + <cd:parameter name="unit"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="inner"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="EQ"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="header"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="repeat"/> + <cd:constant type="text"/> + </cd:parameter> + <cd:parameter name="frame"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + </cd:parameter> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="keeptogether"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tbl.mkiv" generated="yes" name="tabulation" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="tabulation"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptabulation"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tbl.mkiv" name="definetabulate"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:template optional="yes"/> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tbl.mkiv" name="setuptabulate"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setuptabulation"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tbl.mkiv" name="tabulate" type="environment"> + <cd:arguments> + <cd:template optional="yes"/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptabulate"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tbl.mkiv" generated="yes" name="tabulate" type="environment" variant="instance"> + <cd:sequence> + <cd:instance value="tabulate"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptabulate"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="tabl-tbl.mkiv" name="tabulatehead" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tbl.mkiv" name="tabulatetail" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-tbl.mkiv" name="tabulaterule"/> + <cd:command file="tabl-tbl.mkiv" name="tabulateline"/> + <cd:command file="tabl-tbl.mkiv" name="tabulateautorule"/> + <cd:command file="tabl-tbl.mkiv" name="tabulateautoline"/> + </cd:interface> + <cd:interface file="i-tagging.xml"> + <cd:command file="strc-tag.mkiv" name="setuptagging"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant type="start"/> + <cd:constant default="yes" type="stop"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="auto"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command begin="dostart" end="dostop" file="strc-tag.mkiv" name="tagged" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-tag.mkiv" name="element" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="strc-tag.mkiv" name="doifelseinelement"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-tag.mkiv" name="doifinelementelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="strc-tag.mkiv" name="taggedlabeltexts"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="strc-tag.mkiv" name="namedtaggedlabeltexts"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="strc-tag.mkiv" name="settaggedmetadata"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-textbackground.xml"> + <cd:command file="anch-bck.mkiv" name="definetextbackground"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptextbackground"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="anch-bck.mkiv" name="setuptextbackground"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant default="yes" type="text"/> + <cd:constant type="paragraph"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="mp"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="background"> + <cd:constant type="color"/> + </cd:parameter> + <cd:parameter name="backgroundcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="corner"> + <cd:constant default="yes" type="rectangular"/> + <cd:constant type="round"/> + </cd:parameter> + <cd:parameter name="level"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="backgroundoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="dash"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="radius"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="frame"> + <cd:constant default="yes" type="on"/> + <cd:constant type="off"/> + </cd:parameter> + <cd:parameter name="framecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="voffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="frameoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="leftoffset"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightoffset"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="topoffset"> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="line"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="bottomoffset"> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="line"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="anch-bck.mkiv" name="textbackground" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptextbackground"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="anch-bck.mkiv" generated="yes" name="textbackground" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="textbackground"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptextbackground"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="anch-bck.mkiv" generated="yes" name="textbackground" variant="example"> + <cd:sequence> + <cd:variable value="textbackground"/> + </cd:sequence> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="anch-bck.mkiv" name="textbackgroundmanual" type="environment"/> + </cd:interface> + <cd:interface file="i-textflow.xml"> + <cd:command file="page-flw.mkiv" name="definetextflow"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptextflow"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-flw.mkiv" name="setuptextflow"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-flw.mkiv" name="textflowcollector"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-flw.mkiv" name="doifelsetextflowcollector"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-flw.mkiv" name="doiftextflowcollectorelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-flw.mkiv" name="doifelsetextflow"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-flw.mkiv" name="doiftextflowelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-flw.mkiv" name="textflow" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-flw.mkiv" name="flushtextflow"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-textrule.xml"> + <cd:command file="pack-mrl.mkiv" name="setuptextrules"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="location"> + <cd:constant default="yes" type="left"/> + <cd:constant type="inmargin"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="rulecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depthcorrection"> + <cd:constant default="yes" type="on"/> + <cd:constant type="off"/> + </cd:parameter> + <cd:parameter name="bodyfont"> + <cd:inherit name="setupbodyfont"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-mrl.mkiv" name="textrule"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="top"/> + <cd:constant type="middle"/> + <cd:constant default="yes" type="bottom"/> + </cd:keywords> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="pack-mrl.mkiv" name="textrule" type="environment"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-texts.xml"> + <cd:command file="page-txt.mkvi" name="setuplayouttext"> + <cd:arguments> + <cd:keywords> + <cd:constant type="top"/> + <cd:constant type="header"/> + <cd:constant type="text"/> + <cd:constant type="footer"/> + <cd:constant type="bottom"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="text"/> + <cd:constant type="margin"/> + <cd:constant type="edge"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="state"> + <cd:constant type="start"/> + <cd:constant type="stop"/> + <cd:constant type="empty"/> + <cd:constant type="high"/> + <cd:constant type="none"/> + <cd:constant default="yes" type="normal"/> + <cd:constant type="nomarking"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="strut"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="leftstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="rightstyle"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="leftcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="rightcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="leftwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="setuptop"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="text"/> + <cd:constant type="margin"/> + <cd:constant type="edge"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setuplayoutelement"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="setupheader"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="text"/> + <cd:constant type="margin"/> + <cd:constant type="edge"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setuplayoutelement"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="setuptext"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="text"/> + <cd:constant type="margin"/> + <cd:constant type="edge"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setuplayoutelement"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="setupfooter"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="text"/> + <cd:constant type="margin"/> + <cd:constant type="edge"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setuplayoutelement"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="setupbottom"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="text"/> + <cd:constant type="margin"/> + <cd:constant type="edge"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setuplayoutelement"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="doifelselayouttextline"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="doiflayouttextlineelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="doifelselayoutsomeline"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="doiflayoutsomelineelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="noheaderandfooterlines"/> + <cd:command file="page-txt.mkvi" name="notopandbottomlines"/> + <cd:command file="page-txt.mkvi" name="setuptoptexts"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant default="yes" type="text"/> + <cd:constant type="margin"/> + <cd:constant type="edge"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="setupheadertexts"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant default="yes" type="text"/> + <cd:constant type="margin"/> + <cd:constant type="edge"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="setuptexttexts"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant default="yes" type="text"/> + <cd:constant type="margin"/> + <cd:constant type="edge"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="setupfootertexts"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant default="yes" type="text"/> + <cd:constant type="margin"/> + <cd:constant type="edge"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="setupbottomtexts"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant default="yes" type="text"/> + <cd:constant type="margin"/> + <cd:constant type="edge"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="settextcontent"> + <cd:arguments> + <cd:keywords> + <cd:constant type="top"/> + <cd:constant type="header"/> + <cd:constant type="text"/> + <cd:constant type="footer"/> + <cd:constant type="bottom"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="text"/> + <cd:constant type="margin"/> + <cd:constant type="edge"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="left"/> + <cd:constant default="yes" type="middle"/> + <cd:constant type="right"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-txt.mkvi" name="definetext"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="top"/> + <cd:constant type="header"/> + <cd:constant type="text"/> + <cd:constant type="footer"/> + <cd:constant type="bottom"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="text"/> + <cd:constant type="margin"/> + <cd:constant type="edge"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="date"/> + <cd:constant type="pagenumber"/> + <cd:constant type="cd:mark"/> + <cd:constant type="cd:text"/> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-thinrule.xml"> + <cd:command file="pack-mrl.mkiv" name="setupthinrules"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="height"> + <cd:constant type="max"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="max"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="background"> + <cd:constant type="color"/> + </cd:parameter> + <cd:parameter name="frame"> + <cd:constant default="yes" type="on"/> + <cd:constant type="off"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="a"/> + <cd:constant default="yes" type="b"/> + <cd:constant type="c"/> + <cd:constant type="none"/> + </cd:parameter> + <cd:parameter name="backgroundcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="interlinespace"> + <cd:constant default="yes" type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="pack-mrl.mkiv" name="thinrule"/> + <cd:command file="pack-mrl.mkiv" name="hairline"/> + <cd:command file="pack-mrl.mkiv" name="thinrules"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupthinrules"/> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-token.xml"> + <cd:command file="toks-tra.mkiv" name="tokens" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="toks-tra.mkiv" name="flushtokens"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="toks-tra.mkiv" name="showtokens"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="toks-tra.mkiv" name="testtokens"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-tolerance.xml"> + <cd:command file="spac-hor.mkiv" name="setuptolerance"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="horizontal"/> + <cd:constant type="vertical"/> + <cd:constant type="verystrict"/> + <cd:constant type="strict"/> + <cd:constant type="tolerant"/> + <cd:constant type="verytolerant"/> + <cd:constant type="space"/> + <cd:constant type="stretch"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-tooltip.xml"> + <cd:command file="scrn-fld.mkvi" name="definetooltip"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptooltip"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" name="setuptooltip"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="location"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant default="yes" type="right"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="scrn-fld.mkvi" generated="yes" name="tooltip" variant="instance"> + <cd:sequence> + <cd:instance value="tooltip"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptooltip"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="scrn-fld.mkvi" generated="yes" name="tooltip" variant="instance:argument"> + <cd:sequence> + <cd:instance value="tooltip"/> + </cd:sequence> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + <cd:instances/> + </cd:command> + </cd:interface> + <cd:interface file="i-tracker.xml"> + <cd:command file="trac-ctx.mkiv" name="installtextracker"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="trac-ctx.mkiv" name="installtexdirective"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="trac-deb.mkiv" name="enabletrackers"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="trac-deb.mkiv" name="disabletrackers"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="trac-deb.mkiv" name="resettrackers"/> + <cd:command file="trac-deb.mkiv" name="showtrackers"/> + <cd:command file="trac-deb.mkiv" name="enabledirectives"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="trac-deb.mkiv" name="disabledirectives"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="trac-deb.mkiv" name="showdirectives"/> + <cd:command file="trac-deb.mkiv" name="enableexperiments"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="trac-deb.mkiv" name="disableexperiments"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="trac-deb.mkiv" name="showexperiments"/> + <cd:command file="trac-deb.mkiv" name="showedebuginfo"/> + <cd:command file="trac-deb.mkiv" name="overloaderror"/> + <cd:command file="trac-deb.mkiv" name="showlogcategories"/> + <cd:command file="trac-jus.mkiv" name="showjustification"/> + </cd:interface> + <cd:interface file="i-translation.xml"> + <cd:command file="lang-lab.mkiv" name="translate"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="cd:language"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="lang-lab.mkiv" name="assigntranslation"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="cd:language"> + <cd:constant type="cd:text"/> + </cd:parameter> + </cd:assignments> + <cd:delimiter name="to"/> + <cd:csname/> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-twopassdata.xml"> + <cd:command file="core-two.mkiv" name="immediatesavetwopassdata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="core-two.mkiv" name="savetwopassdata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="core-two.mkiv" name="lazysavetwopassdata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="core-two.mkiv" name="savetaggedtwopassdata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="core-two.mkiv" name="lazysavetaggedtwopassdata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="core-two.mkiv" name="definetwopasslist"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-two.mkiv" name="gettwopassdata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-two.mkiv" name="checktwopassdata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-two.mkiv" name="findtwopassdata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-two.mkiv" name="getfirsttwopassdata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-two.mkiv" name="getlasttwopassdata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-two.mkiv" name="getnamedtwopassdatalist"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-two.mkiv" name="gettwopassdatalist"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-two.mkiv" name="doifelseintwopassdata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-two.mkiv" name="doifintwopassdataelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-two.mkiv" name="getfromtwopassdata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-typography.xml"> + <cd:command file="typo-txt.mkvi" name="normalizetextwidth"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="normalizetextheight"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="normalizetextdepth"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="normalizetextline"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="normalizefontwidth"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="normalizefontheight"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="normalizefontdepth"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="normalizefontline"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="widthspanningtext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="heightspanningtext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="depthspanningtext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="linespanningtext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="normalizedfontsize"/> + <cd:command file="typo-txt.mkvi" name="NormalizeTextWidth"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="NormalizeTextHeight"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="NormalizeFontWidth"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="NormalizeFontHeight"> + <cd:arguments> + <cd:csname/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="WidthSpanningText"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="typo-txt.mkvi" name="TheNormalizedFontSize"/> + <cd:command file="typo-txt.mkvi" name="nicelyfilledbox" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="strut"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-unit.xml"> + <cd:command file="phys-dim.mkiv" name="digits"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="phys-dim.mkiv" name="digits" variant="string"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="phys-dim.mkiv" name="defineunit"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupunit"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="phys-dim.mkiv" name="setupunit"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="method"> + <cd:constant type="1"/> + <cd:constant type="2"/> + <cd:constant type="3"/> + <cd:constant type="4"/> + <cd:constant type="5"/> + <cd:constant type="6"/> + </cd:parameter> + <cd:parameter name="language"> + <cd:constant type="cd:language"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="text"/> + <cd:constant type="mathematics"/> + </cd:parameter> + <cd:parameter name="order"> + <cd:constant type="reverse"/> + <cd:constant default="yes" type="normal"/> + </cd:parameter> + <cd:parameter name="separator"> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant default="yes" type="normal"/> + <cd:constant type="none"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="space"> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant default="yes" type="normal"/> + <cd:constant type="none"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="phys-dim.mkiv" generated="yes" name="unit" variant="instance"> + <cd:sequence> + <cd:instance value="unit"/> + </cd:sequence> + <cd:arguments> + <cd:content/> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="phys-dim.mkiv" name="installunitsseparator"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="phys-dim.mkiv" name="installunitsspace"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="phys-dim.mkiv" name="registerunit"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="prefix"/> + <cd:constant default="yes" type="unit"/> + <cd:constant type="operator"/> + <cd:constant type="suffixe"/> + <cd:constant type="symbol"/> + <cd:constant type="packaged"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-variables.xml"> + <cd:command file="core-env.mkiv" name="setvariables"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="set"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="reset"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setevariables"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="set"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="reset"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setgvariables"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="set"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="reset"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setxvariables"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="set"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="reset"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="checkvariables"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="set"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="reset"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setvariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:value"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setevariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:value"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setgvariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:value"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setxvariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:value"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="getvariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="showvariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifelsevariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifvariableelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifvariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifnotvariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifelseemptyvariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifemptyvariableelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifemptyvariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifnotemptyvariable"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="getvariabledefault"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="setupenv"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="set"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="reset"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifelseenv"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifenvelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifenv"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="doifnotenv"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="env"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="core-env.mkiv" name="envvar"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:key"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="setdocumentfilename"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="setdocumentargument"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="setdocumentargumentdefault"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="getdocumentfilename"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="getdocumentargument"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="getdocumentargumentdefault"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="doifelsedocumentargument"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="doifdocumentargumentelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="doifdocumentargument"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="doifnotdocumentargument"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="doifelsedocumentfilename"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="doifdocumentfilenameelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="doifdocumentfilename"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="luat-ini.mkiv" name="doifnotdocumentfilename"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-verbatim.xml"> + <cd:command file="buff-ver.mkiv" name="definetype"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptype"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="setuptype"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="option"> + <cd:constant type="mp"/> + <cd:constant type="lua"/> + <cd:constant type="xml"/> + <cd:constant type="parsed-xml"/> + <cd:constant type="nested"/> + <cd:constant type="tex"/> + <cd:constant type="context"/> + <cd:constant type="none"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant type="cd:csname"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="tab"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="compact"> + <cd:constant type="absolute"/> + <cd:constant type="last"/> + <cd:constant default="yes" type="all"/> + </cd:parameter> + <cd:parameter name="escape"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:text"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="lines"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="normal"/> + <cd:constant type="hyphenated"/> + </cd:parameter> + <cd:parameter name="space"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + <cd:constant type="normal"/> + <cd:constant type="fixed"/> + <cd:constant type="stretch"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="type"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptype"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="type" variant="angles"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptype"/> + </cd:assignments> + <cd:angles/> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="typ"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptype"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="typ" variant="angles"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptype"/> + </cd:assignments> + <cd:angles/> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" generated="yes" name="type" variant="example"> + <cd:sequence> + <cd:variable value="type"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptype"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" generated="yes" name="type" variant="example:angles"> + <cd:sequence> + <cd:variable value="type"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptype"/> + </cd:assignments> + <cd:angles/> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="definetyping"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptyping"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="setuptyping"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="oddmargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="evenmargin"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="margin"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="option"> + <cd:constant type="mp"/> + <cd:constant type="lua"/> + <cd:constant type="xml"/> + <cd:constant type="parsed-xml"/> + <cd:constant type="nested"/> + <cd:constant type="tex"/> + <cd:constant type="context"/> + <cd:constant default="yes" type="none"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:constant type="cd:style"/> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + <cd:parameter name="lines"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="normal"/> + <cd:constant type="hyphenated"/> + </cd:parameter> + <cd:parameter name="space"> + <cd:constant type="on"/> + <cd:constant default="yes" type="off"/> + <cd:constant type="normal"/> + <cd:constant type="fixed"/> + <cd:constant type="stretch"/> + </cd:parameter> + <cd:parameter name="keeptogether"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="strip"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="range"> + <cd:constant type="cd:number"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="tab"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="escape"> + <cd:constant type="yes"/> + <cd:constant default="yes" type="no"/> + <cd:constant type="cd:text"/> + <cd:constant method="apply" prefix="cd:processor" type="cd:text"/> + </cd:parameter> + <cd:parameter name="indentnext"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="auto"/> + </cd:parameter> + <cd:parameter name="continue"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="start"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="stop"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="step"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="numbering"> + <cd:constant type="file"/> + <cd:constant type="line"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="blank"> + <cd:inherit name="blank"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" generated="yes" name="typing" type="environment" variant="instance"> + <cd:sequence> + <cd:instance value="typing"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptyping"/> + </cd:assignments> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="buff-ver.mkiv" generated="yes" name="typing" type="environment" variant="instance:argument"> + <cd:sequence> + <cd:instance value="typing"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="continue"/> + </cd:keywords> + </cd:arguments> + <cd:instances/> + </cd:command> + <cd:command file="buff-ver.mkiv" name="tex"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="arg"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="mat"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="dis"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="astype"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="asciistr"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="verbatim"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="filename"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="typefile"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptyping"/> + </cd:assignments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="doifelsetypingfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="buff-ver.mkiv" name="doiftypingfileelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-version.xml"> + <cd:command file="page-inf.mkiv" name="setupversion"> + <cd:arguments> + <cd:keywords> + <cd:constant type="concept"/> + <cd:constant type="file"/> + <cd:constant type="temporary"/> + <cd:constant type="final"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-inf.mkiv" name="version"> + <cd:arguments> + <cd:keywords> + <cd:constant type="concept"/> + <cd:constant type="file"/> + <cd:constant type="temporary"/> + <cd:constant type="final"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-inf.mkiv" name="installversioninfo"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:command"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="page-inf.mkiv" name="includeversioninfo"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-mod.mkvi" name="doifelseolderversion"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-mod.mkvi" name="doifolderversionelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-mod.mkvi" name="doifelseoldercontext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="file-mod.mkvi" name="doifoldercontextelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-viewerlayer.xml"> + <cd:command file="attr-lay.mkiv" name="defineviewerlayer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupviewerlayer"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="attr-lay.mkiv" name="setupviewerlayer"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="title"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="state"> + <cd:constant default="yes" type="start"/> + <cd:constant type="stop"/> + </cd:parameter> + <cd:parameter name="export"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="printable"> + <cd:constant default="yes" type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + <cd:parameter name="scope"> + <cd:constant default="yes" type="local"/> + <cd:constant type="global"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant default="yes" type="none"/> + <cd:constant type="command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="attr-lay.mkiv" name="viewerlayer" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="attr-lay.mkiv" generated="yes" name="viewerlayer" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="viewerlayer"/> + </cd:sequence> + </cd:command> + <cd:command file="attr-lay.mkiv" name="viewerlayer"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="attr-lay.mkiv" name="showlayoutcomponents"/> + </cd:interface> + <cd:interface file="i-visualizer.xml"> + <cd:command file="trac-vis.mkiv" name="ruledhbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="trac-vis.mkiv" name="ruledvbox"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="trac-vis.mkiv" name="ruledvtop"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="trac-vis.mkiv" name="ruledtopv"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="trac-vis.mkiv" name="ruledhpack"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="trac-vis.mkiv" name="ruledvpack"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="trac-vis.mkiv" name="ruledtpack"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="trac-vis.mkiv" name="ruledmbox"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="trac-vis.mkiv" name="filledhboxr"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="trac-vis.mkiv" name="filledhboxg"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="trac-vis.mkiv" name="filledhboxb"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="trac-vis.mkiv" name="filledhboxc"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="trac-vis.mkiv" name="filledhboxm"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="trac-vis.mkiv" name="filledhboxy"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="trac-vis.mkiv" name="filledhboxk"> + <cd:arguments> + <cd:keywords delimiters="none" optional="yes"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="trc-vis.mkiv" name="showmakeup"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant default="yes" type="makeup"/> + <cd:constant type="all"/> + <cd:constant type="boxes"/> + <cd:constant type="glyph"/> + <cd:constant type="fontkern"/> + <cd:constant type="hbox"/> + <cd:constant type="vbox"/> + <cd:constant type="vtop"/> + <cd:constant type="kern"/> + <cd:constant type="glue"/> + <cd:constant type="penalty"/> + <cd:constant type="strut"/> + <cd:constant type="whatsit"/> + <cd:constant type="simple"/> + <cd:constant type="simplehbox"/> + <cd:constant type="simplevbox"/> + <cd:constant type="simplevtop"/> + <cd:constant type="user"/> + <cd:constant type="math"/> + <cd:constant type="italic"/> + <cd:constant type="origin"/> + <cd:constant type="reset"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="trc-vis.mkiv" name="showallmakeup"/> + <cd:command file="trc-vis.mkiv" name="showboxes"/> + <cd:command file="trc-vis.mkiv" name="showglyphs"/> + <cd:command file="trc-vis.mkiv" name="showfontkerns"/> + <cd:command file="trc-vis.mkiv" name="setvisualizerfont"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:font"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="trc-vis.mkiv" name="resetvisualizers"/> + </cd:interface> + <cd:interface file="i-vspace.xml"> + <cd:command file="spac-ver.mkiv" name="definevspacingamount"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="definevspacing"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:inherit name="vspacing"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="vspacing"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="preference"/> + <cd:constant type="samepage"/> + <cd:constant type="max"/> + <cd:constant type="force"/> + <cd:constant type="enable"/> + <cd:constant type="disable"/> + <cd:constant type="nowhite"/> + <cd:constant type="back"/> + <cd:constant type="overlay"/> + <cd:constant type="always"/> + <cd:constant type="weak"/> + <cd:constant type="strong"/> + <cd:constant type="default"/> + <cd:constant type="before"/> + <cd:constant type="inbetween"/> + <cd:constant type="after"/> + <cd:constant type="fixed"/> + <cd:constant type="flexible"/> + <cd:constant type="none"/> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="line"/> + <cd:constant type="halfline"/> + <cd:constant type="quarterline"/> + <cd:constant type="formula"/> + <cd:constant type="white"/> + <cd:constant type="height"/> + <cd:constant type="depth"/> + <cd:constant type="standard"/> + <cd:constant method="factor" prefix="cd:number" type="small"/> + <cd:constant method="factor" prefix="cd:number" type="medium"/> + <cd:constant method="factor" prefix="cd:number" type="big"/> + <cd:constant method="factor" prefix="cd:number" type="line"/> + <cd:constant method="factor" prefix="cd:number" type="halfline"/> + <cd:constant method="factor" prefix="cd:number" type="quarterline"/> + <cd:constant method="factor" prefix="cd:number" type="formula"/> + <cd:constant method="factor" prefix="cd:number" type="white"/> + <cd:constant method="factor" prefix="cd:number" type="height"/> + <cd:constant method="factor" prefix="cd:number" type="depth"/> + <cd:constant method="range" prefix="category" type="cd:number"/> + <cd:constant method="range" prefix="order" type="cd:number"/> + <cd:constant method="range" prefix="penalty" type="cd:number"/> + <cd:constant type="cd:dimension"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="directvspacing"> + <cd:arguments> + <cd:keywords delimiters="braces" list="yes"> + <cd:inherit name="vspacing"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setupvspacing"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="vspacing"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="setupblank"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="vspacing"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="blank"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="vspacing"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="useblankparameter"> + <cd:arguments> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="inhibitblank"/> + <cd:command file="spac-ver.mkiv" name="synchronizeblank"/> + <cd:command file="spac-ver.mkiv" name="definevspace"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="vspace"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="godown"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="vglue"> + <cd:arguments> + <cd:keywords delimiters="none"> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="smallskip"/> + <cd:command file="spac-ver.mkiv" name="medskip"/> + <cd:command file="spac-ver.mkiv" name="bigskip"/> + </cd:interface> + <cd:interface file="i-whitespace.xml"> + <cd:command file="spac-ver.mkiv" name="setupwhitespace"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="fix"/> + <cd:constant type="fixed"/> + <cd:constant type="flexible"/> + <cd:constant type="line"/> + <cd:constant type="halfline"/> + <cd:constant type="quarterline"/> + <cd:constant default="yes" type="none"/> + <cd:constant type="small"/> + <cd:constant type="medium"/> + <cd:constant type="big"/> + <cd:constant type="default"/> + <cd:constant type="cd:dimension"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="synchronizewhitespace"/> + <cd:command file="spac-ver.mkiv" name="correctwhitespace"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="packed" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="blank"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="unpacked" type="environment"/> + <cd:command file="spac-ver.mkiv" name="linecorrection" type="environment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="blank"/> + <cd:inherit name="blank"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="spac-ver.mkiv" name="locallinecorrection" type="environment"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="blank"/> + <cd:inherit name="blank"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-xml.xml"> + <cd:command name="xmlmain"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlflush"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmltext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlpure"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlflushtext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlflushpure"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlnonspace"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlflushspacewise"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlflushlinewise"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlall"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmllastmatch"/> + <cd:command name="xmlfirst"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmllast"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlcontext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlflushcontext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlshow"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlinfo"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlfilter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlstrip"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlstripped"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlstripnolines"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlstrippednolines"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlposition"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlelement"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlpos"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlsnippet"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:number"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlconcat"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlconcatrange"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:first"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:last"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlcommand"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:xmlsetup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlinlineverbatim"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlinlineverbatim" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldisplayverbatim"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldisplayverbatim" type="environment"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlverbatim"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlprettyprint"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlloadfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:xmlsetup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlloadbuffer"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:xmlsetup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlloaddata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:xmlsetup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlloadonly"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:xmlsetup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlprocessfile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:xmlsetup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlprocessbuffer"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:xmlsetup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlprocessdata"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:xmlsetup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlinclude"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlname"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlpath"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlnamespace"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmltag"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlcount"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlatt"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlattdef"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlrefatt"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmllastatt"/> + <cd:command name="xmlattribute"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlattributedef"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlchainatt"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlchainattdef"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldirectives"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldirectivesbefore"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldirectivesafter"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlinstalldirective"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:csname"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlsetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlsetsetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlremovesetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlremovedocumentsetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlflushdocumentsetups"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlresetsetups"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlresetdocumentsetups"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlprependsetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlappendsetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlbeforesetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlaftersetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlprependdocumentsetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlappenddocumentsetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlbeforedocumentsetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlafterdocumentsetup"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlregisteredsetups"/> + <cd:command name="xmlregistereddocumentsetups"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:setup"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlsetfunction"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:luafunction"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldoif"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldoifnot"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldoifelse"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldoiftext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldoifnottext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldoifelsetext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldoifselfempty"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldoifnotselfempty"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldoifelseselfempty"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldoifelseempty"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlregisterns"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:url"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlregisterns"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlremapname"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlremapnamespace"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlchecknamespace"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlmapvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:category"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlvalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:category"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmldoifelsevalue"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:category"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:true"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:false"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlloaddirectives"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlsave"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmltofile"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:file"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmltobuffer"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmltobufferverbose"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:lpath"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:buffer"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmladdindex"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlinclusion"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlinclusions"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlbadinclusions"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlraw"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlraw" type="environment"/> + <cd:command name="xmlresetinjectors"/> + <cd:command name="xmlsetinjectors"> + <cd:arguments> + <cd:keywords list="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlinjector"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlapplyselectors"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmlsetentity"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="xmltexentity"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="setupxml"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="default"> + <cd:constant type="hidden"/> + <cd:constant type="none"/> + <cd:constant type="text"/> + </cd:parameter> + <cd:parameter name="compress"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command name="xmldefaulttotext"> + <cd:arguments> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:node"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface> + <cd:interface file="i-xtable.xml"> + <cd:command file="tabl-xtb.mkvi" name="definextable"> + <cd:arguments> + <cd:keywords> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupxtable"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="setupxtable"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:parameter name="textwidth"> + <cd:constant type="cd:dimension"/> + <cd:constant default="yes" type="local"/> + </cd:parameter> + <cd:parameter name="bodyfont"> + <cd:inherit name="setupbodyfont"/> + </cd:parameter> + <cd:parameter name="spaceinbetween"> + <cd:inherit name="blank"/> + </cd:parameter> + <cd:parameter name="option"> + <cd:constant type="tight"/> + <cd:constant type="max"/> + <cd:constant type="stretch"/> + <cd:constant type="width"/> + <cd:constant type="height"/> + <cd:constant type="fixed"/> + </cd:parameter> + <cd:parameter name="textheight"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="maxwidth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="columndistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="leftmargindistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rightmargindistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="header"> + <cd:constant type="repeat"/> + </cd:parameter> + <cd:parameter name="footer"> + <cd:constant type="repeat"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="split"> + <cd:constant type="yes"/> + <cd:constant type="no"/> + <cd:constant type="repeat"/> + <cd:constant default="yes" type="auto"/> + </cd:parameter> + <cd:parameter name="splitoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="samepage"> + <cd:constant type="before"/> + <cd:constant type="after"/> + <cd:constant type="both"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="xtable" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupxtable"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="xtable" type="environment" variant="name"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="embeddedxtable" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupxtable"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="embeddedxtable" type="environment" variant="name"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" generated="yes" name="xtable" type="environment" variant="example"> + <cd:sequence> + <cd:variable value="xtable"/> + </cd:sequence> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupxtable"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="processxtablebuffer"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="xrow" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupxtable"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="xcell" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="nx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="ny"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="nc"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="nr"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:inherit name="setupxtable"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="xtablehead" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupxtable"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="xtablehead" type="environment" variant="name"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="xtablefoot" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupxtable"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="xtablefoot" type="environment" variant="name"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="xtablenext" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupxtable"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="xtablenext" type="environment" variant="name"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="xtablebody" type="environment"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupxtable"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="xtablebody" type="environment" variant="name"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="xgroup" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupxtable"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="xrowgroup" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupxtable"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="xcellgroup" type="environment"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupxtable"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command file="tabl-xtb.mkvi" name="currentxtablerow"/> + <cd:command file="tabl-xtb.mkvi" name="currentxtablecolumn"/> + </cd:interface> +</cd:interface> diff --git a/tex/context/interface/mkiv/i-align.xml b/tex/context/interface/mkiv/i-align.xml index 07a66d2dd..d8b75a463 100644 --- a/tex/context/interface/mkiv/i-align.xml +++ b/tex/context/interface/mkiv/i-align.xml @@ -32,6 +32,7 @@ <cd:constant type="center"/> <cd:constant type="disable"/> <cd:constant type="last"/> + <cd:constant type="end"/> <cd:constant type="paragraph"/> <cd:constant type="lefttoright"/> <cd:constant type="righttoleft"/> @@ -242,6 +243,8 @@ <cd:command name="centeredlastline" file="spac-ali.mkiv"/> + <cd:command name="flushedrightlastline" file="spac-ali.mkiv"/> + <cd:command name="ttraggedright" file="spac-ali.mkiv"/> <cd:command name="forgetragged" file="spac-ali.mkiv"/> diff --git a/tex/context/interface/mkiv/i-attachment.xml b/tex/context/interface/mkiv/i-attachment.xml index 6aadc0304..82056a0ad 100644 --- a/tex/context/interface/mkiv/i-attachment.xml +++ b/tex/context/interface/mkiv/i-attachment.xml @@ -107,7 +107,7 @@ </cd:arguments> </cd:command> - <cd:command name="attachment" generated="yes" variant="generated" file="scrn-wid.mkvi"> + <cd:command name="attachment" generated="yes" variant="example" file="scrn-wid.mkvi"> <cd:sequence> <cd:variable value="attachment"/> </cd:sequence> @@ -117,9 +117,12 @@ <cd:inherit name="setupattachment"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:constant value="attachment"/> + </cd:instances> </cd:command> - <cd:command name="attachment" type="environment" generated="yes" variant="generated" file="scrn-wid.mkvi"> + <cd:command name="attachment" type="environment" generated="yes" variant="example" file="scrn-wid.mkvi"> <cd:sequence> <cd:variable value="attachment"/> </cd:sequence> @@ -129,6 +132,9 @@ <cd:inherit name="setupattachment"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:constant value="attachment"/> + </cd:instances> </cd:command> <cd:command name="placeattachments" file="scrn-wid.mkvi"/> diff --git a/tex/context/interface/mkiv/i-attribute.xml b/tex/context/interface/mkiv/i-attribute.xml index eb699b99e..cd1e807d2 100644 --- a/tex/context/interface/mkiv/i-attribute.xml +++ b/tex/context/interface/mkiv/i-attribute.xml @@ -93,4 +93,4 @@ <cd:command name="showattributes" file="attr-ini.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-background.xml b/tex/context/interface/mkiv/i-background.xml index 400e01454..f51a0247c 100644 --- a/tex/context/interface/mkiv/i-background.xml +++ b/tex/context/interface/mkiv/i-background.xml @@ -45,7 +45,7 @@ </cd:arguments> </cd:command> - <cd:command name="background" type="environment" generated="yes" variant="generated" file="pack-bck.mkvi"> + <cd:command name="background" type="environment" generated="yes" variant="example" file="pack-bck.mkvi"> <cd:sequence> <cd:variable value="background"/> </cd:sequence> @@ -54,6 +54,9 @@ <cd:inherit name="setupbackground"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:constant value="background"/> + </cd:instances> </cd:command> <cd:command name="background" type="environment" file="pack-bck.mkvi"> @@ -64,13 +67,16 @@ </cd:arguments> </cd:command> - <cd:command name="background" generated="yes" variant="generated" file="pack-bck.mkvi"> + <cd:command name="background" generated="yes" variant="example" file="pack-bck.mkvi"> <cd:sequence> <cd:variable value="background"/> </cd:sequence> <cd:arguments> <cd:content/> </cd:arguments> + <cd:instances> + <cd:constant value="background"/> + </cd:instances> </cd:command> <cd:command name="background" file="pack-bck.mkvi"> @@ -86,7 +92,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupbackgrounds" variant="1" file="page-bck.mkiv"> + <cd:command name="setupbackgrounds" file="page-bck.mkiv"> <cd:arguments> <cd:keywords list="yes"> <cd:constant type="top"/> @@ -108,7 +114,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupbackgrounds" variant="2" file="page-bck.mkiv"> + <cd:command name="setupbackgrounds" variant="page" file="page-bck.mkiv"> <cd:arguments> <cd:keywords list="yes" optional="yes"> <cd:constant type="paper"/> @@ -158,4 +164,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-bar.xml b/tex/context/interface/mkiv/i-bar.xml index 3f339b9a0..951448249 100644 --- a/tex/context/interface/mkiv/i-bar.xml +++ b/tex/context/interface/mkiv/i-bar.xml @@ -26,6 +26,10 @@ <cd:constant type="no" default="yes"/> <cd:constant type="all"/> </cd:parameter> + <cd:parameter name="empty"> + <cd:constant type="yes"/> + <cd:constant type="no" default="yes"/> + </cd:parameter> <cd:parameter name="unit"> <cd:constant type="ex" default="yes"/> <cd:constant type="em"/> @@ -68,6 +72,12 @@ <cd:parameter name="mp"> <cd:constant type="cd:name"/> </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:text"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> @@ -85,13 +95,31 @@ --> - <cd:command name="bar" generated="yes" variant="generated" file="node-rul.mkiv"> + <cd:command name="bar" generated="yes" variant="example" file="node-rul.mkiv"> <cd:sequence> <cd:variable value="bar"/> </cd:sequence> <cd:arguments> <cd:content/> </cd:arguments> + <cd:instances> + <cd:constant value="overbar"/> + <cd:constant value="underbar"/> + <cd:constant value="overstrike"/> + <cd:constant value="understrike"/> + <cd:constant value="overbars"/> + <cd:constant value="underbars"/> + <cd:constant value="overstrikes"/> + <cd:constant value="understrikes"/> + <cd:constant value="underrandom"/> + <cd:constant value="underrandoms"/> + <cd:constant value="underdash"/> + <cd:constant value="underdashes"/> + <cd:constant value="underdot"/> + <cd:constant value="underdots"/> + <cd:constant value="nobar"/> + <cd:constant value="hiddenbar"/> + </cd:instances> </cd:command> <cd:command name="bar" type="environment" file="node-rul.mkiv"> @@ -130,6 +158,12 @@ </cd:arguments> </cd:command> + <cd:command name="hiddenbar" file="node-rul.mkiv"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command name="overstrike" file="node-rul.mkiv"> <cd:arguments> <cd:content/> @@ -202,4 +236,12 @@ </cd:arguments> </cd:command> + <cd:command name="nobar" file="node-rul.mkiv"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="resetbar" file="node-rul.mkiv"/> + </cd:interface> diff --git a/tex/context/interface/mkiv/i-bleed.xml b/tex/context/interface/mkiv/i-bleed.xml index 15a2fe5f7..301f7d066 100644 --- a/tex/context/interface/mkiv/i-bleed.xml +++ b/tex/context/interface/mkiv/i-bleed.xml @@ -61,4 +61,4 @@ <cd:command name="bleedheight" file="pack-box.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-block.xml b/tex/context/interface/mkiv/i-block.xml index 980b5b435..837b2133d 100644 --- a/tex/context/interface/mkiv/i-block.xml +++ b/tex/context/interface/mkiv/i-block.xml @@ -37,7 +37,7 @@ </cd:arguments> </cd:command> - <cd:command name="block" type="environment" generated="yes" variant="generated" begin="begin" end="end" file="strc-blk.mkiv"> + <cd:command name="block" type="environment" generated="yes" variant="example" begin="begin" end="end" file="strc-blk.mkiv"> <cd:sequence> <cd:variable value="block"/> </cd:sequence> @@ -117,4 +117,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-bookmark.xml b/tex/context/interface/mkiv/i-bookmark.xml index 5b7aec9a8..68d893609 100644 --- a/tex/context/interface/mkiv/i-bookmark.xml +++ b/tex/context/interface/mkiv/i-bookmark.xml @@ -76,4 +76,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-boxes.xml b/tex/context/interface/mkiv/i-boxes.xml index a9eeb96ae..648106b89 100644 --- a/tex/context/interface/mkiv/i-boxes.xml +++ b/tex/context/interface/mkiv/i-boxes.xml @@ -142,7 +142,7 @@ </cd:arguments> </cd:command> - <cd:command name="limitatetext" variant="1" file="supp-box.mkiv"> + <cd:command name="limitatetext" file="supp-box.mkiv"> <cd:arguments> <cd:resolve name="argument-text"/> <cd:keywords delimiters="braces"> @@ -152,7 +152,7 @@ </cd:arguments> </cd:command> - <cd:command name="limitatetext" variant="2" file="supp-box.mkiv"> + <cd:command name="limitatetext" variant="list" file="supp-box.mkiv"> <cd:arguments> <cd:resolve name="argument-text"/> <cd:keywords delimiters="braces" list="yes"> @@ -444,7 +444,7 @@ <cd:content/> </cd:arguments> </cd:command> - + <cd:command name="limitatelines" file="supp-box.mkiv"> <cd:arguments> <cd:resolve name="argument-number"/> @@ -866,6 +866,63 @@ </cd:arguments> </cd:command> + <cd:command name="runninghbox" file="supp-box.mkiv"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="vbox" type="environment" begin="begin" end="end" file="supp-box.mkiv"/> + + <cd:command name="hbox" type="environment" begin="begin" end="end" file="supp-box.mkiv"/> + + <cd:command name="vtop" type="environment" begin="begin" end="end" file="supp-box.mkiv"/> + + <cd:command name="setvboxregister" file="supp-box.mkiv"> + <cd:arguments> + <cd:resolve name="string-box"/> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="sethboxregister" file="supp-box.mkiv"> + <cd:arguments> + <cd:resolve name="string-box"/> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="setvtopregister" file="supp-box.mkiv"> + <cd:arguments> + <cd:resolve name="string-box"/> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="flushboxregister" file="supp-box.mkiv"> + <cd:arguments> + <cd:resolve name="string-box"/> + </cd:arguments> + </cd:command> + + <cd:command name="vboxregister" type="environment" file="supp-box.mkiv"> + <cd:arguments> + <cd:resolve name="string-box"/> + </cd:arguments> + </cd:command> + + <cd:command name="hboxregister" type="environment" file="supp-box.mkiv"> + <cd:arguments> + <cd:resolve name="string-box"/> + </cd:arguments> + </cd:command> + + <cd:command name="vtopregister" type="environment" file="supp-box.mkiv"> + <cd:arguments> + <cd:resolve name="string-box"/> + </cd:arguments> + </cd:command> + <cd:command name="righttolefthbox" file="spac-ali.mkiv"> <cd:arguments> <cd:resolve name="string-boxoptions"/> @@ -969,7 +1026,7 @@ </cd:arguments> </cd:command> - <cd:command name="hbox" generated="yes" variant="generated" file="spac-ali.mkiv"> + <cd:command name="hbox" generated="yes" variant="example" file="spac-ali.mkiv"> <cd:sequence> <cd:string value="hbox"/> <cd:variable value="box"/> @@ -979,4 +1036,7 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file + <cd:command name="lastlinewidth" file="supp-box.mkiv"> + </cd:command> + +</cd:interface> diff --git a/tex/context/interface/mkiv/i-buffer.xml b/tex/context/interface/mkiv/i-buffer.xml index ad1ffd519..38571fcd4 100644 --- a/tex/context/interface/mkiv/i-buffer.xml +++ b/tex/context/interface/mkiv/i-buffer.xml @@ -97,13 +97,16 @@ </cd:arguments> </cd:command> - <cd:command name="buffer" type="environment" generated="yes" variant="generated" file="buff-ini.mkiv"> + <cd:command name="buffer" type="environment" generated="yes" variant="example" file="buff-ini.mkiv"> <cd:sequence> <cd:variable value="buffer"/> </cd:sequence> + <cd:instances> + <cd:constant value="hiding"/> + </cd:instances> </cd:command> - <cd:command name="getbuffer" generated="yes" variant="generated" file="buff-ini.mkiv"> + <cd:command name="getbuffer" generated="yes" variant="example" file="buff-ini.mkiv"> <cd:sequence> <cd:string value="get"/> <cd:variable value="buffer"/> @@ -121,14 +124,14 @@ </cd:arguments> </cd:command> - <cd:command name="savebuffer" variant="1" file="buff-ini.mkiv"> + <cd:command name="savebuffer" variant="list" file="buff-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-buffer-list"/> <cd:resolve name="keyword-file"/> </cd:arguments> </cd:command> - <cd:command name="savebuffer" variant="2" file="buff-ini.mkiv"> + <cd:command name="savebuffer" file="buff-ini.mkiv"> <cd:arguments> <cd:assignments list="yes"> <cd:parameter name="list"> @@ -172,7 +175,7 @@ </cd:arguments> </cd:command> - <cd:command name="typebuffer" generated="yes" variant="generated" file="buff-ver.mkiv"> + <cd:command name="typebuffer" generated="yes" variant="example" file="buff-ver.mkiv"> <cd:sequence> <cd:string value="type"/> <cd:variable value="buffer"/> @@ -193,4 +196,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-button.xml b/tex/context/interface/mkiv/i-button.xml index 1f6dfd5bf..0ccb2d28d 100644 --- a/tex/context/interface/mkiv/i-button.xml +++ b/tex/context/interface/mkiv/i-button.xml @@ -60,7 +60,7 @@ --> - <cd:command name="button" generated="yes" variant="generated" file="scrn-but.mkvi"> + <cd:command name="button" generated="yes" variant="example" file="scrn-but.mkvi"> <cd:sequence> <cd:variable value="button"/> </cd:sequence> @@ -71,6 +71,9 @@ <cd:resolve name="argument-text"/> <cd:resolve name="keyword-reference"/> </cd:arguments> + <cd:instances> + <cd:constant value="button"/> + </cd:instances> </cd:command> <cd:command name="button" file="scrn-but.mkvi"> @@ -83,13 +86,13 @@ </cd:arguments> </cd:command> - <cd:command name="overlaybutton" variant="1" file="scrn-but.mkvi"> + <cd:command name="overlaybutton" file="scrn-but.mkvi"> <cd:arguments> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="overlaybutton" variant="2" file="scrn-but.mkvi"> + <cd:command name="overlaybutton" variant="direct" file="scrn-but.mkvi"> <cd:arguments> <cd:resolve name="argument-reference"/> </cd:arguments> @@ -135,21 +138,25 @@ </cd:arguments> </cd:command> - <cd:command name="psh" variant="button" file="scrn-fld.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference"/> - <cd:resolve name="string-text"/> - <cd:delimiter name="\"/> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="psh" type="environment" variant="button" file="scrn-fld.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference"/> - </cd:arguments> - </cd:command> + <cd:command name="psh" scope="interactionmenu" file="scrn-fld.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference"/> + <cd:resolve name="string-text"/> + <cd:delimiter name="\"/> + </cd:arguments> + </cd:command> + + <cd:command name="psh" type="environment" scope="interactionmenu" file="scrn-fld.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference"/> + </cd:arguments> + </cd:command> + + --> - <cd:command name="rollbutton" variant="1" file="scrn-fld.mkvi"> + <cd:command name="rollbutton" variant="interactionmenu" file="scrn-fld.mkvi"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:assignments list="yes" optional="yes"> @@ -160,7 +167,7 @@ </cd:arguments> </cd:command> - <cd:command name="rollbutton" variant="2" file="scrn-fld.mkvi"> + <cd:command name="rollbutton" variant="button" file="scrn-fld.mkvi"> <cd:arguments> <cd:assignments list="yes"> <cd:inherit name="setupbutton"/> @@ -170,18 +177,22 @@ </cd:arguments> </cd:command> - <cd:command name="rob" variant="button" file="scrn-fld.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference"/> - <cd:resolve name="string-text"/> - <cd:delimiter name="\"/> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="rob" variant="button" type="environment" file="scrn-fld.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference"/> - </cd:arguments> - </cd:command> + <cd:command name="rob" scope="interactionmenu" file="scrn-fld.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference"/> + <cd:resolve name="string-text"/> + <cd:delimiter name="\"/> + </cd:arguments> + </cd:command> + + <cd:command name="rob" type="environment" scope="interactionmenu" file="scrn-fld.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference"/> + </cd:arguments> + </cd:command> + + --> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-capitals.xml b/tex/context/interface/mkiv/i-capitals.xml index bfbb6bb2b..154a1a040 100644 --- a/tex/context/interface/mkiv/i-capitals.xml +++ b/tex/context/interface/mkiv/i-capitals.xml @@ -205,4 +205,4 @@ <cd:command name="randomized" type="environment" file="typo-cap.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-catcodes.xml b/tex/context/interface/mkiv/i-catcodes.xml index 7c3f649d5..b8636ceee 100644 --- a/tex/context/interface/mkiv/i-catcodes.xml +++ b/tex/context/interface/mkiv/i-catcodes.xml @@ -120,4 +120,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-character.xml b/tex/context/interface/mkiv/i-character.xml index 47bc714fa..f7f0e08db 100644 --- a/tex/context/interface/mkiv/i-character.xml +++ b/tex/context/interface/mkiv/i-character.xml @@ -133,4 +133,4 @@ <cd:command name="textplus" file="enco-ini.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-characteralign.xml b/tex/context/interface/mkiv/i-characteralign.xml index 2ee8d0cd9..a515ba1e9 100644 --- a/tex/context/interface/mkiv/i-characteralign.xml +++ b/tex/context/interface/mkiv/i-characteralign.xml @@ -42,4 +42,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-chart.xml b/tex/context/interface/mkiv/i-chart.xml new file mode 100644 index 000000000..06c356041 --- /dev/null +++ b/tex/context/interface/mkiv/i-chart.xml @@ -0,0 +1,217 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?context-directive job ctxfile x-setups.ctx ?> + +<cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> + + <?context-directive job ctxfile x-setups.ctx ?> + + <!-- still incomplete --> + + <cd:command name="setupFLOWcharts" file="m-chart.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="width"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="dx"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="dy"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="nx"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="ny"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="x"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="y"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="labeloffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="commentoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="exitoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="split"> + <cd:constant type="yes"/> + <cd:constant type="no" default="yes"/> + </cd:parameter> + <cd:parameter name="bodyfont"> + <cd:inherit name="setupbodyfont"/> + </cd:parameter> + <cd:parameter name="option"> + <cd:constant type="test"/> + </cd:parameter> + <!-- dot: private option --> + <cd:parameter name="focus"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="autofocus"> + <cd:constant type="yes"/> + <cd:constant type="no" default="yes"/> + </cd:parameter> + <cd:parameter name="autofocus"> + <cd:constant type="yes"/> + <cd:constant type="no" default="yes"/> + </cd:parameter> + <cd:parameter name="background"> + <cd:resolve name="value-background"/> + </cd:parameter> + <cd:parameter name="framecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="backgroundcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="frame"> + <cd:constant type="on" default="yes"/> + <cd:constant type="off"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setupFLOWlines" file="m-chart.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="color"> + <cd:constant name="round"/> + <cd:constant name="normal" default="yes"/> + </cd:parameter> + <cd:parameter name="arrow"> + <cd:constant name="yes" default="yes"/> + <cd:constant name="no"/> + </cd:parameter> + <cd:parameter name="dash"> + <cd:constant name="yes"/> + <cd:constant name="no" default="yes"/> + </cd:parameter> + <cd:parameter name="radius"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant name="cd:color"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant name="cd:dimension"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setupFLOWshapes" file="m-chart.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="default"> + <cd:resolve name="cd:name"/> + </cd:parameter> + <cd:parameter name="framecolor"> + <cd:constant name="cd:color"/> + </cd:parameter> + <cd:parameter name="background"> + <cd:resolve name="value-background"/> + </cd:parameter> + <cd:parameter name="backgroundcolor"> + <cd:constant name="cd:color"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant name="cd:dimension"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="none"/> + <cd:constant type="overlay"/> + <cd:constant type="standard"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setupFLOWfocus" file="m-chart.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="background"> + <cd:inherit name="setupFLOWshape"/> + </cd:parameter> + <cd:parameter name="backgroundcolor"> + <cd:inherit name="setupFLOWshape"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:inherit name="setupFLOWshape"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:inherit name="setupFLOWshape"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setupFLOWsplit" file="m-chart.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="dx"> + <cd:constant name="cd:number"/> + </cd:parameter> + <cd:parameter name="dy"> + <cd:constant name="cd:number"/> + </cd:parameter> + <cd:parameter name="nx"> + <cd:constant name="cd:number"/> + </cd:parameter> + <cd:parameter name="ny"> + <cd:constant name="cd:number"/> + </cd:parameter> + <cd:parameter name="command"> + <cd:constant name="cd:command"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant name="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant name="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <!-- + + startFLOWchart [name] + FLOWchart [name] + startFLOWcell [key=value] + includeFLOWchart + + name shape destination focus overlay location text label comment exit + connection include figure connect locate + --> + +</cd:interface> diff --git a/tex/context/interface/mkiv/i-chemical.xml b/tex/context/interface/mkiv/i-chemical.xml index d300f9008..1a81b82fc 100644 --- a/tex/context/interface/mkiv/i-chemical.xml +++ b/tex/context/interface/mkiv/i-chemical.xml @@ -252,4 +252,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-cleaning.xml b/tex/context/interface/mkiv/i-cleaning.xml index d982a5dd5..e37eb7999 100644 --- a/tex/context/interface/mkiv/i-cleaning.xml +++ b/tex/context/interface/mkiv/i-cleaning.xml @@ -44,4 +44,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-collector.xml b/tex/context/interface/mkiv/i-collector.xml index dab49f14c..a75f3534e 100644 --- a/tex/context/interface/mkiv/i-collector.xml +++ b/tex/context/interface/mkiv/i-collector.xml @@ -111,4 +111,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-color.xml b/tex/context/interface/mkiv/i-color.xml index 3f98914e4..4168216a9 100644 --- a/tex/context/interface/mkiv/i-color.xml +++ b/tex/context/interface/mkiv/i-color.xml @@ -39,7 +39,7 @@ </cd:arguments> </cd:command> - <cd:command name="definecolor" variant="1" file="colo-ini.mkiv"> + <cd:command name="definecolor" file="colo-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:assignments list="yes"> @@ -77,24 +77,7 @@ <cd:constant type="cd:number"/> </cd:parameter> <cd:parameter name="a"> - <cd:constant type="cd:number"/> - <cd:constant type="none"/> - <cd:constant type="normal"/> - <cd:constant type="multiply"/> - <cd:constant type="screen"/> - <cd:constant type="overlay"/> - <cd:constant type="softlight"/> - <cd:constant type="hardlight"/> - <cd:constant type="colordodge"/> - <cd:constant type="colorburn"/> - <cd:constant type="darken"/> - <cd:constant type="lighten"/> - <cd:constant type="difference"/> - <cd:constant type="exclusion"/> - <cd:constant type="hue"/> - <cd:constant type="saturation"/> - <cd:constant type="color"/> - <cd:constant type="luminosity"/> + <cd:resolve name="value-transparency"/> </cd:parameter> <cd:parameter name="t"> <cd:constant type="cd:number"/> @@ -103,14 +86,14 @@ </cd:arguments> </cd:command> - <cd:command name="definecolor" variant="2" file="colo-ini.mkiv"> + <cd:command name="definecolor" variant="name" file="colo-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="keyword-color"/> </cd:arguments> </cd:command> - <cd:command name="defineglobalcolor" variant="1" file="colo-ini.mkiv"> + <cd:command name="defineglobalcolor" file="colo-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:assignments list="yes"> @@ -119,14 +102,14 @@ </cd:arguments> </cd:command> - <cd:command name="defineglobalcolor" variant="2" file="colo-ini.mkiv"> + <cd:command name="defineglobalcolor" variant="name" file="colo-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="keyword-color"/> </cd:arguments> </cd:command> - <cd:command name="definenamedcolor" variant="1" file="colo-ini.mkiv"> + <cd:command name="definenamedcolor" file="colo-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:assignments list="yes"> @@ -135,7 +118,7 @@ </cd:arguments> </cd:command> - <cd:command name="definenamedcolor" variant="2" file="colo-ini.mkiv"> + <cd:command name="definenamedcolor" variant="name" file="colo-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="keyword-color"/> @@ -158,24 +141,7 @@ <cd:resolve name="keyword-color"/> <cd:assignments list="yes"> <cd:parameter name="a"> - <cd:constant type="cd:number"/> - <cd:constant type="none"/> - <cd:constant type="normal"/> - <cd:constant type="multiply"/> - <cd:constant type="screen"/> - <cd:constant type="overlay"/> - <cd:constant type="softlight"/> - <cd:constant type="hardlight"/> - <cd:constant type="colordodge"/> - <cd:constant type="colorburn"/> - <cd:constant type="darken"/> - <cd:constant type="lighten"/> - <cd:constant type="difference"/> - <cd:constant type="exclusion"/> - <cd:constant type="hue"/> - <cd:constant type="saturation"/> - <cd:constant type="color"/> - <cd:constant type="luminosity"/> + <cd:resolve name="value-transparency"/> </cd:parameter> <cd:parameter name="t"> <cd:constant type="cd:number"/> @@ -207,13 +173,34 @@ </cd:arguments> </cd:command> - <cd:command name="definetransparency" file="colo-ini.mkiv"> + <cd:command name="definetransparency" variant="1" file="colo-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="keyword-number"/> </cd:arguments> </cd:command> + <cd:command name="definetransparency" variant="2" file="colo-ini.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name"/> + <cd:assignments list="yes"> + <cd:parameter name="a"> + <cd:resolve name="value-transparency"/> + </cd:parameter> + <cd:parameter name="t"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="definetransparency" variant="3" file="colo-ini.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name"/> + <cd:resolve name="keyword-name"/> + </cd:arguments> + </cd:command> + <cd:command name="switchtocolor" file="colo-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-color"/> @@ -227,6 +214,20 @@ </cd:arguments> </cd:command> + <cd:command name="coloronly" file="colo-ini.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-color"/> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="transparent" file="colo-ini.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-color"/> + <cd:content/> + </cd:arguments> + </cd:command> + <cd:command name="graycolor" file="colo-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-color"/> @@ -234,14 +235,14 @@ </cd:arguments> </cd:command> - <cd:command name="colored" variant="1" file="colo-ini.mkiv"> + <cd:command name="colored" variant="name" file="colo-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-color"/> <cd:content/> </cd:arguments> </cd:command> - <cd:command name="colored" variant="2" file="colo-ini.mkiv"> + <cd:command name="colored" file="colo-ini.mkiv"> <cd:arguments> <cd:assignments list="yes"> <cd:inherit name="definecolor"/> @@ -256,19 +257,31 @@ </cd:arguments> </cd:command> + <cd:command name="coloronly" type="environment" file="colo-ini.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-color"/> + </cd:arguments> + </cd:command> + + <cd:command name="transparent" type="environment" file="colo-ini.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-color"/> + </cd:arguments> + </cd:command> + <cd:command name="directcolor" file="colo-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-color"/> </cd:arguments> </cd:command> - <cd:command name="directcolored" variant="1" file="colo-ini.mkiv"> + <cd:command name="directcolored" variant="name" file="colo-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-color"/> </cd:arguments> </cd:command> - <cd:command name="directcolored" variant="2" file="colo-ini.mkiv"> + <cd:command name="directcolored" file="colo-ini.mkiv"> <cd:arguments> <cd:assignments list="yes"> <cd:inherit name="definecolor"/> @@ -353,7 +366,7 @@ <cd:command name="color" type="environment" begin="save" end="restore" file="colo-ini.mkiv"/> - <cd:command name="definepalet" variant="1" file="colo-ini.mkiv"> + <cd:command name="definepalet" file="colo-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:assignments list="yes"> @@ -364,7 +377,7 @@ </cd:arguments> </cd:command> - <cd:command name="definepalet" variant="2" file="colo-ini.mkiv"> + <cd:command name="definepalet" variant="name" file="colo-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="keyword-name"/> @@ -594,4 +607,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-combination.xml b/tex/context/interface/mkiv/i-combination.xml index 4e7ea2d52..492edadd0 100644 --- a/tex/context/interface/mkiv/i-combination.xml +++ b/tex/context/interface/mkiv/i-combination.xml @@ -85,7 +85,7 @@ --> - <cd:command name="combination" type="environment" variant="1" file="pack-com.mkiv"> + <cd:command name="combination" type="environment" variant="matrix" file="pack-com.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:keywords optional="yes"> @@ -94,7 +94,7 @@ </cd:arguments> </cd:command> - <cd:command name="combination" type="environment" variant="2" file="pack-com.mkiv"> + <cd:command name="combination" type="environment" file="pack-com.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:assignments list="yes" optional="yes"> @@ -105,13 +105,13 @@ <!-- - <cd:command name="content" type="environment" variant="combination" file="pack-com.mkiv"/> + <cd:command name="content" type="environment" scope="combination" file="pack-com.mkiv"/> - <cd:command name="caption" type="environment" variant="combination" file="pack-com.mkiv"/> + <cd:command name="caption" type="environment" scope="combination" file="pack-com.mkiv"/> --> - <cd:command name="floatcombination" type="environment" variant="1" file="pack-com.mkiv"> + <cd:command name="floatcombination" type="environment" variant="matrix" file="pack-com.mkiv"> <cd:arguments> <cd:keywords optional="yes"> <cd:constant type="cd:matrix"/> @@ -120,7 +120,7 @@ </cd:arguments> </cd:command> - <cd:command name="floatcombination" type="environment" variant="2" file="pack-com.mkiv"> + <cd:command name="floatcombination" type="environment" file="pack-com.mkiv"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupcombination"/> @@ -128,4 +128,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-commandhandler.xml b/tex/context/interface/mkiv/i-commandhandler.xml index 210690d3e..6550898b6 100644 --- a/tex/context/interface/mkiv/i-commandhandler.xml +++ b/tex/context/interface/mkiv/i-commandhandler.xml @@ -311,4 +311,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-comment.xml b/tex/context/interface/mkiv/i-comment.xml index 52d54398b..e7f18fb0e 100644 --- a/tex/context/interface/mkiv/i-comment.xml +++ b/tex/context/interface/mkiv/i-comment.xml @@ -91,7 +91,7 @@ </cd:arguments> </cd:command> - <cd:command name="comment" generated="yes" variant="generated" file="scrn-wid.mkvi"> + <cd:command name="comment" generated="yes" variant="example" file="scrn-wid.mkvi"> <cd:sequence> <cd:variable value="comment"/> </cd:sequence> @@ -102,9 +102,12 @@ </cd:assignments> <cd:resolve name="argument-text"/> </cd:arguments> + <cd:instances> + <cd:constant value="comment"/> + </cd:instances> </cd:command> - <cd:command name="comment" type="environment" generated="yes" variant="generated" file="scrn-wid.mkvi"> + <cd:command name="comment" type="environment" generated="yes" variant="example" file="scrn-wid.mkvi"> <cd:sequence> <cd:variable value="comment"/> </cd:sequence> @@ -114,6 +117,9 @@ <cd:inherit name="setupcomment"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:constant value="comment"/> + </cd:instances> </cd:command> <cd:command name="placecomments" file="scrn-wid.mkvi"/> diff --git a/tex/context/interface/mkiv/i-common-argument.xml b/tex/context/interface/mkiv/i-common-argument.xml index 9e7429800..b3b2cd5bc 100644 --- a/tex/context/interface/mkiv/i-common-argument.xml +++ b/tex/context/interface/mkiv/i-common-argument.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<?context-directive job ctxfile x-setups.ctx ?> - <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> <!-- * --> @@ -91,6 +89,32 @@ </cd:keywords> </cd:define> + <!-- @WS: These were unresolved. Shouldn't they become text? --> + + <cd:define name="argument-content"> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + </cd:define> + + <cd:define name="argument-content-optional"> + <cd:keywords delimiters="braces" optional="yes"> + <cd:content/> + </cd:keywords> + </cd:define> + + <cd:define name="argument-content-list"> + <cd:keywords delimiters="braces" list="yes"> + <cd:content/> + </cd:keywords> + </cd:define> + + <cd:define name="argument-content-list-optional"> + <cd:keywords delimiters="braces" list="yes" optional="yes"> + <cd:content/> + </cd:keywords> + </cd:define> + <!-- * --> <!-- \... {...} --> <!-- --> @@ -120,6 +144,35 @@ </cd:keywords> </cd:define> + <!-- * --> + <!-- \... {...} --> + <!-- --> + <!-- * PATH --> + + <cd:define name="argument-path"> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:path"/> + </cd:keywords> + </cd:define> + + <cd:define name="argument-path-optional"> + <cd:keywords delimiters="braces" optional="yes"> + <cd:constant type="cd:path"/> + </cd:keywords> + </cd:define> + + <cd:define name="argument-path-list"> + <cd:keywords delimiters="braces" list="yes"> + <cd:constant type="cd:path"/> + </cd:keywords> + </cd:define> + + <cd:define name="argument-path-list-optional"> + <cd:keywords delimiters="braces" list="yes" optional="yes"> + <cd:constant type="cd:path"/> + </cd:keywords> + </cd:define> + <!-- * --> <!-- \... {...} --> <!-- --> @@ -494,4 +547,4 @@ </cd:keywords> </cd:define> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-common-assignment.xml b/tex/context/interface/mkiv/i-common-assignment.xml index 0f11d0137..900a75452 100644 --- a/tex/context/interface/mkiv/i-common-assignment.xml +++ b/tex/context/interface/mkiv/i-common-assignment.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<?context-directive job ctxfile x-setups.ctx ?> - <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> <!-- * --> diff --git a/tex/context/interface/mkiv/i-common-definitions.xml b/tex/context/interface/mkiv/i-common-definitions.xml index 1bb84efdc..9f6d461f9 100644 --- a/tex/context/interface/mkiv/i-common-definitions.xml +++ b/tex/context/interface/mkiv/i-common-definitions.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<?context-directive job ctxfile x-setups.ctx ?> - <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> <cd:interfacefile filename="i-common-argument.xml"/> @@ -9,5 +7,6 @@ <cd:interfacefile filename="i-common-keyword.xml"/> <cd:interfacefile filename="i-common-string.xml"/> <cd:interfacefile filename="i-common-value.xml"/> + <cd:interfacefile filename="i-common-instance.xml"/> </cd:interface> diff --git a/tex/context/interface/mkiv/i-common-instance.xml b/tex/context/interface/mkiv/i-common-instance.xml new file mode 100644 index 000000000..8cde55b2e --- /dev/null +++ b/tex/context/interface/mkiv/i-common-instance.xml @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> + + <cd:define name="instance-float"> + <cd:constant value="chemical"/> + <cd:constant value="figure"/> + <cd:constant value="table"/> + <cd:constant value="intermezzo"/> + <cd:constant value="graphic"/> + </cd:define> + + <cd:define name="instance-itemgroup"> + <cd:constant value="itemize"/> + </cd:define> + + <cd:define name="instance-labeltext"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-labelclass"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-lines"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-combinedlist"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-low"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-high"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-makeup"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-margindata"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-mathalignment"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-mathcases"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-mathmatrix"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-mixedcolumns"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-note"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-linenote"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-pairedbox"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-register"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-script"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-section"> + <cd:constant value="chapter"/> + <cd:constant value="section"/> + <cd:constant value="subsection"/> + <cd:constant value="subsubsection"/> + <cd:constant value="subsubsubsection"/> + <cd:constant value="subsubsubsubsection"/> + <cd:constant value="title"/> + <cd:constant value="subject"/> + <cd:constant value="subsubject"/> + <cd:constant value="subsubsubject"/> + <cd:constant value="subsubsubsubject"/> + <cd:constant value="subsubsubsubsubject"/> + </cd:define> + + <cd:define name="instance-sectionblock"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-shift"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-sort"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-sortlist"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-synonym"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-synonymlist"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-tabulate"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-tooltip"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-unit"> + <!-- tode --> + </cd:define> + + <cd:define name="instance-typing"> + <!-- tode --> + </cd:define> + +</cd:interface> diff --git a/tex/context/interface/mkiv/i-common-keyword.xml b/tex/context/interface/mkiv/i-common-keyword.xml index 15eed8628..e087ea5ac 100644 --- a/tex/context/interface/mkiv/i-common-keyword.xml +++ b/tex/context/interface/mkiv/i-common-keyword.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<?context-directive job ctxfile x-setups.ctx ?> - <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> <!-- * --> @@ -471,6 +469,35 @@ <!-- * --> <!-- \... [...] --> <!-- --> + <!-- * PATH --> + + <cd:define name="keyword-path"> + <cd:keywords> + <cd:constant type="cd:path"/> + </cd:keywords> + </cd:define> + + <cd:define name="keyword-path-optional"> + <cd:keywords optional="yes"> + <cd:constant type="cd:path"/> + </cd:keywords> + </cd:define> + + <cd:define name="keyword-path-list"> + <cd:keywords list="yes"> + <cd:constant type="cd:path"/> + </cd:keywords> + </cd:define> + + <cd:define name="keyword-path-list-optional"> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:path"/> + </cd:keywords> + </cd:define> + + <!-- * --> + <!-- \... [...] --> + <!-- --> <!-- * FONT --> <cd:define name="keyword-font"> @@ -701,4 +728,26 @@ </cd:keywords> </cd:define> + <!-- * --> + <!-- \... [...] --> + <!-- --> + <!-- * FORMULA --> + + <cd:define name="keyword-formula-list-optional"> + <cd:keywords list="yes" optional="yes"> + <cd:resolve name="value-formula"/> + </cd:keywords> + </cd:define> + + <!-- * --> + <!-- \... [...] --> + <!-- --> + <!-- * FORMULAREFERENCE --> + + <cd:define name="keyword-formulareference-list-optional"> + <cd:keywords list="yes" optional="yes"> + <cd:resolve name="value-formulareference"/> + </cd:keywords> + </cd:define> + </cd:interface>
\ No newline at end of file diff --git a/tex/context/interface/mkiv/i-common-string.xml b/tex/context/interface/mkiv/i-common-string.xml index 8e940e6f3..68bde02ed 100644 --- a/tex/context/interface/mkiv/i-common-string.xml +++ b/tex/context/interface/mkiv/i-common-string.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<?context-directive job ctxfile x-setups.ctx ?> - <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> <!-- * --> diff --git a/tex/context/interface/mkiv/i-common-value.xml b/tex/context/interface/mkiv/i-common-value.xml index f111292b8..36f2c1d52 100644 --- a/tex/context/interface/mkiv/i-common-value.xml +++ b/tex/context/interface/mkiv/i-common-value.xml @@ -1,9 +1,15 @@ <?xml version="1.0" encoding="UTF-8"?> -<?context-directive job ctxfile x-setups.ctx ?> - <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> + <!-- background = ... --> + + <cd:define name="value-background"> + <cd:constant type="foreground"/> + <cd:constant type="color"/> + <cd:constant type="cd:name"/> + </cd:define> + <!-- style = ... --> <cd:define name="value-style"> @@ -11,6 +17,29 @@ <cd:constant type="cd:command"/> </cd:define> + <!-- a = ... --> + + <cd:define name="value-transparency"> + <cd:constant type="cd:number"/> + <cd:constant type="none"/> + <cd:constant type="normal"/> + <cd:constant type="multiply"/> + <cd:constant type="screen"/> + <cd:constant type="overlay"/> + <cd:constant type="softlight"/> + <cd:constant type="hardlight"/> + <cd:constant type="colordodge"/> + <cd:constant type="colorburn"/> + <cd:constant type="darken"/> + <cd:constant type="lighten"/> + <cd:constant type="difference"/> + <cd:constant type="exclusion"/> + <cd:constant type="hue"/> + <cd:constant type="saturation"/> + <cd:constant type="color"/> + <cd:constant type="luminosity"/> + </cd:define> + <!-- mathstyle = ... --> <cd:define name="value-mathstyle"> @@ -267,7 +296,10 @@ <cd:constant type="page"/> <cd:constant type="leftpage"/> <cd:constant type="rightpage"/> + <cd:constant type="header"/> + <cd:constant type="footer"/> <cd:constant type="somewhere"/> + <cd:constant type="effective"/> </cd:define> <!-- sortorder = ... --> @@ -543,4 +575,22 @@ <cd:constant type="editor"/> </cd:define> -</cd:interface>
\ No newline at end of file + <!-- formula = ... --> + + <cd:define name="value-formula"> + <cd:constant type="packed"/> + <cd:constant type="tight"/> + <cd:constant type="middle"/> + <cd:constant type="frame"/> + <cd:inherit name="setupbodyfont"/> + </cd:define> + + <!-- formula = ... --> + + <cd:define name="value-formulareference"> + <cd:constant type="+"/> + <cd:constant type="-"/> + <cd:constant type="cd:reference"/> + </cd:define> + +</cd:interface> diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf Binary files differindex fb29c8b5b..27a797b07 100644 --- a/tex/context/interface/mkiv/i-context.pdf +++ b/tex/context/interface/mkiv/i-context.pdf diff --git a/tex/context/interface/mkiv/i-conversion.xml b/tex/context/interface/mkiv/i-conversion.xml index b4755c27c..47440ddac 100644 --- a/tex/context/interface/mkiv/i-conversion.xml +++ b/tex/context/interface/mkiv/i-conversion.xml @@ -317,8 +317,8 @@ <cd:command name="currentdate" file="core-con.mkiv"> <cd:arguments> <cd:keywords list="yes" optional="yes"> - <cd:constant type="yes"/> - <cd:constant type="moth"/> + <cd:constant type="year"/> + <cd:constant type="month"/> <cd:constant type="day"/> <cd:constant type="weekday"/> <cd:constant type="y"/> @@ -341,6 +341,19 @@ <cd:constant type="dd:ord"/> <cd:constant type="D:ord"/> <cd:constant type="cd:text"/> + <cd:constant type="referral"/> + <cd:constant type="day:+"/> + <cd:constant type="day:++"/> + <cd:constant type="d:+"/> + <cd:constant type="d:++"/> + <cd:constant type="dd:+"/> + <cd:constant type="dd:++"/> + <cd:constant type="D:+"/> + <cd:constant type="D:++"/> + <cd:constant type="month:jalali"/> + <cd:constant type="m:jalali"/> + <cd:constant type="jalali:to"/> + <cd:constant type="jalali:from"/> </cd:keywords> </cd:arguments> </cd:command> @@ -399,7 +412,7 @@ </cd:arguments> </cd:command> - <cd:command name="defineconversion" variant="1" file="core-con.mkiv"> + <cd:command name="defineconversion" file="core-con.mkiv"> <cd:arguments> <cd:resolve name="keyword-language-optional"/> <cd:resolve name="keyword-name"/> @@ -407,7 +420,7 @@ </cd:arguments> </cd:command> - <cd:command name="defineconversion" variant="2" file="core-con.mkiv"> + <cd:command name="defineconversion" variant="list" file="core-con.mkiv"> <cd:arguments> <cd:resolve name="keyword-language-optional"/> <cd:resolve name="keyword-name"/> @@ -629,4 +642,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-counter.xml b/tex/context/interface/mkiv/i-counter.xml index 7701d40cd..55630b511 100644 --- a/tex/context/interface/mkiv/i-counter.xml +++ b/tex/context/interface/mkiv/i-counter.xml @@ -514,4 +514,4 @@ --> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-dataset.xml b/tex/context/interface/mkiv/i-dataset.xml index 914fe0af1..6f4f9fb9f 100644 --- a/tex/context/interface/mkiv/i-dataset.xml +++ b/tex/context/interface/mkiv/i-dataset.xml @@ -16,7 +16,7 @@ <cd:command name="setupdataset" file="core-dat.mkiv"> <cd:arguments> - <cd:resolve name="keyword-name-optional-list"/> + <cd:resolve name="keyword-name-list-optional"/> <cd:assignments list="yes"> <cd:parameter name="delay"> <cd:constant type="yes"/> diff --git a/tex/context/interface/mkiv/i-define.xml b/tex/context/interface/mkiv/i-define.xml index 0d0398e5d..2db8614c0 100644 --- a/tex/context/interface/mkiv/i-define.xml +++ b/tex/context/interface/mkiv/i-define.xml @@ -20,4 +20,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-delimitedtext.xml b/tex/context/interface/mkiv/i-delimitedtext.xml index 24fa581fd..d75fb957e 100644 --- a/tex/context/interface/mkiv/i-delimitedtext.xml +++ b/tex/context/interface/mkiv/i-delimitedtext.xml @@ -25,6 +25,8 @@ <cd:constant type="cd:command"/> </cd:parameter> <cd:parameter name="language"> + <cd:constant type="local"/> + <cd:constant type="global"/> <cd:constant type="cd:language"/> </cd:parameter> <cd:parameter name="method"> @@ -88,29 +90,46 @@ </cd:arguments> </cd:command> - <cd:command name="delimitedtext" generated="yes" variant="generated" file="typo-del.mkiv"> + <cd:command name="delimitedtext" generated="yes" variant="example" file="typo-del.mkiv"> <cd:sequence> <cd:variable value="delimitedtext"/> </cd:sequence> <cd:arguments> + <cd:resolve name="keyword-language-optional"/> <cd:content/> </cd:arguments> + <cd:instances> + <cd:constant value="quotation"/> + <cd:constant value="quote"/> + <cd:constant value="blockquote"/> + <cd:constant value="speech"/> + <cd:constant value="aside"/> + </cd:instances> </cd:command> - <cd:command name="delimitedtext" type="environment" generated="yes" variant="generated" file="typo-del.mkiv"> + <cd:command name="delimitedtext" type="environment" generated="yes" variant="example" file="typo-del.mkiv"> <cd:sequence> <cd:variable value="delimitedtext"/> </cd:sequence> <cd:arguments> + <cd:resolve name="keyword-language-optional"/> <cd:keywords list="yes" optional="yes"> <cd:inherit name="startnarrower"/> </cd:keywords> </cd:arguments> + <cd:instances> + <cd:constant value="quotation"/> + <cd:constant value="quote"/> + <cd:constant value="blockquote"/> + <cd:constant value="speech"/> + <cd:constant value="aside"/> + </cd:instances> </cd:command> <cd:command name="delimitedtext" file="typo-del.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> + <cd:resolve name="keyword-language-optional"/> <cd:content/> </cd:arguments> </cd:command> @@ -118,6 +137,7 @@ <cd:command name="delimitedtext" type="environment" file="typo-del.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> + <cd:resolve name="keyword-language-optional"/> <cd:keywords list="yes" optional="yes"> <cd:inherit name="startnarrower"/> </cd:keywords> @@ -127,6 +147,7 @@ <cd:command name="delimited" file="typo-del.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> + <cd:resolve name="keyword-language-optional"/> <cd:content/> </cd:arguments> </cd:command> @@ -134,6 +155,7 @@ <cd:command name="delimited" type="environment" file="typo-del.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> + <cd:resolve name="keyword-language-optional"/> <cd:keywords list="yes" optional="yes"> <cd:inherit name="startnarrower"/> </cd:keywords> @@ -142,12 +164,14 @@ <cd:command name="quotation" file="typo-del.mkiv"> <cd:arguments> + <cd:resolve name="keyword-language-optional"/> <cd:content/> </cd:arguments> </cd:command> <cd:command name="quotation" type="environment" file="typo-del.mkiv"> <cd:arguments> + <cd:resolve name="keyword-language-optional"/> <cd:keywords list="yes" optional="yes"> <cd:inherit name="startnarrower"/> </cd:keywords> @@ -156,20 +180,27 @@ <cd:command name="quote" file="typo-del.mkiv"> <cd:arguments> + <cd:resolve name="keyword-language-optional"/> <cd:content/> </cd:arguments> </cd:command> - <cd:command name="quote" type="environment" file="typo-del.mkiv"/> + <cd:command name="quote" type="environment" file="typo-del.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + </cd:arguments> + </cd:command> <cd:command name="blockquote" file="typo-del.mkiv"> <cd:arguments> + <cd:resolve name="keyword-language-optional"/> <cd:content/> </cd:arguments> </cd:command> <cd:command name="blockquote" type="environment" file="typo-del.mkiv"> <cd:arguments> + <cd:resolve name="keyword-language-optional"/> <cd:keywords list="yes" optional="yes"> <cd:inherit name="startnarrower"/> </cd:keywords> @@ -178,6 +209,23 @@ <cd:command name="speech" file="typo-del.mkiv"> <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="aside" type="environment" file="typo-del.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="startnarrower"/> + </cd:keywords> + </cd:arguments> + </cd:command> + + <cd:command name="aside" file="typo-del.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> <cd:content/> </cd:arguments> </cd:command> @@ -214,4 +262,4 @@ <cd:command name="subsentence" type="environment" file="typo-del.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-description.xml b/tex/context/interface/mkiv/i-description.xml index 0204b3466..13b056d71 100644 --- a/tex/context/interface/mkiv/i-description.xml +++ b/tex/context/interface/mkiv/i-description.xml @@ -138,7 +138,7 @@ --> - <cd:command name="description" type="environment" generated="yes" variant="generated:1" file="strc-des.mkvi"> + <cd:command name="description" type="environment" generated="yes" variant="example" file="strc-des.mkvi"> <cd:sequence> <cd:variable value="description"/> </cd:sequence> @@ -147,7 +147,7 @@ </cd:arguments> </cd:command> - <cd:command name="description" type="environment" generated="yes" variant="generated:2" file="strc-des.mkvi"> + <cd:command name="description" type="environment" generated="yes" variant="example:title" file="strc-des.mkvi"> <cd:sequence> <cd:variable value="description"/> </cd:sequence> @@ -157,7 +157,7 @@ </cd:arguments> </cd:command> - <cd:command name="description" generated="yes" variant="generated" file="strc-des.mkvi"> + <cd:command name="description" generated="yes" variant="example" file="strc-des.mkvi"> <cd:sequence> <cd:variable value="description"/> </cd:sequence> @@ -169,4 +169,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-digits.xml b/tex/context/interface/mkiv/i-digits.xml index 325febab3..d9a4b9d2d 100644 --- a/tex/context/interface/mkiv/i-digits.xml +++ b/tex/context/interface/mkiv/i-digits.xml @@ -23,4 +23,4 @@ <cd:command name="dummydigit" file="typo-dig.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-dimension.xml b/tex/context/interface/mkiv/i-dimension.xml index 2962a3aef..7bf59467b 100644 --- a/tex/context/interface/mkiv/i-dimension.xml +++ b/tex/context/interface/mkiv/i-dimension.xml @@ -64,4 +64,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-direction.xml b/tex/context/interface/mkiv/i-direction.xml index 725e215a3..630f07cb7 100644 --- a/tex/context/interface/mkiv/i-direction.xml +++ b/tex/context/interface/mkiv/i-direction.xml @@ -66,4 +66,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-document.xml b/tex/context/interface/mkiv/i-document.xml index a2ed222d0..e2417ec63 100644 --- a/tex/context/interface/mkiv/i-document.xml +++ b/tex/context/interface/mkiv/i-document.xml @@ -10,7 +10,7 @@ <cd:command name="notext" type="environment" file="file-job.mkvi"/> - <cd:command name="environment" type="environment" variant="1" file="file-job.mkvi"> + <cd:command name="environment" type="environment" file="file-job.mkvi"> <cd:arguments> <cd:keywords> <cd:constant type="cd:file"/> @@ -19,7 +19,7 @@ </cd:arguments> </cd:command> - <cd:command name="environment" type="environment" variant="2" file="file-job.mkvi"> + <cd:command name="environment" type="environment" variant="string" file="file-job.mkvi"> <cd:arguments> <cd:keywords delimiters="none"> <cd:constant type="cd:file"/> @@ -28,13 +28,13 @@ </cd:arguments> </cd:command> - <cd:command name="environment" variant="1" file="file-job.mkvi"> + <cd:command name="environment" file="file-job.mkvi"> <cd:arguments> <cd:resolve name="keyword-file"/> </cd:arguments> </cd:command> - <cd:command name="environment" variant="2" file="file-job.mkvi"> + <cd:command name="environment" variant="string" file="file-job.mkvi"> <cd:arguments> <cd:resolve name="string-file"/> </cd:arguments> @@ -48,7 +48,7 @@ <cd:command name="currentenvironment" file="file-job.mkvi"/> - <cd:command name="project" type="environment" variant="1" file="file-job.mkvi"> + <cd:command name="project" type="environment" file="file-job.mkvi"> <cd:arguments> <cd:keywords> <cd:constant type="cd:file"/> @@ -57,7 +57,7 @@ </cd:arguments> </cd:command> - <cd:command name="project" type="environment" variant="2" file="file-job.mkvi"> + <cd:command name="project" type="environment" variant="string" file="file-job.mkvi"> <cd:arguments> <cd:keywords delimiters="none"> <cd:constant type="cd:file"/> @@ -66,13 +66,13 @@ </cd:arguments> </cd:command> - <cd:command name="project" variant="1" file="file-job.mkvi"> + <cd:command name="project" file="file-job.mkvi"> <cd:arguments> <cd:resolve name="keyword-file"/> </cd:arguments> </cd:command> - <cd:command name="project" variant="2" file="file-job.mkvi"> + <cd:command name="project" variant="string" file="file-job.mkvi"> <cd:arguments> <cd:resolve name="string-file"/> </cd:arguments> @@ -86,7 +86,7 @@ <cd:command name="currentproject" file="file-job.mkvi"/> - <cd:command name="product" type="environment" variant="1" file="file-job.mkvi"> + <cd:command name="product" type="environment" file="file-job.mkvi"> <cd:arguments> <cd:keywords> <cd:constant type="cd:file"/> @@ -95,7 +95,7 @@ </cd:arguments> </cd:command> - <cd:command name="product" type="environment" variant="2" file="file-job.mkvi"> + <cd:command name="product" type="environment" variant="string" file="file-job.mkvi"> <cd:arguments> <cd:keywords delimiters="none"> <cd:constant type="cd:file"/> @@ -104,13 +104,13 @@ </cd:arguments> </cd:command> - <cd:command name="product" variant="1" file="file-job.mkvi"> + <cd:command name="product" file="file-job.mkvi"> <cd:arguments> <cd:resolve name="keyword-file"/> </cd:arguments> </cd:command> - <cd:command name="product" variant="2" file="file-job.mkvi"> + <cd:command name="product" variant="string" file="file-job.mkvi"> <cd:arguments> <cd:resolve name="string-file"/> </cd:arguments> @@ -124,7 +124,7 @@ <cd:command name="currentproduct" file="file-job.mkvi"/> - <cd:command name="component" type="environment" variant="1" file="file-job.mkvi"> + <cd:command name="component" type="environment" file="file-job.mkvi"> <cd:arguments> <cd:keywords> <cd:constant type="cd:file"/> @@ -133,7 +133,7 @@ </cd:arguments> </cd:command> - <cd:command name="component" type="environment" variant="2" file="file-job.mkvi"> + <cd:command name="component" type="environment" variant="string" file="file-job.mkvi"> <cd:arguments> <cd:keywords delimiters="none"> <cd:constant type="cd:file"/> @@ -142,13 +142,13 @@ </cd:arguments> </cd:command> - <cd:command name="component" variant="1" file="file-job.mkvi"> + <cd:command name="component" file="file-job.mkvi"> <cd:arguments> <cd:resolve name="keyword-file"/> </cd:arguments> </cd:command> - <cd:command name="component" variant="2" file="file-job.mkvi"> + <cd:command name="component" variant="string" file="file-job.mkvi"> <cd:arguments> <cd:resolve name="string-file"/> </cd:arguments> diff --git a/tex/context/interface/mkiv/i-dummy.xml b/tex/context/interface/mkiv/i-dummy.xml index 452ac311e..6c7d4288f 100644 --- a/tex/context/interface/mkiv/i-dummy.xml +++ b/tex/context/interface/mkiv/i-dummy.xml @@ -55,4 +55,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-effect.xml b/tex/context/interface/mkiv/i-effect.xml index c46c689e2..f6fd3e042 100644 --- a/tex/context/interface/mkiv/i-effect.xml +++ b/tex/context/interface/mkiv/i-effect.xml @@ -46,7 +46,7 @@ </cd:arguments> </cd:command> - <cd:command name="effect" type="environment" generated="yes" variant="generated" file="attr-eff.mkiv"> + <cd:command name="effect" type="environment" generated="yes" variant="example" file="attr-eff.mkiv"> <cd:sequence> <cd:variable value="effect"/> </cd:sequence> diff --git a/tex/context/interface/mkiv/i-enumeration.xml b/tex/context/interface/mkiv/i-enumeration.xml index abd1da232..70823cff3 100644 --- a/tex/context/interface/mkiv/i-enumeration.xml +++ b/tex/context/interface/mkiv/i-enumeration.xml @@ -4,7 +4,7 @@ <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> - <cd:command name="defineenumerations" file="strc-enu.mkvi"> + <cd:command name="defineenumeration" file="strc-enu.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="keyword-name-optional"/> @@ -185,7 +185,7 @@ --> - <cd:command name="enumeration" type="environment" generated="yes" variant="generated:1" file="strc-enu.mkvi"> + <cd:command name="enumeration" type="environment" generated="yes" variant="example" file="strc-enu.mkvi"> <cd:sequence> <cd:variable value="enumeration"/> </cd:sequence> @@ -194,7 +194,7 @@ </cd:arguments> </cd:command> - <cd:command name="enumeration" type="environment" generated="yes" variant="generated:2" file="strc-enu.mkvi"> + <cd:command name="enumeration" type="environment" generated="yes" variant="example:title" file="strc-enu.mkvi"> <cd:sequence> <cd:variable value="enumeration"/> </cd:sequence> @@ -204,7 +204,7 @@ </cd:arguments> </cd:command> - <cd:command name="enumeration" generated="yes" variant="generated" file="strc-enu.mkvi"> + <cd:command name="enumeration" generated="yes" variant="example" file="strc-enu.mkvi"> <cd:sequence> <cd:variable value="enumeration"/> </cd:sequence> @@ -216,4 +216,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-export.xml b/tex/context/interface/mkiv/i-export.xml index 40c73ee51..067649402 100644 --- a/tex/context/interface/mkiv/i-export.xml +++ b/tex/context/interface/mkiv/i-export.xml @@ -74,4 +74,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-field.xml b/tex/context/interface/mkiv/i-field.xml index 67ff40ccf..828ab204f 100644 --- a/tex/context/interface/mkiv/i-field.xml +++ b/tex/context/interface/mkiv/i-field.xml @@ -380,4 +380,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-figure.xml b/tex/context/interface/mkiv/i-figure.xml index a53678e89..4b1439f41 100644 --- a/tex/context/interface/mkiv/i-figure.xml +++ b/tex/context/interface/mkiv/i-figure.xml @@ -47,4 +47,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-file.xml b/tex/context/interface/mkiv/i-file.xml index 4805c0faf..a5ed9daa3 100644 --- a/tex/context/interface/mkiv/i-file.xml +++ b/tex/context/interface/mkiv/i-file.xml @@ -4,13 +4,13 @@ <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> - <cd:command name="input" variant="1" file="file-ini.mkvi"> + <cd:command name="input" file="file-ini.mkvi"> <cd:arguments> <cd:resolve name="argument-file"/> </cd:arguments> </cd:command> - <cd:command name="input" variant="2" file="file-ini.mkvi"> + <cd:command name="input" variant="string" file="file-ini.mkvi"> <cd:arguments> <cd:resolve name="string-file"/> </cd:arguments> @@ -74,7 +74,7 @@ <cd:command name="doifelsepath" file="file-ini.mkvi"> <cd:arguments> - <cd:resolve name="argument-file"/> + <cd:resolve name="argument-path"/> <cd:resolve name="argument-true"/> <cd:resolve name="argument-false"/> </cd:arguments> @@ -82,7 +82,7 @@ <cd:command name="doifpathelse" file="file-ini.mkvi"> <cd:arguments> - <cd:resolve name="argument-file"/> + <cd:resolve name="argument-path"/> <cd:resolve name="argument-true"/> <cd:resolve name="argument-false"/> </cd:arguments> @@ -106,7 +106,7 @@ <cd:command name="doifelsepathexists" file="file-ini.mkvi"> <cd:arguments> - <cd:resolve name="argument-file"/> + <cd:resolve name="argument-path"/> <cd:resolve name="argument-true"/> <cd:resolve name="argument-false"/> </cd:arguments> @@ -114,7 +114,7 @@ <cd:command name="doifpathexistselse" file="file-ini.mkvi"> <cd:arguments> - <cd:resolve name="argument-file"/> + <cd:resolve name="argument-path"/> <cd:resolve name="argument-true"/> <cd:resolve name="argument-false"/> </cd:arguments> @@ -180,19 +180,19 @@ <cd:command name="usepath" file="file-job.mkvi"> <cd:arguments> - <cd:resolve name="keyword-file-list"/> + <cd:resolve name="keyword-path-list"/> </cd:arguments> </cd:command> <cd:command name="usesubpath" file="file-job.mkvi"> <cd:arguments> - <cd:resolve name="keyword-file-list"/> + <cd:resolve name="keyword-path-list"/> </cd:arguments> </cd:command> <cd:command name="path" type="environment" begin="push" end="pop" file="file-job.mkvi"> <cd:arguments> - <cd:resolve name="keyword-file"/> + <cd:resolve name="keyword-path"/> </cd:arguments> </cd:command> @@ -313,7 +313,7 @@ <cd:command name="readfixfile" file="file-res.mkvi"> <cd:arguments> - <cd:resolve name="argument-file"/> + <cd:resolve name="argument-path"/> <cd:resolve name="argument-file"/> <cd:resolve name="argument-true"/> <cd:resolve name="argument-false"/> @@ -322,7 +322,7 @@ <cd:command name="readsetfile" file="file-res.mkvi"> <cd:arguments> - <cd:resolve name="argument-file"/> + <cd:resolve name="argument-path"/> <cd:resolve name="argument-file"/> <cd:resolve name="argument-true"/> <cd:resolve name="argument-false"/> @@ -401,4 +401,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-filler.xml b/tex/context/interface/mkiv/i-filler.xml index 919267b30..894780063 100644 --- a/tex/context/interface/mkiv/i-filler.xml +++ b/tex/context/interface/mkiv/i-filler.xml @@ -113,4 +113,98 @@ </cd:arguments> </cd:command> + <cd:command name="definelinefiller" file="node-rul.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplinefiller"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setuplinefiller" file="node-rul.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="location"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="both" default="yes"/> + </cd:parameter> + <cd:parameter name="scope"> + <cd:constant type="left"/> + <cd:constant type="right"/> + <cd:constant type="local" default="yes"/> + </cd:parameter> + <cd:parameter name="mp"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="depth"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="threshold"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="textstyle"> + <cd:resolve name="value-style"/> + </cd:parameter> + <cd:parameter name="textcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:inherit name="setupalign"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setuplinefillers" file="node-rul.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:assignments list="yes"> + <cd:inherit name="setuplinefiller"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="linefiller" type="environment" file="node-rul.mkiv"> + <cd:arguments> + <cd:keywords> + <cd:constant type="filler"/> + <cd:constant type="cd:name"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplinefiller"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setlinefiller" file="node-rul.mkiv"> + <cd:arguments> + <cd:keywords> + <cd:constant type="filler"/> + <cd:constant type="cd:name"/> + </cd:keywords> + </cd:arguments> + </cd:command> + </cd:interface>
\ No newline at end of file diff --git a/tex/context/interface/mkiv/i-firstline.xml b/tex/context/interface/mkiv/i-firstline.xml index ffa706e3d..59579a18c 100644 --- a/tex/context/interface/mkiv/i-firstline.xml +++ b/tex/context/interface/mkiv/i-firstline.xml @@ -49,4 +49,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-fittingpage.xml b/tex/context/interface/mkiv/i-fittingpage.xml index 3489c55e2..29816601f 100644 --- a/tex/context/interface/mkiv/i-fittingpage.xml +++ b/tex/context/interface/mkiv/i-fittingpage.xml @@ -50,7 +50,7 @@ </cd:arguments> </cd:command> - <cd:command name="fittingpage" type="environment" generated="yes" variant="generated" file="page-app.mkiv"> + <cd:command name="fittingpage" type="environment" generated="yes" variant="example" file="page-app.mkiv"> <cd:sequence> <cd:variable value="fittingpage"/> </cd:sequence> @@ -59,6 +59,10 @@ <cd:inherit name="setupfittingpage"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:constant value="TEXpage"/> + <cd:constant value="MPpage"/> + </cd:instances> </cd:command> <cd:command name="TEXpage" type="environment" file="page-app.mkiv"> diff --git a/tex/context/interface/mkiv/i-floats.xml b/tex/context/interface/mkiv/i-floats.xml index d786769fc..edc7f7f03 100644 --- a/tex/context/interface/mkiv/i-floats.xml +++ b/tex/context/interface/mkiv/i-floats.xml @@ -4,7 +4,7 @@ <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> - <cd:command name="definefloat" variant="1" file="strc-flt.mkvi"> + <cd:command name="definefloat" file="strc-flt.mkvi"> <cd:arguments> <cd:resolve name="keyword-singular"/> <cd:resolve name="keyword-plural-optional"/> @@ -12,14 +12,20 @@ <cd:inherit name="setupfloat"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-float"/> + </cd:instances> </cd:command> - <cd:command name="definefloat" variant="2" file="strc-flt.mkvi"> + <cd:command name="definefloat" variant="name" file="strc-flt.mkvi"> <cd:arguments> <cd:resolve name="keyword-singular"/> <cd:resolve name="keyword-plural-optional"/> <cd:resolve name="keyword-singular-optional"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-float"/> + </cd:instances> </cd:command> <cd:command name="setupfloat" file="strc-flt.mkvi"> @@ -58,6 +64,9 @@ <cd:constant type="grid"/> <cd:constant type="normal" default="yes"/> </cd:parameter> + <cd:parameter name="grid"> + <cd:constant type="cd:string"/> + </cd:parameter> <!-- <cd:parameter name="topoffset"> <cd:constant type="cd:dimension"/> @@ -325,10 +334,13 @@ --> - <cd:command name="placefloat" generated="yes" variant="generated" file="strc-flt.mkvi"> + <cd:command name="placefloat" generated="yes" variant="instance" file="strc-flt.mkvi"> <cd:sequence> <cd:string value="place"/> + <cd:instance value="float"/> +<!-- <cd:variable value="float"/> +--> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-floatlocation-list-optional"/> @@ -336,6 +348,9 @@ <cd:resolve name="argument-text"/> <cd:content/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-float"/> + </cd:instances> </cd:command> <cd:command name="placefloat" file="strc-flt.mkvi"> @@ -348,26 +363,47 @@ </cd:arguments> </cd:command> - <cd:command name="placefloat" type="environment" generated="yes" variant="generated" file="strc-flt.mkvi"> +<!-- + <cd:command name="placefloat" type="environment" file="strc-flt.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-singular"/> + <cd:resolve name="assignment-floatdata-list-optional"/> + <cd:resolve name="assignment-userdata-list-optional"/> + </cd:arguments> + </cd:command> + + <cd:command name="placefloat" generated="yes" variant="instance" file="strc-flt.mkvi"> <cd:sequence> <cd:string value="place"/> - <cd:variable value="float"/> + <cd:instance value="float"/> </cd:sequence> <cd:arguments> <cd:resolve name="assignment-floatdata-list-optional"/> <cd:resolve name="assignment-userdata-list-optional"/> + <cd:resolve name="argument-text"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-float"/> + </cd:instances> </cd:command> - <cd:command name="placefloat" type="environment" file="strc-flt.mkvi"> +--> + + <cd:command name="placefloat" type="environment" generated="yes" variant="instance" file="strc-flt.mkvi"> + <cd:sequence> + <cd:string value="place"/> + <cd:instance value="float"/> + </cd:sequence> <cd:arguments> - <cd:resolve name="keyword-singular"/> <cd:resolve name="assignment-floatdata-list-optional"/> <cd:resolve name="assignment-userdata-list-optional"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-float"/> + </cd:instances> </cd:command> - <cd:command name="floattext" type="environment" generated="yes" variant="generated" file="strc-flt.mkvi"> + <cd:command name="floattext" type="environment" generated="yes" variant="example" file="strc-flt.mkvi"> <cd:sequence> <cd:variable value="float"/> <cd:string value="text"/> @@ -379,7 +415,7 @@ </cd:arguments> </cd:command> - <cd:command name="placelistoffloats" generated="yes" variant="generated" file="strc-flt.mkvi"> + <cd:command name="placelistoffloats" generated="yes" variant="example" file="strc-flt.mkvi"> <cd:sequence> <cd:string value="placelistof"/> <cd:variable value="floats"/> @@ -391,7 +427,7 @@ </cd:arguments> </cd:command> - <cd:command name="completelistoffloats" generated="yes" variant="generated" file="strc-flt.mkvi"> + <cd:command name="completelistoffloats" generated="yes" variant="example" file="strc-flt.mkvi"> <cd:sequence> <cd:string value="completelistof"/> <cd:variable value="floats"/> @@ -451,7 +487,9 @@ </cd:arguments> </cd:command> - <cd:command name="placefigure" file="strc-flt.mkvi"> +<!-- + + <cd:command file="strc-flt.mkvi" name="placefigure"> <cd:arguments> <cd:resolve name="keyword-floatlocation-list-optional"/> <cd:resolve name="keyword-reference-list-optional"/> @@ -642,6 +680,7 @@ </cd:assignments> </cd:arguments> </cd:command> +--> <cd:command name="setuplocalfloats" file="strc-flt.mkvi"> <cd:arguments> @@ -733,4 +772,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-fontfamily.xml b/tex/context/interface/mkiv/i-fontfamily.xml index c069a4c17..2cf2fb403 100644 --- a/tex/context/interface/mkiv/i-fontfamily.xml +++ b/tex/context/interface/mkiv/i-fontfamily.xml @@ -4,7 +4,7 @@ <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> - <cd:command name="definefontfamily" variant="1" file="font-sel.mkvi"> + <cd:command name="definefontfamily" file="font-sel.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:keywords> @@ -68,7 +68,7 @@ </cd:arguments> </cd:command> - <cd:command name="definefontfamily" variant="2" file="font-sel.mkvi"> + <cd:command name="definefontfamily" variant="preset" file="font-sel.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:keywords> @@ -97,7 +97,7 @@ </cd:arguments> </cd:command> - <cd:command name="definefallbackfamily" variant="1" file="font-sel.mkvi"> + <cd:command name="definefallbackfamily" file="font-sel.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:keywords> @@ -146,8 +146,8 @@ <cd:constant type="no" default="yes"/> </cd:parameter> <cd:parameter name="force"> - <cd:constant type="yes" default="yes"/> - <cd:constant type="no"/> + <cd:constant type="yes"/> + <cd:constant type="no" default="yes"/> </cd:parameter> <cd:parameter name="features"> <cd:constant type="cd:name"/> @@ -177,7 +177,7 @@ </cd:arguments> </cd:command> - <cd:command name="definefallbackfamily" variant="2" file="font-sel.mkvi"> + <cd:command name="definefallbackfamily" variant="preset" file="font-sel.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:keywords> @@ -206,20 +206,20 @@ </cd:arguments> </cd:command> - <cd:command name="definefontfamilypreset" variant="1" file="font-sel.mkvi"> + <cd:command name="definefontfamilypreset" file="font-sel.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> - <cd:assignment list="yes"> + <cd:assignments list="yes"> <cd:inherit name="definefontfamily"/> - </cd:assignment> + </cd:assignments> </cd:arguments> </cd:command> - <cd:command name="definefontfamilypreset" variant="2" file="font-sel.mkvi"> + <cd:command name="definefontfamilypreset" variant="name" file="font-sel.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="keyword-name"/> </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-fonts.xml b/tex/context/interface/mkiv/i-fonts.xml index 112b93c6e..c246905f0 100644 --- a/tex/context/interface/mkiv/i-fonts.xml +++ b/tex/context/interface/mkiv/i-fonts.xml @@ -65,31 +65,31 @@ <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> - + <cd:command name="emphit" file="font-emp.mkvi"> <cd:arguments> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> - + <cd:command name="emphsl" file="font-emp.mkvi"> <cd:arguments> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> - + <cd:command name="emphtf" file="font-emp.mkvi"> <cd:arguments> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> - + <cd:command name="emph" file="font-emp.mkvi"> <cd:arguments> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> - + <cd:command name="emphasized" file="font-emp.mkvi"> <cd:arguments> <cd:resolve name="argument-text"/> @@ -259,10 +259,26 @@ <cd:constant type="yes"/> <cd:constant type="no"/> </cd:parameter> + <cd:parameter name="checkmarks"> + <cd:constant type="yes" default="yes"/> + <cd:constant type="no"/> + </cd:parameter> <cd:parameter name="cd:name"> <cd:constant type="yes"/> <cd:constant type="no" default="yes"/> </cd:parameter> + <cd:parameter name="mathnolimitsmode"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="adaptfontfeature" file="font-fea.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name"/> <!-- pattern --> + <cd:assignments list="yes"> + <cd:inherit name="definefontfeature"/> </cd:assignments> </cd:arguments> </cd:command> @@ -274,49 +290,49 @@ </cd:arguments> </cd:command> - <cd:command name="addfeature" variant="1" file="font-fea.mkvi"> + <cd:command name="addfeature" file="font-fea.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> </cd:arguments> </cd:command> - <cd:command name="addfeature" variant="2" file="font-fea.mkvi"> + <cd:command name="addfeature" variant="direct" file="font-fea.mkvi"> <cd:arguments> <cd:resolve name="argument-name"/> </cd:arguments> </cd:command> - <cd:command name="subtractfeature" variant="1" file="font-fea.mkvi"> + <cd:command name="subtractfeature" file="font-fea.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> </cd:arguments> </cd:command> - <cd:command name="subtractfeature" variant="2" file="font-fea.mkvi"> + <cd:command name="subtractfeature" variant="direct" file="font-fea.mkvi"> <cd:arguments> <cd:resolve name="argument-name"/> </cd:arguments> </cd:command> - <cd:command name="replacefeature" variant="1" file="font-fea.mkvi"> + <cd:command name="replacefeature" file="font-fea.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> </cd:arguments> </cd:command> - <cd:command name="replacefeature" variant="2" file="font-fea.mkvi"> + <cd:command name="replacefeature" variant="direct" file="font-fea.mkvi"> <cd:arguments> <cd:resolve name="argument-name"/> </cd:arguments> </cd:command> - <cd:command name="resetandaddfeature" variant="1" file="font-fea.mkvi"> + <cd:command name="resetandaddfeature" file="font-fea.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> </cd:arguments> </cd:command> - <cd:command name="resetandaddfeature" variant="2" file="font-fea.mkvi"> + <cd:command name="resetandaddfeature" variant="direct" file="font-fea.mkvi"> <cd:arguments> <cd:resolve name="argument-name"/> </cd:arguments> @@ -332,7 +348,7 @@ </cd:arguments> </cd:command> - <cd:command name="feature" variant="1" file="font-fea.mkvi"> + <cd:command name="feature" file="font-fea.mkvi"> <cd:arguments> <cd:keywords> <cd:constant type="+"/> @@ -353,7 +369,7 @@ </cd:arguments> </cd:command> - <cd:command name="feature" variant="2" file="font-fea.mkvi"> + <cd:command name="feature" variant="direct" file="font-fea.mkvi"> <cd:arguments> <cd:keywords delimiters="braces"> <cd:constant type="+"/> @@ -583,7 +599,7 @@ </cd:arguments> </cd:command> - <cd:command name="definefont" variant="1" file="font-ini.mkvi"> + <cd:command name="definefont" file="font-ini.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="keyword-font"/> @@ -593,7 +609,7 @@ </cd:arguments> </cd:command> - <cd:command name="definefont" variant="2" file="font-ini.mkvi"> + <cd:command name="definefont" variant="argument" file="font-ini.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="keyword-font"/> @@ -716,7 +732,7 @@ <cd:command name="txx" file="font-ini.mkvi"/> - <cd:command name="definebodyfont" variant="1" file="font-fil.mkvi"> + <cd:command name="definebodyfont" file="font-fil.mkvi"> <cd:arguments> <cd:keywords list="yes" optional="yes"> <cd:constant type="cd:name"/> @@ -777,7 +793,7 @@ </cd:arguments> </cd:command> - <cd:command name="definebodyfont" variant="2" file="font-fil.mkvi"> + <cd:command name="definebodyfont" variant="argument" file="font-fil.mkvi"> <cd:arguments> <cd:keywords list="yes" optional="yes"> <cd:constant type="cd:name"/> @@ -798,6 +814,17 @@ </cd:arguments> </cd:command> + <cd:command name="setupfonts" file="font-ini.mkiv"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="language"> + <cd:constant type="no" default="yes"/> + <cd:constant type="auto"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command name="setupbodyfont" file="font-ini.mkiv"> <cd:arguments> <cd:keywords list="yes" optional="yes"> @@ -884,7 +911,7 @@ </cd:arguments> </cd:command> - <cd:command name="switchstyleonly" variant="1" file="font-ini.mkiv"> + <cd:command name="switchstyleonly" file="font-ini.mkiv"> <cd:arguments> <cd:keywords> <cd:constant type="rm"/> @@ -907,7 +934,7 @@ </cd:arguments> </cd:command> - <cd:command name="switchstyleonly" variant="2" file="font-ini.mkiv"> + <cd:command name="switchstyleonly" variant="command" file="font-ini.mkiv"> <cd:arguments> <cd:csname/> </cd:arguments> @@ -1036,6 +1063,8 @@ <cd:command name="settabular" file="font-pre.mkiv"/> + <cd:command name="setfractions" file="font-pre.mkiv"/> + <cd:command name="setsuperiors" file="font-pre.mkiv"/> <cd:command name="tinyfont" file="font-pre.mkiv"/> @@ -1228,13 +1257,13 @@ </cd:arguments> </cd:command> - <cd:command name="style" type="environment" generated="yes" variant="generated" file="font-sty.mkvi"> + <cd:command name="style" type="environment" generated="yes" variant="example" file="font-sty.mkvi"> <cd:sequence> <cd:variable value="style"/> </cd:sequence> </cd:command> - <cd:command name="style" generated="yes" variant="generated" file="font-sty.mkvi"> + <cd:command name="style" generated="yes" variant="example" file="font-sty.mkvi"> <cd:sequence> <cd:variable value="style"/> </cd:sequence> @@ -1243,7 +1272,7 @@ </cd:arguments> </cd:command> - <cd:command name="style" type="environment" variant="1" file="font-sty.mkvi"> + <cd:command name="style" type="environment" variant="argument" file="font-sty.mkvi"> <cd:arguments> <cd:keywords> <cd:constant type="cd:name"/> @@ -1252,7 +1281,7 @@ </cd:arguments> </cd:command> - <cd:command name="style" type="environment" variant="2" file="font-sty.mkvi"> + <cd:command name="style" type="environment" file="font-sty.mkvi"> <cd:arguments> <cd:assignments list="yes"> <cd:inherit name="setupstyle"/> @@ -1260,7 +1289,7 @@ </cd:arguments> </cd:command> - <cd:command name="style" variant="1" file="font-sty.mkvi"> + <cd:command name="style" variant="argument" file="font-sty.mkvi"> <cd:arguments> <cd:keywords> <cd:constant type="cd:name"/> @@ -1270,7 +1299,7 @@ </cd:arguments> </cd:command> - <cd:command name="style" variant="2" file="font-sty.mkvi"> + <cd:command name="style" file="font-sty.mkvi"> <cd:arguments> <cd:assignments list="yes"> <cd:inherit name="setupstyle"/> @@ -1325,6 +1354,18 @@ </cd:arguments> </cd:command> + <cd:command name="getprivateslot" file="font-ini.mkvi"> + <cd:arguments> + <cd:resolve name="argument-name"/> + </cd:arguments> + </cd:command> + + <cd:command name="getprivatechar" file="font-ini.mkvi"> + <cd:arguments> + <cd:resolve name="argument-name"/> + </cd:arguments> + </cd:command> + <cd:command name="glyphfontfile" file="font-sym.mkvi"> <cd:arguments> <cd:resolve name="argument-font"/> @@ -1365,6 +1406,24 @@ </cd:arguments> </cd:command> + <cd:command name="resolvedglyphstyled" file="font-sym.mkvi"> + <cd:arguments> + <cd:resolve name="argument-font"/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + + <cd:command name="resolvedglyphdirect" file="font-sym.mkvi"> + <cd:arguments> + <cd:resolve name="argument-font"/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + </cd:keywords> + </cd:arguments> + </cd:command> + <cd:command name="setfont" file="font-sym.mkvi"> <cd:arguments> <cd:resolve name="string-font"/> @@ -1624,4 +1683,10 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file + <cd:command name="blockligatures" file="font-fea.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-list"/> + </cd:arguments> + </cd:command> + +</cd:interface> diff --git a/tex/context/interface/mkiv/i-form.xml b/tex/context/interface/mkiv/i-form.xml index 0f02d0670..13e669427 100644 --- a/tex/context/interface/mkiv/i-form.xml +++ b/tex/context/interface/mkiv/i-form.xml @@ -20,4 +20,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-formula.xml b/tex/context/interface/mkiv/i-formula.xml index da1d1c0cf..f6522fca4 100644 --- a/tex/context/interface/mkiv/i-formula.xml +++ b/tex/context/interface/mkiv/i-formula.xml @@ -53,8 +53,17 @@ <cd:parameter name="numbercommand"> <cd:constant type="cd:oneargument"/> </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="numberstyle"> + <cd:resolve name="value-style"/> + </cd:parameter> + <cd:parameter name="numbercolor"> + <cd:constant type="cd:color"/> + </cd:parameter> <cd:parameter name="option"> - <cd:constant type="middle"/> + <cd:resolve name="value-formula"/> </cd:parameter> <cd:parameter name="margin"> <cd:resolve name="value-leftskip"/> @@ -74,6 +83,9 @@ <cd:parameter name="grid"> <cd:inherit name="snaptogrid"/> </cd:parameter> + <cd:parameter name="frame"> + <cd:constant type="number"/> + </cd:parameter> <cd:inherit name="setupcounter"/> </cd:assignments> </cd:arguments> @@ -126,55 +138,49 @@ --> - <cd:command name="formula" type="environment" generated="yes" variant="generated" file="strc-mat.mkiv"> + <cd:command name="formula" type="environment" generated="yes" variant="example" file="strc-mat.mkiv"> <cd:sequence> <cd:variable value="formula"/> <cd:string value="formula"/> </cd:sequence> <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:inherit name="setupbodyfont"/> - </cd:keywords> + <cd:resolve name="keyword-formula-list-optional"/> </cd:arguments> + <cd:instances> + <cd:constant value="sp"/> + <cd:constant value="sd"/> + <cd:constant value="mp"/> + <cd:constant value="md"/> + </cd:instances> </cd:command> <cd:command name="formula" type="environment" file="strc-mat.mkiv"> <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:inherit name="setupbodyfont"/> - </cd:keywords> + <cd:resolve name="keyword-formula-list-optional"/> </cd:arguments> </cd:command> <cd:command name="spformula" type="environment" file="strc-mat.mkiv"> <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:inherit name="setupbodyfont"/> - </cd:keywords> + <cd:resolve name="keyword-formula-list-optional"/> </cd:arguments> </cd:command> <cd:command name="sdformula" type="environment" file="strc-mat.mkiv"> <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:inherit name="setupbodyfont"/> - </cd:keywords> + <cd:resolve name="keyword-formula-list-optional"/> </cd:arguments> </cd:command> <cd:command name="mpformula" type="environment" file="strc-mat.mkiv"> <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:inherit name="setupbodyfont"/> - </cd:keywords> + <cd:resolve name="keyword-formula-list-optional"/> </cd:arguments> </cd:command> <cd:command name="mdformula" type="environment" file="strc-mat.mkiv"> <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:inherit name="setupbodyfont"/> - </cd:keywords> + <cd:resolve name="keyword-formula-list-optional"/> </cd:arguments> </cd:command> @@ -188,9 +194,7 @@ <cd:command name="formula" file="strc-mat.mkiv"> <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:inherit name="setupbodyfont"/> - </cd:keywords> + <cd:resolve name="keyword-formula-list-optional"/> <cd:content/> </cd:arguments> </cd:command> @@ -199,46 +203,30 @@ <cd:command name="formulas" type="environment" file="strc-mat.mkiv"> <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:constant type="+"/> - <cd:constant type="-"/> - <cd:constant type="cd:reference"/> - </cd:keywords> + <cd:resolve name="keyword-formulareference-list-optional"/> </cd:arguments> </cd:command> <cd:command name="subformulas" type="environment" file="strc-mat.mkiv"> <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:constant type="+"/> - <cd:constant type="-"/> - <cd:constant type="cd:reference"/> - </cd:keywords> + <cd:resolve name="keyword-formulareference-list-optional"/> </cd:arguments> </cd:command> <cd:command name="namedsubformulas" type="environment" file="strc-mat.mkiv"> <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:constant type="+"/> - <cd:constant type="-"/> - <cd:constant type="cd:reference"/> - </cd:keywords> + <cd:resolve name="keyword-formulareference-list-optional"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> <cd:command name="placeformula" file="strc-mat.mkiv"> <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:constant type="+"/> - <cd:constant type="-"/> - <cd:constant type="cd:reference"/> - </cd:keywords> + <cd:resolve name="keyword-formulareference-list-optional"/> </cd:arguments> </cd:command> - <cd:command name="placeformula" type="environment" variant="1" file="strc-mat.mkiv"> + <cd:command name="placeformula" type="environment" file="strc-mat.mkiv"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:parameter name="title"> @@ -248,42 +236,28 @@ <cd:constant type="cd:text"/> </cd:parameter> <cd:parameter name="reference"> - <cd:constant type="+"/> - <cd:constant type="-"/> - <cd:constant type="cd:text"/> + <cd:resolve name="value-formulareference"/> </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> - <cd:command name="placeformula" type="environment" variant="2" file="strc-mat.mkiv"> + <cd:command name="placeformula" type="environment" variant="argument" file="strc-mat.mkiv"> <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:constant type="+"/> - <cd:constant type="-"/> - <cd:constant type="cd:reference"/> - </cd:keywords> + <cd:resolve name="keyword-formulareference-list-optional"/> </cd:arguments> </cd:command> <cd:command name="placenamedformula" file="strc-mat.mkiv"> <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:constant type="+"/> - <cd:constant type="-"/> - <cd:constant type="cd:reference"/> - </cd:keywords> + <cd:resolve name="keyword-formulareference-list-optional"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> <cd:command name="placesubformula" file="strc-mat.mkiv"> <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:constant type="+"/> - <cd:constant type="-"/> - <cd:constant type="cd:reference"/> - </cd:keywords> + <cd:resolve name="keyword-formulareference-list-optional"/> </cd:arguments> </cd:command> @@ -295,4 +269,4 @@ <cd:command name="placecurrentformulanumber" file="strc-mat"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-fraction.xml b/tex/context/interface/mkiv/i-fraction.xml index 444784dfa..2624b8a5c 100644 --- a/tex/context/interface/mkiv/i-fraction.xml +++ b/tex/context/interface/mkiv/i-fraction.xml @@ -80,7 +80,7 @@ --> - <cd:command name="fraction" generated="yes" variant="generated" file="math-frc.mkiv"> + <cd:command name="fraction" generated="yes" variant="example" file="math-frc.mkiv"> <cd:sequence> <cd:variable value="fraction"/> </cd:sequence> @@ -88,6 +88,16 @@ <cd:content/> <cd:content/> </cd:arguments> + <cd:instances> + <cd:constant value="xfrac"/> + <cd:constant value="xxfrac"/> + <cd:constant value="frac"/> + <cd:constant value="sfrac"/> + <cd:constant value="dfrac"/> + <cd:constant value="binom"/> + <cd:constant value="dbinom"/> + <cd:constant value="tbinom"/> + </cd:instances> </cd:command> <cd:command name="frac" file="math-frc.mkiv"> diff --git a/tex/context/interface/mkiv/i-framed.xml b/tex/context/interface/mkiv/i-framed.xml index 1c214322a..c7633aa91 100644 --- a/tex/context/interface/mkiv/i-framed.xml +++ b/tex/context/interface/mkiv/i-framed.xml @@ -4,8 +4,6 @@ <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> - <?context-directive job ctxfile x-setups.ctx ?> - <cd:command name="defineframed" file="pack-rul.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> @@ -93,9 +91,7 @@ <cd:constant type="none"/> </cd:parameter> <cd:parameter name="background"> - <cd:constant type="foreground"/> - <cd:constant type="color"/> - <cd:constant type="cd:name"/> + <cd:resolve name="value-background"/> </cd:parameter> <cd:parameter name="backgroundoffset"> <cd:constant type="frame"/> @@ -142,6 +138,7 @@ <cd:parameter name="strut"> <cd:constant type="yes" default="yes"/> <cd:constant type="no"/> + <cd:constant type="none"/> <cd:constant type="local"/> <cd:constant type="global"/> </cd:parameter> @@ -161,6 +158,7 @@ <cd:constant type="lohi"/> <cd:constant type="hanging"/> <cd:constant type="keep"/> + <cd:constant type="formula"/> <cd:constant type="mathematics"/> <cd:constant type="normal" default="yes"/> </cd:parameter> @@ -243,7 +241,7 @@ </cd:arguments> </cd:command> - <cd:command name="framed" generated="yes" variant="generated" file="pack-rul.mkiv"> + <cd:command name="framed" generated="yes" variant="example" file="pack-rul.mkiv"> <cd:sequence> <cd:variable value="framed"/> </cd:sequence> @@ -253,6 +251,10 @@ </cd:assignments> <cd:content/> </cd:arguments> + <cd:instances> + <cd:constant value="unframed"/> + <cd:constant value="fitfieldframed"/> + </cd:instances> </cd:command> <cd:command name="normalframedwithsettings" file="pack-rul.mkiv"> @@ -357,7 +359,7 @@ </cd:arguments> </cd:command> - <cd:command name="mathframed" generated="yes" variant="generated" file="pack-rul.mkiv"> + <cd:command name="mathframed" generated="yes" variant="example" file="pack-rul.mkiv"> <cd:sequence> <cd:variable value="mathframed"/> </cd:sequence> @@ -367,6 +369,11 @@ </cd:assignments> <cd:content/> </cd:arguments> + <cd:instances> + <cd:constant value="mframed"/> + <cd:constant value="inmframed"/> + <cd:constant value="mcframed"/> + </cd:instances> </cd:command> <cd:command name="mframed" file="pack-rul.mkiv"> @@ -396,6 +403,25 @@ </cd:arguments> </cd:command> + <cd:command name="defineformulaframed" file="math-for.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupformulaframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setupformulaframed" file="math-for.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:assignments list="yes"> + <cd:inherit name="setupframed"/> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command name="defineframedtext" file="pack-rul.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> @@ -460,7 +486,7 @@ --> - <cd:command name="framedtext" generated="yes" variant="generated" file="pack-rul.mkiv"> + <cd:command name="framedtext" generated="yes" variant="example" file="pack-rul.mkiv"> <cd:sequence> <cd:variable value="framedtext"/> </cd:sequence> @@ -470,9 +496,12 @@ </cd:assignments> <cd:content/> </cd:arguments> + <cd:instances> + <cd:constant value="framedtext"/> + </cd:instances> </cd:command> - <cd:command name="framedtext" type="environment" generated="yes" variant="generated" file="pack-rul.mkiv"> + <cd:command name="framedtext" type="environment" generated="yes" variant="example" file="pack-rul.mkiv"> <cd:sequence> <cd:variable value="framedtext"/> </cd:sequence> @@ -487,6 +516,9 @@ <cd:inherit name="setupframedtext"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:constant value="framedtext"/> + </cd:instances> </cd:command> <cd:command name="framedtext" file="pack-rul.mkiv"> diff --git a/tex/context/interface/mkiv/i-graphics.xml b/tex/context/interface/mkiv/i-graphics.xml index 4e90a0c81..e66a039dc 100644 --- a/tex/context/interface/mkiv/i-graphics.xml +++ b/tex/context/interface/mkiv/i-graphics.xml @@ -85,6 +85,9 @@ <cd:parameter name="color"> <cd:constant type="cd:color"/> </cd:parameter> + <cd:parameter name="arguments"> + <cd:constant type="cd:text"/> + </cd:parameter> <cd:parameter name="repeat"> <cd:constant type="yes"/> <cd:constant type="no" default="yes"/> diff --git a/tex/context/interface/mkiv/i-grid.xml b/tex/context/interface/mkiv/i-grid.xml index d98a1a544..ac678e544 100644 --- a/tex/context/interface/mkiv/i-grid.xml +++ b/tex/context/interface/mkiv/i-grid.xml @@ -59,7 +59,7 @@ </cd:arguments> </cd:command> - <cd:command name="snaptogrid" variant="1" file="spac-ver.mkiv"> + <cd:command name="snaptogrid" file="spac-ver.mkiv"> <cd:arguments> <cd:keywords optional="yes"> <cd:resolve name="value-grid"/> @@ -69,7 +69,7 @@ </cd:arguments> </cd:command> - <cd:command name="snaptogrid" variant="2" file="spac-ver.mkiv"> + <cd:command name="snaptogrid" variant="list" file="spac-ver.mkiv"> <cd:arguments> <cd:keywords list="yes" optional="yes"> <cd:inherit name="definegridsnapping"/> @@ -79,7 +79,7 @@ </cd:arguments> </cd:command> - <cd:command name="placeongrid" variant="1" file="spac-ver.mkiv"> + <cd:command name="placeongrid" file="spac-ver.mkiv"> <cd:arguments> <cd:keywords optional="yes"> <cd:resolve name="value-grid"/> @@ -88,7 +88,7 @@ </cd:arguments> </cd:command> - <cd:command name="placeongrid" variant="2" file="spac-ver.mkiv"> + <cd:command name="placeongrid" variant="list" file="spac-ver.mkiv"> <cd:arguments> <cd:keywords list="yes" optional="yes"> <cd:inherit name="definegridsnapping"/> @@ -97,7 +97,7 @@ </cd:arguments> </cd:command> - <cd:command name="gridsnapping" type="environment" variant="1" file="spac-ver.mkiv"> + <cd:command name="gridsnapping" type="environment" file="spac-ver.mkiv"> <cd:arguments> <cd:keywords optional="yes"> <cd:resolve name="value-grid"/> @@ -105,7 +105,7 @@ </cd:arguments> </cd:command> - <cd:command name="gridsnapping" type="environment" variant="2" file="spac-ver.mkiv"> + <cd:command name="gridsnapping" type="environment" variant="list" file="spac-ver.mkiv"> <cd:arguments> <cd:keywords list="yes" optional="yes"> <cd:inherit name="definegridsnapping"/> diff --git a/tex/context/interface/mkiv/i-help.xml b/tex/context/interface/mkiv/i-help.xml index db2128d53..d0c0aa103 100644 --- a/tex/context/interface/mkiv/i-help.xml +++ b/tex/context/interface/mkiv/i-help.xml @@ -23,7 +23,7 @@ </cd:arguments> </cd:command> - <cd:command name="help" generated="yes" variant="generated" file="scrn-hlp.mkvi"> + <cd:command name="help" generated="yes" variant="example" file="scrn-hlp.mkvi"> <cd:sequence> <cd:variable value="help"/> </cd:sequence> @@ -32,15 +32,21 @@ <cd:resolve name="argument-text"/> <cd:resolve name="argument-text"/> </cd:arguments> + <cd:instances> + <cd:constant value="helptext"/> + </cd:instances> </cd:command> - <cd:command name="help" type="environment" generated="yes" variant="generated" file="scrn-hlp.mkvi"> + <cd:command name="help" type="environment" generated="yes" variant="example" file="scrn-hlp.mkvi"> <cd:sequence> <cd:variable value="help"/> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-reference-optional"/> </cd:arguments> + <cd:instances> + <cd:constant value="helptext"/> + </cd:instances> </cd:command> <cd:command name="doifelsehelp" file="scrn-hlp.mkvi"> diff --git a/tex/context/interface/mkiv/i-highlight.xml b/tex/context/interface/mkiv/i-highlight.xml index 1cc4ed4ca..7a990b13b 100644 --- a/tex/context/interface/mkiv/i-highlight.xml +++ b/tex/context/interface/mkiv/i-highlight.xml @@ -32,7 +32,7 @@ </cd:arguments> </cd:command> - <cd:command name="highlight" generated="yes" variant="generated" file="core-sys.mkiv"> + <cd:command name="highlight" generated="yes" variant="example" file="core-sys.mkiv"> <cd:sequence> <cd:variable value="highlight"/> </cd:sequence> @@ -61,4 +61,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-hspace.xml b/tex/context/interface/mkiv/i-hspace.xml index 3c96fc247..9b9c777a5 100644 --- a/tex/context/interface/mkiv/i-hspace.xml +++ b/tex/context/interface/mkiv/i-hspace.xml @@ -156,4 +156,10 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file + <cd:command name="quads" file="spac-hor.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-number-optional"/> + </cd:arguments> + </cd:command> + +</cd:interface> diff --git a/tex/context/interface/mkiv/i-hyphenation.xml b/tex/context/interface/mkiv/i-hyphenation.xml index 934751712..36cbc67e4 100644 --- a/tex/context/interface/mkiv/i-hyphenation.xml +++ b/tex/context/interface/mkiv/i-hyphenation.xml @@ -173,6 +173,10 @@ <cd:parameter name="right"> <cd:constant type="cd:command"/> </cd:parameter> + <cd:parameter name="range"> + <cd:constant type="yes"/> + <cd:constant type="no" default="yes"/> + </cd:parameter> <cd:parameter name="language"> <cd:constant type="cd:language"/> </cd:parameter> @@ -257,4 +261,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-indent.xml b/tex/context/interface/mkiv/i-indent.xml index 666388b6a..7e2fb5ca3 100644 --- a/tex/context/interface/mkiv/i-indent.xml +++ b/tex/context/interface/mkiv/i-indent.xml @@ -62,11 +62,11 @@ </cd:arguments> </cd:command> - <cd:command name="indentation" file="spac-hor.mkiv"/> + <cd:command name="indentation" file="spac-hor.mkiv" coreprimitive="yes"/> - <cd:command name="noindentation" file="spac-hor.mkiv"/> + <cd:command name="noindentation" file="spac-hor.mkiv" coreprimitive="yes"/> - <cd:command name="doindentation" file="spac-hor.mkiv"/> + <cd:command name="doindentation" file="spac-hor.mkiv" coreprimitive="yes"/> <cd:command name="checknextindentation" file="spac-hor.mkiv"> <cd:arguments> @@ -88,4 +88,4 @@ <cd:command name="indentation" type="environment" begin="push" end="pop" file="spac-hor.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-indentedtext.xml b/tex/context/interface/mkiv/i-indentedtext.xml index c70fb5ba0..98812d5e0 100644 --- a/tex/context/interface/mkiv/i-indentedtext.xml +++ b/tex/context/interface/mkiv/i-indentedtext.xml @@ -57,7 +57,7 @@ </cd:arguments> </cd:command> - <cd:command name="indentedtext" type="environment" generated="yes" variant="generated" file="strc-ind.mkiv"> + <cd:command name="indentedtext" type="environment" generated="yes" variant="example" file="strc-ind.mkiv"> <cd:sequence> <cd:variable value="indentedtext"/> </cd:sequence> @@ -69,4 +69,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-initial.xml b/tex/context/interface/mkiv/i-initial.xml index 170a5e1ba..d50a7bc61 100644 --- a/tex/context/interface/mkiv/i-initial.xml +++ b/tex/context/interface/mkiv/i-initial.xml @@ -78,4 +78,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-injector.xml b/tex/context/interface/mkiv/i-injector.xml index c13e544db..321aa75c8 100644 --- a/tex/context/interface/mkiv/i-injector.xml +++ b/tex/context/interface/mkiv/i-injector.xml @@ -70,4 +70,4 @@ --> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-interaction.xml b/tex/context/interface/mkiv/i-interaction.xml index 06b104f4c..1c3285b84 100644 --- a/tex/context/interface/mkiv/i-interaction.xml +++ b/tex/context/interface/mkiv/i-interaction.xml @@ -14,7 +14,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupinteraction" variant="1" file="scrn-ini.mkvi"> + <cd:command name="setupinteraction" file="scrn-ini.mkvi"> <cd:arguments> <cd:resolve name="keyword-name-list-optional"/> <cd:assignments list="yes"> @@ -119,7 +119,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupinteraction" variant="2" file="scrn-ini.mkvi"> + <cd:command name="setupinteraction" variant="name" file="scrn-ini.mkvi"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> </cd:arguments> @@ -157,4 +157,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-interactionmenu.xml b/tex/context/interface/mkiv/i-interactionmenu.xml index 6bf2f9674..22b928a5a 100644 --- a/tex/context/interface/mkiv/i-interactionmenu.xml +++ b/tex/context/interface/mkiv/i-interactionmenu.xml @@ -148,83 +148,87 @@ </cd:arguments> </cd:command> - <cd:command name="raw" variant="interactionmenu" file="scrn-but.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference"/> - <cd:resolve name="string-text"/> - <cd:delimiter name="\"/> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="raw" type="environment" variant="interactionmenu" file="scrn-but.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference"/> - </cd:arguments> - </cd:command> + <cd:command name="raw" scope="interactionmenu" file="scrn-but.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference"/> + <cd:resolve name="string-text"/> + <cd:delimiter name="\"/> + </cd:arguments> + </cd:command> - <cd:command name="but" variant="interactionmenu" file="scrn-but.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference"/> - <cd:resolve name="string-text"/> - <cd:delimiter name="\"/> - </cd:arguments> - </cd:command> + <cd:command name="raw" type="environment" scope="interactionmenu" file="scrn-but.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference"/> + </cd:arguments> + </cd:command> - <cd:command name="but" type="environment" variant="interactionmenu" file="scrn-but.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference"/> - </cd:arguments> - </cd:command> + <cd:command name="but" scope="interactionmenu" file="scrn-but.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference"/> + <cd:resolve name="string-text"/> + <cd:delimiter name="\"/> + </cd:arguments> + </cd:command> - <cd:command name="got" variant="interactionmenu" file="scrn-but.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference"/> - <cd:resolve name="string-text"/> - <cd:delimiter name="\"/> - </cd:arguments> - </cd:command> + <cd:command name="but" type="environment" scope="interactionmenu" file="scrn-but.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference"/> + </cd:arguments> + </cd:command> - <cd:command name="got" type="environment" variant="interactionmenu" file="scrn-but.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference"/> - </cd:arguments> - </cd:command> + <cd:command name="got" scope="interactionmenu" file="scrn-but.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference"/> + <cd:resolve name="string-text"/> + <cd:delimiter name="\"/> + </cd:arguments> + </cd:command> - <cd:command name="nop" variant="interactionmenu" file="scrn-but.mkvi"> - <cd:arguments> - <cd:resolve name="string-text"/> - <cd:delimiter name="\"/> - </cd:arguments> - </cd:command> + <cd:command name="got" type="environment" scope="interactionmenu" file="scrn-but.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference"/> + </cd:arguments> + </cd:command> - <cd:command name="nop" type="environment" variant="interactionmenu" file="scrn-but.mkvi"/> + <cd:command name="nop" scope="interactionmenu" file="scrn-but.mkvi"> + <cd:arguments> + <cd:resolve name="string-text"/> + <cd:delimiter name="\"/> + </cd:arguments> + </cd:command> - <cd:command name="txt" variant="interactionmenu" file="scrn-but.mkvi"> - <cd:arguments> - <cd:resolve name="string-text"/> - <cd:delimiter name="\"/> - </cd:arguments> - </cd:command> + <cd:command name="nop" type="environment" scope="interactionmenu" file="scrn-but.mkvi"/> + + <cd:command name="txt" scope="interactionmenu" file="scrn-but.mkvi"> + <cd:arguments> + <cd:resolve name="string-text"/> + <cd:delimiter name="\"/> + </cd:arguments> + </cd:command> - <cd:command name="txt" type="environment" variant="interactionmenu" file="scrn-but.mkvi"/> + <cd:command name="txt" type="environment" scope="interactionmenu" file="scrn-but.mkvi"/> - <cd:command name="rul" variant="interactionmenu" file="scrn-but.mkvi"> - <cd:arguments> - <cd:resolve name="string-text"/> - <cd:delimiter name="\"/> - </cd:arguments> - </cd:command> + <cd:command name="rul" scope="interactionmenu" file="scrn-but.mkvi"> + <cd:arguments> + <cd:resolve name="string-text"/> + <cd:delimiter name="\"/> + </cd:arguments> + </cd:command> - <cd:command name="rul" type="environment" variant="interactionmenu" file="scrn-but.mkvi"/> + <cd:command name="rul" type="environment" scope="interactionmenu" file="scrn-but.mkvi"/> - <cd:command name="com" variant="interactionmenu" file="scrn-but.mkvi"> - <cd:arguments> - <cd:resolve name="string-text"/> - <cd:delimiter name="\"/> - </cd:arguments> - </cd:command> + <cd:command name="com" scope="interactionmenu" file="scrn-but.mkvi"> + <cd:arguments> + <cd:resolve name="string-text"/> + <cd:delimiter name="\"/> + </cd:arguments> + </cd:command> - <cd:command name="com" type="environment" variant="interactionmenu" file="scrn-but.mkvi"/> + <cd:command name="com" type="environment" scope="interactionmenu" file="scrn-but.mkvi"/> + + --> <cd:command name="includemenu" file="scrn-but.mkvi"> <cd:arguments> @@ -241,7 +245,7 @@ </cd:arguments> </cd:command> - <cd:command name="menubutton" variant="1" file="scrn-but.mkvi"> + <cd:command name="menubutton" variant="interactionmenu" file="scrn-but.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:assignments list="yes" optional="yes"> @@ -254,7 +258,7 @@ </cd:arguments> </cd:command> - <cd:command name="menubutton" variant="2" file="scrn-but.mkvi"> + <cd:command name="menubutton" variant="button" file="scrn-but.mkvi"> <cd:arguments> <cd:assignments list="yes"> <cd:inherit name="setupbutton"/> diff --git a/tex/context/interface/mkiv/i-interactionscreen.xml b/tex/context/interface/mkiv/i-interactionscreen.xml index 69edbcdb9..6e337f6d6 100644 --- a/tex/context/interface/mkiv/i-interactionscreen.xml +++ b/tex/context/interface/mkiv/i-interactionscreen.xml @@ -31,7 +31,7 @@ <cd:parameter name="topspace"> <cd:constant type="cd:dimension"/> </cd:parameter> - <cd:parameter name="option"> + <cd:parameter name="option" list="yes"> <cd:constant type="fit"/> <cd:constant type="max"/> <cd:constant type="singlesided"/> @@ -44,6 +44,10 @@ <cd:constant type="landscape"/> <cd:constant type="portrait"/> <cd:constant type="page"/> + <cd:constant type="paper"/> + </cd:parameter> + <cd:parameter name="copies"> + <cd:constant type="cd:number"/> </cd:parameter> <cd:parameter name="delay"> <cd:constant type="none" default="yes"/> @@ -61,4 +65,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-interface.xml b/tex/context/interface/mkiv/i-interface.xml index c8c93b72b..a9b35bbe5 100644 --- a/tex/context/interface/mkiv/i-interface.xml +++ b/tex/context/interface/mkiv/i-interface.xml @@ -199,4 +199,4 @@ </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-interlinespace.xml b/tex/context/interface/mkiv/i-interlinespace.xml index 99f5e11af..b93bac7f5 100644 --- a/tex/context/interface/mkiv/i-interlinespace.xml +++ b/tex/context/interface/mkiv/i-interlinespace.xml @@ -14,7 +14,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupinterlinespace" variant="1" file="spac-ver.mkiv"> + <cd:command name="setupinterlinespace" file="spac-ver.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-list-optional"/> <cd:assignments list="yes"> @@ -53,7 +53,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupinterlinespace" variant="2" file="spac-ver.mkiv"> + <cd:command name="setupinterlinespace" variant="argument" file="spac-ver.mkiv"> <cd:arguments> <cd:keywords list="yes" optional="yes"> <cd:constant type="on"/> @@ -69,13 +69,13 @@ </cd:arguments> </cd:command> - <cd:command name="setupinterlinespace" variant="3" file="spac-ver.mkiv"> + <cd:command name="setupinterlinespace" variant="name" file="spac-ver.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> </cd:arguments> </cd:command> - <cd:command name="setuplocalinterlinespace" variant="1" file="spac-ver.mkiv"> + <cd:command name="setuplocalinterlinespace" file="spac-ver.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-list-optional"/> <cd:assignments list="yes"> @@ -84,7 +84,7 @@ </cd:arguments> </cd:command> - <cd:command name="setuplocalinterlinespace" variant="2" file="spac-ver.mkiv"> + <cd:command name="setuplocalinterlinespace" variant="argument" file="spac-ver.mkiv"> <cd:arguments> <cd:keywords list="yes" optional="yes"> <cd:constant type="on"/> @@ -100,13 +100,13 @@ </cd:arguments> </cd:command> - <cd:command name="setuplocalinterlinespace" variant="3" file="spac-ver.mkiv"> + <cd:command name="setuplocalinterlinespace" variant="name" file="spac-ver.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> </cd:arguments> </cd:command> - <cd:command name="switchtointerlinespace" variant="1" file="spac-ver.mkiv"> + <cd:command name="switchtointerlinespace" file="spac-ver.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-list-optional"/> <cd:assignments list="yes"> @@ -115,7 +115,7 @@ </cd:arguments> </cd:command> - <cd:command name="switchtointerlinespace" variant="2" file="spac-ver.mkiv"> + <cd:command name="switchtointerlinespace" variant="argument" file="spac-ver.mkiv"> <cd:arguments> <cd:keywords list="yes" optional="yes"> <cd:constant type="on"/> @@ -131,13 +131,13 @@ </cd:arguments> </cd:command> - <cd:command name="switchtointerlinespace" variant="3" file="spac-ver.mkiv"> + <cd:command name="switchtointerlinespace" variant="name" file="spac-ver.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> </cd:arguments> </cd:command> - <cd:command name="dosetupcheckedinterlinespace" variant="1" file="spac-ver.mkiv"> + <cd:command name="dosetupcheckedinterlinespace" file="spac-ver.mkiv"> <cd:arguments> <cd:assignments delimiters="braces" list="yes"> <cd:inherit name="setupinterlinespace"/> @@ -145,7 +145,7 @@ </cd:arguments> </cd:command> - <cd:command name="dosetupcheckedinterlinespace" variant="2" file="spac-ver.mkiv"> + <cd:command name="dosetupcheckedinterlinespace" variant="argument" file="spac-ver.mkiv"> <cd:arguments> <cd:keywords delimiters="braces" list="yes"> <cd:constant type="on"/> @@ -161,7 +161,7 @@ </cd:arguments> </cd:command> - <cd:command name="dosetupcheckedinterlinespace" variant="3" file="spac-ver.mkiv"> + <cd:command name="dosetupcheckedinterlinespace" variant="name" file="spac-ver.mkiv"> <cd:arguments> <cd:resolve name="argument-name"/> </cd:arguments> @@ -173,4 +173,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-ipsum.xml b/tex/context/interface/mkiv/i-ipsum.xml new file mode 100644 index 000000000..f96fc5229 --- /dev/null +++ b/tex/context/interface/mkiv/i-ipsum.xml @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?context-directive job ctxfile x-setups.ctx ?> + +<cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> + + <cd:command name="defineipsum" file="m-ipsum.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupipsum"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setupipsum" file="m-ipsum.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="alternative"> + <cd:constant type="paragraph" default="yes"/> + <cd:constant type="line"/> + <cd:constant type="lines"/> + <cd:constant type="word"/> + <cd:constant type="words"/> + </cd:parameter> + <cd:parameter name="file"> + <cd:constant type="cd:file"/> + </cd:parameter> + <cd:parameter name="n"> + <cd:constant type="random"/> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="inbetween"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:resolve name="value-style"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="language"> + <cd:constant type="cd:language"/> + </cd:parameter> + <cd:parameter name="separator"> + <cd:constant type="cd:command"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="ipsum" file="m-ipsum.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupipsum"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="directipsum" file="m-ipsum.mkiv"> + <cd:arguments> + <cd:resolve name="argument-name"/> + </cd:arguments> + </cd:command> + +</cd:interface>
\ No newline at end of file diff --git a/tex/context/interface/mkiv/i-itemgroup.xml b/tex/context/interface/mkiv/i-itemgroup.xml index 69e817efd..6fb28b635 100644 --- a/tex/context/interface/mkiv/i-itemgroup.xml +++ b/tex/context/interface/mkiv/i-itemgroup.xml @@ -14,7 +14,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupitemgroup" variant="1" file="strc-itm.mkvi"> + <cd:command name="setupitemgroup" file="strc-itm.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:keywords list="yes" optional="yes"> @@ -116,7 +116,7 @@ <cd:inherit name="setupalign"/> </cd:parameter> <cd:parameter name="indenting"> - <cd:resolve name="setupindenting"/> + <cd:inherit name="setupindenting"/> </cd:parameter> <cd:parameter name="start"> <cd:constant type="cd:number"/> @@ -198,7 +198,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupitemgroup" variant="2" file="strc-itm.mkvi"> + <cd:command name="setupitemgroup" variant="assignment" file="strc-itm.mkvi"> <cd:arguments> <cd:keywords list="yes" optional="yes"> <cd:constant type="cd:name"/> @@ -299,7 +299,7 @@ <cd:inherit name="setupalign"/> </cd:parameter> <cd:parameter name="indenting"> - <cd:resolve name="setupindenting"/> + <cd:inherit name="setupindenting"/> </cd:parameter> <cd:parameter name="start"> <cd:constant type="cd:number"/> @@ -381,23 +381,45 @@ </cd:arguments> </cd:command> - <cd:command name="itemgroup" type="environment" generated="yes" variant="generated" file="strc-itm.mkvi"> + <cd:command name="setupitemgroups" file="strc-itm.mkvi"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:number" prefix="cd:name" method="range"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupitemgroup"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setupitemgroup" generated="yes" variant="instance" file="strc-itm.mkvi"> <cd:sequence> - <cd:variable value="itemgroup"/> + <cd:string value="setup"/> + <cd:instance value="itemgroup"/> </cd:sequence> <cd:arguments> <cd:keywords list="yes" optional="yes"> + <cd:constant type="each"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> <cd:inherit name="setupitemgroup"/> </cd:keywords> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupitemgroup"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-itemgroup"/> + </cd:instances> </cd:command> - <cd:command name="itemgroup" type="environment" file="strc-itm.mkvi"> + <cd:command name="itemgroup" type="environment" generated="yes" variant="instance" file="strc-itm.mkvi"> + <cd:sequence> + <cd:instance value="itemgroup"/> + </cd:sequence> <cd:arguments> - <cd:resolve name="keyword-name"/> <cd:keywords list="yes" optional="yes"> <cd:inherit name="setupitemgroup"/> </cd:keywords> @@ -405,93 +427,114 @@ <cd:inherit name="setupitemgroup"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-itemgroup"/> + </cd:instances> </cd:command> - <cd:command name="item" variant="itemgroup" file="strc-itm.mkvi"> + <cd:command name="itemgroup" type="environment" file="strc-itm.mkvi"> <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="keyword-name"/> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="setupitemgroup"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupitemgroup"/> + </cd:assignments> </cd:arguments> </cd:command> - <cd:command name="itemtag" variant="itemgroup" file="strc-itm.mkvi"> + <cd:command name="item" scope="itemgroup" file="strc-itm.mkvi"> <cd:arguments> <cd:resolve name="keyword-reference-list-optional"/> </cd:arguments> </cd:command> - <cd:command name="itm" variant="itemgroup" file="strc-itm.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="noitem" scope="itemgroup" file="strc-itm.mkvi"/> - <cd:command name="but" variant="itemgroup" file="strc-itm.mkvi"> + <cd:command name="itemtag" scope="itemgroup" file="strc-itm.mkvi"> <cd:arguments> - <cd:resolve name="keyword-reference"/> <cd:resolve name="keyword-reference-list-optional"/> </cd:arguments> </cd:command> - <cd:command name="nop" variant="itemgroup" file="strc-itm.mkvi"/> + <!-- - <cd:command name="txt" variant="itemgroup" file="strc-itm.mkvi"> - <cd:arguments> - <cd:resolve name="argument-text"/> - <cd:resolve name="keyword-reference-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="itm" scope="itemgroup" file="strc-itm.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="head" variant="itemgroup" file="strc-itm.mkvi"> - <cd:arguments> - <cd:resolve name="string-text"/> - <cd:delimiter name="par"/> - </cd:arguments> - </cd:command> + <cd:command name="but" scope="itemgroup" file="strc-itm.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference"/> + <cd:resolve name="keyword-reference-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="headsym" variant="itemgroup" file="strc-itm.mkvi"> - <cd:arguments> - <cd:resolve name="argument-text"/> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="nop" scope="itemgroup" file="strc-itm.mkvi"/> - <cd:command name="sym" variant="itemgroup" file="strc-itm.mkvi"> - <cd:arguments> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="txt" scope="itemgroup" file="strc-itm.mkvi"> + <cd:arguments> + <cd:resolve name="argument-text"/> + <cd:resolve name="keyword-reference-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="ran" variant="itemgroup" file="strc-itm.mkvi"> - <cd:arguments> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="head" scope="itemgroup" file="strc-itm.mkvi"> + <cd:arguments> + <cd:resolve name="string-text"/> + <cd:delimiter name="par"/> + </cd:arguments> + </cd:command> - <cd:command name="mar" variant="itemgroup" file="strc-itm.mkvi"> - <cd:arguments> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="headsym" scope="itemgroup" file="strc-itm.mkvi"> + <cd:arguments> + <cd:resolve name="argument-text"/> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text-optional"/> + </cd:arguments> + </cd:command> + + <cd:command name="sym" scope="itemgroup" file="strc-itm.mkvi"> + <cd:arguments> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="ran" scope="itemgroup" file="strc-itm.mkvi"> + <cd:arguments> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="mar" scope="itemgroup" file="strc-itm.mkvi"> + <cd:arguments> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="sub" scope="itemgroup" file="strc-itm.mkvi"/> - <cd:command name="sub" variant="itemgroup" file="strc-itm.mkvi"/> + <cd:command name="its" scope="itemgroup" file="strc-itm.mkvi"/> - <cd:command name="its" variant="itemgroup" file="strc-itm.mkvi"/> + --> - <cd:command name="item" type="environment" file="strc-itm.mkvi"> + <cd:command name="item" type="environment" scope="itemgroup" file="strc-itm.mkvi"> <cd:arguments> <cd:resolve name="keyword-reference-list-optional"/> </cd:arguments> </cd:command> - <cd:command name="head" type="environment" file="strc-itm.mkvi"> + <cd:command name="head" type="environment" scope="itemgroup" file="strc-itm.mkvi"> <cd:arguments> <cd:resolve name="keyword-reference-list-optional"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> - <cd:command name="specialitem" type="environment" variant="1" file="strc-itm.mkvi"> + <cd:command name="specialitem" type="environment" variant="item" scope="itemgroup" file="strc-itm.mkvi"> <cd:arguments> <cd:keywords optional="yes"> <cd:constant type="item" default="yes"/> @@ -500,7 +543,7 @@ </cd:arguments> </cd:command> - <cd:command name="specialitem" type="environment" variant="2" file="strc-itm.mkvi"> + <cd:command name="specialitem" type="environment" variant="symbol" scope="itemgroup" file="strc-itm.mkvi"> <cd:arguments> <cd:keywords> <cd:constant type="sym"/> @@ -511,7 +554,7 @@ </cd:arguments> </cd:command> - <cd:command name="specialitem" type="environment" variant="3" file="strc-itm.mkvi"> + <cd:command name="specialitem" type="environment" variant="none" scope="itemgroup" file="strc-itm.mkvi"> <cd:arguments> <cd:keywords> <cd:constant type="sub"/> @@ -520,15 +563,34 @@ </cd:arguments> </cd:command> - <cd:command name="itemize" type="environment" file="strc-itm.mkvi"> - <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:inherit name="setupitemgroup"/> - </cd:keywords> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupitemgroup"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <!-- + + <cd:command name="itemize" type="environment" file="strc-itm.mkvi"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="setupitemgroup"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupitemgroup"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setupitemize" file="strc-itm.mkvi"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="each"/> + <cd:constant type="cd:number"/> + </cd:keywords> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="setupitemgroup"/> + </cd:keywords> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupitemgroup"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> </cd:interface> diff --git a/tex/context/interface/mkiv/i-javascript.xml b/tex/context/interface/mkiv/i-javascript.xml index 790d13523..965ed5388 100644 --- a/tex/context/interface/mkiv/i-javascript.xml +++ b/tex/context/interface/mkiv/i-javascript.xml @@ -48,4 +48,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-kerning.xml b/tex/context/interface/mkiv/i-kerning.xml index 167bfc4f8..aacb4a6ea 100644 --- a/tex/context/interface/mkiv/i-kerning.xml +++ b/tex/context/interface/mkiv/i-kerning.xml @@ -49,7 +49,7 @@ <cd:command name="resetcharacterkerning" file="typo-krn.mkiv"/> - <cd:command name="characterkerning" generated="yes" variant="generated" file="typo-krn.mkiv"> + <cd:command name="characterkerning" generated="yes" variant="example" file="typo-krn.mkiv"> <cd:sequence> <cd:variable value="characterkerning"/> </cd:sequence> @@ -90,4 +90,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-label.xml b/tex/context/interface/mkiv/i-label.xml index 320c105f9..fe7851d9d 100644 --- a/tex/context/interface/mkiv/i-label.xml +++ b/tex/context/interface/mkiv/i-label.xml @@ -149,6 +149,9 @@ <cd:constant type="no" default="yes"/> <cd:constant type="xml"/> </cd:parameter> + <cd:parameter name="referenceprefix"> + <cd:resolve name="value-referenceprefix"/> + </cd:parameter> <cd:parameter name="sample"> <cd:constant type="cd:text"/> </cd:parameter> @@ -186,7 +189,7 @@ --> - <cd:command name="label" generated="yes" variant="generated" file="strc-lab.mkiv"> + <cd:command name="label" generated="yes" variant="example" file="strc-lab.mkiv"> <cd:sequence> <cd:variable value="label"/> </cd:sequence> @@ -196,7 +199,7 @@ </cd:arguments> </cd:command> - <cd:command name="currentlabel" generated="yes" variant="generated" file="strc-lab.mkiv"> + <cd:command name="currentlabel" generated="yes" variant="example" file="strc-lab.mkiv"> <cd:sequence> <cd:string value="current"/> <cd:variable value="label"/> @@ -207,4 +210,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-labeltext.xml b/tex/context/interface/mkiv/i-labeltext.xml index 247783762..34c70231f 100644 --- a/tex/context/interface/mkiv/i-labeltext.xml +++ b/tex/context/interface/mkiv/i-labeltext.xml @@ -11,486 +11,513 @@ </cd:arguments> </cd:command> - <cd:command name="setuplabeltext" generated="yes" variant="generated" file="lang-lab.mkiv"> + <cd:command name="setuplabeltext" generated="yes" variant="instance" file="lang-lab.mkiv"> <cd:sequence> <cd:string value="setup"/> - <cd:variable value="label"/> + <cd:instance value="label"/> <cd:string value="text"/> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-language-optional"/> <cd:resolve name="assignment-userdata-list"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-labelclass"/> + </cd:instances> </cd:command> - <cd:command name="presetlabeltext" generated="yes" variant="generated" file="lang-lab.mkiv"> + <cd:command name="presetlabeltext" generated="yes" variant="instance" file="lang-lab.mkiv"> <cd:sequence> <cd:string value="preset"/> - <cd:variable value="label"/> + <cd:instance value="label"/> <cd:string value="text"/> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-language-optional"/> <cd:resolve name="assignment-userdata-list"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-labelclass"/> + </cd:instances> </cd:command> - <cd:command name="copylabeltext" generated="yes" variant="generated" file="lang-lab.mkiv"> + <cd:command name="copylabeltext" generated="yes" variant="instance" file="lang-lab.mkiv"> <cd:sequence> <cd:string value="copy"/> - <cd:variable value="label"/> + <cd:instance value="label"/> <cd:string value="text"/> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-language-optional"/> <cd:resolve name="assignment-labeldata-list"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-labelclass"/> + </cd:instances> </cd:command> - <cd:command name="labeltext" type="environment" generated="yes" variant="generated" file="lang-lab.mkiv"> + <cd:command name="labeltext" type="environment" generated="yes" variant="instance" file="lang-lab.mkiv"> <cd:sequence> - <cd:variable value="label"/> + <cd:instance value="label"/> <cd:string value="text"/> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-language-optional"/> <cd:resolve name="keyword-key"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-labelclass"/> + </cd:instances> </cd:command> - <cd:command name="labellanguage" generated="yes" variant="generated" file="lang-lab.mkiv"> + <cd:command name="labellanguage" generated="yes" variant="instance" file="lang-lab.mkiv"> <cd:sequence> - <cd:variable value="label"/> + <cd:instance value="label"/> <cd:string value="language"/> </cd:sequence> + <cd:instances> + <cd:resolve name="instance-labelclass"/> + </cd:instances> </cd:command> - <cd:command name="labeltext" generated="yes" variant="generated" file="lang-lab.mkiv"> + <cd:command name="labeltext" generated="yes" variant="instance" file="lang-lab.mkiv"> <cd:sequence> - <cd:variable value="label"/> + <cd:instance value="label"/> <cd:string value="text"/> </cd:sequence> <cd:arguments> <cd:resolve name="argument-key"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-labelclass"/> + </cd:instances> </cd:command> - <cd:command name="labeltexts" generated="yes" variant="generated" file="lang-lab.mkiv"> + <cd:command name="labeltexts" generated="yes" variant="instance" file="lang-lab.mkiv"> <cd:sequence> - <cd:variable value="label"/> + <cd:instance value="label"/> <cd:string value="texts"/> </cd:sequence> <cd:arguments> <cd:resolve name="argument-key"/> <cd:resolve name="argument-text"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-labeltext"/> + </cd:instances> </cd:command> - <cd:command name="leftlabeltext" generated="yes" variant="generated" file="lang-lab.mkiv"> + <cd:command name="leftlabeltext" generated="yes" variant="instance" file="lang-lab.mkiv"> <cd:sequence> <cd:string value="left"/> - <cd:variable value="label"/> + <cd:instance value="label"/> <cd:string value="text"/> </cd:sequence> <cd:arguments> <cd:resolve name="argument-key"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-labeltext"/> + </cd:instances> </cd:command> - <cd:command name="rightlabeltext" generated="yes" variant="generated" file="lang-lab.mkiv"> + <cd:command name="rightlabeltext" generated="yes" variant="instance" file="lang-lab.mkiv"> <cd:sequence> <cd:string value="right"/> - <cd:variable value="label"/> + <cd:instance value="label"/> <cd:string value="text"/> </cd:sequence> <cd:arguments> <cd:resolve name="argument-key"/> </cd:arguments> - </cd:command> - - <cd:command name="setuplabeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="presetlabeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="copylabeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-labeldata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="labeltext" type="environment" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="keyword-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="labellanguage" file="lang-lab.mkiv"/> - - <cd:command name="labeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="labeltexts" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> - - <cd:command name="leftlabeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="rightlabeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="setupheadtext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="presetheadtext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="copyheadtext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-labeldata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="headtext" type="environment" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="keyword-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="headlanguage" file="lang-lab.mkiv"/> - - <cd:command name="headtext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="headtexts" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> - - <cd:command name="leftheadtext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="rightheadtext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="setupmathlabeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="presetmathlabeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="copymathlabeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-labeldata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="mathlabeltext" type="environment" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="keyword-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="mathlabellanguage" file="lang-lab.mkiv"/> - - <cd:command name="mathlabeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="mathlabeltexts" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> - - <cd:command name="leftmathlabeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="rightmathlabeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="setuptaglabeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="presettaglabeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="copytaglabeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-labeldata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="taglabeltext" type="environment" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="keyword-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="taglabellanguage" file="lang-lab.mkiv"/> - - <cd:command name="taglabeltext" file="lang-lab.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="setupunittext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="presetunittext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="copyunittext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-labeldata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="unittext" type="environment" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="keyword-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="unitlanguage" file="phys-dim.mkiv"/> - - <cd:command name="unittext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="setupoperatortext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="presetoperatortext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="copyoperatortext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-labeldata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="operatortext" type="environment" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="keyword-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="operatorlanguage" file="phys-dim.mkiv"/> - - <cd:command name="operatortext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="setupprefixtext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="presetprefixtext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="copyprefixtext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-labeldata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="prefixtext" type="environment" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="keyword-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="prefixlanguage" file="phys-dim.mkiv"/> - - <cd:command name="prefixtext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - </cd:arguments> - </cd:command> - -<!-- - - <cd:command name="setupsuffixtext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="presetsuffixtext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="copysuffixtext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-labeldata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="suffixtext" type="environment" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="keyword-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="suffixlanguage" file="phys-dim.mkiv"/> - - <cd:command name="suffixtext" file="phys-dim.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - </cd:arguments> - </cd:command> - ---> - - <cd:command name="setupbtxlabeltext" file="publ-ini.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="presetbtxlabeltext" file="publ-ini.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-userdata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="copybtxlabeltext" file="publ-ini.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="assignment-labeldata-list"/> - </cd:arguments> - </cd:command> - - <cd:command name="btxlabeltext" type="environment" file="publ-ini.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-language-optional"/> - <cd:resolve name="keyword-key"/> - </cd:arguments> - </cd:command> - - <cd:command name="btxlabellanguage" file="publ-ini.mkiv"/> - - <cd:command name="btxlabeltext" file="publ-ini.mkiv"> - <cd:arguments> - <cd:resolve name="argument-key"/> - </cd:arguments> - </cd:command> - -</cd:interface>
\ No newline at end of file + <cd:instances> + <cd:resolve name="instance-labeltext"/> + </cd:instances> + </cd:command> + + <!-- + + <cd:command name="setuplabeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="presetlabeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="copylabeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-labeldata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="labeltext" type="environment" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="keyword-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="labellanguage" file="lang-lab.mkiv"/> + + <cd:command name="labeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="labeltexts" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="leftlabeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="rightlabeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="setupheadtext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="presetheadtext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="copyheadtext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-labeldata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="headtext" type="environment" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="keyword-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="headlanguage" file="lang-lab.mkiv"/> + + <cd:command name="headtext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="headtexts" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="leftheadtext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="rightheadtext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="setupmathlabeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="presetmathlabeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="copymathlabeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-labeldata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="mathlabeltext" type="environment" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="keyword-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="mathlabellanguage" file="lang-lab.mkiv"/> + + <cd:command name="mathlabeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="mathlabeltexts" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="leftmathlabeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="rightmathlabeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="setuptaglabeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="presettaglabeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="copytaglabeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-labeldata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="taglabeltext" type="environment" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="keyword-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="taglabellanguage" file="lang-lab.mkiv"/> + + <cd:command name="taglabeltext" file="lang-lab.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="setupunittext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="presetunittext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="copyunittext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-labeldata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="unittext" type="environment" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="keyword-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="unitlanguage" file="phys-dim.mkiv"/> + + <cd:command name="unittext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="setupoperatortext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="presetoperatortext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="copyoperatortext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-labeldata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="operatortext" type="environment" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="keyword-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="operatorlanguage" file="phys-dim.mkiv"/> + + <cd:command name="operatortext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="setupprefixtext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="presetprefixtext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="copyprefixtext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-labeldata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="prefixtext" type="environment" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="keyword-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="prefixlanguage" file="phys-dim.mkiv"/> + + <cd:command name="prefixtext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="setupsuffixtext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="presetsuffixtext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="copysuffixtext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-labeldata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="suffixtext" type="environment" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="keyword-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="suffixlanguage" file="phys-dim.mkiv"/> + + <cd:command name="suffixtext" file="phys-dim.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="setupbtxlabeltext" file="publ-ini.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="presetbtxlabeltext" file="publ-ini.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-userdata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="copybtxlabeltext" file="publ-ini.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="assignment-labeldata-list"/> + </cd:arguments> + </cd:command> + + <cd:command name="btxlabeltext" type="environment" file="publ-ini.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-language-optional"/> + <cd:resolve name="keyword-key"/> + </cd:arguments> + </cd:command> + + <cd:command name="btxlabellanguage" file="publ-ini.mkiv"/> + + <cd:command name="btxlabeltext" file="publ-ini.mkiv"> + <cd:arguments> + <cd:resolve name="argument-key"/> + </cd:arguments> + </cd:command> + + --> + +</cd:interface> diff --git a/tex/context/interface/mkiv/i-language.xml b/tex/context/interface/mkiv/i-language.xml index 26bdbf060..395e08c34 100644 --- a/tex/context/interface/mkiv/i-language.xml +++ b/tex/context/interface/mkiv/i-language.xml @@ -4,7 +4,7 @@ <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> - <cd:command name="installlanguage" variant="1" file="lang-ini.mkiv"> + <cd:command name="installlanguage" file="lang-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:assignments list="yes"> @@ -13,7 +13,7 @@ </cd:arguments> </cd:command> - <cd:command name="installlanguage" variant="2" file="lang-ini.mkiv"> + <cd:command name="installlanguage" variant="name" file="lang-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="keyword-language"/> @@ -116,6 +116,10 @@ <cd:parameter name="rightsubsentence"> <cd:constant type="cd:command"/> </cd:parameter> + <cd:parameter name="factor"> + <cd:constant type="yes"/> + <cd:constant type="no" default="yes"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> @@ -152,7 +156,7 @@ </cd:arguments> </cd:command> - <cd:command name="language" generated="yes" variant="generated" file="lang-ini.mkiv"> + <cd:command name="language" generated="yes" variant="example" file="lang-ini.mkiv"> <cd:sequence> <cd:variable value="language"/> </cd:sequence> @@ -197,4 +201,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-layer.xml b/tex/context/interface/mkiv/i-layer.xml index 6be7cccc9..9157ecdbf 100644 --- a/tex/context/interface/mkiv/i-layer.xml +++ b/tex/context/interface/mkiv/i-layer.xml @@ -46,7 +46,7 @@ </cd:arguments> </cd:command> - <cd:command name="setlayerframed" variant="1" file="pack-box.mkiv"> + <cd:command name="setlayerframed" file="pack-box.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:assignments list="yes" optional="yes"> @@ -59,7 +59,7 @@ </cd:arguments> </cd:command> - <cd:command name="setlayerframed" variant="2" file="pack-box.mkiv"> + <cd:command name="setlayerframed" variant="combination" file="pack-box.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:assignments list="yes" optional="yes"> @@ -267,7 +267,7 @@ </cd:arguments> </cd:command> - <cd:command name="definelayerpreset" variant="1" file="pack-lyr.mkiv"> + <cd:command name="definelayerpreset" file="pack-lyr.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:assignments list="yes"> @@ -276,7 +276,7 @@ </cd:arguments> </cd:command> - <cd:command name="definelayerpreset" variant="2" file="pack-lyr.mkiv"> + <cd:command name="definelayerpreset" variant="name" file="pack-lyr.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="keyword-name"/> @@ -324,4 +324,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-layout.xml b/tex/context/interface/mkiv/i-layout.xml index 984995f10..f3e42515e 100644 --- a/tex/context/interface/mkiv/i-layout.xml +++ b/tex/context/interface/mkiv/i-layout.xml @@ -14,7 +14,7 @@ </cd:arguments> </cd:command> - <cd:command name="setuplayout" variant="1" file="page-lay.mkiv"> + <cd:command name="setuplayout" file="page-lay.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:assignments list="yes"> @@ -174,6 +174,9 @@ <cd:constant type="page"/> <cd:constant type="empty"/> <cd:constant type="color"/> + <cd:constant type="one"/> + <cd:constant type="two"/> + <cd:constant type="four"/> </cd:parameter> <cd:parameter name="grid"> <cd:constant type="yes"/> @@ -208,7 +211,7 @@ </cd:arguments> </cd:command> - <cd:command name="setuplayout" variant="2" file="page-lay.mkiv"> + <cd:command name="setuplayout" variant="name" file="page-lay.mkiv"> <cd:arguments> <cd:keywords> <cd:constant type="reset"/> @@ -364,4 +367,4 @@ <cd:command name="spread" type="environment" file="page-spr.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-linenumber.xml b/tex/context/interface/mkiv/i-linenumber.xml index 623595140..1c7ca2f75 100644 --- a/tex/context/interface/mkiv/i-linenumber.xml +++ b/tex/context/interface/mkiv/i-linenumber.xml @@ -89,16 +89,30 @@ </cd:arguments> </cd:command> - <cd:command name="linenumbering" type="environment" variant="1" file="page-lin.mkvi"> + <cd:command name="linenumbering" type="environment" file="page-lin.mkvi"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setuplinenumbering"/> + <cd:parameter name="continue"> + <cd:constant type="yes"/> + <cd:constant type="no" default="yes"/> + </cd:parameter> + <cd:parameter name="start"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="step"> + <cd:constant type="cd:number"/> + </cd:parameter> + <cd:parameter name="method"> + <cd:constant type="page"/> + <cd:constant type="first" default="yes"/> + <cd:constant type="next"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> - <cd:command name="linenumbering" type="environment" variant="2" file="page-lin.mkvi"> + <cd:command name="linenumbering" type="environment" variant="argument" file="page-lin.mkvi"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:keywords optional="yes"> diff --git a/tex/context/interface/mkiv/i-lines.xml b/tex/context/interface/mkiv/i-lines.xml index e43945e4d..32c3c6b70 100644 --- a/tex/context/interface/mkiv/i-lines.xml +++ b/tex/context/interface/mkiv/i-lines.xml @@ -78,28 +78,41 @@ <cd:parameter name="color"> <cd:constant type="cd:color"/> </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> - <cd:command name="lines" type="environment" generated="yes" variant="generated" file="spac-lin.mkiv"> + <cd:command name="lines" type="environment" generated="yes" variant="instance" file="spac-lin.mkiv"> <cd:sequence> - <cd:variable value="lines"/> + <cd:instance value="lines"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setuplines"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-lines"/> + </cd:instances> </cd:command> - <cd:command name="lines" type="environment" file="spac-lin.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setuplines"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <!-- + + <cd:command name="lines" type="environment" file="spac-lin.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplines"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> <cd:command name="emptylines" file="spac-lin.mkiv"> <cd:arguments> @@ -107,4 +120,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-linetable.xml b/tex/context/interface/mkiv/i-linetable.xml index a10479161..9b4cae16a 100644 --- a/tex/context/interface/mkiv/i-linetable.xml +++ b/tex/context/interface/mkiv/i-linetable.xml @@ -162,4 +162,4 @@ --> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-list.xml b/tex/context/interface/mkiv/i-list.xml index 38e534252..7e0def052 100644 --- a/tex/context/interface/mkiv/i-list.xml +++ b/tex/context/interface/mkiv/i-list.xml @@ -88,7 +88,7 @@ <cd:constant type="cd:command"/> </cd:parameter> <cd:parameter name="command"> - <cd:constant type="cd:threeargument"/> + <cd:constant type="cd:threearguments"/> </cd:parameter> <cd:parameter name="numbercommand"> <cd:constant type="cd:oneargument"/> @@ -409,65 +409,78 @@ </cd:arguments> </cd:command> - <cd:command name="setupcombinedlist" generated="yes" variant="generated" file="strc-lst.mkvi"> + <cd:command name="setupcombinedlist" generated="yes" variant="instance" file="strc-lst.mkvi"> <cd:sequence> <cd:string value="setup"/> - <cd:variable value="combinedlist"/> + <cd:instance value="combinedlist"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes"> <cd:inherit name="setuplist"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-combinedlist"/> + </cd:instances> </cd:command> - <cd:command name="placecombinedlist" generated="yes" variant="generated" file="strc-lst.mkvi"> + <cd:command name="placecombinedlist" generated="yes" variant="instance" file="strc-lst.mkvi"> <cd:sequence> <cd:string value="place"/> - <cd:variable value="combinedlist"/> + <cd:instance value="combinedlist"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setuplist"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-combinedlist"/> + </cd:instances> </cd:command> - <cd:command name="completecombinedlist" generated="yes" variant="generated" file="strc-lst.mkvi"> + <cd:command name="completecombinedlist" generated="yes" variant="instance" file="strc-lst.mkvi"> <cd:sequence> <cd:string value="complete"/> - <cd:variable value="combinedlist"/> + <cd:instance value="combinedlist"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setuplist"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-combinedlist"/> + </cd:instances> </cd:command> - <cd:command name="setupcontent" file="strc-lst.mkvi"> - <cd:arguments> - <cd:assignments list="yes"> - <cd:inherit name="setuplist"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="placecontent" file="strc-lst.mkvi"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setuplist"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="setupcontent" file="strc-lst.mkvi"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + </cd:command> - <cd:command name="completecontent" file="strc-lst.mkvi"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setuplist"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="placecontent" file="strc-lst.mkvi"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="completecontent" file="strc-lst.mkvi"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuplist"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> <cd:command name="structurelistuservariable" file="strc-lst.mkvi"> <cd:arguments> diff --git a/tex/context/interface/mkiv/i-lohi.xml b/tex/context/interface/mkiv/i-lohi.xml index 7cfd489eb..1fe891b2c 100644 --- a/tex/context/interface/mkiv/i-lohi.xml +++ b/tex/context/interface/mkiv/i-lohi.xml @@ -34,13 +34,16 @@ </cd:arguments> </cd:command> - <cd:command name="low" generated="yes" variant="generated" file="typo-scr.mkiv"> + <cd:command name="low" generated="yes" variant="instance" file="typo-scr.mkiv"> <cd:sequence> - <cd:variable value="low"/> + <cd:instance value="low"/> </cd:sequence> <cd:arguments> <cd:content/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-low"/> + </cd:instances> </cd:command> <cd:command name="low" file="typo-scr.mkiv"> @@ -79,13 +82,16 @@ </cd:arguments> </cd:command> - <cd:command name="high" generated="yes" variant="generated" file="typo-scr.mkiv"> + <cd:command name="high" generated="yes" variant="instance" file="typo-scr.mkiv"> <cd:sequence> - <cd:variable value="high"/> + <cd:instance value="high"/> </cd:sequence> <cd:arguments> <cd:content/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-high"/> + </cd:instances> </cd:command> <cd:command name="high" file="typo-scr.mkiv"> @@ -127,9 +133,9 @@ </cd:arguments> </cd:command> - <cd:command name="lowhigh" generated="yes" variant="generated" file="typo-scr.mkiv"> + <cd:command name="lowhigh" generated="yes" variant="instance" file="typo-scr.mkiv"> <cd:sequence> - <cd:variable value="lowhigh"/> + <cd:instance value="lowhigh"/> </cd:sequence> <cd:arguments> <cd:keywords optional="yes"> @@ -193,9 +199,9 @@ </cd:arguments> </cd:command> - <cd:command name="lowmidhigh" generated="yes" variant="generated" file="typo-scr.mkiv"> + <cd:command name="lowmidhigh" generated="yes" variant="instance" file="typo-scr.mkiv"> <cd:sequence> - <cd:variable value="lowmidhigh"/> + <cd:instance value="lowmidhigh"/> </cd:sequence> <cd:arguments> <cd:content/> @@ -220,4 +226,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-lua.xml b/tex/context/interface/mkiv/i-lua.xml index 525753723..ef970609b 100644 --- a/tex/context/interface/mkiv/i-lua.xml +++ b/tex/context/interface/mkiv/i-lua.xml @@ -166,7 +166,7 @@ </cd:arguments> </cd:command> - <cd:command name="ctxfunctiondefinition" generated="yes" variant="generated" file="luat-ini.mkiv"> + <cd:command name="ctxfunctiondefinition" generated="yes" variant="example" file="luat-ini.mkiv"> <cd:sequence> <cd:variable value="ctxfunctiondefinition"/> </cd:sequence> @@ -184,10 +184,10 @@ </cd:arguments> </cd:command> - <cd:command name="ctxfunction" generated="yes" variant="generated" file="luat-ini.mkiv"> + <cd:command name="ctxfunction" generated="yes" variant="example" file="luat-ini.mkiv"> <cd:sequence> <cd:variable value="ctxfunction"/> </cd:sequence> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-makeup.xml b/tex/context/interface/mkiv/i-makeup.xml index 2128464ef..8831a8b0b 100644 --- a/tex/context/interface/mkiv/i-makeup.xml +++ b/tex/context/interface/mkiv/i-makeup.xml @@ -113,7 +113,7 @@ </cd:arguments> </cd:command> - <cd:command file="page-mak.mkvi" name="makeup" type="environment"> + <cd:command name="makeup" type="environment" file="page-mak.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:assignments list="yes" optional="yes"> @@ -122,9 +122,9 @@ </cd:arguments> </cd:command> - <cd:command file="page-mak.mkvi" generated="yes" name="makeup" type="environment" variant="generated"> + <cd:command name="makeup" type="environment" generated="yes" variant="instance" file="page-mak.mkvi"> <cd:sequence> - <cd:variable value="makeup"/> + <cd:instance value="makeup"/> <cd:string value="makeup"/> </cd:sequence> <cd:arguments> @@ -133,47 +133,43 @@ </cd:assignments> </cd:arguments> <cd:instances> - <cd:constant value="standard"/> - <cd:constant value="page"/> - <cd:constant value="text"/> - <cd:constant value="middle"/> + <cd:resolve name="instance-makeup"/> </cd:instances> </cd:command> - <!-- - <cd:command name="standardmakeup" type="environment" file="page-mak.mkvi"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmakeup"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="standardmakeup" type="environment" file="page-mak.mkvi"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmakeup"/> + </cd:assignments> + </cd:arguments> + </cd:command> - <cd:command name="textmakeup" type="environment" file="page-mak.mkvi"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmakeup"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="textmakeup" type="environment" file="page-mak.mkvi"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmakeup"/> + </cd:assignments> + </cd:arguments> + </cd:command> - <cd:command name="pagemakeup" type="environment" file="page-mak.mkvi"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmakeup"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="pagemakeup" type="environment" file="page-mak.mkvi"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmakeup"/> + </cd:assignments> + </cd:arguments> + </cd:command> - <cd:command name="middlemakeup" type="environment" file="page-mak.mkvi"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmakeup"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="middlemakeup" type="environment" file="page-mak.mkvi"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmakeup"/> + </cd:assignments> + </cd:arguments> + </cd:command> --> diff --git a/tex/context/interface/mkiv/i-margindata.xml b/tex/context/interface/mkiv/i-margindata.xml index 5a2b014ea..a54362fec 100644 --- a/tex/context/interface/mkiv/i-margindata.xml +++ b/tex/context/interface/mkiv/i-margindata.xml @@ -128,9 +128,9 @@ </cd:arguments> </cd:command> - <cd:command name="margindata" generated="yes" variant="generated" file="typo-mar.mkiv"> + <cd:command name="margindata" generated="yes" variant="instance" file="typo-mar.mkiv"> <cd:sequence> - <cd:variable value="margindata"/> + <cd:instance value="margindata"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> @@ -144,6 +144,9 @@ </cd:assignments> <cd:content/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-margindata"/> + </cd:instances> </cd:command> <cd:command name="margindata" file="typo-mar.mkiv"> @@ -162,292 +165,253 @@ </cd:arguments> </cd:command> - <cd:command name="inleftmargin" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="inrightmargin" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="inleftmargin" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="inoutermargin" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="inrightmargin" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="ininnermargin" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="inoutermargin" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="inleftedge" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="ininnermargin" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="inrightedge" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="inleftedge" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="ininneredge" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="inrightedge" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="inouteredge" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="ininneredge" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="atleftmargin" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="inouteredge" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="atrightmargin" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="atleftmargin" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="inleft" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="atrightmargin" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="inright" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="inleft" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmarginframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="ininner" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="inright" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmarginframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="inouter" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="ininner" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmarginframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="inmargin" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="inouter" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmarginframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="inother" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="inmargin" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmarginframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="margintext" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="inother" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmarginframed"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="marginword" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="margintext" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <cd:command name="margintitle" file="typo-mar.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="reference"> - <cd:constant type="cd:reference"/> - </cd:parameter> - <cd:inherit name="setupmargindata"/> - </cd:assignments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmarginframed"/> - </cd:assignments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="marginword" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> - <!-- + <cd:command name="margintitle" file="typo-mar.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="reference"> + <cd:constant type="cd:reference"/> + </cd:parameter> + <cd:inherit name="setupmargindata"/> + </cd:assignments> + <cd:content/> + </cd:arguments> + </cd:command> <cd:command name="inothermargin" file="typo-mar.mkiv"> <cd:arguments> @@ -466,4 +430,4 @@ --> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-marker.xml b/tex/context/interface/mkiv/i-marker.xml index 103fc5e55..fe491650e 100644 --- a/tex/context/interface/mkiv/i-marker.xml +++ b/tex/context/interface/mkiv/i-marker.xml @@ -30,4 +30,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-marking.xml b/tex/context/interface/mkiv/i-marking.xml index a556f1007..644f0ac5b 100644 --- a/tex/context/interface/mkiv/i-marking.xml +++ b/tex/context/interface/mkiv/i-marking.xml @@ -171,4 +171,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-math.xml b/tex/context/interface/mkiv/i-math.xml index d16ba5173..58890d6ea 100644 --- a/tex/context/interface/mkiv/i-math.xml +++ b/tex/context/interface/mkiv/i-math.xml @@ -4,7 +4,7 @@ <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> - <cd:command name="definemathematics" file="math-ini.mkiv"> + <cd:command name="definemathematics" category="mathematics" file="math-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="keyword-name-optional"/> @@ -14,7 +14,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupmathematics" file="math-ini.mkiv"> + <cd:command name="setupmathematics" category="mathematics" file="math-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-list-optional"/> <cd:assignments list="yes"> @@ -81,8 +81,8 @@ <cd:parameter name="textcolor"> <cd:constant type="cd:color"/> </cd:parameter> - <cd:parameter name="functionstyle"> - <cd:resolve name="value-style"/> + <cd:parameter name="functioncolor"> + <cd:constant type="cd:color"/> </cd:parameter> <cd:parameter name="integral"> <cd:constant type="limits"/> @@ -91,43 +91,50 @@ <cd:constant type="displaylimits"/> <cd:constant type="none"/> </cd:parameter> + <cd:parameter name="stylealternative"> + <cd:constant type="cd:name"/> + </cd:parameter> <cd:parameter name="default"> <cd:constant type="normal"/> <cd:constant type="italic" default="yes"/> </cd:parameter> + <cd:parameter name="fraction"> + <cd:constant type="ams"/> + <cd:constant type="ctx" default="yes"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> - <cd:command name="inlineordisplaymath" file="math-ini.mkiv"> + <cd:command name="inlineordisplaymath" category="mathematics" file="math-ini.mkiv"> <cd:arguments> <cd:content/> <cd:content/> </cd:arguments> </cd:command> - <cd:command name="mathematics" file="math-ini.mkiv"> + <cd:command name="mathematics" category="mathematics" file="math-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:content/> </cd:arguments> </cd:command> - <cd:command name="math" file="math-ini.mkiv"> + <cd:command name="math" category="mathematics" file="math-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:content/> </cd:arguments> </cd:command> - <cd:command name="m" file="math-ini.mkiv"> + <cd:command name="m" category="mathematics" file="math-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:content/> </cd:arguments> </cd:command> - <cd:command name="definemathcommand" file="math-ini.mkiv"> + <cd:command name="definemathcommand" category="mathematics" file="math-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:keywords optional="yes"> @@ -157,7 +164,7 @@ </cd:arguments> </cd:command> - <cd:command name="mathcommand" generated="yes" variant="generated" file="math-ini.mkiv"> + <cd:command name="mathcommand" generated="yes" variant="example" file="math-ini.mkiv"> <cd:sequence> <cd:variable value="mathcommand"/> </cd:sequence> @@ -191,13 +198,13 @@ </cd:arguments> </cd:command> - <cd:command name="mathfunction" file="math-ini.mkiv"> + <cd:command name="mathfunction" category="mathematics" file="math-ini.mkiv"> <cd:arguments> <cd:content/> </cd:arguments> </cd:command> - <cd:command name="mfunction" file="math-ini.mkiv"> + <cd:command name="mfunction" category="mathematics" file="math-ini.mkiv"> <cd:arguments> <cd:content/> </cd:arguments> @@ -275,84 +282,98 @@ <cd:command name="mathtext" file="math-ini.mkiv"> <cd:arguments> + <cd:resolve name="string-boxoptions"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> <cd:command name="mathtexttf" file="math-ini.mkiv"> <cd:arguments> + <cd:resolve name="string-boxoptions"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> <cd:command name="mathtextit" file="math-ini.mkiv"> <cd:arguments> + <cd:resolve name="string-boxoptions"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> <cd:command name="mathtextsl" file="math-ini.mkiv"> <cd:arguments> + <cd:resolve name="string-boxoptions"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> <cd:command name="mathtextbf" file="math-ini.mkiv"> <cd:arguments> + <cd:resolve name="string-boxoptions"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> <cd:command name="mathtextbi" file="math-ini.mkiv"> <cd:arguments> + <cd:resolve name="string-boxoptions"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> <cd:command name="mathtextbs" file="math-ini.mkiv"> <cd:arguments> + <cd:resolve name="string-boxoptions"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> <cd:command name="mathword" file="math-ini.mkiv"> <cd:arguments> + <cd:resolve name="string-boxoptions"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> <cd:command name="mathwordtf" file="math-ini.mkiv"> <cd:arguments> + <cd:resolve name="string-boxoptions"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> <cd:command name="mathwordit" file="math-ini.mkiv"> <cd:arguments> + <cd:resolve name="string-boxoptions"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> <cd:command name="mathwordsl" file="math-ini.mkiv"> <cd:arguments> + <cd:resolve name="string-boxoptions"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> <cd:command name="mathwordbf" file="math-ini.mkiv"> <cd:arguments> + <cd:resolve name="string-boxoptions"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> <cd:command name="mathwordbi" file="math-ini.mkiv"> <cd:arguments> + <cd:resolve name="string-boxoptions"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> <cd:command name="mathwordbs" file="math-ini.mkiv"> <cd:arguments> + <cd:resolve name="string-boxoptions"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> diff --git a/tex/context/interface/mkiv/i-mathalignment.xml b/tex/context/interface/mkiv/i-mathalignment.xml index cc0ff6fa7..5caa1348c 100644 --- a/tex/context/interface/mkiv/i-mathalignment.xml +++ b/tex/context/interface/mkiv/i-mathalignment.xml @@ -37,31 +37,38 @@ </cd:arguments> </cd:command> - <cd:command name="mathalignment" type="environment" generated="yes" variant="generated" file="math-ali.mkiv"> + <cd:command name="mathalignment" type="environment" generated="yes" variant="instance" file="math-ali.mkiv"> <cd:sequence> - <cd:variable value="mathalignment"/> + <cd:instance value="mathalignment"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupmathalignment"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-mathalignment"/> + </cd:instances> </cd:command> - <cd:command name="mathalignment" type="environment" file="math-ali.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmathalignment"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="align" type="environment" file="math-ali.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmathalignment"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="mathalignment" type="environment" file="math-ali.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathalignment"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="align" type="environment" file="math-ali.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathalignment"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> </cd:interface> diff --git a/tex/context/interface/mkiv/i-mathcases.xml b/tex/context/interface/mkiv/i-mathcases.xml index 9744fa9e5..8a27c4413 100644 --- a/tex/context/interface/mkiv/i-mathcases.xml +++ b/tex/context/interface/mkiv/i-mathcases.xml @@ -41,31 +41,38 @@ </cd:arguments> </cd:command> - <cd:command name="mathcases" type="environment" generated="yes" variant="generated" file="math-ali.mkiv"> + <cd:command name="mathcases" type="environment" generated="yes" variant="instance" file="math-ali.mkiv"> <cd:sequence> - <cd:variable value="mathcases"/> + <cd:instance value="mathcases"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupmathcases"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-mathcases"/> + </cd:instances> </cd:command> - <cd:command name="mathcases" type="environment" file="math-ali.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmathcases"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="cases" type="environment" file="math-ali.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmathcases"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="mathcases" type="environment" file="math-ali.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathcases"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="cases" type="environment" file="math-ali.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathcases"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> </cd:interface> diff --git a/tex/context/interface/mkiv/i-mathfence.xml b/tex/context/interface/mkiv/i-mathfence.xml index b23f8558e..9676e2a37 100644 --- a/tex/context/interface/mkiv/i-mathfence.xml +++ b/tex/context/interface/mkiv/i-mathfence.xml @@ -40,11 +40,16 @@ <cd:parameter name="state"> <cd:constant type="auto"/> </cd:parameter> + <cd:parameter name="factor"> + <cd:constant type="auto" default="yes"/> + <cd:constant type="none"/> + <cd:constant type="number"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> - <cd:command name="fence" generated="yes" variant="generated" file="math-fen.mkiv"> + <cd:command name="fence" generated="yes" variant="example" file="math-fen.mkiv"> <cd:sequence> <cd:variable value="fence"/> </cd:sequence> @@ -196,4 +201,4 @@ <cd:command name="checkedfences" type="environment" file="math-fen.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-mathmatrix.xml b/tex/context/interface/mkiv/i-mathmatrix.xml index a934d2b31..50f99205a 100644 --- a/tex/context/interface/mkiv/i-mathmatrix.xml +++ b/tex/context/interface/mkiv/i-mathmatrix.xml @@ -53,32 +53,39 @@ </cd:arguments> </cd:command> - <cd:command name="mathmatrix" type="environment" generated="yes" variant="generated" file="math-ali.mkiv"> + <cd:command name="mathmatrix" type="environment" generated="yes" variant="instance" file="math-ali.mkiv"> <cd:sequence> - <cd:variable value="mathmatrix"/> + <cd:instance value="mathmatrix"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupmathmatrix"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-mathmatrix"/> + </cd:instances> </cd:command> - <cd:command name="mathmatrix" type="environment" file="math-ali.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmathmatrix"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="matrix" type="environment" file="math-ali.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmathmatrix"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="mathmatrix" type="environment" file="math-ali.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathmatrix"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="matrix" type="environment" file="math-ali.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmathmatrix"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> <cd:command name="matrices" type="environment" file="math-ali.mkiv"> <cd:arguments> @@ -112,4 +119,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-mathornament.xml b/tex/context/interface/mkiv/i-mathornament.xml index 6009b7921..cfa7b0d18 100644 --- a/tex/context/interface/mkiv/i-mathornament.xml +++ b/tex/context/interface/mkiv/i-mathornament.xml @@ -34,7 +34,7 @@ </cd:arguments> </cd:command> - <cd:command name="mathornament" generated="yes" variant="generated" file="math-rad.mkvi"> + <cd:command name="mathornament" generated="yes" variant="example" file="math-rad.mkvi"> <cd:sequence> <cd:variable value="mathornament"/> </cd:sequence> @@ -43,4 +43,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-mathradical.xml b/tex/context/interface/mkiv/i-mathradical.xml index cedbb4200..e3ab9a6aa 100644 --- a/tex/context/interface/mkiv/i-mathradical.xml +++ b/tex/context/interface/mkiv/i-mathradical.xml @@ -36,7 +36,7 @@ </cd:arguments> </cd:command> - <cd:command name="mathradical" generated="yes" variant="generated" file="math-rad.mkvi"> + <cd:command name="mathradical" generated="yes" variant="example" file="math-rad.mkvi"> <cd:sequence> <cd:variable value="mathradical"/> </cd:sequence> @@ -53,4 +53,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-mathstackers.xml b/tex/context/interface/mkiv/i-mathstackers.xml index 37b5737ff..ef8d9d5e3 100644 --- a/tex/context/interface/mkiv/i-mathstackers.xml +++ b/tex/context/interface/mkiv/i-mathstackers.xml @@ -120,7 +120,7 @@ </cd:arguments> </cd:command> - <cd:command name="mathextensible" generated="yes" variant="generated" file="math-stc.mkvi"> + <cd:command name="mathextensible" generated="yes" variant="example" file="math-stc.mkvi"> <cd:sequence> <cd:variable value="mathextensible"/> </cd:sequence> @@ -147,7 +147,7 @@ </cd:arguments> </cd:command> - <cd:command name="mathoverextensible" generated="yes" variant="generated" file="math-stc.mkvi"> + <cd:command name="mathoverextensible" generated="yes" variant="example" file="math-stc.mkvi"> <cd:sequence> <cd:variable value="mathoverextensible"/> </cd:sequence> @@ -167,7 +167,7 @@ </cd:arguments> </cd:command> - <cd:command name="mathunderextensible" generated="yes" variant="generated" file="math-stc.mkvi"> + <cd:command name="mathunderextensible" generated="yes" variant="example" file="math-stc.mkvi"> <cd:sequence> <cd:variable value="mathunderextensible"/> </cd:sequence> @@ -188,7 +188,7 @@ </cd:arguments> </cd:command> - <cd:command name="mathdoubleextensible" generated="yes" variant="generated" file="math-stc.mkvi"> + <cd:command name="mathdoubleextensible" generated="yes" variant="example" file="math-stc.mkvi"> <cd:sequence> <cd:variable value="mathdoubleextensible"/> </cd:sequence> @@ -207,7 +207,7 @@ </cd:arguments> </cd:command> - <cd:command name="mathovertextextensible" generated="yes" variant="generated" file="math-stc.mkvi"> + <cd:command name="mathovertextextensible" generated="yes" variant="example" file="math-stc.mkvi"> <cd:sequence> <cd:variable value="mathovertextextensible"/> </cd:sequence> @@ -227,7 +227,7 @@ </cd:arguments> </cd:command> - <cd:command name="mathundertextextensible" generated="yes" variant="generated" file="math-stc.mkvi"> + <cd:command name="mathundertextextensible" generated="yes" variant="example" file="math-stc.mkvi"> <cd:sequence> <cd:variable value="mathundertextextensible"/> </cd:sequence> @@ -245,7 +245,7 @@ </cd:arguments> </cd:command> - <cd:command name="mathtriplet" generated="yes" variant="generated" file="math-stc.mkvi"> + <cd:command name="mathtriplet" generated="yes" variant="example" file="math-stc.mkvi"> <cd:sequence> <cd:variable value="mathtriplet"/> </cd:sequence> @@ -1772,7 +1772,7 @@ </cd:arguments> </cd:command> - <cd:command name="mathunstacked" generated="yes" variant="generated" file="math-stc.mkvi"> + <cd:command name="mathunstacked" generated="yes" variant="example" file="math-stc.mkvi"> <cd:sequence> <cd:variable value="mathunstacked"/> </cd:sequence> @@ -1786,4 +1786,4 @@ <cd:command name="iff" file="math-stc.mkvi"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-metapost.xml b/tex/context/interface/mkiv/i-metapost.xml index ca15ebb9d..00250f787 100644 --- a/tex/context/interface/mkiv/i-metapost.xml +++ b/tex/context/interface/mkiv/i-metapost.xml @@ -389,7 +389,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupMPgraphics" file="meta-ini"> + <cd:command name="setupMPgraphics" file="meta-ini.mkiv"> <cd:arguments> <cd:assignments list="yes"> <cd:parameter name="color"> @@ -403,4 +403,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-mixedcolumns.xml b/tex/context/interface/mkiv/i-mixedcolumns.xml index 09e0f3b34..6d0142536 100644 --- a/tex/context/interface/mkiv/i-mixedcolumns.xml +++ b/tex/context/interface/mkiv/i-mixedcolumns.xml @@ -19,7 +19,7 @@ <cd:resolve name="keyword-name-list-optional"/> <cd:assignments list="yes"> <cd:parameter name="grid"> - <cd:inherit name="setupgrid"/> + <cd:inherit name="definegridsnapping"/> </cd:parameter> <cd:parameter name="rulethickness"> <cd:constant type="cd:dimension"/> @@ -105,23 +105,30 @@ </cd:arguments> </cd:command> - <cd:command name="mixedcolumns" type="environment" generated="yes" variant="generated" file="page-mix.mkiv"> + <cd:command name="mixedcolumns" type="environment" generated="yes" variant="instance" file="page-mix.mkiv"> <cd:sequence> - <cd:variable value="mixedcolumns"/> + <cd:instance value="mixedcolumns"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupmixedcolumns"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-mixedcolumns"/> + </cd:instances> </cd:command> - <cd:command name="boxedcolumns" type="environment" file="page-mix.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupmixedcolumns"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <!-- + + <cd:command name="boxedcolumns" type="environment" file="page-mix.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupmixedcolumns"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> </cd:interface> diff --git a/tex/context/interface/mkiv/i-modes.xml b/tex/context/interface/mkiv/i-modes.xml index 8df4c27f6..0a0abc7c7 100644 --- a/tex/context/interface/mkiv/i-modes.xml +++ b/tex/context/interface/mkiv/i-modes.xml @@ -213,4 +213,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-modules.xml b/tex/context/interface/mkiv/i-modules.xml index 9567cb9af..d8eda7fba 100644 --- a/tex/context/interface/mkiv/i-modules.xml +++ b/tex/context/interface/mkiv/i-modules.xml @@ -62,13 +62,13 @@ </cd:arguments> </cd:command> - <cd:command name="module" type="environment" variant="1" file="file-mod.mkvi"> + <cd:command name="module" type="environment" file="file-mod.mkvi"> <cd:arguments> <cd:resolve name="keyword-file"/> </cd:arguments> </cd:command> - <cd:command name="module" type="environment" variant="2" file="file-mod.mkvi"> + <cd:command name="module" type="environment" variant="string" file="file-mod.mkvi"> <cd:arguments> <cd:resolve name="string-file"/> </cd:arguments> @@ -123,4 +123,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-narrow.xml b/tex/context/interface/mkiv/i-narrow.xml index 1fa8699e1..25e40fd08 100644 --- a/tex/context/interface/mkiv/i-narrow.xml +++ b/tex/context/interface/mkiv/i-narrow.xml @@ -60,7 +60,7 @@ </cd:arguments> </cd:command> - <cd:command name="narrower" type="environment" generated="yes" variant="generated" file="spac-hor.mkiv"> + <cd:command name="narrower" type="environment" generated="yes" variant="example" file="spac-hor.mkiv"> <cd:sequence> <cd:variable value="narrower"/> </cd:sequence> @@ -77,7 +77,7 @@ </cd:arguments> </cd:command> - <cd:command name="narrow" type="environment" variant="1" file="spac-hor.mkiv"> + <cd:command name="narrow" type="environment" file="spac-hor.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:assignments list="yes" optional="yes"> @@ -86,7 +86,7 @@ </cd:arguments> </cd:command> - <cd:command name="narrow" type="environment" variant="2" file="spac-hor.mkiv"> + <cd:command name="narrow" type="environment" variant="name" file="spac-hor.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:keywords list="yes" optional="yes"> @@ -101,7 +101,7 @@ </cd:arguments> </cd:command> - <cd:command name="narrow" type="environment" variant="3" file="spac-hor.mkiv"> + <cd:command name="narrow" type="environment" variant="assignment" file="spac-hor.mkiv"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupnarrower"/> @@ -118,4 +118,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-naturaltable.xml b/tex/context/interface/mkiv/i-naturaltable.xml index d7ba1aac8..e18be1b79 100644 --- a/tex/context/interface/mkiv/i-naturaltable.xml +++ b/tex/context/interface/mkiv/i-naturaltable.xml @@ -105,6 +105,8 @@ </cd:parameter> <cd:parameter name="alignmentcharacter"> <cd:constant type="cd:text"/> + <cd:constant type="cd:text" prefix="number" method="apply"/> + <cd:constant type="cd:text" prefix="text" method="apply"/> </cd:parameter> <cd:parameter name="distance"> <cd:constant type="cd:dimension"/> @@ -113,6 +115,7 @@ <cd:constant type="cd:color"/> </cd:parameter> <cd:parameter name="style"> + <cd:constant type="math"/> <cd:resolve name="value-style"/> </cd:parameter> <cd:inherit name="setupframed"/> diff --git a/tex/context/interface/mkiv/i-note.xml b/tex/context/interface/mkiv/i-note.xml index be74ca3a6..a7ecb5401 100644 --- a/tex/context/interface/mkiv/i-note.xml +++ b/tex/context/interface/mkiv/i-note.xml @@ -156,6 +156,9 @@ <cd:constant type="no" default="yes"/> <cd:constant type="xml"/> </cd:parameter> + <cd:parameter name="referenceprefix"> + <cd:resolve name="value-referenceprefix"/> + </cd:parameter> <cd:parameter name="sample"> <cd:constant type="cd:text"/> </cd:parameter> @@ -180,54 +183,62 @@ </cd:arguments> </cd:command> - <!-- - - <cd:command name="setupnotations" file="strc-not.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-name-list-optional"/> - <cd:assignments list="yes"> - <cd:inherit name="setupnotation"/> - </cd:assignments> - </cd:arguments> - </cd:command> - - --> + <cd:command name="setupnotations" file="strc-not.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:assignments list="yes"> + <cd:inherit name="setupnotation"/> + </cd:assignments> + </cd:arguments> + </cd:command> - <cd:command name="note" type="environment" generated="yes" variant="generated:1" file="strc-not.mkvi"> + <cd:command name="note" type="environment" generated="yes" variant="instance:assignment" file="strc-not.mkvi"> <cd:sequence> - <cd:variable value="note"/> + <cd:instance value="note"/> </cd:sequence> <cd:arguments> <cd:resolve name="assignment-constructiondata-list-optional"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-note"/> + </cd:instances> </cd:command> - <cd:command name="note" type="environment" generated="yes" variant="generated:2" file="strc-not.mkvi"> + <cd:command name="note" type="environment" generated="yes" variant="instance" file="strc-not.mkvi"> <cd:sequence> - <cd:variable value="note"/> + <cd:instance value="note"/> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-reference-list-optional"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-note"/> + </cd:instances> </cd:command> - <cd:command name="note" generated="yes" variant="generated:1" file="strc-not.mkvi"> + <cd:command name="note" generated="yes" variant="instance" file="strc-not.mkvi"> <cd:sequence> - <cd:variable value="note"/> + <cd:instance value="note"/> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-reference-list-optional"/> <cd:resolve name="argument-text"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-note"/> + </cd:instances> </cd:command> - <cd:command name="note" generated="yes" variant="generated:2" file="strc-not.mkvi"> + <cd:command name="note" generated="yes" variant="instance:assignment" file="strc-not.mkvi"> <cd:sequence> - <cd:variable value="note"/> + <cd:instance value="note"/> </cd:sequence> <cd:arguments> <cd:resolve name="assignment-constructiondata-list"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-note"/> + </cd:instances> </cd:command> <cd:command name="definenote" file="strc-not.mkvi"> @@ -330,7 +341,7 @@ <cd:constant type="cd:command"/> </cd:parameter> <cd:parameter name="after"> - <cd:constant type="cd.command"/> + <cd:constant type="cd:command"/> </cd:parameter> <cd:parameter name="inbetween"> <cd:constant type="cd:command"/> @@ -375,20 +386,16 @@ </cd:arguments> </cd:command> - <!-- - - <cd:command name="setupnotes" file="strc-not.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-name-list-optional"/> - <cd:assignments list="yes"> - <cd:inherit name="setupnote"/> - </cd:assignments> - </cd:arguments> - </cd:command> - - --> + <cd:command name="setupnotes" file="strc-not.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:assignments list="yes"> + <cd:inherit name="setupnote"/> + </cd:assignments> + </cd:arguments> + </cd:command> - <cd:command name="setnote" variant="1" file="strc-not.mkvi"> + <cd:command name="setnote" file="strc-not.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="keyword-reference-list-optional"/> @@ -396,14 +403,14 @@ </cd:arguments> </cd:command> - <cd:command name="setnote" variant="2" file="strc-not.mkvi"> + <cd:command name="setnote" variant="assignment" file="strc-not.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="assignment-constructiondata-list"/> </cd:arguments> </cd:command> - <cd:command name="setnotetext" variant="1" file="strc-not.mkvi"> + <cd:command name="setnotetext" file="strc-not.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="keyword-reference-list-optional"/> @@ -411,7 +418,7 @@ </cd:arguments> </cd:command> - <cd:command name="setnotetext" variant="2" file="strc-not.mkvi"> + <cd:command name="setnotetext" variant="assignment" file="strc-not.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="assignment-constructiondata-list"/> @@ -483,39 +490,43 @@ </cd:arguments> </cd:command> - <cd:command name="footnote" type="environment" variant="1" file="strc-not.mkvi"> - <cd:arguments> - <cd:resolve name="assignment-constructiondata-list-optional"/> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="footnote" type="environment" variant="2" file="strc-not.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="footnote" type="environment" variant="assignment" file="strc-not.mkvi"> + <cd:arguments> + <cd:resolve name="assignment-constructiondata-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="footnote" variant="1" file="strc-not.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="footnote" type="environment" file="strc-not.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="footnote" variant="2" file="strc-not.mkvi"> - <cd:arguments> - <cd:resolve name="assignment-constructiondata-list"/> - </cd:arguments> - </cd:command> + <cd:command name="footnote" file="strc-not.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="footnote" variant="assignment" file="strc-not.mkvi"> + <cd:arguments> + <cd:resolve name="assignment-constructiondata-list"/> + </cd:arguments> + </cd:command> + + --> - <cd:command name="footnotetext" variant="1" file="strc-not.mkvi"> + <cd:command name="footnotetext" file="strc-not.mkvi"> <cd:arguments> <cd:resolve name="keyword-reference-list-optional"/> <cd:resolve name="argument-text"/> </cd:arguments> </cd:command> - <cd:command name="footnotetext" variant="2" file="strc-not.mkvi"> + <cd:command name="footnotetext" variant="assignment" file="strc-not.mkvi"> <cd:arguments> <cd:resolve name="assignment-constructiondata-list"/> </cd:arguments> @@ -539,30 +550,34 @@ </cd:arguments> </cd:command> - <cd:command name="endnote" type="environment" variant="1" file="strc-not.mkvi"> - <cd:arguments> - <cd:resolve name="assignment-constructiondata-list-optional"/> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="endnote" type="environment" variant="2" file="strc-not.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="endnote" type="environment" variant="assignment" file="strc-not.mkvi"> + <cd:arguments> + <cd:resolve name="assignment-constructiondata-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="endnote" variant="1" file="strc-not.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="endnote" type="environment" file="strc-not.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="endnote" variant="2" file="strc-not.mkvi"> - <cd:arguments> - <cd:resolve name="assignment-constructiondata-list"/> - </cd:arguments> - </cd:command> + <cd:command name="endnote" file="strc-not.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="endnote" variant="assignment" file="strc-not.mkvi"> + <cd:arguments> + <cd:resolve name="assignment-constructiondata-list"/> + </cd:arguments> + </cd:command> + + --> <cd:command name="definelinenote" file="strc-lnt.mkvi"> <cd:arguments> @@ -598,34 +613,43 @@ </cd:arguments> </cd:command> - <cd:command name="linenote" generated="yes" variant="generated" file="strc-lnt.mkvi"> + <cd:command name="linenote" generated="yes" variant="instance" file="strc-lnt.mkvi"> <cd:sequence> - <cd:variable value="linenote"/> + <cd:instance value="linenote"/> </cd:sequence> <cd:arguments> <cd:resolve name="argument-text"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-linenote"/> + </cd:instances> </cd:command> - <cd:command name="startlinenote" generated="yes" variant="generated" file="strc-lnt.mkvi"> + <cd:command name="startlinenote" generated="yes" variant="instance" file="strc-lnt.mkvi"> <cd:sequence> <cd:string value="start"/> - <cd:variable value="linenote"/> + <cd:instance value="linenote"/> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-reference"/> <cd:resolve name="argument-text"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-linenote"/> + </cd:instances> </cd:command> - <cd:command name="stoplinenote" generated="yes" variant="generated" file="strc-lnt.mkvi"> + <cd:command name="stoplinenote" generated="yes" variant="instance" file="strc-lnt.mkvi"> <cd:sequence> <cd:string value="stop"/> - <cd:variable value="linenote"/> + <cd:instance value="linenote"/> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-reference"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-linenote"/> + </cd:instances> </cd:command> <cd:command name="fromlinenote" file="strc-lnt.mkvi"> @@ -641,23 +665,27 @@ </cd:arguments> </cd:command> - <cd:command name="linenote" file="strc-lnt.mkvi"> - <cd:arguments> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="startlinenote" file="strc-lnt.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="linenote" file="strc-lnt.mkvi"> + <cd:arguments> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> - <cd:command name="stoplinenote" file="strc-lnt.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-reference"/> - </cd:arguments> - </cd:command> + <cd:command name="startlinenote" file="strc-lnt.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="stoplinenote" file="strc-lnt.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-reference"/> + </cd:arguments> + </cd:command> + + --> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-object.xml b/tex/context/interface/mkiv/i-object.xml index 804d17af8..6e105b377 100644 --- a/tex/context/interface/mkiv/i-object.xml +++ b/tex/context/interface/mkiv/i-object.xml @@ -129,4 +129,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-offset.xml b/tex/context/interface/mkiv/i-offset.xml index 8e68a3bef..fc759673d 100644 --- a/tex/context/interface/mkiv/i-offset.xml +++ b/tex/context/interface/mkiv/i-offset.xml @@ -71,4 +71,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-ornament.xml b/tex/context/interface/mkiv/i-ornament.xml index 8ad0b7cfb..f4ae43a6d 100644 --- a/tex/context/interface/mkiv/i-ornament.xml +++ b/tex/context/interface/mkiv/i-ornament.xml @@ -4,7 +4,7 @@ <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> - <cd:command name="ornamenttext" variant="1" file="pack-box.mkiv"> + <cd:command name="ornamenttext" variant="collector" file="pack-box.mkiv"> <cd:arguments> <cd:assignments list="yes"> <cd:parameter name="alternative"> @@ -27,7 +27,7 @@ </cd:arguments> </cd:command> - <cd:command name="ornamenttext" variant="2" file="pack-box.mkiv"> + <cd:command name="ornamenttext" variant="layer" file="pack-box.mkiv"> <cd:arguments> <cd:assignments list="yes"> <cd:parameter name="alternative"> @@ -44,7 +44,7 @@ </cd:arguments> </cd:command> - <cd:command name="ornamenttext" variant="3" file="pack-box.mkiv"> + <cd:command name="ornamenttext" variant="direct" file="pack-box.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:resolve name="argument-text"/> @@ -52,7 +52,7 @@ </cd:arguments> </cd:command> - <cd:command name="defineornament" variant="1" file="pack-box.mkiv"> + <cd:command name="defineornament" variant="collector" file="pack-box.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:assignments list="yes"> @@ -74,7 +74,7 @@ </cd:arguments> </cd:command> - <cd:command name="defineornament" variant="2" file="pack-box.mkiv"> + <cd:command name="defineornament" variant="layer" file="pack-box.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:assignments list="yes"> @@ -90,7 +90,7 @@ </cd:arguments> </cd:command> - <cd:command name="ornament" generated="yes" variant="generated" file="pack-box.mkiv"> + <cd:command name="ornament" generated="yes" variant="example" file="pack-box.mkiv"> <cd:sequence> <cd:variable value="ornament"/> </cd:sequence> @@ -100,4 +100,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-output.xml b/tex/context/interface/mkiv/i-output.xml index 1f59284ff..bf719ca6a 100644 --- a/tex/context/interface/mkiv/i-output.xml +++ b/tex/context/interface/mkiv/i-output.xml @@ -14,7 +14,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupoutputroutine" variant="1" file="page-otr.mkvi"> + <cd:command name="setupoutputroutine" file="page-otr.mkvi"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:assignments list="yes"> @@ -25,7 +25,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupoutputroutine" variant="2" file="page-otr.mkvi"> + <cd:command name="setupoutputroutine" variant="name" file="page-otr.mkvi"> <cd:arguments> <cd:resolve name="keyword-name"/> </cd:arguments> @@ -46,4 +46,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-overlay.xml b/tex/context/interface/mkiv/i-overlay.xml index dd2d43363..91e9f4873 100644 --- a/tex/context/interface/mkiv/i-overlay.xml +++ b/tex/context/interface/mkiv/i-overlay.xml @@ -42,4 +42,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-pagebreak.xml b/tex/context/interface/mkiv/i-pagebreak.xml index abc586ea6..917e4a718 100644 --- a/tex/context/interface/mkiv/i-pagebreak.xml +++ b/tex/context/interface/mkiv/i-pagebreak.xml @@ -132,4 +132,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-pagegrid.xml b/tex/context/interface/mkiv/i-pagegrid.xml index 29810d7db..21f906a0c 100644 --- a/tex/context/interface/mkiv/i-pagegrid.xml +++ b/tex/context/interface/mkiv/i-pagegrid.xml @@ -55,7 +55,7 @@ </cd:arguments> </cd:command> - <cd:command name="pagegrid" type="environment" generated="yes" variant="generated" file="page-cst.mkiv"> + <cd:command name="pagegrid" type="environment" generated="yes" variant="example" file="page-cst.mkiv"> <cd:sequence> <cd:variable value="pagegrid"/> </cd:sequence> @@ -217,4 +217,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-pageinjection.xml b/tex/context/interface/mkiv/i-pageinjection.xml index 64becc385..c069dbc8b 100644 --- a/tex/context/interface/mkiv/i-pageinjection.xml +++ b/tex/context/interface/mkiv/i-pageinjection.xml @@ -49,14 +49,14 @@ </cd:arguments> </cd:command> - <cd:command name="pageinjection" variant="1" file="page-inj.mkvi"> + <cd:command name="pageinjection" file="page-inj.mkvi"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:resolve name="assignment-userdata-list-optional"/> </cd:arguments> </cd:command> - <cd:command name="pageinjection" variant="2" file="page-inj.mkvi"> + <cd:command name="pageinjection" variant="assignment" file="page-inj.mkvi"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setuppageinjection"/> diff --git a/tex/context/interface/mkiv/i-pageselection.xml b/tex/context/interface/mkiv/i-pageselection.xml index 45c433269..99d55bb8a 100644 --- a/tex/context/interface/mkiv/i-pageselection.xml +++ b/tex/context/interface/mkiv/i-pageselection.xml @@ -15,6 +15,9 @@ <cd:parameter name="n"> <cd:constant type="cd:number"/> </cd:parameter> + <cd:parameter name="category"> + <cd:constant type="cd:name"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> @@ -35,6 +38,9 @@ <cd:parameter name="n"> <cd:constant type="cd:number"/> </cd:parameter> + <cd:parameter name="category"> + <cd:constant type="cd:name"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> diff --git a/tex/context/interface/mkiv/i-pagestate.xml b/tex/context/interface/mkiv/i-pagestate.xml index 0d6a94811..82396d000 100644 --- a/tex/context/interface/mkiv/i-pagestate.xml +++ b/tex/context/interface/mkiv/i-pagestate.xml @@ -16,7 +16,7 @@ <cd:command name="setuppagestate" file="core-dat.mkiv"> <cd:arguments> - <cd:resolve name="keyword-name-optional-list"/> + <cd:resolve name="keyword-name-list-optional"/> <cd:assignments list="yes"> <cd:parameter name="delay"> <cd:constant type="yes" default="yes"/> diff --git a/tex/context/interface/mkiv/i-pairedbox.xml b/tex/context/interface/mkiv/i-pairedbox.xml index fbf190257..bbab966ba 100644 --- a/tex/context/interface/mkiv/i-pairedbox.xml +++ b/tex/context/interface/mkiv/i-pairedbox.xml @@ -90,22 +90,25 @@ </cd:arguments> </cd:command> - <cd:command name="setuppairedbox" generated="yes" variant="generated" file="pack-com.mkiv"> + <cd:command name="setuppairedbox" generated="yes" variant="instance" file="pack-com.mkiv"> <cd:sequence> <cd:string value="setup"/> - <cd:variable value="pairedbox"/> + <cd:instance value="pairedbox"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes"> <cd:inherit name="setuppairedbox"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-pairedbox"/> + </cd:instances> </cd:command> - <cd:command name="placepairedbox" generated="yes" variant="generated" file="pack-com.mkiv"> + <cd:command name="placepairedbox" generated="yes" variant="instance" file="pack-com.mkiv"> <cd:sequence> <cd:string value="place"/> - <cd:variable value="pairedbox"/> + <cd:instance value="pairedbox"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> @@ -114,45 +117,55 @@ <cd:content/> <cd:resolve name="argument-text"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-pairedbox"/> + </cd:instances> </cd:command> - <cd:command name="placepairedbox" type="environment" generated="yes" variant="generated" file="pack-com.mkiv"> + <cd:command name="placepairedbox" type="environment" generated="yes" variant="instance" file="pack-com.mkiv"> <cd:sequence> <cd:string value="place"/> - <cd:variable value="pairedbox"/> + <cd:instance value="pairedbox"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setuppairedbox"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-pairedbox"/> + </cd:instances> </cd:command> - <cd:command name="setuplegend" file="pack-com.mkiv"> - <cd:arguments> - <cd:assignments list="yes"> - <cd:inherit name="setuppairedbox"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="placelegend" file="pack-com.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setuppairedbox"/> - </cd:assignments> - <cd:content/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="setuplegend" file="pack-com.mkiv"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:inherit name="setuppairedbox"/> + </cd:assignments> + </cd:arguments> + </cd:command> - <cd:command name="placelegend" type="environment" file="pack-com.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setuppairedbox"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="placelegend" file="pack-com.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppairedbox"/> + </cd:assignments> + <cd:content/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="placelegend" type="environment" file="pack-com.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuppairedbox"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> <cd:command name="placeontopofeachother" file="pack-com.mkiv"> <cd:arguments> @@ -168,4 +181,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-papersize.xml b/tex/context/interface/mkiv/i-papersize.xml index 99d6b9d9d..dab5e03bd 100644 --- a/tex/context/interface/mkiv/i-papersize.xml +++ b/tex/context/interface/mkiv/i-papersize.xml @@ -102,7 +102,7 @@ --> - <cd:command name="definepapersize" variant="1" file="page-lay.mkiv"> + <cd:command name="definepapersize" file="page-lay.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:assignments list="yes"> @@ -137,7 +137,7 @@ </cd:arguments> </cd:command> - <cd:command name="definepapersize" variant="2" file="page-lay.mkiv"> + <cd:command name="definepapersize" variant="name" file="page-lay.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:keywords list="yes"> @@ -149,7 +149,7 @@ </cd:arguments> </cd:command> - <cd:command name="setuppapersize" variant="1" file="page-lay.mkiv"> + <cd:command name="setuppapersize" variant="name" file="page-lay.mkiv"> <cd:arguments> <cd:keywords list="yes" optional="yes"> <cd:constant type="reset"/> @@ -178,7 +178,7 @@ <!-- - <cd:command name="setuppapersize" variant="2" file="page-lay.mkiv"> + <cd:command name="setuppapersize" file="page-lay.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:assignments list="yes"> @@ -197,7 +197,7 @@ --> - <cd:command name="setuppapersize" variant="2" file="page-lay.mkiv"> + <cd:command name="setuppapersize" file="page-lay.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:assignments list="yes"> diff --git a/tex/context/interface/mkiv/i-paragraph.xml b/tex/context/interface/mkiv/i-paragraph.xml index 63ddab64f..8a88f72fc 100644 --- a/tex/context/interface/mkiv/i-paragraph.xml +++ b/tex/context/interface/mkiv/i-paragraph.xml @@ -68,4 +68,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-paragraphs.xml b/tex/context/interface/mkiv/i-paragraphs.xml index 6c1dae0db..99092f668 100644 --- a/tex/context/interface/mkiv/i-paragraphs.xml +++ b/tex/context/interface/mkiv/i-paragraphs.xml @@ -14,7 +14,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupparagraphs" variant="1" file="tabl-mis.mkiv"> + <cd:command name="setupparagraphs" file="tabl-mis.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:keywords list="yes" optional="yes"> @@ -76,7 +76,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupparagraphs" variant="2" file="tabl-mis.mkiv"> + <cd:command name="setupparagraphs" variant="assignment" file="tabl-mis.mkiv"> <cd:arguments> <cd:keywords optional="yes"> <cd:constant type="cd:number" prefix="cd:name" method="range"/> @@ -144,19 +144,19 @@ <cd:command name="nextparagraphs" file="tabl-mis.mkiv"/> - <cd:command name="paragraphs" type="environment" generated="yes" variant="generated" file="tabl-mis.mkiv"> + <cd:command name="paragraphs" type="environment" generated="yes" variant="example" file="tabl-mis.mkiv"> <cd:sequence> <cd:variable value="paragraphs"/> </cd:sequence> </cd:command> - <cd:command name="paragraphs" generated="yes" variant="generated" file="tabl-mis.mkiv"> + <cd:command name="paragraphs" generated="yes" variant="example" file="tabl-mis.mkiv"> <cd:sequence> <cd:variable value="paragraphs"/> </cd:sequence> </cd:command> - <cd:command name="nextparagraphs" generated="yes" variant="generated" file="tabl-mis.mkiv"> + <cd:command name="nextparagraphs" generated="yes" variant="example" file="tabl-mis.mkiv"> <cd:sequence> <cd:string value="next"/> <cd:variable value="paragraphs"/> diff --git a/tex/context/interface/mkiv/i-parallel.xml b/tex/context/interface/mkiv/i-parallel.xml index ef2c55f3f..ed1c50c86 100644 --- a/tex/context/interface/mkiv/i-parallel.xml +++ b/tex/context/interface/mkiv/i-parallel.xml @@ -76,10 +76,10 @@ </cd:arguments> </cd:command> - <cd:command name="parallel" type="environment" generated="yes" variant="generated" file="buff-par.mkvi"> + <cd:command name="parallel" type="environment" generated="yes" variant="example" file="buff-par.mkvi"> <cd:sequence> <cd:variable value="parallel"/> </cd:sequence> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-pdf.xml b/tex/context/interface/mkiv/i-pdf.xml index 9d75ddfd3..5b4eab2c3 100644 --- a/tex/context/interface/mkiv/i-pdf.xml +++ b/tex/context/interface/mkiv/i-pdf.xml @@ -128,4 +128,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-penalty.xml b/tex/context/interface/mkiv/i-penalty.xml index 8cadf672b..ee241b9ff 100644 --- a/tex/context/interface/mkiv/i-penalty.xml +++ b/tex/context/interface/mkiv/i-penalty.xml @@ -26,4 +26,4 @@ <cd:command name="setdefaultpenalties" file="spac-ver.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-periods.xml b/tex/context/interface/mkiv/i-periods.xml index e72152c38..9114ae550 100644 --- a/tex/context/interface/mkiv/i-periods.xml +++ b/tex/context/interface/mkiv/i-periods.xml @@ -24,13 +24,13 @@ </cd:arguments> </cd:command> - <cd:command name="periods" variant="1" file="enco-ini.mkiv"> + <cd:command name="periods" file="enco-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-number-optional"/> </cd:arguments> </cd:command> - <cd:command name="periods" variant="2" file="enco-ini.mkiv"> + <cd:command name="periods" variant="assignment" file="enco-ini.mkiv"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupperiods"/> diff --git a/tex/context/interface/mkiv/i-placement.xml b/tex/context/interface/mkiv/i-placement.xml index 4db307957..958ffaa6f 100644 --- a/tex/context/interface/mkiv/i-placement.xml +++ b/tex/context/interface/mkiv/i-placement.xml @@ -60,7 +60,7 @@ </cd:arguments> </cd:command> - <cd:command name="placement" generated="yes" variant="generated" file="pack-mis.mkiv"> + <cd:command name="placement" generated="yes" variant="example" file="pack-mis.mkiv"> <cd:sequence> <cd:variable value="placement"/> </cd:sequence> diff --git a/tex/context/interface/mkiv/i-position.xml b/tex/context/interface/mkiv/i-position.xml index 54bc952dc..e43ee58ef 100644 --- a/tex/context/interface/mkiv/i-position.xml +++ b/tex/context/interface/mkiv/i-position.xml @@ -183,6 +183,12 @@ </cd:arguments> </cd:command> + <cd:command name="MPwhd" file="anch-pos.mkiv"> + <cd:arguments> + <cd:resolve name="argument-name"/> + </cd:arguments> + </cd:command> + <cd:command name="MPxy" file="anch-pos.mkiv"> <cd:arguments> <cd:resolve name="argument-name"/> @@ -525,4 +531,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-positionbar.xml b/tex/context/interface/mkiv/i-positionbar.xml index e6dadf8c5..481540691 100644 --- a/tex/context/interface/mkiv/i-positionbar.xml +++ b/tex/context/interface/mkiv/i-positionbar.xml @@ -70,4 +70,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-processor.xml b/tex/context/interface/mkiv/i-processor.xml index a43037754..0c313c77a 100644 --- a/tex/context/interface/mkiv/i-processor.xml +++ b/tex/context/interface/mkiv/i-processor.xml @@ -48,4 +48,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-profile.xml b/tex/context/interface/mkiv/i-profile.xml index 2df175cdf..a3fe7ea6e 100644 --- a/tex/context/interface/mkiv/i-profile.xml +++ b/tex/context/interface/mkiv/i-profile.xml @@ -97,4 +97,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-publication.xml b/tex/context/interface/mkiv/i-publication.xml index 4d3583e7e..83cb6c2c8 100644 --- a/tex/context/interface/mkiv/i-publication.xml +++ b/tex/context/interface/mkiv/i-publication.xml @@ -32,7 +32,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupbtx" variant="1" file="publ-ini.mkiv"> + <cd:command name="setupbtx" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:assignments list="yes"> @@ -114,7 +114,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupbtx" variant="2" file="publ-ini.mkiv"> + <cd:command name="setupbtx" variant="name" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> </cd:arguments> @@ -370,90 +370,90 @@ </cd:arguments> </cd:command> - <cd:command name="btxhybridcite" variant="1" file="publ-ini.mkiv"> + <cd:command name="btxhybridcite" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="btxhybridcite" variant="2" file="publ-ini.mkiv"> + <cd:command name="btxhybridcite" variant="userdata" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list"/> <cd:resolve name="assignment-userdata-list"/> </cd:arguments> </cd:command> - <cd:command name="btxhybridcite" variant="3" file="publ-ini.mkiv"> + <cd:command name="btxhybridcite" variant="alternative" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-btxalternative-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="btxhybridcite" variant="4" file="publ-ini.mkiv"> + <cd:command name="btxhybridcite" variant="direct" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="argument-reference"/> </cd:arguments> </cd:command> - <cd:command name="btxlistcitation" variant="1" file="publ-ini.mkiv"> + <cd:command name="btxlistcitation" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="btxlistcitation" variant="2" file="publ-ini.mkiv"> + <cd:command name="btxlistcitation" variant="userdata" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list"/> <cd:resolve name="assignment-userdata-list"/> </cd:arguments> </cd:command> - <cd:command name="btxlistcitation" variant="3" file="publ-ini.mkiv"> + <cd:command name="btxlistcitation" variant="alternative" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-btxalternative-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="btxtextcitation" variant="1" file="publ-ini.mkiv"> + <cd:command name="btxtextcitation" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="btxtextcitation" variant="2" file="publ-ini.mkiv"> + <cd:command name="btxtextcitation" variant="userdata" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list"/> <cd:resolve name="assignment-userdata-list"/> </cd:arguments> </cd:command> - <cd:command name="btxtextcitation" variant="3" file="publ-ini.mkiv"> + <cd:command name="btxtextcitation" variant="alternative" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-btxalternative-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="btxalwayscitation" variant="1" file="publ-ini.mkiv"> + <cd:command name="btxalwayscitation" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="btxalwayscitation" variant="2" file="publ-ini.mkiv"> + <cd:command name="btxalwayscitation" variant="userdata" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list"/> <cd:resolve name="assignment-userdata-list"/> </cd:arguments> </cd:command> - <cd:command name="btxalwayscitation" variant="3" file="publ-ini.mkiv"> + <cd:command name="btxalwayscitation" variant="alternative" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-btxalternative-optional"/> <cd:resolve name="keyword-reference"/> @@ -466,126 +466,126 @@ </cd:arguments> </cd:command> - <cd:command name="listcitation" variant="1" file="publ-ini.mkiv"> + <cd:command name="listcitation" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="listcitation" variant="2" file="publ-ini.mkiv"> + <cd:command name="listcitation" variant="userdata" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list"/> <cd:resolve name="assignment-userdata-list"/> </cd:arguments> </cd:command> - <cd:command name="listcitation" variant="3" file="publ-ini.mkiv"> + <cd:command name="listcitation" variant="alternative" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-btxalternative-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="listcite" variant="1" file="publ-ini.mkiv"> + <cd:command name="listcite" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="listcite" variant="2" file="publ-ini.mkiv"> + <cd:command name="listcite" variant="userdata" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list"/> <cd:resolve name="assignment-userdata-list"/> </cd:arguments> </cd:command> - <cd:command name="listcite" variant="3" file="publ-ini.mkiv"> + <cd:command name="listcite" variant="alternative" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-btxalternative-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="textcitation" variant="1" file="publ-ini.mkiv"> + <cd:command name="textcitation" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="textcitation" variant="2" file="publ-ini.mkiv"> + <cd:command name="textcitation" variant="userdata" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list"/> <cd:resolve name="assignment-userdata-list"/> </cd:arguments> </cd:command> - <cd:command name="textcitation" variant="3" file="publ-ini.mkiv"> + <cd:command name="textcitation" variant="alternative" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-btxalternative-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="textcite" variant="1" file="publ-ini.mkiv"> + <cd:command name="textcite" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="textcite" variant="2" file="publ-ini.mkiv"> + <cd:command name="textcite" variant="userdata" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list"/> <cd:resolve name="assignment-userdata-list"/> </cd:arguments> </cd:command> - <cd:command name="textcite" variant="3" file="publ-ini.mkiv"> + <cd:command name="textcite" variant="alternative" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-btxalternative-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="alwayscitation" variant="1" file="publ-ini.mkiv"> + <cd:command name="alwayscitation" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="alwayscitation" variant="2" file="publ-ini.mkiv"> + <cd:command name="alwayscitation" variant="userdata" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list"/> <cd:resolve name="assignment-userdata-list"/> </cd:arguments> </cd:command> - <cd:command name="alwayscitation" variant="3" file="publ-ini.mkiv"> + <cd:command name="alwayscitation" variant="alternative" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-btxalternative-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="alwayscite" variant="1" file="publ-ini.mkiv"> + <cd:command name="alwayscite" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="alwayscite" variant="2" file="publ-ini.mkiv"> + <cd:command name="alwayscite" variant="userdata" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list"/> <cd:resolve name="assignment-userdata-list"/> </cd:arguments> </cd:command> - <cd:command name="alwayscite" variant="3" file="publ-ini.mkiv"> + <cd:command name="alwayscite" variant="alternative" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-btxalternative-optional"/> <cd:resolve name="keyword-reference"/> @@ -604,79 +604,79 @@ </cd:arguments> </cd:command> - <cd:command name="citation" variant="1" file="publ-ini.mkiv"> + <cd:command name="citation" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="citation" variant="2" file="publ-ini.mkiv"> + <cd:command name="citation" variant="userdata" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list"/> <cd:resolve name="assignment-userdata-list"/> </cd:arguments> </cd:command> - <cd:command name="citation" variant="3" file="publ-ini.mkiv"> + <cd:command name="citation" variant="alternative" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-btxalternative-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="citation" variant="4" file="publ-ini.mkiv"> + <cd:command name="citation" variant="direct" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="argument-reference"/> </cd:arguments> </cd:command> - <cd:command name="cite" variant="1" file="publ-ini.mkiv"> + <cd:command name="cite" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="cite" variant="2" file="publ-ini.mkiv"> + <cd:command name="cite" variant="userdata" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="assignment-citedata-list"/> <cd:resolve name="assignment-userdata-list"/> </cd:arguments> </cd:command> - <cd:command name="cite" variant="3" file="publ-ini.mkiv"> + <cd:command name="cite" variant="alternative" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-btxalternative-optional"/> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="cite" variant="4" file="publ-ini.mkiv"> + <cd:command name="cite" variant="direct" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="argument-reference"/> </cd:arguments> </cd:command> - <cd:command name="nocitation" variant="1" file="publ-ini.mkiv"> + <cd:command name="nocitation" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="nocitation" variant="2" file="publ-ini.mkiv"> + <cd:command name="nocitation" variant="direct" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="argument-reference"/> </cd:arguments> </cd:command> - <cd:command name="nocite" variant="1" file="publ-ini.mkiv"> + <cd:command name="nocite" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-reference"/> </cd:arguments> </cd:command> - <cd:command name="nocite" variant="2" file="publ-ini.mkiv"> + <cd:command name="nocite" variant="direct" file="publ-ini.mkiv"> <cd:arguments> <cd:resolve name="argument-reference"/> </cd:arguments> @@ -1024,7 +1024,7 @@ </cd:arguments> </cd:command> - <cd:command name="showbtxdatasetfields" variant="1" file="publ-tra.mkiv"> + <cd:command name="showbtxdatasetfields" file="publ-tra.mkiv"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:parameter name="specification"> @@ -1040,13 +1040,13 @@ </cd:arguments> </cd:command> - <cd:command name="showbtxdatasetfields" variant="2" file="publ-tra.mkiv"> + <cd:command name="showbtxdatasetfields" variant="argument" file="publ-tra.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> </cd:arguments> </cd:command> - <cd:command name="showbtxdatasetcompleteness" variant="1" file="publ-tra.mkiv"> + <cd:command name="showbtxdatasetcompleteness" file="publ-tra.mkiv"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:parameter name="specification"> @@ -1062,13 +1062,13 @@ </cd:arguments> </cd:command> - <cd:command name="showbtxdatasetcompleteness" variant="2" file="publ-tra.mkiv"> + <cd:command name="showbtxdatasetcompleteness" variant="argument" file="publ-tra.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> </cd:arguments> </cd:command> - <cd:command name="showbtxdatasetauthors" variant="1" file="publ-tra.mkiv"> + <cd:command name="showbtxdatasetauthors" file="publ-tra.mkiv"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:parameter name="specification"> @@ -1084,7 +1084,7 @@ </cd:arguments> </cd:command> - <cd:command name="showbtxdatasetauthors" variant="2" file="publ-tra.mkiv"> + <cd:command name="showbtxdatasetauthors" variant="argument" file="publ-tra.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> </cd:arguments> @@ -1096,7 +1096,7 @@ </cd:arguments> </cd:command> - <cd:command name="showbtxfields" variant="1" file="publ-tra.mkiv"> + <cd:command name="showbtxfields" file="publ-tra.mkiv"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:parameter name="rotation"> @@ -1109,7 +1109,7 @@ </cd:arguments> </cd:command> - <cd:command name="showbtxfields" variant="2" file="publ-tra.mkiv"> + <cd:command name="showbtxfields" variant="argument" file="publ-tra.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> </cd:arguments> @@ -1121,4 +1121,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-random.xml b/tex/context/interface/mkiv/i-random.xml index 969cef05f..54dc66c5f 100644 --- a/tex/context/interface/mkiv/i-random.xml +++ b/tex/context/interface/mkiv/i-random.xml @@ -61,4 +61,4 @@ <cd:command name="mprandomnumber" file="supp-ran.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf Binary files differindex 652553799..e08b84165 100644 --- a/tex/context/interface/mkiv/i-readme.pdf +++ b/tex/context/interface/mkiv/i-readme.pdf diff --git a/tex/context/interface/mkiv/i-references.xml b/tex/context/interface/mkiv/i-references.xml index 7b117e4f7..e7a713796 100644 --- a/tex/context/interface/mkiv/i-references.xml +++ b/tex/context/interface/mkiv/i-references.xml @@ -346,7 +346,7 @@ </cd:arguments> </cd:command> - <cd:command name="referenceformat" generated="yes" variant="generated" file="strc-ref.mkvi"> + <cd:command name="referenceformat" generated="yes" variant="example" file="strc-ref.mkvi"> <cd:sequence> <cd:variable value="referenceformat"/> </cd:sequence> @@ -563,4 +563,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-regime.xml b/tex/context/interface/mkiv/i-regime.xml index 6c9e5b356..cd0374023 100644 --- a/tex/context/interface/mkiv/i-regime.xml +++ b/tex/context/interface/mkiv/i-regime.xml @@ -85,4 +85,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-register.xml b/tex/context/interface/mkiv/i-register.xml index 561912f6a..e13b009ea 100644 --- a/tex/context/interface/mkiv/i-register.xml +++ b/tex/context/interface/mkiv/i-register.xml @@ -14,7 +14,7 @@ </cd:arguments> </cd:command> - <cd:command name="setupregister" variant="1" file="strc-reg.mkiv"> + <cd:command name="setupregister" variant="argument" file="strc-reg.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-list-optional"/> <cd:resolve name="keyword-number-list-optional"/> @@ -178,9 +178,10 @@ </cd:arguments> </cd:command> - <cd:command name="setupregister" variant="2" file="strc-reg.mkiv"> + <cd:command name="setupregister" file="strc-reg.mkiv"> <cd:arguments> <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> <cd:constant type="cd:number" prefix="cd:name" method="range"/> </cd:keywords> <cd:assignments list="yes"> @@ -343,34 +344,31 @@ </cd:arguments> </cd:command> - <!-- - - <cd:command name="setupregisters" variant="1" file="strc-reg.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-name-list-optional"/> - <cd:resolve name="keyword-number-list-optional"/> - <cd:assignments list="yes"> - <cd:inherit name="setupregister"/> - </cd:assignments> - </cd:arguments> - </cd:command> - - <cd:command name="setupregisters" variant="2" file="strc-reg.mkiv"> - <cd:arguments> - <cd:keywords optional="yes"> - <cd:constant type="cd:number" prefix="cd:name" method="range"/> - </cd:keywords> - <cd:assignments list="yes"> - <cd:inherit name="setupregister"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="setupregisters" variant="argument" file="strc-reg.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:resolve name="keyword-number-list-optional"/> + <cd:assignments list="yes"> + <cd:inherit name="setupregister"/> + </cd:assignments> + </cd:arguments> + </cd:command> - --> + <cd:command name="setupregisters" file="strc-reg.mkiv"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:name"/> + <cd:constant type="cd:number" prefix="cd:name" method="range"/> + </cd:keywords> + <cd:assignments list="yes"> + <cd:inherit name="setupregister"/> + </cd:assignments> + </cd:arguments> + </cd:command> - <cd:command name="register" generated="yes" variant="generated:1" file="strc-reg.mkiv"> + <cd:command name="register" generated="yes" variant="instance" file="strc-reg.mkiv"> <cd:sequence> - <cd:variable value="register"/> + <cd:instance value="register"/> </cd:sequence> <cd:arguments> <cd:keywords optional="yes"> @@ -379,11 +377,14 @@ </cd:keywords> <cd:index list="yes"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-register"/> + </cd:instances> </cd:command> - <cd:command name="register" generated="yes" variant="generated:2" file="strc-reg.mkiv"> + <cd:command name="register" generated="yes" variant="instance:ownnumber" file="strc-reg.mkiv"> <cd:sequence> - <cd:variable value="register"/> + <cd:instance value="register"/> </cd:sequence> <cd:arguments> <cd:keywords optional="yes"> @@ -393,12 +394,15 @@ <cd:resolve name="argument-text"/> <cd:index list="yes"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-register"/> + </cd:instances> </cd:command> - <cd:command name="seeregister" generated="yes" variant="generated" file="strc-reg.mkiv"> + <cd:command name="seeregister" generated="yes" variant="instance" file="strc-reg.mkiv"> <cd:sequence> <cd:string value="see"/> - <cd:variable value="register"/> + <cd:instance value="register"/> </cd:sequence> <cd:arguments> <cd:keywords optional="yes"> @@ -411,36 +415,45 @@ <cd:constant type="cd:text" prefix="cd:processor" method="apply"/> </cd:keywords> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-register"/> + </cd:instances> </cd:command> - <cd:command name="placeregister" generated="yes" variant="generated" file="strc-reg.mkiv"> + <cd:command name="placeregister" generated="yes" variant="instance" file="strc-reg.mkiv"> <cd:sequence> <cd:string value="place"/> - <cd:variable value="register"/> + <cd:instance value="register"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupregister"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-register"/> + </cd:instances> </cd:command> - <cd:command name="completeregister" generated="yes" variant="generated" file="strc-reg.mkiv"> + <cd:command name="completeregister" generated="yes" variant="instance" file="strc-reg.mkiv"> <cd:sequence> <cd:string value="complete"/> - <cd:variable value="register"/> + <cd:instance value="register"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupregister"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-register"/> + </cd:instances> </cd:command> - <cd:command name="setupregister" generated="yes" variant="generated" file="strc-reg.mkiv"> + <cd:command name="setupregister" generated="yes" variant="instance" file="strc-reg.mkiv"> <cd:sequence> <cd:string value="setup"/> - <cd:variable value="register"/> + <cd:instance value="register"/> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-number-list-optional"/> @@ -448,67 +461,74 @@ <cd:inherit name="setupregister"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-register"/> + </cd:instances> </cd:command> - <cd:command name="index" variant="1" file="strc-reg.mkiv"> - <cd:arguments> - <cd:keywords optional="yes"> - <cd:constant type="cd:text"/> - <cd:constant type="cd:text" prefix="cd:processor" method="apply"/> - </cd:keywords> - <cd:index list="yes"/> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="index" variant="2" file="strc-reg.mkiv"> - <cd:arguments> - <cd:keywords optional="yes"> - <cd:constant type="cd:text"/> - <cd:constant type="cd:text" prefix="cd:processor" method="apply"/> - </cd:keywords> - <cd:resolve name="argument-text"/> - <cd:index list="yes"/> - </cd:arguments> - </cd:command> + <cd:command name="index" file="strc-reg.mkiv"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + <cd:constant type="cd:text" prefix="cd:processor" method="apply"/> + </cd:keywords> + <cd:index list="yes"/> + </cd:arguments> + </cd:command> - <cd:command name="seeindex" file="strc-reg.mkiv"> - <cd:arguments> - <cd:keywords optional="yes"> - <cd:constant type="cd:text"/> - <cd:constant type="cd:text" prefix="cd:processor" method="apply"/> - </cd:keywords> - <cd:index list="yes"/> - <cd:keywords delimiters="braces"> - <cd:constant type="cd:text"/> - <cd:constant type="cd:text" prefix="cd:processor" method="apply"/> - </cd:keywords> - </cd:arguments> - </cd:command> + <cd:command name="index" variant="ownnumber" file="strc-reg.mkiv"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + <cd:constant type="cd:text" prefix="cd:processor" method="apply"/> + </cd:keywords> + <cd:resolve name="argument-text"/> + <cd:index list="yes"/> + </cd:arguments> + </cd:command> - <cd:command name="placeindex" file="strc-reg.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupregister"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="seeindex" file="strc-reg.mkiv"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="cd:text"/> + <cd:constant type="cd:text" prefix="cd:processor" method="apply"/> + </cd:keywords> + <cd:index list="yes"/> + <cd:keywords delimiters="braces"> + <cd:constant type="cd:text"/> + <cd:constant type="cd:text" prefix="cd:processor" method="apply"/> + </cd:keywords> + </cd:arguments> + </cd:command> - <cd:command name="completeindex" file="strc-reg.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupregister"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="placeindex" file="strc-reg.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupregister"/> + </cd:assignments> + </cd:arguments> + </cd:command> - <cd:command name="setupindex" file="strc-reg.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-number-list-optional"/> - <cd:assignments list="yes"> - <cd:inherit name="setupregister"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="completeindex" file="strc-reg.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupregister"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setupindex" file="strc-reg.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-number-list-optional"/> + <cd:assignments list="yes"> + <cd:inherit name="setupregister"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> <cd:command name="startregister" file="strc-reg.mkiv"> <cd:arguments> @@ -643,4 +663,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-rotatation.xml b/tex/context/interface/mkiv/i-rotatation.xml index 95a5815e9..3e8eb6699 100644 --- a/tex/context/interface/mkiv/i-rotatation.xml +++ b/tex/context/interface/mkiv/i-rotatation.xml @@ -51,4 +51,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-ruby.xml b/tex/context/interface/mkiv/i-ruby.xml new file mode 100644 index 000000000..698e4f24f --- /dev/null +++ b/tex/context/interface/mkiv/i-ruby.xml @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?context-directive job ctxfile x-setups.ctx ?> + +<cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> + + <cd:command name="defineruby" file="typo-rub.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupruby"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setupruby" file="typo-rub.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="location"> + <cd:constant type="top" default="yes"/> + <cd:constant type="left"/> + <cd:constant type="right"/> + </cd:parameter> + <cd:parameter name="align"> + <cd:constant type="auto"/> + <cd:constant type="flushleft"/> + <cd:constant type="middle" default="yes"/> + <cd:constant type="flushright"/> + </cd:parameter> + <cd:parameter name="stretch"> + <cd:constant type="yes"/> + <cd:constant type="no" default="yes"/> + </cd:parameter> + <cd:parameter name="hoffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="voffset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="none"/> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="left"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="right"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:resolve name="value-style"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="ruby" file="typo-rub.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:resolve name="argument-text"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="ruby" type="environment" file="typo-rub.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name"/> + </cd:arguments> + </cd:command> + +</cd:interface> diff --git a/tex/context/interface/mkiv/i-scite.xml b/tex/context/interface/mkiv/i-scite.xml new file mode 100644 index 000000000..e62bc9067 --- /dev/null +++ b/tex/context/interface/mkiv/i-scite.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?context-directive job ctxfile x-setups.ctx ?> + +<cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> + + <cd:command name="scite" type="environment" file="m-scite.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-scite-optional"/> + </cd:arguments> + </cd:command> + + <cd:command name="scitefile" file="m-scite.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-file"/> + </cd:arguments> + </cd:command> + + <cd:command name="scitebuffer" file="m-scite.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-scite-optional"/> + <cd:resolve name="keyword-buffer"/> + </cd:arguments> + </cd:command> + +</cd:interface>
\ No newline at end of file diff --git a/tex/context/interface/mkiv/i-script.xml b/tex/context/interface/mkiv/i-script.xml index f1aee232a..10ae6a79e 100644 --- a/tex/context/interface/mkiv/i-script.xml +++ b/tex/context/interface/mkiv/i-script.xml @@ -36,18 +36,14 @@ </cd:arguments> </cd:command> - <!-- - - <cd:command name="setupscripts" file="scrp-ini.mkvi"> - <cd:arguments> - <cd:resolve name="keyword-name-list-optional"/> - <cd:assignments list="yes"> - <cd:inherit name="setupscript"/> - </cd:assignments> - </cd:arguments> - </cd:command> - - --> + <cd:command name="setupscripts" file="scrp-ini.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:assignments list="yes"> + <cd:inherit name="setupscript"/> + </cd:assignments> + </cd:arguments> + </cd:command> <cd:command name="setscript" file="scrp-ini.mkvi"> <cd:arguments> @@ -79,28 +75,31 @@ </cd:arguments> </cd:command> - <cd:command name="script" generated="yes" varianet="generated" file="scrp-ini.mkvi"> + <cd:command name="script" generated="yes" varianet="instance" file="scrp-ini.mkvi"> <cd:sequence> - <cd:variable value="script"/> + <cd:instance value="script"/> </cd:sequence> + <cd:instances> + <cd:resolve name="instance-script"/> + </cd:instances> </cd:command> - <cd:command name="hangul" file="scrp-ini.mkvi"/> + <!-- - <cd:command name="hanzi" file="scrp-ini.mkvi"/> + <cd:command name="hangul" file="scrp-ini.mkvi"/> - <cd:command name="nihongo" file="scrp-ini.mkvi"/> + <cd:command name="hanzi" file="scrp-ini.mkvi"/> - <cd:command name="ethiopic" file="scrp-ini.mkvi"/> + <cd:command name="nihongo" file="scrp-ini.mkvi"/> - <cd:command name="thai" file="scrp-ini.mkvi"/> + <cd:command name="ethiopic" file="scrp-ini.mkvi"/> - <cd:command name="latin" file="scrp-ini.mkvi"/> + <cd:command name="thai" file="scrp-ini.mkvi"/> - <!-- + <cd:command name="latin" file="scrp-ini.mkvi"/> <cd:command name="test" file="scrp-ini.mkvi"/> --> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-section.xml b/tex/context/interface/mkiv/i-section.xml index 32b79323d..bcdc836af 100644 --- a/tex/context/interface/mkiv/i-section.xml +++ b/tex/context/interface/mkiv/i-section.xml @@ -125,9 +125,6 @@ <cd:constant type="reset"/> </cd:parameter> <cd:parameter name="header"> - <cd:constant type=""/> - </cd:parameter> - <cd:parameter name="header"> <cd:resolve name="value-textstate"/> </cd:parameter> <cd:parameter name="text"> @@ -200,6 +197,11 @@ <cd:constant type="middle"/> <cd:constant type="bottom"/> <cd:constant type="reverse"/> + <cd:constant type="margintext"/> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="location"> + <!-- optional margin location --> <cd:constant type="cd:name"/> </cd:parameter> <cd:parameter name="width"> @@ -214,6 +216,9 @@ <cd:parameter name="distance"> <cd:constant type="cd:dimension"/> </cd:parameter> + <cd:parameter name="textdistance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> <cd:parameter name="commandbefore"> <cd:constant type="cd:command"/> </cd:parameter> @@ -239,240 +244,252 @@ </cd:arguments> </cd:command> - <!-- - - <cd:command name="setupheads" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-section-list-optional"/> - <cd:assignments list="yes"> - <cd:inherit name="setuphead"/> - </cd:assignments> - </cd:arguments> - </cd:command> - - --> + <cd:command name="setupheads" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-section-list-optional"/> + <cd:assignments list="yes"> + <cd:inherit name="setuphead"/> + </cd:assignments> + </cd:arguments> + </cd:command> - <cd:command name="section" generated="yes" variant="generated:1" file="strc-sec.mkiv"> + <cd:command name="section" generated="yes" variant="instance" file="strc-sec.mkiv"> <cd:sequence> - <cd:variable value="section"/> + <cd:instance value="section"/> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-reference-list-optional"/> <cd:resolve name="argument-text"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-section"/> + </cd:instances> </cd:command> - <cd:command name="section" generated="yes" variant="generated:2" file="strc-sec.mkiv"> + <cd:command name="section" generated="yes" variant="instance:ownnumber" file="strc-sec.mkiv"> <cd:sequence> - <cd:variable value="section"/> + <cd:instance value="section"/> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-reference-list-optional"/> <cd:resolve name="argument-number"/> <cd:resolve name="argument-text"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-section"/> + </cd:instances> </cd:command> - <cd:command name="section" generated="yes" variant="generated:3" file="strc-sec.mkiv"> + <cd:command name="section" generated="yes" variant="instance:assignment" file="strc-sec.mkiv"> <cd:sequence> - <cd:variable value="section"/> + <cd:instance value="section"/> </cd:sequence> <cd:arguments> <cd:resolve name="assignment-sectiondata-list"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-section"/> + </cd:instances> </cd:command> - <cd:command name="section" type="environment" generated="yes" variant="generated" file="strc-sec.mkiv"> + <cd:command name="section" type="environment" generated="yes" variant="instance" file="strc-sec.mkiv"> <cd:sequence> - <cd:variable value="section"/> + <cd:instance value="section"/> </cd:sequence> <cd:arguments> <cd:resolve name="assignment-sectiondata-list-optional"/> <cd:resolve name="assignment-userdata-list-optional"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-section"/> + </cd:instances> </cd:command> - <cd:command name="part" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="chapter" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="part" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> - <cd:command name="section" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="chapter" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> - <cd:command name="subsection" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="section" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> - <cd:command name="subsubsection" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="subsection" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> - <cd:command name="subsubsubsection" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="subsubsection" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> - <cd:command name="subsubsubsubsection" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="subsubsubsection" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> - <cd:command name="title" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="subsubsubsubsection" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> - <cd:command name="subject" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="title" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> - <cd:command name="subsubject" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="subject" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> - <cd:command name="subsubsubject" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="subsubject" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> - <cd:command name="subsubsubsubject" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="subsubsubject" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> - <cd:command name="subsubsubsubsubject" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-reference-list-optional"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="subsubsubsubject" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> - <cd:command name="part" type="environment" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="assignment-sectiondata-list-optional"/> - <cd:resolve name="assignment-userdata-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="subsubsubsubsubject" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> - <cd:command name="chapter" type="environment" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="assignment-sectiondata-list-optional"/> - <cd:resolve name="assignment-userdata-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="part" type="environment" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="assignment-sectiondata-list-optional"/> + <cd:resolve name="assignment-userdata-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="section" type="environment" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="assignment-sectiondata-list-optional"/> - <cd:resolve name="assignment-userdata-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="chapter" type="environment" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="assignment-sectiondata-list-optional"/> + <cd:resolve name="assignment-userdata-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="subsection" type="environment" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="assignment-sectiondata-list-optional"/> - <cd:resolve name="assignment-userdata-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="section" type="environment" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="assignment-sectiondata-list-optional"/> + <cd:resolve name="assignment-userdata-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="subsubsection" type="environment" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="assignment-sectiondata-list-optional"/> - <cd:resolve name="assignment-userdata-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="subsection" type="environment" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="assignment-sectiondata-list-optional"/> + <cd:resolve name="assignment-userdata-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="subsubsubsection" type="environment" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="assignment-sectiondata-list-optional"/> - <cd:resolve name="assignment-userdata-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="subsubsection" type="environment" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="assignment-sectiondata-list-optional"/> + <cd:resolve name="assignment-userdata-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="subsubsubsubsection" type="environment" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="assignment-sectiondata-list-optional"/> - <cd:resolve name="assignment-userdata-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="subsubsubsection" type="environment" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="assignment-sectiondata-list-optional"/> + <cd:resolve name="assignment-userdata-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="title" type="environment" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="assignment-sectiondata-list-optional"/> - <cd:resolve name="assignment-userdata-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="subsubsubsubsection" type="environment" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="assignment-sectiondata-list-optional"/> + <cd:resolve name="assignment-userdata-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="subject" type="environment" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="assignment-sectiondata-list-optional"/> - <cd:resolve name="assignment-userdata-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="title" type="environment" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="assignment-sectiondata-list-optional"/> + <cd:resolve name="assignment-userdata-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="subsubject" type="environment" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="assignment-sectiondata-list-optional"/> - <cd:resolve name="assignment-userdata-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="subject" type="environment" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="assignment-sectiondata-list-optional"/> + <cd:resolve name="assignment-userdata-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="subsubsubject" type="environment" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="assignment-sectiondata-list-optional"/> - <cd:resolve name="assignment-userdata-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="subsubject" type="environment" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="assignment-sectiondata-list-optional"/> + <cd:resolve name="assignment-userdata-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="subsubsubsubject" type="environment" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="assignment-sectiondata-list-optional"/> - <cd:resolve name="assignment-userdata-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="subsubsubject" type="environment" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="assignment-sectiondata-list-optional"/> + <cd:resolve name="assignment-userdata-list-optional"/> + </cd:arguments> + </cd:command> - <cd:command name="subsubsubsubsubject" type="environment" file="strc-sec.mkiv"> - <cd:arguments> - <cd:resolve name="assignment-sectiondata-list-optional"/> - <cd:resolve name="assignment-userdata-list-optional"/> - </cd:arguments> - </cd:command> + <cd:command name="subsubsubsubject" type="environment" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="assignment-sectiondata-list-optional"/> + <cd:resolve name="assignment-userdata-list-optional"/> + </cd:arguments> + </cd:command> + + <cd:command name="subsubsubsubsubject" type="environment" file="strc-sec.mkiv"> + <cd:arguments> + <cd:resolve name="assignment-sectiondata-list-optional"/> + <cd:resolve name="assignment-userdata-list-optional"/> + </cd:arguments> + </cd:command> + + --> <cd:command name="namedsection" type="environment" file="strc-sec.mkiv"> <cd:arguments> @@ -638,6 +655,7 @@ <cd:parameter name="alternative"> <cd:constant type="horizontal"/> <cd:constant type="vertical" default="yes"/> + <cd:constant type="somewhere"/> </cd:parameter> <cd:parameter name="renderingsetup"> <cd:constant type="cd:name"/> @@ -676,4 +694,8 @@ <cd:command name="headnumberdistance" file="strc-ren.mkiv"/> + <cd:command name="headtextdistance" file="strc-ren.mkiv"/> + + <cd:command name="headsetupspacing" file="strc-ren.mkiv"/> + </cd:interface> diff --git a/tex/context/interface/mkiv/i-sectionblock.xml b/tex/context/interface/mkiv/i-sectionblock.xml index fc6d87cff..d6fc97ee0 100644 --- a/tex/context/interface/mkiv/i-sectionblock.xml +++ b/tex/context/interface/mkiv/i-sectionblock.xml @@ -58,9 +58,9 @@ </cd:arguments> </cd:command> - <cd:command name="sectionblock" type="environment" generated="yes" variant="generated" file="strc-sbe.mkiv"> + <cd:command name="sectionblock" type="environment" generated="yes" variant="instance" file="strc-sbe.mkiv"> <cd:sequence> - <cd:variable value="sectionblock"/> + <cd:instance value="sectionblock"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> @@ -70,6 +70,9 @@ <cd:inherit name="setupsectionblock"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-sectionblock"/> + </cd:instances> </cd:command> <cd:command name="sectionblockenvironment" type="environment" file="strc-sbe.mkiv"> @@ -78,48 +81,52 @@ </cd:arguments> </cd:command> - <cd:command name="frontmatter" type="environment" file="strc-sbe.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="bookmark"> - <cd:constant type="cd:text"/> - </cd:parameter> - <cd:inherit name="setupsectionblock"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="bodymatter" type="environment" file="strc-sbe.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="bookmark"> - <cd:constant type="cd:text"/> - </cd:parameter> - <cd:inherit name="setupsectionblock"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="frontmatter" type="environment" file="strc-sbe.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:inherit name="setupsectionblock"/> + </cd:assignments> + </cd:arguments> + </cd:command> - <cd:command name="appendices" type="environment" file="strc-sbe.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="bookmark"> - <cd:constant type="cd:text"/> - </cd:parameter> - <cd:inherit name="setupsectionblock"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="bodymatter" type="environment" file="strc-sbe.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:inherit name="setupsectionblock"/> + </cd:assignments> + </cd:arguments> + </cd:command> - <cd:command name="backmatter" type="environment" file="strc-sbe.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:parameter name="bookmark"> - <cd:constant type="cd:text"/> - </cd:parameter> - <cd:inherit name="setupsectionblock"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="appendices" type="environment" file="strc-sbe.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:inherit name="setupsectionblock"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="backmatter" type="environment" file="strc-sbe.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:parameter name="bookmark"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:inherit name="setupsectionblock"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> </cd:interface> diff --git a/tex/context/interface/mkiv/i-setup.xml b/tex/context/interface/mkiv/i-setup.xml new file mode 100644 index 000000000..4771230eb --- /dev/null +++ b/tex/context/interface/mkiv/i-setup.xml @@ -0,0 +1,145 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?context-directive job ctxfile x-setups.ctx ?> + +<cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> + + <cd:command name="setupsetup" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:assignments list="yes"> + <cd:parameter name="criterium"> + <cd:constant type="current"/> + <cd:constant type="previous"/> + <cd:constant type="local"/> + <cd:constant type="text"/> + <cd:constant type="all" default="yes"/> + <cd:constant type="cd:section"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="basicsetup" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="basicsetup" variant="argument" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="shortsetup" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="shortsetup" variant="argument" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="setup" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="setup" variant="argument" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="showsetup" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="showsetup" variant="argument" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="cmdinternal" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="cmdbasicsetup" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="cmdbasicsetup" variant="argument" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="cmdshortsetup" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="cmdshortsetup" variant="argument" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="cmdfullsetup" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="cmdfullsetup" variant="argument" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="cmdbasicsetupinstance" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="argument-text"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="cmdshortsetupinstance" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="argument-text"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="cmdfullsetupinstance" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="argument-text"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="showdefinition" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="definition" file="x-setups-basics.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-text-list"/> + </cd:arguments> + </cd:command> + +</cd:interface>
\ No newline at end of file diff --git a/tex/context/interface/mkiv/i-setups.xml b/tex/context/interface/mkiv/i-setups.xml index fec773f2e..d6b7b4d5a 100644 --- a/tex/context/interface/mkiv/i-setups.xml +++ b/tex/context/interface/mkiv/i-setups.xml @@ -4,25 +4,25 @@ <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> - <cd:command name="setups" variant="1" file="core-env.mkiv"> + <cd:command name="setups" file="core-env.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-list"/> </cd:arguments> </cd:command> - <cd:command name="setups" variant="2" file="core-env.mkiv"> + <cd:command name="setups" variant="direct" file="core-env.mkiv"> <cd:arguments> <cd:resolve name="argument-name-list"/> </cd:arguments> </cd:command> - <cd:command name="setup" variant="1" file="core-env.mkiv"> + <cd:command name="setup" file="core-env.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> </cd:arguments> </cd:command> - <cd:command name="setup" variant="2" file="core-env.mkiv"> + <cd:command name="setup" variant="direct" file="core-env.mkiv"> <cd:arguments> <cd:resolve name="argument-name"/> </cd:arguments> @@ -146,7 +146,7 @@ </cd:arguments> </cd:command> - <cd:command name="luasetups" type="environment" variant="1" file="core-env.mkiv"> + <cd:command name="luasetups" type="environment" file="core-env.mkiv"> <cd:arguments> <cd:keywords optional="yes"> <cd:constant type="grid"/> @@ -155,13 +155,13 @@ </cd:arguments> </cd:command> - <cd:command name="luasetups" type="environment" variant="2" file="core-env.mkiv"> + <cd:command name="luasetups" type="environment" variant="string" file="core-env.mkiv"> <cd:arguments> <cd:resolve name="string-name"/> </cd:arguments> </cd:command> - <cd:command name="xmlsetups" type="environment" variant="1" file="core-env.mkiv"> + <cd:command name="xmlsetups" type="environment" file="core-env.mkiv"> <cd:arguments> <cd:keywords optional="yes"> <cd:constant type="grid"/> @@ -170,13 +170,13 @@ </cd:arguments> </cd:command> - <cd:command name="xmlsetups" type="environment" variant="2" file="core-env.mkiv"> + <cd:command name="xmlsetups" type="environment" variant="string" file="core-env.mkiv"> <cd:arguments> <cd:resolve name="string-name"/> </cd:arguments> </cd:command> - <cd:command name="rawsetups" type="environment" variant="1" file="core-env.mkiv"> + <cd:command name="rawsetups" type="environment" file="core-env.mkiv"> <cd:arguments> <cd:keywords optional="yes"> <cd:constant type="grid"/> @@ -185,13 +185,13 @@ </cd:arguments> </cd:command> - <cd:command name="rawsetups" type="environment" variant="2" file="core-env.mkiv"> + <cd:command name="rawsetups" type="environment" variant="string" file="core-env.mkiv"> <cd:arguments> <cd:resolve name="string-name"/> </cd:arguments> </cd:command> - <cd:command name="localsetups" type="environment" variant="1" file="core-env.mkiv"> + <cd:command name="localsetups" type="environment" file="core-env.mkiv"> <cd:arguments> <cd:keywords optional="yes"> <cd:constant type="grid"/> @@ -200,13 +200,13 @@ </cd:arguments> </cd:command> - <cd:command name="localsetups" type="environment" variant="2" file="core-env.mkiv"> + <cd:command name="localsetups" type="environment" variant="string" file="core-env.mkiv"> <cd:arguments> <cd:resolve name="string-name"/> </cd:arguments> </cd:command> - <cd:command name="setups" type="environment" variant="1" file="core-env.mkiv"> + <cd:command name="setups" type="environment" file="core-env.mkiv"> <cd:arguments> <cd:keywords optional="yes"> <cd:constant type="grid"/> @@ -215,10 +215,10 @@ </cd:arguments> </cd:command> - <cd:command name="setups" type="environment" variant="2" file="core-env.mkiv"> + <cd:command name="setups" type="environment" variant="string" file="core-env.mkiv"> <cd:arguments> <cd:resolve name="string-name"/> </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-shift.xml b/tex/context/interface/mkiv/i-shift.xml index d9b8bf7e4..792a8d84f 100644 --- a/tex/context/interface/mkiv/i-shift.xml +++ b/tex/context/interface/mkiv/i-shift.xml @@ -55,13 +55,16 @@ </cd:arguments> </cd:command> - <cd:command name="shift" generated="yes" variant="generated" file="node-rul.mkiv"> + <cd:command name="shift" generated="yes" variant="instance" file="node-rul.mkiv"> <cd:sequence> - <cd:variable value="shift"/> + <cd:instance value="shift"/> </cd:sequence> <cd:arguments> <cd:content/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-shift"/> + </cd:instances> </cd:command> <cd:command name="shift" type="environment" file="node-rul.mkiv"> @@ -70,16 +73,20 @@ </cd:arguments> </cd:command> - <cd:command name="shiftup" file="node-rul.mkiv"> - <cd:arguments> - <cd:content/> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="shiftdown" file="node-rul.mkiv"> - <cd:arguments> - <cd:content/> - </cd:arguments> - </cd:command> + <cd:command name="shiftup" file="node-rul.mkiv"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="shiftdown" file="node-rul.mkiv"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + + --> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-sidebar.xml b/tex/context/interface/mkiv/i-sidebar.xml index 8c00ce1ff..25a7ed306 100644 --- a/tex/context/interface/mkiv/i-sidebar.xml +++ b/tex/context/interface/mkiv/i-sidebar.xml @@ -86,13 +86,13 @@ </cd:arguments> </cd:command> - <cd:command name="marginrule" type="environment" variant="1" file="anch-bar.mkiv"> + <cd:command name="marginrule" type="environment" file="anch-bar.mkiv"> <cd:arguments> <cd:resolve name="keyword-number-optional"/> </cd:arguments> </cd:command> - <cd:command name="marginrule" type="environment" variant="2" file="anch-bar.mkiv"> + <cd:command name="marginrule" type="environment" variant="assignment" file="anch-bar.mkiv"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupmarginrule"/> @@ -100,4 +100,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-sort.xml b/tex/context/interface/mkiv/i-sort.xml index 5ecc83f18..a72df624b 100644 --- a/tex/context/interface/mkiv/i-sort.xml +++ b/tex/context/interface/mkiv/i-sort.xml @@ -78,14 +78,17 @@ </cd:arguments> </cd:command> - <cd:command name="sorting" generated="yes" variant="generated" file="strc-syn.mkiv"> + <cd:command name="sorting" generated="yes" variant="instance" file="strc-syn.mkiv"> <cd:sequence> - <cd:variable value="sorting"/> + <cd:instance value="sorting"/> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:content/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-sort"/> + </cd:instances> </cd:command> <cd:command name="definesort" file="strc-syn.mkiv"> @@ -100,28 +103,34 @@ </cd:arguments> </cd:command> - <cd:command name="placelistofsorts" generated="yes" variant="generated" file="strc-syn.mkiv"> + <cd:command name="placelistofsorts" generated="yes" variant="instance" file="strc-syn.mkiv"> <cd:sequence> <cd:string value="placelistof"/> - <cd:variable value="sorts"/> + <cd:instance value="sorts"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupsorting"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-sortlist"/> + </cd:instances> </cd:command> - <cd:command name="completelistofsorts" generated="yes" variant="generated" file="strc-syn.mkiv"> + <cd:command name="completelistofsorts" generated="yes" variant="instance" file="strc-syn.mkiv"> <cd:sequence> <cd:string value="completelistof"/> - <cd:variable value="sorts"/> + <cd:instance value="sorts"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupsorting"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-sortlist"/> + </cd:instances> </cd:command> <cd:command name="doifelsecurrentsortingused" file="strc-syn.mkiv"> @@ -162,27 +171,31 @@ </cd:arguments> </cd:command> - <cd:command name="logo" file="strc-syn.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-name-optional"/> - <cd:content/> - </cd:arguments> - </cd:command> - - <cd:command name="placelistoflogos" file="strc-syn.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupsorting"/> - </cd:assignments> - </cd:arguments> - </cd:command> - - <cd:command name="completelistoflogos" file="strc-syn.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupsorting"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <!-- + + <cd:command name="logo" file="strc-syn.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="placelistoflogos" file="strc-syn.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsorting"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="completelistoflogos" file="strc-syn.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsorting"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> </cd:interface> diff --git a/tex/context/interface/mkiv/i-spreadsheet.xml b/tex/context/interface/mkiv/i-spreadsheet.xml new file mode 100644 index 000000000..9f6273891 --- /dev/null +++ b/tex/context/interface/mkiv/i-spreadsheet.xml @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?context-directive job ctxfile x-setups.ctx ?> + +<cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> + + <cd:command name="definespreadsheet" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupspreadsheet"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setupspreadsheet" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="period"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="comma"> + <cd:constant type="cd:text"/> + </cd:parameter> + <cd:parameter name="split"> + <cd:constant type="yes"/> + <cd:constant type="no" default="yes"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="resetspreadsheet" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + </cd:arguments> + </cd:command> + + <cd:command name="spreadsheet" type="environment" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + </cd:arguments> + </cd:command> + + <cd:command name="showspreadsheet" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name"/> + </cd:arguments> + </cd:command> + + <cd:command name="inspectspreadsheet" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name"/> + </cd:arguments> + </cd:command> + + <cd:command name="setspreadsheet" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:resolve name="argument-number"/> + <cd:resolve name="argument-number"/> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="getspreadsheet" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:resolve name="argument-number"/> + <cd:resolve name="argument-number"/> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="doifelsespreadsheetcell" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:resolve name="argument-number"/> + <cd:resolve name="argument-number"/> + <cd:resolve name="argument-true"/> + <cd:resolve name="argument-false"/> + </cd:arguments> + </cd:command> + + <cd:command name="doifspreadsheetcellelse" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:resolve name="argument-number"/> + <cd:resolve name="argument-number"/> + <cd:resolve name="argument-true"/> + <cd:resolve name="argument-false"/> + </cd:arguments> + </cd:command> + + <cd:command name="TABLEsetspreadsheet" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="TABLEgetspreadsheet" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="setspr" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="getspr" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="spreadsheettable" type="environment" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupTABLE"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="row" type="environment" file="m-spreadsheet.mkiv"/> + + <cd:command name="cell" type="environment" file="m-spreadsheet.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="bTD"/> + </cd:assignments> + </cd:arguments> + </cd:command> + +</cd:interface>
\ No newline at end of file diff --git a/tex/context/interface/mkiv/i-startstop.xml b/tex/context/interface/mkiv/i-startstop.xml index e23485fd6..2a6be1393 100644 --- a/tex/context/interface/mkiv/i-startstop.xml +++ b/tex/context/interface/mkiv/i-startstop.xml @@ -51,7 +51,7 @@ </cd:arguments> </cd:command> - <cd:command name="startstop" type="environment" generated="yes" variant="generated" file="core-sys.mkiv"> + <cd:command name="startstop" type="environment" generated="yes" variant="example" file="core-sys.mkiv"> <cd:sequence> <cd:variable value="startstop"/> </cd:sequence> @@ -66,7 +66,7 @@ </cd:arguments> </cd:command> - <cd:command name="startstop" generated="yes" variant="generated" file="core-sys.mkiv"> + <cd:command name="startstop" generated="yes" variant="example" file="core-sys.mkiv"> <cd:sequence> <cd:variable value="startstop"/> </cd:sequence> diff --git a/tex/context/interface/mkiv/i-steps.xml b/tex/context/interface/mkiv/i-steps.xml new file mode 100644 index 000000000..47a3b45ca --- /dev/null +++ b/tex/context/interface/mkiv/i-steps.xml @@ -0,0 +1,412 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?context-directive job ctxfile x-setups.ctx ?> + +<cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> + + <!-- + + <cd:command name="setupSTEPchart" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="category"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="horizontal" default="yes"/> + <cd:constant type="vertical"/> + <cd:constant type="three"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setupSTEPcharts" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes"> + <cd:inherit name="setupSTEPchart"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> + + <cd:command name="setupSTEPcharts" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="category"> + <cd:constant type="cd:name"/> + </cd:parameter> + <cd:parameter name="before"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="after"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="horizontal" default="yes"/> + <cd:constant type="vertical"/> + <cd:constant type="three"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <!-- + + <cd:command name="setupSTEPcell" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="framecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="backgroundcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:resolve name="value-style"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="dx"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="dy"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setupSTEPcells" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes"> + <cd:inherit name="setupSTEPcell"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> + + <cd:command name="setupSTEPcells" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="framecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="backgroundcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:resolve name="value-style"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="dx"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="dy"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <!-- + + <cd:command name="setupSTEPtext" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="framecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="backgroundcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:resolve name="value-style"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setupSTEPtexts" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes"> + <cd:inherit name="setupSTEPtexts"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> + + <cd:command name="setupSTEPtexts" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="framecolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="backgroundcolor"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="style"> + <cd:resolve name="value-style"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <!-- + + <cd:command name="setupSTEPline" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="setupSTEPlines" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes"> + <cd:inherit name="setupSTEPline"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> + + <cd:command name="setupSTEPlines" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-list-optional"/> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes"> + <cd:parameter name="rulethickness"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="height"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="distance"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="offset"> + <cd:constant type="cd:dimension"/> + </cd:parameter> + <cd:parameter name="color"> + <cd:constant type="cd:color"/> + </cd:parameter> + <cd:parameter name="alternative"> + <cd:constant type="cd:number"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="STEPchart" type="environment" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupSTEPchart"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="STEPtable" type="environment" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupSTEPchart"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="STEPaligntable" type="environment" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupSTEPchart"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="STEPchart" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name"/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupSTEPchart"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="makeSTEPchart" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name"/> + </cd:arguments> + </cd:command> + + <cd:command name="STEPcell" type="environment" file="m-steps.mkvi"/> + + <cd:command name="cells" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:resolve name="argument-text"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="cells" variant="aligntable" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:resolve name="argument-text"/> + <cd:resolve name="argument-text"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="texts" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:resolve name="argument-text"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="cell" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="text" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="toptext" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="bottext" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="topcell" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="botcell" file="m-steps.mkvi"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + +</cd:interface>
\ No newline at end of file diff --git a/tex/context/interface/mkiv/i-stream.xml b/tex/context/interface/mkiv/i-stream.xml index 40ddc89de..97be35774 100644 --- a/tex/context/interface/mkiv/i-stream.xml +++ b/tex/context/interface/mkiv/i-stream.xml @@ -71,4 +71,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-string.xml b/tex/context/interface/mkiv/i-string.xml index b3efe552b..7a7eb1c98 100644 --- a/tex/context/interface/mkiv/i-string.xml +++ b/tex/context/interface/mkiv/i-string.xml @@ -66,4 +66,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-symbol.xml b/tex/context/interface/mkiv/i-symbol.xml index 33d5b4707..7797a3bee 100644 --- a/tex/context/interface/mkiv/i-symbol.xml +++ b/tex/context/interface/mkiv/i-symbol.xml @@ -55,14 +55,14 @@ </cd:arguments> </cd:command> - <cd:command name="symbol" variant="1" file="symb-ini.mkiv"> + <cd:command name="symbol" file="symb-ini.mkiv"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:resolve name="keyword-name"/> </cd:arguments> </cd:command> - <cd:command name="symbol" variant="2" file="symb-ini.mkiv"> + <cd:command name="symbol" variant="direct" file="symb-ini.mkiv"> <cd:arguments> <cd:resolve name="argument-name"/> </cd:arguments> @@ -142,4 +142,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-synonym.xml b/tex/context/interface/mkiv/i-synonym.xml index c64c1c759..6c615b12a 100644 --- a/tex/context/interface/mkiv/i-synonym.xml +++ b/tex/context/interface/mkiv/i-synonym.xml @@ -80,15 +80,18 @@ </cd:arguments> </cd:command> - <cd:command name="synonym" generated="yes" variant="generated" file="strc-syn.mkiv"> + <cd:command name="synonym" generated="yes" variant="instance" file="strc-syn.mkiv"> <cd:sequence> - <cd:variable value="synonym"/> + <cd:instance value="synonym"/> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-name-optional"/> <cd:resolve name="argument-text"/> <cd:content/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-synonym"/> + </cd:instances> </cd:command> <cd:command name="definesynonym" file="strc-syn.mkiv"> @@ -104,28 +107,34 @@ </cd:arguments> </cd:command> - <cd:command name="placelistofsynonyms" generated="yes" variant="generated" file="strc-syn.mkiv"> + <cd:command name="placelistofsynonyms" generated="yes" variant="instance" file="strc-syn.mkiv"> <cd:sequence> <cd:string value="placelistof"/> - <cd:variable value="synonyms"/> + <cd:instance value="synonyms"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupsynonyms"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-synonymlist"/> + </cd:instances> </cd:command> - <cd:command name="completelistofsynonyms" generated="yes" variant="generated" file="strc-syn.mkiv"> + <cd:command name="completelistofsynonyms" generated="yes" variant="instance" file="strc-syn.mkiv"> <cd:sequence> <cd:string value="completelistof"/> - <cd:variable value="synonyms"/> + <cd:instance value="synonyms"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupsynonyms"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-synonymlist"/> + </cd:instances> </cd:command> <cd:command name="registersynonym" file="strc-syn.mkiv"> @@ -179,34 +188,38 @@ </cd:arguments> </cd:command> - <cd:command name="abbreviation" file="strc-syn.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-name-optional"/> - <cd:resolve name="argument-text"/> - <cd:content/> - </cd:arguments> - </cd:command> - <cd:command name="infull" file="strc-syn.mkiv"> <cd:arguments> <cd:resolve name="argument-name"/> </cd:arguments> </cd:command> - <cd:command name="placelistofabbreviations" file="strc-syn.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupsynonyms"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="completelistofabbreviations" file="strc-syn.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setupsynonyms"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="abbreviation" file="strc-syn.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:resolve name="argument-text"/> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="placelistofabbreviations" file="strc-syn.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsynonyms"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="completelistofabbreviations" file="strc-syn.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setupsynonyms"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + --> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-system.xml b/tex/context/interface/mkiv/i-system.xml index e1404754e..aa12bd779 100644 --- a/tex/context/interface/mkiv/i-system.xml +++ b/tex/context/interface/mkiv/i-system.xml @@ -1157,13 +1157,13 @@ </cd:arguments> </cd:command> - <cd:command name="strippedcsname" variant="1" file="syst-aux.mkiv"> + <cd:command name="strippedcsname" file="syst-aux.mkiv"> <cd:arguments> <cd:csname/> </cd:arguments> </cd:command> - <cd:command name="strippedcsname" variant="2" file="syst-aux.mkiv"> + <cd:command name="strippedcsname" variant="string" file="syst-aux.mkiv"> <cd:arguments> <cd:keywords delimiters="none"> <cd:constant type="cd:text"/> @@ -1171,13 +1171,13 @@ </cd:arguments> </cd:command> - <cd:command name="complexorsimple" variant="1" file="syst-aux.mkiv"> + <cd:command name="complexorsimple" file="syst-aux.mkiv"> <cd:arguments> <cd:csname/> </cd:arguments> </cd:command> - <cd:command name="complexorsimple" variant="2" file="syst-aux.mkiv"> + <cd:command name="complexorsimple" variant="argument" file="syst-aux.mkiv"> <cd:arguments> <cd:keywords delimiters="braces"> <cd:constant type="cd:text"/> @@ -1186,13 +1186,13 @@ </cd:arguments> </cd:command> - <cd:command name="complexorsimpleempty" variant="1" file="syst-aux.mkiv"> + <cd:command name="complexorsimpleempty" file="syst-aux.mkiv"> <cd:arguments> <cd:csname/> </cd:arguments> </cd:command> - <cd:command name="complexorsimpleempty" variant="2" file="syst-aux.mkiv"> + <cd:command name="complexorsimpleempty" variant="argument" file="syst-aux.mkiv"> <cd:arguments> <cd:keywords delimiters="braces"> <cd:constant type="cd:text"/> @@ -1201,13 +1201,13 @@ </cd:arguments> </cd:command> - <cd:command name="definecomplexorsimple" variant="1" file="syst-aux.mkiv"> + <cd:command name="definecomplexorsimple" file="syst-aux.mkiv"> <cd:arguments> <cd:csname/> </cd:arguments> </cd:command> - <cd:command name="definecomplexorsimple" variant="2" file="syst-aux.mkiv"> + <cd:command name="definecomplexorsimple" variant="argument" file="syst-aux.mkiv"> <cd:arguments> <cd:keywords delimiters="braces"> <cd:constant type="cd:text"/> @@ -1216,13 +1216,13 @@ </cd:arguments> </cd:command> - <cd:command name="definecomplexorsimpleempty" variant="1" file="syst-aux.mkiv"> + <cd:command name="definecomplexorsimpleempty" file="syst-aux.mkiv"> <cd:arguments> <cd:csname/> </cd:arguments> </cd:command> - <cd:command name="definecomplexorsimpleempty" variant="2" file="syst-aux.mkiv"> + <cd:command name="definecomplexorsimpleempty" variant="argument" file="syst-aux.mkiv"> <cd:arguments> <cd:keywords delimiters="braces"> <cd:constant type="cd:text"/> @@ -1619,13 +1619,13 @@ </cd:arguments> </cd:command> - <cd:command name="increment" variant="1" file="syst-aux.mkiv"> + <cd:command name="increment" file="syst-aux.mkiv"> <cd:arguments> <cd:csname/> </cd:arguments> </cd:command> - <cd:command name="increment" variant="2" file="syst-aux.mkiv"> + <cd:command name="increment" variant="argument" file="syst-aux.mkiv"> <cd:arguments> <cd:keywords delimiters="parentheses" list="yes"> <cd:constant type="cd:csname"/> @@ -1634,28 +1634,13 @@ </cd:arguments> </cd:command> - <cd:command name="increment" variant="1" file="syst-aux.mkiv"> + <cd:command name="decrement" file="syst-aux.mkiv"> <cd:arguments> <cd:csname/> </cd:arguments> </cd:command> - <cd:command name="increment" variant="2" file="syst-aux.mkiv"> - <cd:arguments> - <cd:keywords delimiters="parentheses" list="yes"> - <cd:constant type="cd:csname"/> - <cd:constant type="cd:number"/> - </cd:keywords> - </cd:arguments> - </cd:command> - - <cd:command name="decrement" variant="1" file="syst-aux.mkiv"> - <cd:arguments> - <cd:csname/> - </cd:arguments> - </cd:command> - - <cd:command name="decrement" variant="2" file="syst-aux.mkiv"> + <cd:command name="decrement" variant="argument" file="syst-aux.mkiv"> <cd:arguments> <cd:keywords delimiters="parentheses" list="yes"> <cd:constant type="cd:csname"/> @@ -1682,13 +1667,13 @@ </cd:arguments> </cd:command> - <cd:command name="checkedstrippedcsname" variant="1" file="syst-aux.mkiv"> + <cd:command name="checkedstrippedcsname" file="syst-aux.mkiv"> <cd:arguments> <cd:csname/> </cd:arguments> </cd:command> - <cd:command name="checkedstrippedcsname" variant="2" file="syst-aux.mkiv"> + <cd:command name="checkedstrippedcsname" variant="string" file="syst-aux.mkiv"> <cd:arguments> <cd:resolve name="string-text"/> </cd:arguments> @@ -2259,6 +2244,46 @@ </cd:arguments> </cd:command> + <cd:command name="splitatcolon" file="syst-aux.mkiv"> + <cd:arguments> + <cd:resolve name="string-text"/> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + + <cd:command name="splitatcomma" file="syst-aux.mkiv"> + <cd:arguments> + <cd:resolve name="string-text"/> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + + <cd:command name="splitatasterisk" file="syst-aux.mkiv"> + <cd:arguments> + <cd:resolve name="string-text"/> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + + <cd:command name="splitatcolon" file="syst-aux.mkiv"> + <cd:arguments> + <cd:resolve name="string-text"/> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + + <cd:command name="splitatcolons" file="syst-aux.mkiv"> + <cd:arguments> + <cd:resolve name="string-text"/> + <cd:csname/> + <cd:csname/> + </cd:arguments> + </cd:command> + <cd:command name="removesubstring" file="syst-aux.mkiv"> <cd:arguments> <cd:resolve name="string-text"/> @@ -3531,4 +3556,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-systemlog.xml b/tex/context/interface/mkiv/i-systemlog.xml index 3f2967912..02c4bece9 100644 --- a/tex/context/interface/mkiv/i-systemlog.xml +++ b/tex/context/interface/mkiv/i-systemlog.xml @@ -28,4 +28,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-table.xml b/tex/context/interface/mkiv/i-table.xml index 649b198ae..950a9ff34 100644 --- a/tex/context/interface/mkiv/i-table.xml +++ b/tex/context/interface/mkiv/i-table.xml @@ -4,7 +4,7 @@ <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> - <cd:command name="table" type="environment" variant="1" file="tabl-tab.mkiv"> + <cd:command name="table" type="environment" file="tabl-tab.mkiv"> <cd:arguments> <cd:template/> <cd:assignments list="yes" optional="yes"> @@ -13,7 +13,7 @@ </cd:arguments> </cd:command> - <cd:command name="table" type="environment" variant="2" file="tabl-tab.mkiv"> + <cd:command name="table" type="environment" variant="name" file="tabl-tab.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> <cd:assignments list="yes" optional="yes"> @@ -31,13 +31,13 @@ </cd:arguments> </cd:command> - <cd:command name="tables" type="environment" variant="1" file="tabl-tab.mkiv"> + <cd:command name="tables" type="environment" file="tabl-tab.mkiv"> <cd:arguments> <cd:template/> </cd:arguments> </cd:command> - <cd:command name="tables" type="environment" variant="2" file="tabl-tab.mkiv"> + <cd:command name="tables" type="environment" variant="name" file="tabl-tab.mkiv"> <cd:arguments> <cd:resolve name="keyword-name"/> </cd:arguments> @@ -117,6 +117,9 @@ <cd:constant type="strut"/> <cd:constant type="cd:number"/> </cd:parameter> + <cd:parameter name="openup"> + <cd:constant type="cd:dimension"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> @@ -170,7 +173,7 @@ </cd:arguments> </cd:command> - <cd:command name="Raise" variant="1" scope="table" file="tabl-tab.mkiv"> + <cd:command name="Raise" variant="argument" scope="table" file="tabl-tab.mkiv"> <cd:arguments> <cd:keywords delimiters="parentheses" optional="yes"> <cd:constant type="cd:dimension"/> @@ -179,14 +182,14 @@ </cd:arguments> </cd:command> - <cd:command name="Raise" variant="2" scope="table" file="tabl-tab.mkiv"> + <cd:command name="Raise" variant="string" scope="table" file="tabl-tab.mkiv"> <cd:arguments> <cd:resolve name="string-number-optional"/> <cd:content/> </cd:arguments> </cd:command> - <cd:command name="Lower" variant="1" scope="table" file="tabl-tab.mkiv"> + <cd:command name="Lower" variant="argument" scope="table" file="tabl-tab.mkiv"> <cd:arguments> <cd:keywords delimiters="parentheses" optional="yes"> <cd:constant type="cd:dimension"/> @@ -195,14 +198,14 @@ </cd:arguments> </cd:command> - <cd:command name="Lower" variant="2" scope="table" file="tabl-tab.mkiv"> + <cd:command name="Lower" variant="string" scope="table" file="tabl-tab.mkiv"> <cd:arguments> <cd:resolve name="string-number-optional"/> <cd:content/> </cd:arguments> </cd:command> - <cd:command name="BackSpace" variant="1" scope="table" file="tabl-tab.mkiv"> + <cd:command name="BackSpace" variant="argument" scope="table" file="tabl-tab.mkiv"> <cd:arguments> <cd:keywords delimiters="parentheses" optional="yes"> <cd:constant type="cd:dimension"/> @@ -210,13 +213,13 @@ </cd:arguments> </cd:command> - <cd:command name="BackSpace" variant="2" scope="table" file="tabl-tab.mkiv"> + <cd:command name="BackSpace" variant="string" scope="table" file="tabl-tab.mkiv"> <cd:arguments> <cd:resolve name="string-number-optional"/> </cd:arguments> </cd:command> - <cd:command name="Vspace" variant="1" scope="table" file="tabl-tab.mkiv"> + <cd:command name="Vspace" variant="argument" scope="table" file="tabl-tab.mkiv"> <cd:arguments> <cd:keywords delimiters="parentheses" optional="yes"> <cd:constant type="cd:dimension"/> @@ -224,7 +227,7 @@ </cd:arguments> </cd:command> - <cd:command name="Vspace" variant="2" scope="table" file="tabl-tab.mkiv"> + <cd:command name="Vspace" variant="string" scope="table" file="tabl-tab.mkiv"> <cd:arguments> <cd:resolve name="string-number-optional"/> </cd:arguments> @@ -404,4 +407,4 @@ --> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-tabulation.xml b/tex/context/interface/mkiv/i-tabulation.xml index 1e6dfc1fc..be3a602ac 100644 --- a/tex/context/interface/mkiv/i-tabulation.xml +++ b/tex/context/interface/mkiv/i-tabulation.xml @@ -91,11 +91,15 @@ <cd:parameter name="title"> <cd:constant type="cd:text"/> </cd:parameter> + <cd:parameter name="keeptogether"> + <cd:constant type="yes" default="yes"/> + <cd:constant type="no"/> + </cd:parameter> </cd:assignments> </cd:arguments> </cd:command> - <cd:command name="tabulation" type="environment" generated="yes" variant="generated" file="tabl-tbl.mkiv"> + <cd:command name="tabulation" type="environment" generated="yes" variant="example" file="tabl-tbl.mkiv"> <cd:sequence> <cd:variable value="tabulation"/> </cd:sequence> @@ -134,9 +138,9 @@ </cd:arguments> </cd:command> - <cd:command name="tabulate" type="environment" generated="yes" variant="generated" file="tabl-tbl.mkiv"> + <cd:command name="tabulate" type="environment" generated="yes" variant="instance" file="tabl-tbl.mkiv"> <cd:sequence> - <cd:variable value="tabulate"/> + <cd:instance value="tabulate"/> </cd:sequence> <cd:arguments> <cd:resolve name="keyword-name-optional"/> @@ -144,6 +148,9 @@ <cd:inherit name="setuptabulate"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-tabulate"/> + </cd:instances> </cd:command> <cd:command name="tabulatehead" type="environment" file="tabl-tbl.mkiv"> @@ -166,25 +173,25 @@ <cd:command name="tabulateautoline" file="tabl-tbl.mkiv"/> - <cd:command name="legend" type="environment" file="tabl-tbl.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-name-optional"/> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setuptabulate"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="fact" type="environment" file="tabl-tbl.mkiv"> - <cd:arguments> - <cd:resolve name="keyword-name-optional"/> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setuptabulate"/> - </cd:assignments> - </cd:arguments> - </cd:command> + <cd:command name="legend" type="environment" file="tabl-tbl.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptabulate"/> + </cd:assignments> + </cd:arguments> + </cd:command> - <!-- + <cd:command name="fact" type="environment" file="tabl-tbl.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name-optional"/> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptabulate"/> + </cd:assignments> + </cd:arguments> + </cd:command> <cd:command name="VL" scope="tabulate" file="tabl-tbl.mkiv"> <cd:arguments> diff --git a/tex/context/interface/mkiv/i-tagging.xml b/tex/context/interface/mkiv/i-tagging.xml index 14f413ce3..063a0c436 100644 --- a/tex/context/interface/mkiv/i-tagging.xml +++ b/tex/context/interface/mkiv/i-tagging.xml @@ -25,6 +25,13 @@ </cd:arguments> </cd:command> + <cd:command name="element" type="environment" file="strc-tag.mkiv"> + <cd:arguments> + <cd:resolve name="argument-name"/> + <cd:resolve name="assignment-userdata-list-optional"/> + </cd:arguments> + </cd:command> + <cd:command name="doifelseinelement" file="strc-tag.mkiv"> <cd:arguments> <cd:resolve name="argument-name"/> diff --git a/tex/context/interface/mkiv/i-textbackground.xml b/tex/context/interface/mkiv/i-textbackground.xml index 3b17e0efd..bc16ffa8d 100644 --- a/tex/context/interface/mkiv/i-textbackground.xml +++ b/tex/context/interface/mkiv/i-textbackground.xml @@ -122,7 +122,7 @@ </cd:arguments> </cd:command> - <cd:command name="textbackground" type="environment" generated="yes" variant="generated" file="anch-bck.mkiv"> + <cd:command name="textbackground" type="environment" generated="yes" variant="example" file="anch-bck.mkiv"> <cd:sequence> <cd:variable value="textbackground"/> </cd:sequence> @@ -133,7 +133,7 @@ </cd:arguments> </cd:command> - <cd:command name="textbackground" generated="yes" variant="generated" file="anch-bck.mkiv"> + <cd:command name="textbackground" generated="yes" variant="example" file="anch-bck.mkiv"> <cd:sequence> <cd:variable value="textbackground"/> </cd:sequence> @@ -144,4 +144,4 @@ <cd:command name="textbackgroundmanual" type="environment" file="anch-bck.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-tolerance.xml b/tex/context/interface/mkiv/i-tolerance.xml index 26b554132..b33fef05d 100644 --- a/tex/context/interface/mkiv/i-tolerance.xml +++ b/tex/context/interface/mkiv/i-tolerance.xml @@ -19,4 +19,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-tooltip.xml b/tex/context/interface/mkiv/i-tooltip.xml index 775d0abcf..f46ffb091 100644 --- a/tex/context/interface/mkiv/i-tooltip.xml +++ b/tex/context/interface/mkiv/i-tooltip.xml @@ -28,9 +28,9 @@ </cd:arguments> </cd:command> - <cd:command name="tooltip" generated="yes" variant="generated:1" file="scrn-fld.mkvi"> + <cd:command name="tooltip" generated="yes" variant="instance" file="scrn-fld.mkvi"> <cd:sequence> - <cd:variable value="tooltip"/> + <cd:instance value="tooltip"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> @@ -39,11 +39,14 @@ <cd:resolve name="argument-text"/> <cd:resolve name="argument-text"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-tooltip"/> + </cd:instances> </cd:command> - <cd:command name="tooltip" generated="yes" variant="generated:2" file="scrn-fld.mkvi"> + <cd:command name="tooltip" generated="yes" variant="instance:argument" file="scrn-fld.mkvi"> <cd:sequence> - <cd:variable value="tooltip"/> + <cd:instance value="tooltip"/> </cd:sequence> <cd:arguments> <cd:keywords optional="yes"> @@ -54,28 +57,35 @@ <cd:resolve name="argument-text"/> <cd:resolve name="argument-text"/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-tooltip"/> + </cd:instances> </cd:command> - <cd:command name="tooltip" variant="1" file="scrn-fld.mkvi"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setuptooltip"/> - </cd:assignments> - <cd:resolve name="argument-text"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <!-- - <cd:command name="tooltip" variant="2" file="scrn-fld.mkvi"> - <cd:arguments> - <cd:keywords optional="yes"> - <cd:constant type="left"/> - <cd:constant type="middle"/> - <cd:constant type="right"/> - </cd:keywords> - <cd:resolve name="argument-text"/> - <cd:resolve name="argument-text"/> - </cd:arguments> - </cd:command> + <cd:command name="tooltip" file="scrn-fld.mkvi"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptooltip"/> + </cd:assignments> + <cd:resolve name="argument-text"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="tooltip" variant="argument" file="scrn-fld.mkvi"> + <cd:arguments> + <cd:keywords optional="yes"> + <cd:constant type="left"/> + <cd:constant type="middle"/> + <cd:constant type="right"/> + </cd:keywords> + <cd:resolve name="argument-text"/> + <cd:resolve name="argument-text"/> + </cd:arguments> + </cd:command> + + --> </cd:interface> diff --git a/tex/context/interface/mkiv/i-tracker.xml b/tex/context/interface/mkiv/i-tracker.xml index e2b48ade2..4dbc31886 100644 --- a/tex/context/interface/mkiv/i-tracker.xml +++ b/tex/context/interface/mkiv/i-tracker.xml @@ -72,4 +72,4 @@ <cd:command name="showjustification" file="trac-jus.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-translate.xml b/tex/context/interface/mkiv/i-translate.xml new file mode 100644 index 000000000..ba3510f0b --- /dev/null +++ b/tex/context/interface/mkiv/i-translate.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?context-directive job ctxfile x-setups.ctx ?> + +<cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> + + <cd:command name="translateinput" file="m-translate.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-text"/> + <cd:resolve name="keyword-text"/> + </cd:arguments> + </cd:command> + + <cd:command name="resetinputtranslation" file="m-translate.mkiv"/> + + <cd:command name="enableinputtranslation" file="m-translate.mkiv"/> + + <cd:command name="disableinputtranslation" file="m-translate.mkiv"/> + + <cd:command name="readtranslatedfile" file="m-translate.mkiv"> + <cd:arguments> + <cd:resolve name="argument-file"/> + </cd:arguments> + </cd:command> + +</cd:interface>
\ No newline at end of file diff --git a/tex/context/interface/mkiv/i-twopassdata.xml b/tex/context/interface/mkiv/i-twopassdata.xml index f30b8bb23..508294f08 100644 --- a/tex/context/interface/mkiv/i-twopassdata.xml +++ b/tex/context/interface/mkiv/i-twopassdata.xml @@ -121,4 +121,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-typography.xml b/tex/context/interface/mkiv/i-typography.xml index ffb80c211..6c2aa7389 100644 --- a/tex/context/interface/mkiv/i-typography.xml +++ b/tex/context/interface/mkiv/i-typography.xml @@ -170,4 +170,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-unit.xml b/tex/context/interface/mkiv/i-unit.xml index 3502b544a..3380585dc 100644 --- a/tex/context/interface/mkiv/i-unit.xml +++ b/tex/context/interface/mkiv/i-unit.xml @@ -4,13 +4,13 @@ <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> - <cd:command name="digits" variant="1" file="phys-dim.mkiv"> + <cd:command name="digits" file="phys-dim.mkiv"> <cd:arguments> <cd:resolve name="argument-number"/> </cd:arguments> </cd:command> - <cd:command name="digits" variant="2" file="phys-dim.mkiv"> + <cd:command name="digits" variant="string" file="phys-dim.mkiv"> <cd:arguments> <cd:resolve name="string-number"/> </cd:arguments> @@ -75,20 +75,27 @@ </cd:arguments> </cd:command> - <cd:command name="unit" generated="yes" variant="generated" file="phys-dim.mkiv"> + <cd:command name="unit" generated="yes" variant="instance" file="phys-dim.mkiv"> <cd:sequence> - <cd:variable value="unit"/> + <cd:instance value="unit"/> </cd:sequence> <cd:arguments> <cd:content/> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-unit"/> + </cd:instances> </cd:command> - <cd:command name="unit" file="phys-dim.mkiv"> - <cd:arguments> - <cd:content/> - </cd:arguments> - </cd:command> + <!-- + + <cd:command name="unit" file="phys-dim.mkiv"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + + --> <cd:command name="installunitsseparator" file="phys-dim.mkiv"> <cd:arguments> @@ -118,4 +125,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-variables.xml b/tex/context/interface/mkiv/i-variables.xml index 28aaa6df4..63b34329c 100644 --- a/tex/context/interface/mkiv/i-variables.xml +++ b/tex/context/interface/mkiv/i-variables.xml @@ -72,6 +72,23 @@ </cd:arguments> </cd:command> + <cd:command name="checkvariables" file="core-env.mkiv"> + <cd:arguments> + <cd:resolve name="keyword-name"/> + <cd:assignments list="yes"> + <cd:parameter name="set"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="reset"> + <cd:constant type="cd:command"/> + </cd:parameter> + <cd:parameter name="cd:key"> + <cd:constant type="cd:value"/> + </cd:parameter> + </cd:assignments> + </cd:arguments> + </cd:command> + <cd:command name="setvariable" file="core-env.mkiv"> <cd:arguments> <cd:resolve name="argument-name"/> @@ -353,4 +370,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-verbatim.xml b/tex/context/interface/mkiv/i-verbatim.xml index 7026d2b10..b23f57efe 100644 --- a/tex/context/interface/mkiv/i-verbatim.xml +++ b/tex/context/interface/mkiv/i-verbatim.xml @@ -75,9 +75,9 @@ </cd:parameter> </cd:assignments> </cd:arguments> - </cd:command> + </cd:command> - <cd:command name="type" variant="1" file="buff-ver.mkiv"> + <cd:command name="type" file="buff-ver.mkiv"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setuptype"/> @@ -86,7 +86,7 @@ </cd:arguments> </cd:command> - <cd:command name="type" variant="2" file="buff-ver.mkiv"> + <cd:command name="type" variant="angles" file="buff-ver.mkiv"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setuptype"/> @@ -95,7 +95,7 @@ </cd:arguments> </cd:command> - <cd:command name="typ" variant="1" file="buff-ver.mkiv"> + <cd:command name="typ" file="buff-ver.mkiv"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setuptype"/> @@ -104,7 +104,7 @@ </cd:arguments> </cd:command> - <cd:command name="typ" variant="2" file="buff-ver.mkiv"> + <cd:command name="typ" variant="angles" file="buff-ver.mkiv"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setuptype"/> @@ -113,7 +113,7 @@ </cd:arguments> </cd:command> - <cd:command name="type" generated="yes" variant="generated:1" file="buff-ver.mkiv"> + <cd:command name="type" generated="yes" variant="example" file="buff-ver.mkiv"> <cd:sequence> <cd:variable value="type"/> </cd:sequence> @@ -125,7 +125,7 @@ </cd:arguments> </cd:command> - <cd:command name="type" generated="yes" variant="generated:2" file="buff-ver.mkiv"> + <cd:command name="type" generated="yes" variant="example:angles" file="buff-ver.mkiv"> <cd:sequence> <cd:variable value="type"/> </cd:sequence> @@ -149,7 +149,7 @@ <cd:command name="setuptyping" file="buff-ver.mkiv"> <cd:arguments> - <cd:resolve name="keyword-name-optional-list"/> + <cd:resolve name="keyword-name-list-optional"/> <cd:assignments list="yes"> <cd:parameter name="oddmargin"> <cd:constant type="cd:dimension"/> @@ -251,42 +251,32 @@ </cd:arguments> </cd:command> - <cd:command name="typing" type="environment" variant="1" file="buff-ver.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setuptyping"/> - </cd:assignments> - </cd:arguments> - </cd:command> - - <cd:command name="typing" type="environment" variant="2" file="buff-ver.mkiv"> - <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:constant type="continue"/> - </cd:keywords> - </cd:arguments> - </cd:command> - - <cd:command name="typing" type="environment" generated="yes" variant="generated:1" file="buff-ver.mkiv"> + <cd:command name="typing" type="environment" generated="yes" variant="instance" file="buff-ver.mkiv"> <cd:sequence> - <cd:variable value="typing"/> + <cd:instance value="typing"/> </cd:sequence> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setuptyping"/> </cd:assignments> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-typing"/> + </cd:instances> </cd:command> - <cd:command name="typing" type="environment" generated="yes" variant="generated:2" file="buff-ver.mkiv"> + <cd:command name="typing" type="environment" generated="yes" variant="instance:argument" file="buff-ver.mkiv"> <cd:sequence> - <cd:variable value="typing"/> + <cd:instance value="typing"/> </cd:sequence> <cd:arguments> <cd:keywords list="yes" optional="yes"> <cd:constant type="continue"/> </cd:keywords> </cd:arguments> + <cd:instances> + <cd:resolve name="instance-typing"/> + </cd:instances> </cd:command> <cd:command name="tex" file="buff-ver.mkiv"> @@ -363,87 +353,107 @@ </cd:arguments> </cd:command> - <cd:command name="LUA" type="environment" variant="1" file="buff-ver.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setuptyping"/> - </cd:assignments> - </cd:arguments> - </cd:command> - - <cd:command name="LUA" type="environment" variant="2" file="buff-ver.mkiv"> - <cd:sequence> - <cd:variable value="lua"/> - </cd:sequence> - <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:constant type="continue"/> - </cd:keywords> - </cd:arguments> - </cd:command> - - <cd:command name="MP" type="environment" variant="1" file="buff-ver.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setuptyping"/> - </cd:assignments> - </cd:arguments> - </cd:command> - - <cd:command name="MP" type="environment" variant="2" file="buff-ver.mkiv"> - <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:constant type="continue"/> - </cd:keywords> - </cd:arguments> - </cd:command> - - <cd:command name="XML" type="environment" variant="1" file="buff-ver.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setuptyping"/> - </cd:assignments> - </cd:arguments> - </cd:command> - - <cd:command name="XML" type="environment" variant="2" file="buff-ver.mkiv"> - <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:constant type="continue"/> - </cd:keywords> - </cd:arguments> - </cd:command> - - <cd:command name="PARSEDXML" type="environment" variant="1" file="buff-ver.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setuptyping"/> - </cd:assignments> - </cd:arguments> - </cd:command> - - <cd:command name="PARSEDXML" type="environment" variant="2" file="buff-ver.mkiv"> - <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:constant type="continue"/> - </cd:keywords> - </cd:arguments> - </cd:command> - - <cd:command name="TEX" type="environment" variant="1" file="buff-ver.mkiv"> - <cd:arguments> - <cd:assignments list="yes" optional="yes"> - <cd:inherit name="setuptyping"/> - </cd:assignments> - </cd:arguments> - </cd:command> - - <cd:command name="TEX" type="environment" variant="2" file="buff-ver.mkiv"> - <cd:arguments> - <cd:keywords list="yes" optional="yes"> - <cd:constant type="continue"/> - </cd:keywords> - </cd:arguments> - </cd:command> - -</cd:interface>
\ No newline at end of file + <!-- + + <cd:command name="typing" type="environment" file="buff-ver.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptyping"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="typing" type="environment" variant="argument" file="buff-ver.mkiv"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="continue"/> + </cd:keywords> + </cd:arguments> + </cd:command> + + <cd:command name="LUA" type="environment" file="buff-ver.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptyping"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="LUA" type="environment" variant="argument" file="buff-ver.mkiv"> + <cd:sequence> + <cd:variable value="lua"/> + </cd:sequence> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="continue"/> + </cd:keywords> + </cd:arguments> + </cd:command> + + <cd:command name="MP" type="environment" file="buff-ver.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptyping"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="MP" type="environment" variant="argument" file="buff-ver.mkiv"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="continue"/> + </cd:keywords> + </cd:arguments> + </cd:command> + + <cd:command name="XML" type="environment" file="buff-ver.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptyping"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="XML" type="environment" variant="argument" file="buff-ver.mkiv"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="continue"/> + </cd:keywords> + </cd:arguments> + </cd:command> + + <cd:command name="PARSEDXML" type="environment" file="buff-ver.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptyping"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="PARSEDXML" type="environment" variant="argument" file="buff-ver.mkiv"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="continue"/> + </cd:keywords> + </cd:arguments> + </cd:command> + + <cd:command name="TEX" type="environment" file="buff-ver.mkiv"> + <cd:arguments> + <cd:assignments list="yes" optional="yes"> + <cd:inherit name="setuptyping"/> + </cd:assignments> + </cd:arguments> + </cd:command> + + <cd:command name="TEX" type="environment" variant="argument" file="buff-ver.mkiv"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:constant type="continue"/> + </cd:keywords> + </cd:arguments> + </cd:command> + + --> + +</cd:interface> diff --git a/tex/context/interface/mkiv/i-version.xml b/tex/context/interface/mkiv/i-version.xml index d01659815..9f7864e8a 100644 --- a/tex/context/interface/mkiv/i-version.xml +++ b/tex/context/interface/mkiv/i-version.xml @@ -75,4 +75,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-viewerlayer.xml b/tex/context/interface/mkiv/i-viewerlayer.xml index 3de29b1fd..8e321971e 100644 --- a/tex/context/interface/mkiv/i-viewerlayer.xml +++ b/tex/context/interface/mkiv/i-viewerlayer.xml @@ -50,7 +50,7 @@ </cd:arguments> </cd:command> - <cd:command name="viewerlayer" type="environment" generated="yes" variant="generated" file="attr-lay.mkiv"> + <cd:command name="viewerlayer" type="environment" generated="yes" variant="example" file="attr-lay.mkiv"> <cd:sequence> <cd:variable value="viewerlayer"/> </cd:sequence> @@ -65,4 +65,4 @@ <cd:command name="showlayoutcomponents" file="attr-lay.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-visual.xml b/tex/context/interface/mkiv/i-visual.xml new file mode 100644 index 000000000..64ae3f79d --- /dev/null +++ b/tex/context/interface/mkiv/i-visual.xml @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?context-directive job ctxfile x-setups.ctx ?> + +<cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> + + <cd:command name="fakerule" file="m-visual.mkiv"> + <cd:arguments> + <cd:resolve name="argument-dimension"/> + </cd:arguments> + </cd:command> + + <cd:command name="dorandomrecurse" file="m-visual.mkiv"> + <cd:arguments> + <cd:resolve name="argument-number"/> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="fakelines" file="m-visual.mkiv"> + <cd:arguments> + <cd:keywords name="keywords" delimiters="braces"> + <cd:constant type="cd:number"/> + <cd:constant type="cd:nothing"/> + </cd:keywords> + <cd:keywords name="keywords" delimiters="braces"> + <cd:constant type="cd:number"/> + <cd:constant type="cd:nothing"/> + </cd:keywords> + </cd:arguments> + </cd:command> + + <cd:command name="fakewords" file="m-visual.mkiv"> + <cd:arguments> + <cd:keywords name="keywords" delimiters="braces"> + <cd:constant type="cd:number"/> + <cd:constant type="cd:nothing"/> + </cd:keywords> + <cd:keywords name="keywords" delimiters="braces"> + <cd:constant type="cd:number"/> + <cd:constant type="cd:nothing"/> + </cd:keywords> + </cd:arguments> + </cd:command> + + <cd:command name="fakenwords" file="m-visual.mkiv"> + <cd:arguments> + <cd:resolve name="argument-number"/> + <cd:keywords name="keywords" delimiters="braces"> + <cd:constant type="cd:number"/> + <cd:constant type="cd:nothing"/> + </cd:keywords> + </cd:arguments> + </cd:command> + + <cd:command name="showfakewords" file="m-visual.mkiv"/> + + <cd:command name="fakeword" file="m-visual.mkiv"/> + + <cd:command name="fakeparindent" file="m-visual.mkiv"/> + + <cd:command name="fakeddroppedcaps" file="m-visual.mkiv"> + <cd:arguments> + <cd:resolve name="argument-number"/> + </cd:arguments> + </cd:command> + + <cd:command name="fakefigure" file="m-visual.mkiv"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="placefloat"/> + </cd:keywords> + <cd:resolve name="keyword-reference-list-optional"/> + <cd:resolve name="argument-dimension"/> + <cd:resolve name="argument-dimension"/> + <cd:resolve name="argument-dimension"/> + <cd:resolve name="argument-dimension"/> + </cd:arguments> + </cd:command> + + <cd:command name="fakeimage" file="m-visual.mkiv"> + <cd:arguments> + <cd:resolve name="argument-dimension"/> + <cd:resolve name="argument-dimension"/> + <cd:resolve name="argument-dimension"/> + <cd:resolve name="argument-dimension"/> + </cd:arguments> + </cd:command> + + <cd:command name="fakeformula" file="m-visual.mkiv"/> + + <cd:command name="fakespacingformula" file="m-visual.mkiv"/> + + <cd:command name="smashedgrid" file="m-visual.mkiv"> + <cd:arguments> + <cd:keywords list="yes" optional="yes"> + <cd:inherit name="basegrid"/> + </cd:keywords> + </cd:arguments> + </cd:command> + + <cd:command name="bodyfontgrid" file="m-visual.mkiv"/> + + <cd:command name="emexgrid" file="m-visual.mkiv"/> + + <cd:command name="simplethesis" file="m-visual.mkiv"/> + + <cd:command name="showbaselines" file="m-visual.mkiv"/> + + <cd:command name="showpagebuilder" file="m-visual.mkiv"/> + + <cd:command name="tagbox" file="m-visual.mkiv"> + <cd:arguments> + <cd:resolve name="argument-text"/> + <cd:keywords optional="yes"> + <cd:constant type="l"/> + <cd:constant type="r"/> + <cd:constant type="t"/> + <cd:constant type="b"/> + <cd:constant type="lt"/> + <cd:constant type="lb"/> + <cd:constant type="rt"/> + <cd:constant type="rb"/> + <cd:constant type="tl"/> + <cd:constant type="bl"/> + <cd:constant type="tr"/> + <cd:constant type="br"/> + </cd:keywords> + <cd:csname/> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="coloredhbox" file="m-visual.mkiv"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="coloredvbox" file="m-visual.mkiv"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="coloredvtop" file="m-visual.mkiv"> + <cd:arguments> + <cd:content/> + </cd:arguments> + </cd:command> + + <cd:command name="coloredstrut" file="m-visual.mkiv"/> + +</cd:interface>
\ No newline at end of file diff --git a/tex/context/interface/mkiv/i-visualizer.xml b/tex/context/interface/mkiv/i-visualizer.xml index fd7198f9d..3d30b7f4d 100644 --- a/tex/context/interface/mkiv/i-visualizer.xml +++ b/tex/context/interface/mkiv/i-visualizer.xml @@ -153,4 +153,4 @@ <cd:command name="resetvisualizers" file="trc-vis.mkiv"/> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-vspace.xml b/tex/context/interface/mkiv/i-vspace.xml index b6d7381ee..4618fc00a 100644 --- a/tex/context/interface/mkiv/i-vspace.xml +++ b/tex/context/interface/mkiv/i-vspace.xml @@ -28,6 +28,7 @@ <cd:constant type="samepage"/> <cd:constant type="max"/> <cd:constant type="force"/> + <cd:constant type="enable"/> <cd:constant type="disable"/> <cd:constant type="nowhite"/> <cd:constant type="back"/> diff --git a/tex/context/interface/mkiv/i-whitespace.xml b/tex/context/interface/mkiv/i-whitespace.xml index 8f9fa0823..06e1997c5 100644 --- a/tex/context/interface/mkiv/i-whitespace.xml +++ b/tex/context/interface/mkiv/i-whitespace.xml @@ -59,4 +59,4 @@ </cd:arguments> </cd:command> -</cd:interface>
\ No newline at end of file +</cd:interface> diff --git a/tex/context/interface/mkiv/i-xtable.xml b/tex/context/interface/mkiv/i-xtable.xml index 31b4a6842..7500ff47f 100644 --- a/tex/context/interface/mkiv/i-xtable.xml +++ b/tex/context/interface/mkiv/i-xtable.xml @@ -82,7 +82,7 @@ </cd:arguments> </cd:command> - <cd:command name="xtable" type="environment" variant="1" file="tabl-xtb.mkvi"> + <cd:command name="xtable" type="environment" file="tabl-xtb.mkvi"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupxtable"/> @@ -90,13 +90,13 @@ </cd:arguments> </cd:command> - <cd:command name="xtable" type="environment" variant="2" file="tabl-xtb.mkvi"> + <cd:command name="xtable" type="environment" variant="name" file="tabl-xtb.mkvi"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> </cd:arguments> </cd:command> - <cd:command name="embeddedxtable" type="environment" variant="1" file="tabl-xtb.mkvi"> + <cd:command name="embeddedxtable" type="environment" file="tabl-xtb.mkvi"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupxtable"/> @@ -104,13 +104,13 @@ </cd:arguments> </cd:command> - <cd:command name="embeddedxtable" type="environment" variant="2" file="tabl-xtb.mkvi"> + <cd:command name="embeddedxtable" type="environment" variant="name" file="tabl-xtb.mkvi"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> </cd:arguments> </cd:command> - <cd:command name="xtable" type="environment" generated="yes" variant="generated" file="tabl-xtb.mkvi"> + <cd:command name="xtable" type="environment" generated="yes" variant="example" file="tabl-xtb.mkvi"> <cd:sequence> <cd:variable value="xtable"/> </cd:sequence> @@ -157,7 +157,7 @@ </cd:arguments> </cd:command> - <cd:command name="xtablehead" type="environment" variant="1" file="tabl-xtb.mkvi"> + <cd:command name="xtablehead" type="environment" file="tabl-xtb.mkvi"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupxtable"/> @@ -165,13 +165,13 @@ </cd:arguments> </cd:command> - <cd:command name="xtablehead" type="environment" variant="2" file="tabl-xtb.mkvi"> + <cd:command name="xtablehead" type="environment" variant="name" file="tabl-xtb.mkvi"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> </cd:arguments> </cd:command> - <cd:command name="xtablefoot" type="environment" variant="1" file="tabl-xtb.mkvi"> + <cd:command name="xtablefoot" type="environment" file="tabl-xtb.mkvi"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupxtable"/> @@ -179,13 +179,13 @@ </cd:arguments> </cd:command> - <cd:command name="xtablefoot" type="environment" variant="2" file="tabl-xtb.mkvi"> + <cd:command name="xtablefoot" type="environment" variant="name" file="tabl-xtb.mkvi"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> </cd:arguments> </cd:command> - <cd:command name="xtablenext" type="environment" variant="1" file="tabl-xtb.mkvi"> + <cd:command name="xtablenext" type="environment" file="tabl-xtb.mkvi"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupxtable"/> @@ -193,13 +193,13 @@ </cd:arguments> </cd:command> - <cd:command name="xtablenext" type="environment" variant="2" file="tabl-xtb.mkvi"> + <cd:command name="xtablenext" type="environment" variant="name" file="tabl-xtb.mkvi"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> </cd:arguments> </cd:command> - <cd:command name="xtablebody" type="environment" variant="1" file="tabl-xtb.mkvi"> + <cd:command name="xtablebody" type="environment" file="tabl-xtb.mkvi"> <cd:arguments> <cd:assignments list="yes" optional="yes"> <cd:inherit name="setupxtable"/> @@ -207,7 +207,7 @@ </cd:arguments> </cd:command> - <cd:command name="xtablebody" type="environment" variant="2" file="tabl-xtb.mkvi"> + <cd:command name="xtablebody" type="environment" variant="name" file="tabl-xtb.mkvi"> <cd:arguments> <cd:resolve name="keyword-name-optional"/> </cd:arguments> diff --git a/tex/context/modules/common/s-abr-01.tex b/tex/context/modules/common/s-abr-01.tex index 00a1a5c1e..fd6c66419 100644 --- a/tex/context/modules/common/s-abr-01.tex +++ b/tex/context/modules/common/s-abr-01.tex @@ -127,7 +127,8 @@ \logo [GUST] {Gust} \logo [GCC] {gcc} \logo [GWTEX] {gw\TeX} -\logo [HSB] {hsb} +\logo [HSB] {hsb} % ? +\logo [HSV] {hsv} \logo [HTML] {html} \logo [HTTP] {http} \logo [HZ] {hz} @@ -178,6 +179,7 @@ \logo [METATYPE] {MetaType1} \logo [MODULA] {Modula} \logo [MOV] {mov} +\logo [MPEG] {mpeg} \logo [MPS] {mps} \logo [MPTOPDF] {mptopdf} \logo [MPLIB] {mplib} diff --git a/tex/context/modules/common/s-pre-00.tex b/tex/context/modules/common/s-pre-00.tex index 7f217d5bb..2acbc13b7 100644 --- a/tex/context/modules/common/s-pre-00.tex +++ b/tex/context/modules/common/s-pre-00.tex @@ -11,6 +11,8 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. +% This might go away! + %D This module provides some non core functionality that can %D be used in the presentations styles. This module contains %D experimental macros. diff --git a/tex/context/modules/common/s-pre-12.tex b/tex/context/modules/common/s-pre-12.tex index 23418fbba..64949e30c 100644 --- a/tex/context/modules/common/s-pre-12.tex +++ b/tex/context/modules/common/s-pre-12.tex @@ -63,7 +63,7 @@ \dorecurse{\CurrentMaxItem} {\startMPdrawing initialize_box(\MPpos{item-\realfolio-\recurselevel}) ; - linewidth := .25cm ; + linewidth := .25cm ; p := tensecircle (wxy,hxy,linewidth) shifted cxy ; fill p withcolor .9white ; pickup pencircle scaled linewidth ; @@ -73,8 +73,8 @@ \else draw p withcolor \MPcolor{DoneColor} ; \fi - dxab := xpart a-xpart b ; - dyab := ypart a-ypart b ; + dxab := xpart a-xpart b ; + dyab := ypart a-ypart b ; sign := if dyab>0 : - fi 1 ; drawarrow a -- @@ -82,7 +82,7 @@ if abs(dyab)>4linewidth : a shifted (-dxab/2,+sign*2linewidth) -- b shifted (+dxab/2,-sign*2linewidth) .. - fi + fi {left} b shifted (-2linewidth+dxab/2,0) -- b withcolor \MPcolor{ArrowColor} ; @@ -107,7 +107,7 @@ \setupinteraction[color=GotoColor,contrastcolor=GotoColor] \defineoverlay [shape] [\SomeShape] -\defineoverlay [next] [\overlaybutton{forward}] +\defineoverlay [next] [\overlaybutton{forward}] \setupbackgrounds [page] @@ -183,44 +183,44 @@ \vfil#1\vfil\vfil \stopstandardmakeup} -\endinput - -% \starttext -% -% \StartIdea -% \StartTopic -% What a topic -% \StopTopic -% \StartItem -% \input reich \relax -% \StopItem -% \StartItem -% \input reich \relax -% \StopItem -% \StartItem -% \input reich \relax -% \StopItem -% \StopIdea -% -% \StartIdea -% \StartTopic -% One More Nice Idea -% \StopTopic -% \StartItem -% \input reich \relax -% \StopItem -% \StartItem -% \input reich \relax -% \StopItem -% \StopIdea -% -% \StartIdea -% \StartTopic -% The Last Idea -% \StopTopic -% \StartItem -% \input tufte \relax -% \StopItem -% \StopIdea -% -% \stoptext +\doifnotmode{demo}{\endinput} + +\starttext + +\StartIdea + \StartTopic + What a topic + \StopTopic + \StartItem + \input reich \relax + \StopItem + \StartItem + \input reich \relax + \StopItem + \StartItem + \input reich \relax + \StopItem +\StopIdea + +\StartIdea + \StartTopic + One More Nice Idea + \StopTopic + \StartItem + \input reich \relax + \StopItem + \StartItem + \input reich \relax + \StopItem +\StopIdea + +\StartIdea + \StartTopic + The Last Idea + \StopTopic + \StartItem + \input tufte \relax + \StopItem +\StopIdea + +\stoptext diff --git a/tex/context/modules/common/s-pre-16.tex b/tex/context/modules/common/s-pre-16.tex index 715936890..a7e127828 100644 --- a/tex/context/modules/common/s-pre-16.tex +++ b/tex/context/modules/common/s-pre-16.tex @@ -1,6 +1,6 @@ %D \module %D [ file=s-pre-16, -%D version=1999.09.01, +%D version=1999.09.01, %D title=\CONTEXT\ Style File, %D subtitle=Presentation Environment 16, %D author=Hans Hagen, @@ -13,7 +13,7 @@ %D The first version of this style was made late summer 1999, %D but its first usage was during a course I gave in BRNO. -%D It's a rather simple style with a dominating background. +%D It's a rather simple style with a dominating background. \setuppapersize [S6][S6] @@ -42,11 +42,11 @@ [state=start] \definecolor[gray] [s=.4] -\definecolor[white][s=.8] +\definecolor[white][s=.8] -\definecolor[red] [r=.8] \definecolor[cyan] [g=.8,b=.8] -\definecolor[green][g=.8] \definecolor[magenta][r=.8,b=.8] -\definecolor[blue] [b=.8] \definecolor[yellow] [r=.8,g=.8] +\definecolor[red] [r=.8] \definecolor[cyan] [g=.8,b=.8] +\definecolor[green][g=.8] \definecolor[magenta][r=.8,b=.8] +\definecolor[blue] [b=.8] \definecolor[yellow] [r=.8,g=.8] \definecolor[PageColor][gray] \definecolor[TextColor][yellow] @@ -66,49 +66,49 @@ symbol=FuzzyDot] \startuseMPgraphic{FuzzyCircle} - path p ; numeric w, h, l ; - w := OverlayWidth ; h := OverlayHeight ; - def dd = (1 randomized (1/5)) enddef ; + path p ; numeric w, h, l ; + w := OverlayWidth ; h := OverlayHeight ; + def dd = (1 randomized (1/5)) enddef ; pickup pencircle xscaled 10pt yscaled 2pt rotated 30; - for i:=1 upto 50 : - p := (-dd,-dd)..(dd,-dd)..(dd,dd)..(-dd,dd)..cycle ; - p := p rotatedaround (center p, uniformdeviate 360) ; - p := p xscaled (w/2) yscaled (h/2) ; - l := length(p)/2 ; - p := p cutbefore point (uniformdeviate l) of p ; - p := p cutafter point (l+uniformdeviate l) of p ; + for i:=1 upto 50 : + p := (-dd,-dd)..(dd,-dd)..(dd,dd)..(-dd,dd)..cycle ; + p := p rotatedaround (center p, uniformdeviate 360) ; + p := p xscaled (w/2) yscaled (h/2) ; + l := length(p)/2 ; + p := p cutbefore point (uniformdeviate l) of p ; + p := p cutafter point (l+uniformdeviate l) of p ; draw p withcolor \MPcolor{LineColor} randomized (.4,1) ; - endfor ; + endfor ; picture s ; s := currentpicture xysized (w-15,h-15) ; currentpicture := nullpicture ; - fill boundingbox s enlarged 60pt withcolor \MPcolor{PageColor} ; - addto currentpicture also s ; + fill boundingbox s enlarged 60pt withcolor \MPcolor{PageColor} ; + addto currentpicture also s ; \stopuseMPgraphic \startuseMPgraphic{FuzzyDot} - path p ; numeric w ; - w := BodyFontSize/2 ; - def dd = (w randomized (w/2)) enddef ; + path p ; numeric w ; + w := BodyFontSize/2 ; + def dd = (w randomized (w/2)) enddef ; pickup pencircle xscaled (w/2) yscaled (w/3) rotated 30 ; - for i=0 step 45 until 135 : + for i=0 step 45 until 135 : p := (-dd,0)--(dd,0) ; p := p rotatedaround (origin,i-w+uniformdeviate w) ; draw p withcolor \MPcolor{LineColor} randomized (.3,.8) ; - endfor ; + endfor ; \stopuseMPgraphic \defineoverlay [FuzzyCircle] [\useMPgraphic{FuzzyCircle}] \defineoverlay [GoOn] [{\setupinteraction[click=no]\overlaybutton{forward}}] \defineoverlay [Again] [\overlaybutton{firstpage}] -\definesymbol - [FuzzyDot] +\definesymbol + [FuzzyDot] [\lower\dp\strutbox\hbox{\useMPgraphic{FuzzyDot}}] \def\Item% {\par\noindent\symbol[FuzzyDot]\hskip.5em\nobreak} -\setupitemize +\setupitemize [all] [packed] [symbol=FuzzyDot] @@ -134,15 +134,15 @@ [alternative=g, interaction=all] -%D Since we want a colored text, and since color directive -%D can spoil the spacing, we use a foregroundcolor. +%D Since we want a colored text, and since color directive +%D can spoil the spacing, we use a foregroundcolor. \setupbackgrounds [text] [foregroundcolor=TextColor] -%D Unfortunately this does not work when on the page colors -%D are set, so we play safe and say: +%D Unfortunately this does not work when on the page colors +%D are set, so we play safe and say: \setupmakeup [standard] @@ -165,13 +165,13 @@ \stopcolumns \page} -%D Some fakes. +%D Some fakes. \def\Subject {\Topic} \def\Subjects {} -%D A bonus (copied from \type {s-pre-02} but with a different -%D vertical alignment. +%D A bonus (copied from \type {s-pre-02} but with a different +%D vertical alignment. \def\StartTitlePage% {\startstandardmakeup @@ -188,16 +188,16 @@ {\StartTitlePage#1\StopTitlePage} \doifnotmode{demo}{\endinput} - -\starttext + +\starttext \Topics{...} -\StartIdea +\StartIdea \Topic{...} - ... - \NextIdea + ... + \NextIdea ... \StopIdea -\stoptext +\stoptext diff --git a/tex/context/modules/common/s-pre-23.tex b/tex/context/modules/common/s-pre-23.tex index f9983a89e..c5ae82eed 100644 --- a/tex/context/modules/common/s-pre-23.tex +++ b/tex/context/modules/common/s-pre-23.tex @@ -14,7 +14,7 @@ %D This style looks a lot like number 22. This time we don't %D cycle but build up the page. One can click on the text go %D to the page wanted. Clicking on the titl ebrings you to the -%D previous page. +%D previous page. \startmode [demo] \disablemode[demo] \usemodule[pre-22] \enablemode[demo] @@ -24,13 +24,13 @@ \usemodule[pre-22] \stopnotmode -%D We use a simple two||color scheme. +%D We use a simple two||color scheme. \definecolor[DotColor][r=.5,g=.6,b=.7] \definecolor[TopColor][r=.7,g=.6,b=.5] \definecolor[BotColor][TopColor] -%D We will not delay page building. +%D We will not delay page building. \let\BuildPage\relax @@ -51,14 +51,14 @@ \setlayer[temp]{\foundbox{Subtext}\CurrentSummary} \stopstandardmakeup} -%D The title page is not added to the main layer (or -%D actually, it is, but we erase the layer before it's -%D used). +%D The title page is not added to the main layer (or +%D actually, it is, but we erase the layer before it's +%D used). \long\def\MakeTitlePage#1#2% {\startstandardmakeup \definereference[thispage][] - \switchtobodyfont[32pt] + \switchtobodyfont[32pt] \StartSummary{#1}{}#2\StopSummary \resetlayer[main] \setlayer[temp]{\foundbox{Summary}\CurrentSummary} diff --git a/tex/context/modules/common/s-pre-50.tex b/tex/context/modules/common/s-pre-50.tex index ff3e48631..8b55cf67a 100644 --- a/tex/context/modules/common/s-pre-50.tex +++ b/tex/context/modules/common/s-pre-50.tex @@ -90,9 +90,9 @@ \StartSteps \title[whow]{How Much?} \FlushStep - \item More \FlushStep - \item And More \FlushStep - \item And Even More \FlushStep + \startitem More \stopitem \FlushStep + \startitem And More \stopitem \FlushStep + \startitem And Even More \stopitem \FlushStep \StartStep And So On \StopStep diff --git a/tex/context/modules/mkii/m-quest.mkii b/tex/context/modules/mkii/m-quest.mkii new file mode 100644 index 000000000..596abaa0a --- /dev/null +++ b/tex/context/modules/mkii/m-quest.mkii @@ -0,0 +1,232 @@ +%D \module +%D [ file=m-invull, +%D version=1995.01.10, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Exercise, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%I Invuloefeningen kunnen worden vormgegeven met het +%I de commando's: +%I +%I \definieerinvulwoord[trefwoord]{woord,woord} +%I \invulwoord[trefwoord] +%I \invulwoord{woord,woord,...} +%I +%I Daarbij kan het een en ander worden ingesteld met +%I +%I \stelinvullenin[status=,nummer=,links=,rechts=,letter=] +%P +%I Er zijn drie manieren om woorden in te vullen. De meest +%I eenvoudige is die waarbij de in te vullen woorden in de +%I tekst staan. +%I +%I bla bla \invulwoord{een,alfa} bla bla bla bla bla bla +%I bla bla bla bla bla bla bla bla \invulwoord{twee,beta}. +%I +%I De gezette tekst hangt af van de instellingen: +%I +%I [status=leeg] ________ +%I [status=vol,nummer=1] 'een' respectievelijk 'twee' +%I [status=vol,nummer=2] 'alfa' respectievelijk 'beta' +%I +%I Het nummer heeft dus betrekking op het volgnummer in de +%I opgegeven reeks. +%P +%I Bij de tweede manier worden eerste de alternatieven +%I gedefinieerd: +%I +%I \definieerinvulwoord{een,alfa} +%I \definieerinvulwoord{twee,beta} +%I +%I die vervolgens worden opgeroepen: +%I +%I bla \invulwoord[+] bla bla bla bla bla bla bla bla bla +%I bla bla bla bla bla bla bla bla bla bla \invulwoord[+]. +%I +%I De mogelijke instellingen komen overeen met die van de +%I eerste manier. +%P +%I De derde manier is een variant op de tweede. Bij grote +%I teksten kan men het overzicht kwijtraken. Het is daarom +%I mogelijk 'logische' namen toe te kennen aan woorden. +%I +%I \definieerinvulwoord[a]{een,alfa} +%I \definieerinvulwoord[b]{twee,beta} +%I +%I die vervolgens worden opgeroepen: +%I +%I bla \invulwoord[a] bla bla bla bla bla bla bla bla bla +%I bla bla bla bla bla bla bla bla bla bla \invulwoord[b]. +%I +%I Dit maakt het bovendien mogelijk woorden meerdere malen +%I (in een willekeurige volgorde op te roepen: +%I +%I bla \invulwoord[a] bla \invulwoord[b] bla bla bla bla +%I bla bla bla bla \invulwoord[b] bla bla \invulwoord[a]. +%P +%I Bij [status=leeg] wordt een streep gezet die in breedte +%I overeenkomt met het woord dat er eigenlijk hoort te +%I staan. De ingevulde tekst komt visueel daardoor overeen +%I met de in te vullen tekst, wat vergelijken vereenvoudigd. +%I +%I Met [status=reset] worden enkele tellers weer op 0 gezet. +%I Dit kan nodig zijn als meerdere invuloefeningen in een +%I tekst worden gezet. +%I +%I Als \versie[voorlopig] is ingesteld, worden bij invullers +%I zonder logische namen tussen haakjes de volgnummers +%I getoond. + +%S \startsetup +%S \command +%S [stelinvullenin] +%S \type +%S [\c!vars!] +%S \variable +%S [\c!letter] +%S [\v!normaal,\v!vet,\v!schuin,\v!vetschuin,\v!type,\v!kap, +%S \v!klein...,\c!command!] +%S [\v!vet] +%S \variable +%S [\c!links] +%S [\c!text!] +%S [] +%S \variable +%S [\c!rechts] +%S [\c!text!] +%S [] +%S \variable +%S [\c!status] +%S [\v!leeg,\v!vol,\v!reset] +%S [\v!vol] +%S \variable +%S [\c!nummer] +%S [\c!number!] +%S [1] +%S \variable +%S [\c!lijn] +%S [\v!aan,\v!uit] +%S [\v!aan] +%S \stopsetup + +%S \startsetup +%S \command +%S [invulwoord] +%S \type +%S [\c!ref!,\c!opt!\c!val!\c!opt!\c!args!] +%S \value +%S [\c!text!] +%S \stopsetup + +%S \startsetup +%S \command +%S [definieerinvulwoord] +%S \type +%S [\c!ref!,\c!opt!\c!val!\c!args!] +%S \value +%S [\c!text!] +%S \stopsetup + +% Mogelijke uitbreidingen +% +% - [breedte=<maat>,passend,ruim] +% - invullijst met nummers +% - weergeven lijst tijdens definitie blokkeren +% - door elkaar definieren + +\unprotect + +\definesystemvariable {iv} + +\definereferenceconstant {fillin} {:iv:} + +\newcount\invulteller \newcount\invulput \newcount\invulget + +\def\stelinvullenin + {\dosingleargument\dostelinvullenin} + +\def\dostelinvullenin[#1]% + {\getparameters[\??iv][#1]% + \doif\@@ivstate\v!reset + {\global\invulput\zerocount + \global\invulget\zerocount + \let\@@ivstate\empty}} + +\def\definieerinvulwoord + {\dosingleempty\dodefinieerinvulwoord} + +\def\dodefinieerinvulwoord[#1]#2% + {\iffirstargument + \setgvalue{\r!fillin#1}{\simpleinvulwoord{#2}}% + \else + \global\advance\invulput \plusone + \setgvalue{\r!fillin\the\invulput}{\simpleinvulwoord{#2}}% + \fi + \doifconcepttracing + {\ifnum\invulput>\zerocount + \setbox\scratchbox\hbox{~\ttx(\the\invulput)}% + \wd\scratchbox\zeropoint + \box\scratchbox + \par + \fi}} + +\def\dosimpleinvulwoord#1% + {\ifnum\@@ivnumber>\zerocount \advance\invulteller \plusone \fi + \ifnum\invulteller=\@@ivnumber\relax + \bgroup + \doconvertfont\@@ivstyle + {\@@ivleft + \doifelse\@@ivstate\v!empty + {\doifelse\@@ivrule\v!on\leeginvulwoord\geeninvulwoord} + {\doifelse\@@ivrule\v!on\underbar \firstofoneargument}% + {#1}% + \@@ivright}% + \egroup + \fi}% + +\def\simpleinvulwoord#1% + {\ifnum\@@ivnumber>0 + \invulteller\zerocount + \processcommalist[#1]\dosimpleinvulwoord + \else + \dosimpleinvulwoord{#1}% + \fi} + +\def\complexinvulwoord[#1]% + {\bgroup + \doifsomething{#1} + {\global\advance\invulget \plusone + \doconvertfont\@@ivstyle + {\@@ivleft\getvalue{\r!fillin\the\invulget}\@@ivright}} + {\doconvertfont\@@ivstyle + {\@@ivleft\getvalue{\r!fillin #1}\@@ivright}}% + \egroup} + +\definecomplexorsimple\invulwoord + +\def\leeginvulwoord#1% + {{\let\redounderbar\dodounderbar + \def\dodounderbar##1{\redounderbar{\hphantom{##1}}}% + \underbar{#1}}} + +\def\geeninvulwoord#1% + {{\def\dodounderbar##1{\hphantom{##1}}% + \underbar{#1}}} + +% when nummer > 0, then commalist processing; beware of $(1,2)$, use { } there + +\stelinvullenin + [\c!number=0, + \c!style=\v!bold, + \c!rule=\v!on, + \c!left=, + \c!right=, + \c!state=] + +\protect \endinput diff --git a/tex/context/modules/mkii/m-streams.mkii b/tex/context/modules/mkii/m-streams.mkii new file mode 100644 index 000000000..a8589a89c --- /dev/null +++ b/tex/context/modules/mkii/m-streams.mkii @@ -0,0 +1,446 @@ +%D \module +%D [ file=m-streams, +%D version=2006.03.21, +%D title=\CONTEXT\ Modules, +%D subtitle=Streams, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D First we implement a simple left||right synchronization +%D mechanism, which we may perfect and extend over time. + +\unprotect + +\defineoutputstream [\v!left] +\defineoutputstream [\v!right] + +\definemarknote[\v!left] +\definemarknote[\v!right] + +\startsetups stream:\v!left:bottom + \flushmarknotes[\v!left] +\stopsetups +\startsetups stream:\v!right:bottom + \flushmarknotes[\v!right] +\stopsetups +\startsetups stream:\v!left:reset + \erasemarknotes[\v!left] +\stopsetups +\startsetups stream:\v!right:reset + \erasemarknotes[\v!right] +\stopsetups + +\def\LeftNote {\setmarknote [\v!left]} % {#1} +\def\RightNote {\setmarknote [\v!right]} % {#1} +\def\SwitchToLeft {\enableoutputstream [\v!left]} +\def\SwitchToRight {\enableoutputstream [\v!right]} +\def\SwitchToNormal {\enableoutputstream [\s!default]} +\def\SynchronizeLeftAndRight{\synchronizeoutputstreams[\v!left,\v!right]} +\def\FlushLeftAndRight {\flushoutputstreampages [\v!left,\v!right]} + +\protect + +% \topskip \strutheight +% \splittopskip\strutheight + +%D Example of usage: +%D +%D \starttyping +%D \nopenalties \setupinterlinespace[top=height] \setupcolors[state=start] +%D +%D \showgrid \showstruts +%D +%D \starttext +%D +%D \title{Whatever} \page +%D +%D \dorecurse {5} { +%D \let\RecurseLevel\recurselevel +%D \SwitchToLeft \dorecurse{10}{\dontleavehmode{\tf\RecurseLevel:l \begstrut \input tufte \endstrut \endgraf}} +%D \SwitchToRight \dorecurse{10}{\dontleavehmode{\sl\RecurseLevel:r \begstrut \input knuth \endstrut \endgraf}} +%D \SwitchToNormal \SynchronizeLeftAndRight +%D \SwitchToLeft \dorecurse{10}{\dontleavehmode{\bf\RecurseLevel:l \begstrut \input zapf \endstrut \endgraf}} +%D \SwitchToRight \dorecurse{10}{\dontleavehmode{\bs\RecurseLevel:r \begstrut \input davis \endstrut \endgraf}} +%D \SwitchToNormal \SynchronizeLeftAndRight +%D } +%D +%D \FlushLeftAndRight +%D +%D \stoptext +%D \stoptyping +%D +%D Another example: +%D +%D \starttyping +%D \nopenalties \setupinterlinespace[top=height] \setupcolors[state=start] +%D +%D \showgrid \showstruts +%D +%D \starttext +%D +%D \SwitchToNormal \FlushLeftAndRight \page +%D +%D \def\StartCouple{\page\SwitchToNormal} +%D \def\StopCouple {\SwitchToNormal \SynchronizeLeftAndRight \FlushLeftAndRight} +%D +%D \def\Original {\SwitchToNormal\SynchronizeLeftAndRight\SwitchToLeft} +%D \def\Translation{\SwitchToRight} +%D +%D \StartCouple +%D \dorecurse{10} { +%D \Original o: \begstrut \inright{\blackrule}\input tufte \endstrut \LeftNote {tufte} \endgraf +%D \Translation t: \begstrut \inleft {\blackrule}\input zapf \endstrut \RightNote{zapf} \endgraf +%D \Original o: \begstrut \inright{\blackrule}\input knuth \endstrut \LeftNote {knuth} \endgraf +%D \Translation t: \begstrut \inleft {\blackrule}\input davis \endstrut \RightNote{davis} \endgraf +%D \Original o: \begstrut \inright{\blackrule}\input douglas \endstrut \LeftNote {douglas} \endgraf +%D \Translation t: \begstrut \inleft {\blackrule}\input bryson \endstrut \RightNote{bryson} \endgraf +%D } +%D \StopCouple +%D \stoptext +%D \stoptyping + +%D Next we implement stream layers. + +\unprotect + +\def\overloadtextwidth#1% + {\makeupwidth#1\relax + \textwidth\makeupwidth + \hsize\makeupwidth} + +\startsetups streamlayer:default:settings + % set hsize etc, like \overloadtextwidth{12cm} +\stopsetups + +\startsetups streamlayer:default:extras + % flush goodies, like local floats +\stopsetups + +\startsetups streamlayer:default:place + \setlayer + [\currentstreamlayer] + [\c!preset=\v!left\v!top] + {\outputstreambox[\currentstreamlayer]}% +\stopsetups + +\startsetups streamlayer:default:copy + \setlayer + [\currentstreamlayer] + [\c!preset=\v!left\v!top] + {\outputstreamcopy[\currentstreamlayer]}% +\stopsetups + +\startsetups streamlayer:default:reset + \outputstreambox[\currentstreamlayer] +\stopsetups + +\startsetups streamlayer:default:flush + \tightlayer[\currentstreamlayer] +\stopsetups + +\def\definestreamlayer + {\dodoubleempty\dodefinestreamlayer} + +\def\dodefinestreamlayer[#1][#2]% + {\defineoutputstream[#1]% + \defineoutputstream[main]% + \definelayer[#1][\c!method=\v!fit,\c!width=\textwidth,#2]} + +\def\dostreamsetups#1% + {\doifsetupselse{streamlayer:\currentstreamlayer:#1} + {\directsetup{streamlayer:\currentstreamlayer:#1}} + {\directsetup{streamlayer:\s!default:#1}}} + +\def\startstreamlayer[#1]% + {\bgroup +% \def\startstreamlayer[##1]{\bgroup\let\stopstreamlayer\egroup}% + \edef\currentstreamlayer{#1}% + \enableoutputstream[main]% + \synchronizeoutput + \enableoutputstream[\currentstreamlayer]% + \bgroup + \dostreamsetups{settings}} + +\def\stopstreamlayer + {\endgraf + \egroup + \disableoutputstream % \enableoutputstream[\s!default]% + \outputstreambox[main]% +% \dostreamsetups{place}% +% \dostreamsetups{extras}% +% \dostreamsetups{flush}% + \egroup} + +\def\preparestreamlayer{\dosingleempty\dopreparestreamlayer} +\def\flushstreamlayer {\dosingleempty\doflushstreamlayer } +\def\placestreamlayer {\dosingleempty\doplacestreamlayer } + +\def\dopreparestreamlayer[#1]% + {\bgroup + \edef\currentstreamlayer{\iffirstargument#1\else\currentstreamlayer\fi}% + \dostreamsetups{place}% + \dostreamsetups{extras}% +% \dostreamsetups{flush}% + \egroup} + +\def\doflushstreamlayer[#1]% + {\bgroup + \edef\currentstreamlayer{\iffirstargument#1\else\currentstreamlayer\fi}% + \dostreamsetups{flush}% + \egroup} + +\def\doplacestreamlayer[#1]% + {\preparestreamlayer[#1]% + \flushstreamlayer[#1]} + +\protect + +%D Usage: + +%D \starttyping +%D \setupinterlinespace[top=height] +%D +%D \setupcolors[state=start] +%D +%D \definestreamlayer[block] +%D +%D \definemeasure[localtextwidth] [\dimexpr.7\textwidth\relax] +%D \definemeasure[localfloatwidth][\dimexpr.3\textwidth-2\bodyfontsize\relax] +%D +%D \startsetups streamlayer:block:settings +%D \hsize=\measure{localtextwidth} +%D \setupfloat[figure][maxwidth=\measure{localfloatwidth}] +%D \stopsetups +%D +%D \startsetups streamlayer:block:extras +%D \setuplocalfloats +%D [before=\blank, +%D after=\blank, +%D inbetween=\blank] +%D \setbox\scratchbox\vbox{\hsize\measure{localfloatwidth}\getlocalfloats} +%D \ifdim\ht\scratchbox>\thelayerheight\currentstreamlayer\relax +%D % more float than text +%D \setlayerframed +%D [\currentstreamlayer] +%D [preset=righttop] +%D [frame=off, +%D offset=overlay] +%D {\box\scratchbox} +%D \else +%D % more text than float +%D \setuplocalfloats +%D [before=\vfill, +%D after=\removedepth\vfill, +%D inbetween=\removedepth\vfill] +%D \setlayerframed +%D [\currentstreamlayer] +%D [preset=righttop] +%D [frame=off, +%D offset=overlay] +%D {\vbox to \thelayerheight\currentstreamlayer {\hsize\measure{localfloatwidth}\getlocalfloats}} +%D \fi +%D \resetlocalfloats +%D \stopsetups +%D +%D \startsetups streamlayer:block:place +%D \setlayerframed +%D [\currentstreamlayer] +%D [preset=lefttop] +%D [frame=off, +%D offset=overlay] +%D {\outputstreambox[\currentstreamlayer]}% +%D \stopsetups +%D +%D \startsetups streamlayer:block:flush +%D \framed +%D [offset=overlay, +%D frame=off, +%D background=color, +%D backgroundcolor=red] +%D {\tightlayer[\currentstreamlayer]} +%D \stopsetups +%D +%D \setupbodyfont[small] +%D +%D \starttext +%D +%D \dorecurse {10} { +%D \startstreamlayer[block] +%D \title{Sample \recurselevel} +%D \input tufte \endgraf +%D \placefigure[local]{}{} +%D \placefigure[local]{}{} +%D \ifodd\recurselevel\relax \placefigure[local]{}{} \fi +%D \startitemize[columns] +%D \item xxx +%D \item xxx +%D \item xxx +%D \item xxx +%D \item xxx +%D \stopitemize +%D \stopstreamlayer +%D \placestreamlayer[block] +%D } +%D +%D \dorecurse {10} { +%D \startstreamlayer[block] +%D \title{Sample \recurselevel} +%D \startcolumns +%D \input tufte +%D \stopcolumns +%D \stopstreamlayer +%D \placestreamlayer[block] +%D } +%D +%D \stoptext +%D \stoptyping + +\def\starttextstreamlayer + {\startstreamlayer} + +\def\stoptextstreamlayer + {\endgraf + % maybe depth if no proper depth and no skip + \removelastskip + \stopstreamlayer} + +\def\placetextstreamlayer{\placestreamlayer} + +%D \starttyping +%D \definestreamlayer[whatever][width=12cm] +%D +%D \startstreamlayer[whatever] +%D \startitemize[columns,two][after=] +%D \item one +%D \item two +%D \item three +%D \item four +%D \stopitemize +%D \stopstreamlayer +%D +%D \framed[strut=no,align=normal]{\placestreamlayer[whatever]\obeydepth} +%D +%D \starttextstreamlayer[whatever] +%D \startitemize[columns,two] +%D \item one +%D \item two +%D \item three +%D \item four +%D \stopitemize +%D \stoptextstreamlayer +%D +%D \framed[strut=no]{\placetextstreamlayer[whatever]} +%D \stoptyping + +\endinput + +\setupinterlinespace[top=height] + +\setupcolors[state=start] + +\definestreamlayer[block] + +\definemeasure[localtextwidth] [\dimexpr.7\textwidth\relax] +\definemeasure[localfloatwidth][\dimexpr.3\textwidth-2\bodyfontsize\relax] + +\startsetups streamlayer:block:settings + \hsize=\measure{localtextwidth} + \setupfloat[figure][maxwidth=\measure{localfloatwidth}] +\stopsetups + +\startsetups streamlayer:block:extras + \setuplocalfloats + [before=\whitespace\blank, + after=\whitespace\blank, + inbetween=\whitespace\blank] + \setbox\scratchbox\vbox{\hsize\measure{localfloatwidth}\getlocalfloats} + \ifdim\ht\scratchbox>\thelayerheight\currentstreamlayer\relax + % more float than text + \setlayerframed + [\currentstreamlayer] + [preset=righttop] + [frame=off, + offset=overlay] + {\box\scratchbox} + \else + % more text than float + \setuplocalfloats + [before=\vfill, + after=\removedepth\vfill, + inbetween=\removedepth\vfill] + \setlayerframed + [\currentstreamlayer] + [preset=righttop] + [frame=off, + offset=overlay] + {\vbox to \thelayerheight\currentstreamlayer {\hsize\measure{localfloatwidth}\getlocalfloats}} + \fi + \resetlocalfloats +\stopsetups + +\startsetups streamlayer:block:place + \setlayerframed + [\currentstreamlayer] + [preset=lefttop] + [frame=off, + offset=overlay] + {\outputstreambox[\currentstreamlayer]}% +\stopsetups + +\startsetups streamlayer:block:flush + \framed + [offset=overlay, + frame=off, + background=color, + backgroundcolor=red] + {\tightlayer[\currentstreamlayer]} +\stopsetups + +\setupbodyfont[small] + +\starttext + +% \definestreamlayer[block] +% +% \startstreamlayer[block] +% \title{Sample \recurselevel} +% \startcolumns +% \dorecurse{4}{\input tufte \par} +% \stopcolumns +% \stopstreamlayer +% \placestreamlayer[block] + +\dorecurse {10} { + \startstreamlayer[block] + \title{Sample \recurselevel} + \input tufte \endgraf + \placefigure[local]{}{} + \placefigure[local]{}{} + \ifodd\recurselevel\relax \placefigure[local]{}{} \fi + \startitemize[columns] + \item xxx + \item xxx + \item xxx + \item xxx + \item xxx + \stopitemize + \stopstreamlayer + \placestreamlayer[block] +} + +\dorecurse {10} { + \startstreamlayer[block] + \title{Sample \recurselevel} + \startcolumns + \input tufte + \stopcolumns + \stopstreamlayer + \placestreamlayer[block] +} + +\stoptext diff --git a/tex/context/modules/mkii/s-mag-01.mkii b/tex/context/modules/mkii/s-mag-01.mkii new file mode 100644 index 000000000..e2d30f4e5 --- /dev/null +++ b/tex/context/modules/mkii/s-mag-01.mkii @@ -0,0 +1,438 @@ +%D \module +%D [ file=s-mag-01, +%D version=2002.12.14, +%D title=\CONTEXT\ Style File, +%D subtitle=\CONTEXT\ Magazine Base Style, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% This style is used for producing explanationary documents. +% Don't misuse it for other purposes, since it may confuse +% users. Don't change the title either, since it provides a +% way to categorize documents. Numbers are disabled in +% instances produced outside PRAGMA ADE. +% +% The layout setup is such that one has several text areas +% available: headers and footers, margins and edges as well +% as the main text area. The surrounding (gray) makes the +% main page stand out and is suitable for viewing in spread +% mode. +% +% Since this style is under constant construction, messing +% around with settings will produce unwanted side effects. +% So, if some feature or settings is needed, let me know. + +% todo: mp frames + +\setvariables[magazine][number=0] +\setvariables[magazine][author=] +\setvariables[magazine][title={Zero Issue}] +\setvariables[magazine][date=\currentdate] + +% These are reserved for PRAGMA-ADE, don't use them yourself! + +% \setvariables[magazine][main=Tricky] +% \setvariables[magazine][main=Update] +% \setvariables[magazine][main=HOWTO] + +% \setvariables[magazine][main=This Way] % preludes to a/the manual +% \setvariables[magazine][main=A Better Way] % dirty versus clean +% \setvariables[magazine][main=No Way] % how users should not do it +% \setvariables[magazine][main=Your Way] % how users do it +% \setvariables[magazine][main=My Way] % how users do it +% \setvariables[magazine][main=Our Way] % how we do things at pragma +% \setvariables[magazine][main=Their Way] % how to do latex things in context + +\setvariables[magazine][main=My Way] + +\startmode[atpragma] + \setvariables[magazine][main=This Way] +\stopmode + +\definepapersize + [magazine] + [width=\dimexpr\paperwidth-.1\paperwidth\relax, + height=\dimexpr\paperheight-.1\paperheight\relax] + +\setuppapersize + [magazine] + [A4] + +\setupinteractionscreen + [option=doublesided] + +\definecolor[OuterColor][s=.3] +\definecolor[InnerColor][s=.8] +\definecolor[MainColor] [s=.2] +\definecolor[TitleColor][s=.7] + +\definecolor[MyRed] [r=.6] +\definecolor[MyGreen][g=.6] +\definecolor[MyBlue] [b=.6] + +\startuseMPgraphic{paper} + sh := define_circular_shade(a,a,0,bbheight(OverlayBox), + \MPcolor{InnerColor},\MPcolor{OuterColor}) ; + fill OverlayBox withshade sh ; +\stopuseMPgraphic + +\startreusableMPgraphic{middlepaper} + pair a ; a := center OverlayBox ; + \includeMPgraphic{paper} +\stopreusableMPgraphic + +\startreusableMPgraphic{rightpaper} + pair a ; a := .5[urcorner OverlayBox,lrcorner OverlayBox] ; + \includeMPgraphic{paper} +\stopreusableMPgraphic + +\startreusableMPgraphic{leftpaper} + pair a ; a := .5[ulcorner OverlayBox,llcorner OverlayBox] ; + \includeMPgraphic{paper} +\stopreusableMPgraphic + +\startreusableMPgraphic{page} + fill OverlayBox withcolor white ; +\stopreusableMPgraphic + +\startusableMPgraphic{text} + StartPage ; + for i = Header,Text,Footer : + for j = LeftEdge, LeftMargin, Text, RightMargin, RightEdge : + draw Field[i][j] withpen pencircle scaled .5pt ; + endfor ; + endfor ; + StopPage ; + setbounds currentpicture to Field[Text][Text] ; +\stopusableMPgraphic + +\startsetups[paper] + + \doifmodeelse{*makeup} + {\reuseMPgraphic{middlepaper}} + {\doifoddpageelse + {\reuseMPgraphic{rightpaper}} + {\reuseMPgraphic{leftpaper}}} + +\stopsetups + +\defineoverlay[paper] [\setups{paper}] +\defineoverlay[page] [\reuseMPgraphic{page}] +\defineoverlay[text] [\doifmode{frame}{\useMPgraphic{text}}] + +\setupbackgrounds [paper] [background=paper] +\setupbackgrounds [page] [background={page,title}] +\setupbackgrounds [text] [background=text] + +\definelayer + [title] + [state=repeat, + hoffset=-1cm, + voffset=1cm, + width=\paperwidth, + height=\paperheight] + +\setupoutput + [pdftex] + +\setuplayout + [width=middle, + topspace=1.5cm, + height=middle, + header=1.5cm, + footer=1cm, + %grid=yes, + headerdistance=.25cm, + footerdistance=.5cm, + backspace=3cm, + margin=1.5cm, + margindistance=.25cm, + edge=.75cm, + edgedistance=.25cm, + bottomdistance=1.5cm, + bottom=.1\printpaperheight] + +\definelayout + [makeup] + [topspace=1cm, + backspace=1cm, + header=0pt, + footer=0pt, + bottom=0pt] + +\setuppagenumbering + [alternative=doublesided] + +\setupcolors + [state=start] + +\usetypescript + [palatino][\defaultencoding] + +\setupbodyfont + [palatino,10pt] + +\setuptolerance + [verytolerant,stretch] + +\appendtoks\setups[papershift]\to\beforeeverypage + +\startsetups[papershift] + + \setuppapersize[top=\vskip.5cm,bottom=\vss] + + \doifmodeelse{*makeup} + {\setuppapersize[left=\hfill,right=\hfill]} + {\doifoddpageelse + {\setuppapersize[right=\hfill]} + {\setuppapersize[left=\hfill]}} + +\stopsetups + +\setupbottomtexts + [\setups{rightbanner}] [] + [] [\setups{leftbanner}] + +\startsetups [leftbanner] + + \definedfont[Regular at \the\bottomheight] + \setbox\scratchbox\hbox{\TitleColor\getvariable{magazine}{main}} + \ht\scratchbox1ex + \dp\scratchbox\zeropoint + \MainColor + \definedfont[Regular sa 2] + \doifsomething{\getvariable{magazine}{number}} + {\doifnot{\getvariable{magazine}{number}}{0} + {\#\getvariable{magazine}{number}}} + \quad + \currentdate + \quad + \scale[height=.25\bottomheight]{\box\scratchbox} + \quad + \hbox to 1.5em{\hss\pagenumber\hss} + \quad + \hskip-\backspace + +\stopsetups + +\startsetups [rightbanner] + + \definedfont[Regular at \the\bottomheight] + \setbox\scratchbox\hbox{\TitleColor\getvariable{magazine}{main}} + \ht\scratchbox1ex + \dp\scratchbox\zeropoint + \MainColor + \hskip-\backspace + \definedfont[Regular sa 2] + \quad + \hbox to 1.5em{\hss\pagenumber\hss} + \quad + \scale[height=.25\bottomheight]{\box\scratchbox} + \quad + \currentdate + \quad + \doifmode{atpragma}{\#\getvariable{magazine}{number}} + +\stopsetups + +\startsetups[titlepage] + + \disablemode[frame] + + \setuplayout[makeup] + + \startstandardmakeup[doublesided=no] + + \dontcomplain + + \definelayer + [makeup] + [width=\textwidth, + height=\textheight] + + \setlayerframed + [makeup] + [corner={left,top},location={right,bottom}] + [frame=off, + foregroundcolor=MainColor] + {\scale + [width=\makeupwidth] + {\definedfont[Regular sa 10]% + \getvariable{magazine}{main}}} + + \setlayerframed + [makeup] + [corner={right,top},location={left},y=.4\textheight] + [frame=off, + foregroundcolor=MainColor, + width=\textwidth, + align=left] + {\definedfont[Regular sa 2.5]\setupinterlinespace + \startmode[atpragma] + \strut \ConTeXt\ magazine \#\getvariable{magazine}{number}\endgraf + \stopmode + \strut \getvariable{magazine}{date} \endgraf + \blank + \strut \getvariable{magazine}{title}\endgraf + \doifsomething{\getvariable{magazine}{author}} + {\strut \getvariable{magazine}{author}\endgraf} + \doifsomething{\getvariable{magazine}{affiliation}} + {\strut \getvariable{magazine}{affiliation}\endgraf}} + + \setlayerframed + [makeup] + [corner={right,bottom},location={left,top}] + [frame=off, + align=normal, + width=.8\textwidth, + foregroundcolor=MainColor] + {\getbuffer[abstract]} + + \flushlayer[makeup] + + \stopstandardmakeup + + \setuplayout[reset] + +\stopsetups + +\startsetups[listing] + + \page \disablemode[frame] + + \setuptexttexts [][] \setuptexttexts [] + \setupheadertexts[][] \setupheadertexts[source code of this document] + \setupfootertexts[][] \setupfootertexts[] + + \start \dontcomplain + + \typefile[TEX]{\inputfilename} + + \stop + +\stopsetups + +\startsetups[lastpage] + + \page \disablemode[frame] \page[even] + + \doifoddpageelse + {} + {\setuplayout[makeup] + \startstandardmakeup[doublesided=no,page=] + \stopstandardmakeup + \setuplayout[reset]} + +\stopsetups + +\startsetups[title] + + \disablemode[frame] + + \setlayerframed + [title] + [corner={left,top},location={left,bottom}, + rotation=90] + [frame=off, + foregroundcolor=MainColor] + {\definedfont[RegularBold sa 2]\strut\getvariable{magazine}{title}} + + \setlayerframed + [title] + [corner={right,top}, + rotation=270] + [frame=off, + foregroundcolor=MainColor] + {\definedfont[RegularBold sa 2]\strut\getvariable{magazine}{title}} + +\stopsetups + +\startbuffer[abstract] + % no abstract +\stopbuffer + +\setuphead + [chapter] + [page=yes, + after={\blank[2*big]}, + color=MainColor, + style=\bfc] + +\setuphead + [section] + [before={\blank[2*big]}, + after=\blank, + color=MainColor, + style=\bfb] + +\setuphead + [subsection] + [before=\blank, + after=, + color=MainColor, + style=\bf] + +\setupwhitespace + [big] + +\definetyping[xtyping] [style=\ttx] +\definetyping[xxtyping][style=\ttxx] + +\definetypeface + [narrowtt] [tt] + [mono] [modern-cond] [default] [encoding=\defaultencoding] + +\definetyping[ntyping] \setuptyping[ntyping][style=\narrowtt] +\definetype [ntype] \setuptype [ntype] [style=\narrowtt] + +\doifnotmode{demo}{\endinput} + +% \usemodule[mag-01] + +\setvariables + [magazine] + [title={Introduction}, + author=Hans Hagen, + affiliation=PRAGMA ADE, + date=Januari 2003, + number=0] + +\startbuffer[abstract] + This is the zero issue of a semi periodical. The + associated style can be used by \CONTEXT\ users to + typeset and publish their own issues. +\stopbuffer + +\starttext \setups [titlepage] \setups [title] + +\setupheadertexts[welcome] + +This is the zero issue of a range of \CONTEXT\ related +publications, in most cases short introductions to new +functionality. The style may be used by users for providing +similar documents, but preferably not for other purposes, +since it may confuse readers in their expectations. + +We've chosen a layout which is more functional than +beautiful. This layout provides several text areas: headers +and footers, margins and edges as well as a main text area. +The surrounding (gray) makes the main page (which is +slightly smaller than A4) stand out and is suitable for +viewing in spread mode. + +The documents produced at \PRAGMA\ are called {\bf This +Way}, user documents gets the title {\bf My Way}. The +\PRAGMA\ issues are numbered. We strongly advise you not to +use the \type {mag-} prefix for your issues, since this may +lead to clashes with files distributed by \PRAGMA. + +\setups [listing] + +\setups [lastpage] + +\stoptext diff --git a/tex/context/modules/mkii/s-pre-01.mkii b/tex/context/modules/mkii/s-pre-01.mkii new file mode 100644 index 000000000..89c5642f9 --- /dev/null +++ b/tex/context/modules/mkii/s-pre-01.mkii @@ -0,0 +1,404 @@ +%D \module +%D [ file=s-pre-01, +%D version=1997.07.22, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 1, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This environment can be used to typeset interactive +%D presentations. This module was first used at the 1997 \TUG\ +%D meeting. + +\usemodule[pre-general] + +%D \macros +%D {language} +%D +%D Because this module is defined in english, we default to the +%D english hyphenation patterns and labels too. + +\language + [en] + +%D \macros +%D {setupbodyfont,setuplayout} +%D +%D For screen reading, a Lucida Bright font looks nice. We use +%D a 14.4 point bodyfont for the main text, but switch back to +%D 12 points for ornaments. + +\startmode[asintended] \setupbodyfont[lbr] \stopmode + +\setupbodyfont[14.4pt] + +\setuplayout + [style=smallbodyfont] + +%D \macros +%D {setupcolors,definecolor} +%D +%D Screen presentations without color just look dull, so we +%D enable color support. We define ourselves a yellowish +%D backgroundcolor and a not too dark blue interactioncolor. + +\setupcolors + [state=start] + +\definecolor [BackgroundColor] [r=1, g=1, b=.7] +\definecolor [InteractionColor] [r=.1, g=.5, b=.8] +\definecolor [ContrastColor] [r=.9, g=.5, b=.2] + +%D \macros +%D {setuppapersize,setuplayout,setupinteractionscreen} +%D +%D +%D We use a nice large screen, and dedicate the right edge and +%D bottom part to navigational tools. We automatically set +%D the width and height of the page and start up full screen. + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=12pt, + header=0pt, + footer=0pt, + height=402pt, % 450 - 12 - 15 - 12 - 12 + 3 + bottomdistance=15pt, + bottom=12pt, + backspace=12pt, + margin=0pt, + width=fit, + edgedistance=12pt, + rightedge=96pt] + +\setupinteractionscreen + [option=max] + +%D \macros +%D {setupbackgrounds} +%D +%D We set the pagecolor to yellow except the part of the screen +%D that is used to display the running text. By seting the +%D offset to 3pt the text will not touch the yellow parts. We +%D do not set the depth. + +\setupbackgrounds + [page] + [background=color, + backgroundcolor=BackgroundColor, + offset=3pt] + +\setupbackgrounds + [text][text] + [background=color, + backgroundcolor=white] + +%D I considered the next setup too, but finaly decided to +%D comment it out. +%D +%D \starttyping +%D \setupbackgrounds +%D [bottom][text] +%D [frame=on, +%D framecolor=white] +%D \stoptyping + +%D \macros +%D {setupinteraction} +%D +%D We did not enable interactive text support yet, so let's do +%D that now. We force page reference to circumvent problems +%D with named destinations in buggy viewers. + +\setupinteraction + [page=yes, + color=InteractionColor, + contrastcolor=ContrastColor, + menu=on, + state=start] + +%D \macros +%D {setupinteractionmenu,startinteractionmenu} +%D +%D At the bottom of the screen we show two navigational bars. +%D At the left we show the subpage bar, at the right we use a +%D non default backward|/|forward bar. + +\setupinteractionmenu + [bottom] + [leftoffset=-3pt, + rightoffset=-3pt] + +\startinteractionmenu[bottom] + \txt \InteractionBar \\ + \txt \InteractionButtons \\ +\stopinteractionmenu + +%D \macros +%D {interactionbar} +%D +%D The left bar gets a white border (on the yellow background). +%D Because we don't want to typeset an empty frame when no +%D subpage bar is shown, we check for the number of subpages. + +\def\InteractionBar% + {\ifnum\nofsubpages>1 + \framed + [framecolor=white,rulethickness=1pt, + height=\bottomheight,strut=no] + {\interactionbar[alternative=f,width=.5\makeupwidth,height=1ex]} + \fi} + +%D \macros +%D {setupinteractionbar, interactionbuttons} +%D +%D The right hand buttons enable us to jump backward and forward, +%D as well as to the previous and next jump. We also enable to +%D close the presentation. + +\setupinteractionbar + [framecolor=white,rulethickness=1pt, + height=\bottomheight,strut=no] + +\def\InteractionButtons% + {\interactionbuttons + [width=15em] + [PreviousJump,NextJump, + firstpage, + firstsubpage,previouspage,nextpage,lastsubpage, + lastpage, + CloseDocument]} + +%D \macros +%D {StartTitlePage, TitlePage} +%D +%D The titlepage is rather simple and can be typeset in two +%D ways: +%D +%D \starttyping +%D \StartTitlePage +%D text \\ text \\ text +%D \StopTitlepage +%D \stoptyping +%D +%D or more straightforward: +%D +%D \starttyping +%D \TitlePage{text\\text\\text} +%D \stoptyping +%D +%D The first alternative can be used for more complicated +%D title pages. + +\def\StartTitlePage% + {\startstandardmakeup + \bfd\setupinterlinespace + \setupalign[middle] + \vfil + \let\\=\vfil} + +\def\StopTitlePage% + {\vfil\vfil\vfil + \stopstandardmakeup} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D \macros +%D {TitlePage, Topics, Topic, Subject} +%D +%D A presentation after loading this module looks like: +%D +%D \starttyping +%D \TitlePage {About Whatever\\Topics} +%D +%D \Topics {Todays Talk} +%D +%D \Topic {Some topic} +%D +%D \Subject {Alfa} +%D +%D ..... +%D +%D \Subject {Beta} +%D +%D ..... +%D \stoptyping + +%D \macros +%D {definehead} +%D +%D The commands \type{\Topic} and \type{\Subject} are defined +%D as copies of head. We use \type{\Nopic} for internal +%D purposes. + +\definehead [Topic] [chapter] +\definehead [Subject] [section] + +\definehead [Nopic] [title] + +%D \macros +%D {setuphead} +%D +%D Because chapters and sections do not make sense in +%D presentations, we use our own command for typesetting the +%D titles. Sectionnumbers are of course hidden from viewing. +%D Each topic is followed by a list of subjects that belong +%D to the topic. + +\setuphead + [Topic, Nopic, Subject] + [command=\HeadLine, + page=yes, + style=\tfb, + after=\blank, + sectionnumber=no] + +\setuphead + [Topic] + [after=\PlaceSubjectList] + +\setuphead + [Subject] + [continue=no] + +%D \macros +%D {framed, midalined} +%D +%D The command used to typeset the head lines is rather simple. +%D We just center the framed title. The frame macro optimizes +%D the alignment and at the same time enables us to typeset a +%D nice colored rule. + +\def\HeadLine#1#2% + {\midaligned + {\framed + [framecolor=BackgroundColor,rulethickness=1pt, + width=.8\hsize,align=middle,strut=no] + {#2}}} + +%D \macros +%D {setuplist} +%D +%D The subject list is automatically placed. We center each +%D subject line by using one of the default alternatives (g). We +%D could have said: +%D +%D \starttyping +%D \setuplist +%D [Subject] +%D [alternative=none, +%D command=\SubjectListLine, +%D interaction=all] +%D +%D \def\SubjectListLine#1#2#3% +%D {\midaligned{#2}} +%D \stoptyping +%D +%D But why should we complicate things when we can use +%D alternative~\type{g}. The test is only needed if one +%D does not automatically goes a new page with each subject. + +\def\PlaceSubjectList% + {\blank + \determinelistcharacteristics[Subject] + % \ifnum\utilitylistlength>0 \placelist[Subject] \fi} + \doifmode{*list}{\placelist[Subject]}} + +\setuplist + [Subject, Topic] + [alternative=g, + interaction=all, + before=, + after=] + +% %D \macros +% %D {setuptexttexts} +% %D +% %D The topics will be listed in the right edge, using: +% +% \setuptexttexts +% [edge] +% [][\TopicList] + +%D \macros +%D {setuplist, placelist,startinteractionmenu} +%D +%D The actual topic list is typeset using a \type{\vbox}. We +%D have to specify \type{criteriumcriterium=all} because otherwise no +%D list will be typeset. (By default lists are typeset +%D locally.) + +\startinteractionmenu[right] + \placelist + [Topic] + [alternative=f, % command, % none, + maxwidth=\hsize, + width=\hsize, + offset=0pt, + criterium=all, + align=left, + style=\setsmallbodyfont\bfx] +\stopinteractionmenu + +\def\Topics#1% temporary hack + {\Nopic{#1} + \placelist[Topic][criterium=all]} + +\def\Subjects% + {} + +%D \macros +%D {setuptexttexts, button} +%D +%D During a presentation, we want to use the cursor to point to +%D parts of the text. Furthermore we want to be able to jump to +%D the next page, without the need to move the cursor on buttons. +%D Therefore we make the text part of the screen into an +%D invisible button. + +\setuptexttexts + [\GotoNextPage][] + +\def\GotoNextPage + {\button[width=\hsize,height=\vsize,frame=off]{}[nextpage]} + +%D \macros +%D {setupsubpagenumber} +%D +%D The left bottom navigation bar shows the subpages, which will +%D be counted by text. One can change this in the preentation +%D itself by saying \type {[way=byTopic]}. + +\setupsubpagenumber + [way=bytext, % Topic, + state=start] + +\doifnotmode{demo}{\endinput} + +%D The (rather silly) demo section. + +\starttext + +\TitlePage{Title Page\\pre-original} + +\Topics{Some Nice Quotes} + +\Topic{A Few} + +\Subject{Knuth} \input knuth +\Subject{Tufte} \input tufte + +\Topic{Some More} + +\Subject{Zapf} \input zapf +\Subject{Bryson} \input bryson + +\stoptext diff --git a/tex/context/modules/mkii/s-pre-02.mkii b/tex/context/modules/mkii/s-pre-02.mkii new file mode 100644 index 000000000..d7a6fe458 --- /dev/null +++ b/tex/context/modules/mkii/s-pre-02.mkii @@ -0,0 +1,381 @@ +%D \module +%D [ file=s-pre-02, +%D version=1998.04.21, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 2, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This environment can be used to typeset interactive +%D presentations. This module was first used at the 1998 +%D publishers conference of the European Portable Document +%D Association (now merged into a graphics association). + +\usemodule[pre-general] + +%D \macros +%D {setupbodyfont, switchtobodyfont, setuplayout} +%D +%D At \PRAGMA\ we prefer using the Lucida Bright fonts, but +%D one can of course load another typeface. + +\startmode[asintended] \setupbodyfont[lbr] \stopmode + +\setupbodyfont[14.4pt] + +\setuplayout + [style=smallbodyfont] + +%D \macros +%D {setuppapersize, setuplayout} +%D +%D The papersize suits the screen dimensions. The layout is +%D rather simple. We use the whole width of the screen and only +%D have navigational tools at the bottom of the screen. + +\setuppapersize + [S6][S6] + +\setuplayout + [backspace=1cm, + topspace=1cm, + margin=0pt, + header=0pt, + footer=0pt, + bottomdistance=.875cm, + bottom=1cm, + width=fit, + height=fit] + +%D \macros +%D {setupwhitespace, setuptyping} +%D +%D We don't have much height, so we use a more cramped +%D spacing. Verbatim text looks better when indented. +%D + +\setupwhitespace + [medium] + +\setuptyping + [margin=standard] + +%D \macros +%D {definecolor, setupcolors} +%D +%D Of course we enable color. We define some logical colors, +%D of which most default to the same green shade. + +\definecolor [BackgroundColor] [r=.8, g=.8, b=.8] +\definecolor [OrnamentColor] [r= 0, g=.7, b=.4] + +\setupcolors + [state=start] + +%D \macros +%D {setupinteraction, setupinteractionscreen} +%D +%D We still have to enable interaction mode. We go full +%D screen! + +\setupinteraction + [state=start, + color=OrnamentColor, + contrastcolor=OrnamentColor] + +\setupinteractionscreen + [option=max, + width=fit, + height=fit] + +%D \macros +%D {setupitemize} +%D +%D And why not bring some color in itemizations too? + +\setupitemize + [color=OrnamentColor] + +%D \macros +%D {defineoverlay, setupbackgrounds} +%D +%D The navigational elements and the backgrounds are +%D provided by \METAPOST. +%D +%D When \METAPOST\ is used, it makes sense to generate the +%D graphics at runtime. This is supported when one enables +%D system calls in the local \type {texmf.cnf} file and add the +%D switch \type {\runMPgraphicstrue} to the local file \type +%D {cont-sys.tex}. When direct processing is disabled or not +%D supported, \TEXEXEC\ will take care of graphic generation. + +\startuniqueMPgraphic{PageBackground} + fill unitsquare + xyscaled(OverlayWidth,OverlayHeight) + withcolor OverlayColor ; + draw unitsquare + xyscaled(OverlayWidth,OverlayHeight) + enlarged (-2*OverlayLineWidth) + withpen pencircle scaled OverlayLineWidth + withcolor OverlayLineColor ; +\stopuniqueMPgraphic + +\defineoverlay + [PageBackground] + [\uniqueMPgraphic{PageBackground}] + +\setupbackgrounds + [page] + [background=PageBackground, + backgroundcolor=BackgroundColor, + rulethickness=.125cm, + framecolor=OrnamentColor] + +%D \macros +%D {setuptexttexts} +%D +%D By clicking on the text area, one goes to the next page. +%D We hook this feature into the text backgrounds. + +\startuniqueMPgraphic{TextBackground} + draw unitsquare + xyscaled(OverlayWidth,OverlayHeight) + enlarged (4*OverlayLineWidth) + withpen pencircle scaled OverlayLineWidth + withcolor OverlayLineColor ; +\stopuniqueMPgraphic + +\defineoverlay + [TextBackground] + [\uniqueMPgraphic{TextBackground}] + +\defineoverlay + [NextPage] + [\overlaybutton{nextpage}] + +\setupbackgrounds + [text] + [background={TextBackground,NextPage}, + backgroundcolor=BackgroundColor, + rulethickness=.0625cm, + framecolor=OrnamentColor] + +%D \macros +%D {setupinteractionmenu,startinteractionmenu} +%D +%D At the bottom of the screen, we show three buttons. These +%D direct us to the previous or next jump or exit the document. + +\setupMPvariables[RightArrow][height=\bottomheight] +\setupMPvariables[LeftArrow] [height=\bottomheight] +\setupMPvariables[Circle] [height=\bottomheight] +\setupMPvariables[UpArrow] [height=\bottomheight] + +\startuniqueMPgraphic{RightArrow}{height} + z1=(0,0) ; z2=(\MPvar{height},.5y3) ; z3=(0,\MPvar{height}) ; + drawfill z1--z2--z3--cycle + withpen pencircle scaled (\MPvar{height}/5) + withcolor \MPcolor{OrnamentColor} ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{LeftArrow}{height} + z1=(\MPvar{height},0) ; z2=(0,.5y3) ; z3=(\MPvar{height},\MPvar{height}) ; + drawfill z1--z2--z3--cycle + withpen pencircle scaled (\MPvar{height}/5) + withcolor \MPcolor{OrnamentColor} ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{Circle}{height} + drawfill fullcircle scaled \MPvar{height} + withpen pencircle scaled (\MPvar{height}/5) + withcolor \MPcolor{OrnamentColor} ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{UpArrow}{height} + z1=(0,0) ; z2=(\MPvar{height},0) ; z3=(.5x2,\MPvar{height}) ; + drawfill z1--z2--z3--cycle + withpen pencircle scaled (\MPvar{height}/5) + withcolor \MPcolor{OrnamentColor} ; +\stopuniqueMPgraphic + +\setupinteractionmenu + [bottom] + [state=start, + frame=off, + width=.3\textwidth, + height=\bottomheight] + +\setupinteraction + [menu=on] + +\def\WhateverButton + {\doifreferencefoundelse{Whatever} + {\raw [Whatever] \uniqueMPgraphic{UpArrow} \\} + {}} + +\startinteractionmenu[bottom] + \but [Topics] \\ % secret button + \hfill + \WhateverButton % user specific + \kern2\bottomheight + \raw [previouspage] \uniqueMPgraphic{LeftArrow} \\ + \kern.5\bottomheight + \raw [CloseDocument] \uniqueMPgraphic{Circle} \\ + \kern.5\bottomheight + \raw [nextpage] \uniqueMPgraphic{RightArrow} \\ + \kern.5\bottomheight +\stopinteractionmenu + +%D \macros +%D {TitlePage, Topics, Topic, Subject} +%D +%D A presentation after loading this module looks like: +%D +%D \starttyping +%D \TitlePage {About Whatever\\Topics} +%D +%D \Topics {Todays Talk} +%D +%D \Topic {Some topic} +%D +%D ..... +%D +%D \Topic {Next Topic} +%D +%D ..... +%D \stoptyping + +%D \macros +%D {StartTitlePage, TitlePage} +%D +%D The titlepage is rather simple and can be typeset in two +%D ways: +%D +%D \starttyping +%D \StartTitlePage +%D text \\ text \\ text +%D \StopTitlepage +%D \stoptyping +%D +%D or as one||liner: +%D +%D \starttyping +%D \TitlePage{text\\text\\text} +%D \stoptyping +%D +%D The first alternative can be used for more complicated +%D title pages. + +\def\StartTitlePage% + {\startstandardmakeup + \bfd\setupinterlinespace + \setupalign[middle] + \vfil + \let\\=\vfil} + +\def\StopTitlePage% + {\vfil\vfil\vfil + \stopstandardmakeup} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D \macros +%D {definehead} +%D +%D The commands \type{\Topic} and \type{\Subject} are defined +%D as copies of head. We use \type{\Nopic} for internal +%D purposes. + +\definehead [Topic] [chapter] +\definehead [Subject] [section] + +\definehead [Nopic] [title] + +%D \macros +%D {setuphead} +%D +%D We use our own command for typesetting the titles. We hide +%D sectionnumbers from viewing. Each topic is followed by a +%D list of subjects that belong to the topic. + +\setuphead + [Topic, Nopic] + [after={\blank[3*medium]}, + number=no, + style=\tfb, + page=yes, + alternative=middle] + +\setuphead + [Subject] + [after=\blank, + number=no, + page=yes, + continue=no, + style=\tfa] + +%D \macros +%D {setuplist} +%D +%D When found, the subject list is automatically placed +%D after the topic head. + +\setuplist + [Topic,Subject] + [alternative=g, + interaction=all, + before=, + after=] + +\setuplist + [Topic] + [criterium=all] + +\def\Topics#1% + {\determinelistcharacteristics[Topic] + \doifmode{*list} + {\Nopic[Topics]{#1} + \startcolumns + \placelist[Topic] + \stopcolumns}} + +\setuplist + [Subject] + [criterium=Topic] + +\def\Subjects% + {\determinelistcharacteristics[Subject] + \doifmode{*list} + {\placelist[Subject]}} + +\setuphead + [Topic] + [after={\blank[3*medium]\Subjects}] + +\doifnotmode{demo}{\endinput} + +%D The (rather silly) demo section. + +\starttext + +\TitlePage{Title Page\\pre-green} + +\Topics{Some Nice Quotes} + +\Topic{A Few} + +\Subject{Knuth} \input knuth +\Subject{Tufte} \input tufte + +\Topic{Some More} + +\Subject{Zapf} \input zapf +\Subject{Bryson} \input bryson + +\stoptext diff --git a/tex/context/modules/mkii/s-pre-03.mkii b/tex/context/modules/mkii/s-pre-03.mkii new file mode 100644 index 000000000..19a11d24e --- /dev/null +++ b/tex/context/modules/mkii/s-pre-03.mkii @@ -0,0 +1,257 @@ +%D \module +%D [ file=s-pre-03, +%D version=1998.09.06, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 3, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is the third environment for typesetting interactive +%D presentations. I used this style for a talk on \TEX\ and +%D \JAVASCRIPT\ at \TUG98, mainly because I didn't want to +%D use the same style three times. Therefore this is a rather +%D simple, silly style. + +\usemodule[pre-general] + +%D \macros +%D {setupbodyfont} +%D +%D We use a large bodyfont. Combined with the fancy +%D background, this does not leave that much room for text, but +%D presentations should use much text anyway. + +\startmode[asintended] \setupbodyfont[lbr] \stopmode + +\setupbodyfont[14.4pt] + +%D \macros +%D {setuppapersize,setuplayout,setupinteractionscreen} +%D +%D The page dimensions are set to size \type {S6}, being +%D 600pt by 450pt. We use wide margins and discard headers +%D and footers. We also launch the document full screen. + +\setuppapersize + [S6][S6] + +\setuplayout + [width=middle, + height=middle, + topspace=75pt, + backspace=100pt, + header=0pt, + footer=0pt] + +\setupinteractionscreen + [option=max] + +%D \macros +%D {setupcolors,definecolor} +%D +%D Next, color support is turned on and a dark red color is +%D defined. Other red shades will be derived from this one +%D color. + +\setupcolors + [state=start] + +\definecolor [PageColor] [black] +\definecolor [BackgroundColor] [s=.85] +\definecolor [OrnamentColor] [r=.75] + +%D \macros +%D {setupinteraction} +%D +%D We turn on interaction mode and use the same color for +%D hyperlinks and redundant hyperlinks (the ones that point +%D to the current page). + +\setupinteraction + [state=start, + contrastcolor=OrnamentColor, + color=OrnamentColor] + +%D \macros +%D {defineoverlay, setupbackgrounds} +%D +%D The joke in this presentation is the elliptical shape of +%D which the bottom part includes a page indication. + +\defineoverlay + [PageShape][\useMPgraphic{PageShape}] + +% \startuseMPgraphic{PageShape} +% lin := 20pt ; off := .75lin ; +% wid := \overlaywidth ; hei := \overlayheight ; +% pos := \currentpage ; tot := \lastpage ; +% path bb; bb := unitsquare xscaled wid yscaled hei ; +% filldraw bb withcolor \MPcolor{PageColor} ; +% pickup pencircle xscaled .5lin yscaled lin rotated 45 ; +% pair r, t, l, b ; +% r := (wid-off,.5hei) ; t := (.5wid,hei-off) ; +% l := (off,.5hei) ; b := (.5wid,off) ; +% path p; p := superellipse(r,t,l,b,.8) ; +% fill p withcolor \MPcolor{Backgroundcolor} ; +% draw p withcolor \MPcolor{OrnamentColor} ; +% color contrastcolor ; contrastcolor = 2/3 * \MPcolor{OrnamentColor} ; +% if (pos>0) and (tot>0): +% pair pa ; pa := point 5 of p ; +% pair pb ; pb := point 7 of p ; +% draw pa withcolor contrastcolor ; +% draw pb withcolor contrastcolor ; +% len := 2/tot ; +% pair pa ; pa := point (5+len*pos) of p ; +% pair pb ; pb := point (5+len*(pos-1)) of p ; +% p := p cutafter pa ; +% p := p cutbefore pb ; +% draw p withcolor contrastcolor ; +% fi ; +% setbounds currentpicture to bb ; +% \stopuseMPgraphic + +\startuseMPgraphic{PageShape} + StartPage ; + path p ; pair pa, pb ; numeric len ; color contrastcolor ; + fill Page withcolor \MPcolor {PageColor} ; + pickup pencircle rotated 45 xscaled 10pt yscaled 20pt ; + p := Page enlarged (-10pt,-15pt) superellipsed .8 ; + p := p shifted (-1.5pt,0) ; % looks better + fill p withcolor \MPcolor{BackgroundColor} ; + draw p withcolor \MPcolor{OrnamentColor} ; + contrastcolor = 2/3 * \MPcolor{OrnamentColor} ; + if (PageNumber>0) and (NOfPages>0): + draw point 5 of p withcolor contrastcolor ; + draw point 7 of p withcolor contrastcolor ; + len := 2/NOfPages ; + pa := point (5+len*PageNumber) of p ; + pb := point (5+len*(PageNumber-1)) of p ; + draw (p cutafter pa) cutbefore pb + withcolor contrastcolor ; + fi ; + StopPage ; +\stopuseMPgraphic + +%D We use the viewer provided feature to go to the previous or +%D next page. + +\defineoverlay[PrevButton][\overlaybutton{PreviousPage}] +\defineoverlay[NextButton][\overlaybutton{NextPage}] + +\setupbackgrounds + [page] + [background={PageShape,PrevButton}] + +\setupbackgrounds + [text][text] + [background=NextButton] + +% or using hard coded next/prev pages: +% +% \defineoverlay[PrevButton][\overlaybutton{previouspage}] +% \defineoverlay[NextButton][\overlaybutton{nextpage}] +% +% \setupbackgrounds[state=repeat] +% \setupbackground[text][text][background=NextButton] +% +% or simply (using an repeated layer): +% +% \setupbackground[text][background=NextButton] + +%D \macros +%D {definehead, setuphead} +%D +%D Like the other presentation styles, we use \type {\Topic} +%D instead of \type {\chapters}. This time we don't provide +%D an additional sectioning. So we have: +%D +%D \starttyping +%D \TitlePage{How nice} +%D +%D \Topics{This is about ...} +%D +%D \Topic{The first one} +%D +%D \Topic{Another one} +%D \stoptyping + +\definehead [Topic] [chapter] +\definehead [Nopic] [title] + +\setuphead + [Topic,Nopic] + [after={\blank[3*medium]}, + number=no, + style=\tfb, + page=yes, + alternative=middle] + +\setuplist + [Topic] + [alternative=g, + interaction=all, + before=, + after=] + +\def\Subject + {\Topic} + +%D The tables of contents is associated with \type +%D {\Topics}. + +\def\Topics#1% + {\Nopic[Topics]{#1} + \placelist[Topic][criterium=all]} + +\def\Subjects + {} + +%D Instead of \type {\TitlePage}, one can use the pair +%D \type {\StartTitlePage} -- \type {\StopTitlePage}: +%D +%D \starttyping +%D \StartTitlePage +%D A Self Made Title +%D \StopTitlePage +%D \stoptyping + +\def\StartTitlePage% + {\startstandardmakeup + \bfd\setupinterlinespace + \setupalign[middle] + \vfil + \def\\{\vfil\bfb\setupinterlinespace}} + +\def\StopTitlePage% + {\vfil\vfil\vfil + \stopstandardmakeup} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +\doifnotmode{demo}{\endinput} + +%D The (rather silly) demo section. + +\starttext + +\TitlePage{Title Page\\pre-funny} + +\Topics{Some Nice Quotes} + +\Topic{A Few} + +\Subject{Knuth} \input knuth +\Subject{Tufte} \input tufte + +\Topic{Some More} + +\Subject{Zapf} \input zapf +\Subject{Bryson} \input bryson + +\stoptext diff --git a/tex/context/modules/mkii/s-pre-04.mkii b/tex/context/modules/mkii/s-pre-04.mkii new file mode 100644 index 000000000..088f4e510 --- /dev/null +++ b/tex/context/modules/mkii/s-pre-04.mkii @@ -0,0 +1,377 @@ +%D \module +%D [ file=s-pre-04, +%D version=1998.09.06, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 4, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[pre-general] + +%D \macros +%D {setupbodyfont} +%D +%D This is just another environment for typesetting interactive +%D presentations. I wrote this module on behalf of a course I +%D gave for the United Kingdom \TeX\ users group. + +\setupbodyfont[ams,pos,14.4pt] + +%D \macros +%D {setupcolors,definecolor} +%D +%D I started using dark blue for the navigational elements. In +%D that context, dark red is a logical choice for the contrast +%D color. While playing around with the navigational elements +%D I decided to use the not so dominant color yellow for the +%D status bar. +%D +%D A few days before I wrote this style, the recent acquisition +%D of Mondriaans last painting by the Dutch governement was a +%D hot topic in the dutch news scenary. Therefore I decided to +%D replace the rather dull title page by something more +%D colorful, in mondriaan colors, but far more random than any +%D of his paintings. For consistence we remap the already +%D defined primary colors. + +\setupcolors [state=start] + +\definecolor [NoneColor] [s=.6] +\definecolor [GotoColor] [b=.6] \definecolor[blue] [GotoColor] +\definecolor [ExitColor] [r=.6] \definecolor[red] [ExitColor] +\definecolor [JumpColor] [s=.6] +\definecolor [UserColor] [g=.6] \definecolor[green] [UserColor] +\definecolor [StepColor] [r=.6,g=.6] \definecolor[yellow][StepColor] + +\definecolor [PageColor] [s=.80] \definecolor[gray] [PageColor] +\definecolor [TextColor] [s=.90] + +%D \macros +%D {setuppapersize} +%D +%D As usual, we take a screen oriented paper size: + +\setuppapersize + [S6][S6] + +%D \macros +%D {setuplayout,setupinteractionscreen} +%D +%D The layout definition fits into this $600\times450$ point +%D area, but the dimensions are somewhat diffused by the text +%D background offset. + +\setuplayout + [width=530pt, + height=400pt, + header=0pt, + footer=0pt, + backspace=15pt, + topspace=15pt, + bottomdistance=15pt, + bottom=10pt, + margin=0pt, + rightedgedistance=15pt, + rightedge=30pt] + +\setupinteractionscreen + [option=max] + +%D \macros +%D {setupbackgrounds} +%D +%D Both the page and the text area have a gray background. +%D The \type {[text,text]} area also has an offset. Later we +%D will see that we have to compensate for that in the +%D navigational areas. + +\setupbackgrounds + [page] + [background=color, + backgroundcolor=PageColor] + +\setupbackgrounds + [text][text] + [background=color, + backgroundcolor=TextColor, + backgroundoffset=5pt] + +%D \macros +%D {setupinteraction} +%D +%D For convenient navigation, we turn on interaction. + +\setupinteraction + [state=start, + menu=on, + color=UserColor, + contrastcolor=NoneColor] + +%D \macros +%D {setupsubpagenumber} +%D +%D When navigating the document, we keep the title page out +%D of sight, therefore we use sub page numbers. + +\setupsubpagenumber + [state=start, + way=bytext] + +%D \macros +%D {setupinteractionmenu} +%D +%D There is only one interaction menu, located in the right +%D edge of the screen. Both offsets enlarge the edge by the +%D same amount as the text background offset. + +\setupinteractionmenu + [right] + [state=start, + frame=off, + strut=no, + offset=0pt, + inbetween=, + bottomoffset=-5pt, + topoffset=-5pt] + +%D \macros +%D {startinteractionmenu} +%D +%D The menu itself is not that spectacular. We use the +%D start||stop alternative for setting the content. The macro +%D \type {\interactioncolor} expands into either the +%D interaction color or the contrast color, the latter only +%D when no jump is possible. + +\startinteractionmenu[right] + \setupinteraction[color=GotoColor] + \but [previoussubpage] \Triangle {90}\framedwidth\interactioncolor \\ + \vskip10pt + \but [nextsubpage] \Triangle{270}\framedwidth\interactioncolor \\ + \vfill + \but [PreviousJump] \Triangle{180}\framedwidth{NoneColor} \\ + \vskip-5pt + \but [NextJump] \Triangle {0}\framedwidth{NoneColor} \\ +\stopinteractionmenu + +%D \macros +%D {setupinteractionbar} +%D +%D The interaction bar at the bottom is also larger than the +%D normal width of the bottom area. + +\setupinteractionbar + [alternative=f, + width=\textwidth, + height=\bottomheight, + distance=10pt, + color=NoneColor, + contrastcolor=StepColor] + +%D \macros +%D {setupbottomtexts} +%D +%D The bar is centered in the middle. + +\setupbottomtexts + [\interactionbar] + +%D We can exit viewing with a close button, located on the +%D rightmost bottom area. + +\def\CloseButton + {\button + [width=\rightedgewidth,height=\bottomheight,offset=overlay, + background=color,backgroundcolor=ExitColor,frame=off] + {}% + [CloseDocument]} + +\setupbottomtexts + [edge][][\CloseButton] + +%D \macros +%D {definesymbol,setupitemize} +%D +%D Because some prominent things are rectangular or triangular, +%D we prefer some different symbols in itemizations: + +\definesymbol[1][$\blacktriangleright$] +\definesymbol[2][$\blacktriangledown$] +\definesymbol[3][$\blacktriangleright$] +\definesymbol[4][$\blacktriangledown$] + +\setupitemize[each][color=NoneColor] + +%D \macros +%D {TitlePage,defineoverlay,button,setupalign, +%D setupbackgrounds,setupinteraction,setupinteractionbar, +%D startstandardmakeup,switchtobodyfont,setupinterlinespace} +%D +%D Now the main layout and navigational definitions are +%D done, it makes sense to define and tune some structuring +%D commands. First we build the titlepage. + +\defineoverlay [TitleGraphic] [\useMPgraphic{title}] +\defineoverlay [NextPage] [\overlaybutton{nextpage}] + +\def\StartTitlePage + {\setupbackgrounds[page][background={color,TitleGraphic,NextPage}] + \setupbackgrounds[text][text][background=] + \setupinteraction[menu=off] + \setupinteractionbar[state=stop] + \startstandardmakeup + \switchtobodyfont[24pt] + \bfd\setupinterlinespace + \setupalign[middle] + \vfil + \let\\=\vfil} + +\def\StopTitlePage + {\vfil\vfil\vfil + \stopstandardmakeup + \setupinteraction[menu=on] + \setupinteractionbar[state=start] + \setupbackgrounds[page][background=color] + \setupbackgrounds[text][text][background=color] + \setupsubpagenumber[reset]} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D \macros +%D {Topic, Nopic, Subject, +%D definehead, setuphead} +%D +%D We use \type {\Topic} and \type {\Subject} instead of +%D chapters and sections. The \type {\Nopic} alternative is +%D meant for internal use. + +\definehead [Topic] [chapter] +\definehead [Nopic] [title] +\definehead [Subject] [section] + +\setuphead + [Topic, Nopic] + [after={\blank[3*medium]}, + number=no, + style=\tfb, + page=yes, + alternative=middle] + +\setuphead + [Subject] + [after=\blank, + number=no, + page=yes, + continue=no, + style=\tfa] + +%D \macros +%D {Topics, Subjects, +%D setuplist, placelist, startcolumns} +%D +%D This style is meant for the more large presentations, and +%D therefore provided for a list of topics as well as local +%D lists of subjects. When many topics are introduces, the +%D list is typeset in columns. + +\setuplist + [Topic,Subject] + [alternative=g, + interaction=all, + before=, + after=] + +\setuplist + [Topic] + [criterium=all] + +\def\Topics#1% + {\determinelistcharacteristics[Topic] + \ifnum\utilitylistlength>0 + \Nopic[Topics]{#1} + \ifnum\utilitylistlength>12 + \startcolumns + \placelist[Topic] + \stopcolumns + \else + \placelist[Topic] + \fi + \fi} + +\def\Subjects% + {\placelist[Subject]} + +%D Last we define the overlays. Look at the way colors are +%D linked into the macros. + +\startMPinclusions + def triangle (expr wid, rot, col) = + x1 := x3 := y1 := 0 ; x2 := y3 := wid ; y2 := .5y3 ; + fill (z1--z2--z3--cycle) rotated rot withcolor col ; + currentpicture := currentpicture xysized (wid,wid) ; + enddef ; +\stopMPinclusions + +\setupMPvariables + [triangle] + [width=1cm, + rotation=0, + color=black] + +\startuniqueMPgraphic{triangle}{width,rotation,color} + triangle(\MPvar{width},\MPvar{rotation},\MPvar{color}) ; +\stopuniqueMPgraphic + +\def\Triangle#1#2#3% + {\uniqueMPgraphic{triangle}{rotation=#1,width=#2,color=#3}} + +\startuseMPgraphic{title} % can be simplified with "randomized" + color c ; path p ; + for i=1 upto 250 : + x0 := uniformdeviate \overlaywidth ; + y0 := uniformdeviate \overlayheight ; + sx := uniformdeviate 20 ; + sy := uniformdeviate 20 ; + cc := round(uniformdeviate 2) ; + if cc=0 : c := \MPcolor{GotoColor} fi ; + if cc=1 : c := \MPcolor{ExitColor} fi ; + if cc=2 : c := \MPcolor{StepColor} fi ; + qq := round(uniformdeviate 1) ; + if qq=0 : + p := unitsquare xscaled sx yscaled sy ; + else : + rr := round(uniformdeviate 3) * 90 ; + x1 := x3 := y1 := 0 ; x2 := y3 := sx; y2 := .5y3 ; + p := (z1--z2--z3--cycle) rotated rr ; + fi ; + fill p shifted z0 withcolor c ; + endfor ; +\stopuseMPgraphic + +\doifnotmode{demo}{\endinput} + +%D The (rather silly) demo section. + +\starttext + +\TitlePage{Title Page\\pre-colorfull} + +\Topics{Some Nice Quotes} + +\Topic{A Few} + +\Subject{Knuth} \input knuth +\Subject{Tufte} \input tufte + +\Topic{Some More} + +\Subject{Zapf} \input zapf +\Subject{Bryson} \input bryson + +\stoptext diff --git a/tex/context/modules/mkii/s-pre-05.mkii b/tex/context/modules/mkii/s-pre-05.mkii new file mode 100644 index 000000000..dcb3f5e81 --- /dev/null +++ b/tex/context/modules/mkii/s-pre-05.mkii @@ -0,0 +1,240 @@ +%D \module +%D [ file=s-pre-05, +%D version=1998.12.12, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 5, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[pre-general] + +%D As all styles sofar, this one has the same structuring +%D commands. + +\startmode[asintended] \setupbodyfont[ludicaot] \stopmode + +\setupbodyfont[14.4pt] + +\setupcolors [state=start] + +\definecolor [BackgroundColor] [s=.95] +\definecolor [OrnamentColor] [r=.6,g=.7,b=.8] + +\setuppapersize + [S6][S6] + +\setuplayout + [width=430pt, + height=400pt, + header=0pt, + footer=0pt, + margin=0pt, + backspace=25pt, + topspace=25pt, + rightedgedistance=20pt, + rightedge=110pt] + +\setupinteractionscreen + [option=max] + +\setupbackgrounds + [state=repeat] + +\setupbackgrounds + [page] + [backgroundcolor=white] + +\setupbackgrounds + [text][text] + [background={HashFrameA,NextPage}, + backgroundoffset=20pt] + +\defineoverlay + [HashFrameA] + [\useMPgraphic{HashFrameA}] + +\defineoverlay + [HashFrameB] + [\useMPgraphic{HashFrameB}] + +\setupinteraction + [state=start, + menu=on, + color=OrnamentColor, + contrastcolor=OrnamentColor] + +%D Watch how we use a list alternative that matches the +%D menu. + +\setupinteractionmenu + [right] + [background=HashFrameB, + style=smallbold, + frame=off, + offset=10pt, + height=35pt, + before=, + after=, + inbetween=\endgraf, + width=\rightedgewidth] + +\startinteractionmenu[right] + \placelist + [Topic] + [criterium=all, + alternative=right, + maxwidth=.8\rightedgewidth, + interaction=all, + before=, + after=] + \vfill + \setupinteractionmenu + [right] + [height=30pt] + \but [CloseDocument] Close \\ +\stopinteractionmenu + +\setupwhitespace + [big] + +\setupblank + [big] + +%D \macros +%D {TitlePage} +%D +%D Now the main layout and navigational definitions are +%D done, it makes sense to define and tune some structuring +%D commands. First we build the titlepage. + +\defineoverlay [TitleGraphic] [\useMPgraphic{TitleGraphic}] +\defineoverlay [NextPage] [\overlaybutton{forward}] + +\unexpanded\def\StartTitlePage + {\setupbackgrounds[page][background={color,TitleGraphic,NextPage}] + \setupbackgrounds[text][text][background=] + \setupinteraction[menu=off] + \setupinteractionbar[state=stop] + \setuplayout[width=550pt,rightedge=0pt] + \startstandardmakeup + \switchtobodyfont[24pt] + \bfd\setupinterlinespace + \setupalign[middle] + \vfil + \let\\=\vfil} + +\unexpanded\def\StopTitlePage + {\vfil\vfil\vfil + \stopstandardmakeup + \setuplayout[width=430pt,rightedge=110pt] + \setupinteraction[menu=on] + \setupinteractionbar[state=start] + \setupbackgrounds[page][background=color] + \setupbackgrounds[text][text][background={HashFrameA,NextPage}]} + +\unexpanded\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D \macros +%D {Topics,Subjects} +%D +%D Since the lists are in the menu, we don't honor list +%D placement macros. + +\unexpanded\def\Topics#1{} +\unexpanded\def\Subjects{} + +%D \macros +%D {Topic, Nopic, Subject} +%D +%D Since t his style is meant for rather flat structured +%D documents, only \type {\Topic} makes sense. + +\definehead [Topic] [chapter] +\definehead [Nopic] [title] +\definehead [Subject] [section] + +\setuphead + [Topic, Nopic] + [after={\blank[3*medium]}, + number=no, + style=\tfb, + page=yes, + alternative=middle] + +\setuphead + [Subject] + [after=\blank, + number=no, + page=yes, + continue=no, + style=\tfa] + +%D We use only one kind of base graphic, which is sligthly +%D tuned for the different usage. + +\startMPinclusions + def random_hash_frame (expr width, height, offset, linewidth ) = + + def delta = ((uniformdeviate .5offset) + .25offset) enddef ; + x1 := offset ; y1 := offset ; x2 := width-offset ; y2 := height-offset ; + + drawoptions(withpen pencircle scaled linewidth withcolor \MPcolor{BackgroundColor}) ; + fill z1--(x2,y1)--z2--(x1,y2)--cycle ; + + drawoptions(withpen pencircle scaled linewidth withcolor \MPcolor{OrnamentColor}) ; + draw (x1-delta,y1)--(x2+delta,y1) ; + draw (x2,y1-delta)--(x2,y2+delta) ; + draw (x2+delta,y2)--(x1-delta,y2) ; + draw (x1,y2+delta)--(x1,y1-delta) ; + + drawoptions(); + setbounds currentpicture to unitsquare xscaled width yscaled height ; + enddef ; +\stopMPinclusions + +\startuseMPgraphic{HashFrameA} + random_hash_frame(OverlayWidth,OverlayHeight,15pt,2pt) ; +\stopuseMPgraphic + +\startuseMPgraphic{HashFrameB} + random_hash_frame(OverlayWidth,OverlayHeight, 5pt,2pt) ; +\stopuseMPgraphic + +\startuseMPgraphic{TitleGraphic} + for i=1 upto 300 : + offset := uniformdeviate 10pt ; + width := 2*offset + 30pt + uniformdeviate 30pt ; + height := 2*offset + 10pt + uniformdeviate 10pt ; + addto currentpicture also + image(random_hash_frame(width,height,offset,1pt)) shifted + (uniformdeviate OverlayWidth, uniformdeviate OverlayHeight) ; + endfor ; +\stopuseMPgraphic + +\doifnotmode{demo}{\endinput} + +%D The (rather silly) demo section. + +\starttext + +\TitlePage{Title Page\\pre-fuzzy} + +\Topics{Some Nice Quotes} + +\Topic{A Few} + +\Subject{Knuth} \input knuth +\Subject{Tufte} \input tufte + +\Topic{Some More} + +\Subject{Zapf} \input zapf +\Subject{Bryson} \input bryson + +\stoptext diff --git a/tex/context/modules/mkii/s-pre-09.mkii b/tex/context/modules/mkii/s-pre-09.mkii new file mode 100644 index 000000000..a20b9f31a --- /dev/null +++ b/tex/context/modules/mkii/s-pre-09.mkii @@ -0,0 +1,380 @@ +%D \module +%D [ file=s-pre-09, +%D version=unknown, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 9, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D I made this style when I had to give a presentation on +%D the \MAPS\ bibliography production for several user group +%D meetings. This style is rather tuned for combinations of +%D examples and explanations. The colors match the \MAPS\ +%D bibliography colors. + +\startmode[asintended] \setupbodyfont[lbr] \stopmode + +\setupbodyfont[14.4pt] + +%D A couple of years later, in 2001 this style was documented +%D and made public. While documenting, I also changed box +%D building on top of overlays into the now available layer +%D positioning. So, this styles demonstrates quite some +%D tricks. + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=0cm, + backspace=0cm, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +%D Local environments can be set by using the setups commands. +%D For downward compatibility, we keep supporting the \type +%D {\...Settings} hooks. Using local environments is seldom +%D needed. + +\let\TextSettings \empty +\let\SampleSettings\empty + +\startsetups [text] \TextSettings \stopsetups +\startsetups [sample] \SampleSettings \stopsetups + +%D The dimensions are kind of fixed. + +\def\FrameWidth {448pt} +\def\FrameHeight {348pt} +\def\FrameOffset {24pt} +\def\FrameSkip {12pt} + +%D But they {\em can} and {\em will} be changed. + +\def\FrameWidth {408pt} +\def\FrameHeight {318pt} + +%D The funny values come from the $3:4$ display aspect +%D ratio. + +\setupcolors + [state=start] + +\definecolor[PageColor] [s=.40] +\definecolor[TextColor] [s=.90] +\definecolor[InteractionColor][r=.40] +\definecolor[LineColor] [r=.60,g=.60] + +%D Of course we go interactive and since we will probably +%D open other documents, we make sure that the viewer opens a +%D new window. + +\setupinteraction + [color=InteractionColor, + contrastcolor=LineColor, + display=new, + state=start] + +\setupinteractionscreen + [option=max] + +%D Before we come to the real macros, we do a little bit of +%D tuning. + +\setupitemize + [1][packed] + +\setuptyping + [blank=medium] + +%D Apart from the titlepage, the page gets a simple colored +%D background. Later we will activate the background. + +\setupbackgrounds + [page] + [backgroundcolor=PageColor] + +%D Everything gets frames by a nice \METAPOST\ frame. + +\defineoverlay [background] [\uniqueMPgraphic{background}] + +\startuniqueMPgraphic{background} + path p ; color c, w, d ; + c := \MPcolor{PageColor} ; + w := \MPcolor{TextColor} ; + d := \MPcolor{LineColor} ; + p := unitsquare xscaled OverlayWidth yscaled OverlayHeight ; + pickup pencircle scaled (1.5*\FrameSkip) ; + draw p withcolor c ; + pickup pencircle scaled \FrameSkip ; + fill p withcolor w ; + draw p withcolor d ; +\stopuniqueMPgraphic + +%D We will present samples and explanation pair||wise, so +%D we need a hyperlink that skips a page. + +\defineoverlay [nextpage] [\overlaybutton{nextpage}] +\defineoverlay [previouspage] [\overlaybutton{previouspage}] +\defineoverlay [skippage] [\overlaybutton{page(+2)}] + +%D Layers are normally used to position multiple content on +%D a specific overlay. Here we will use them to position +%D only and since the samples and text will swap place, we +%D will use quite a few layers. + +\defineoverlay [text] [\composedlayer{text}] +\defineoverlay [sample] [\composedlayer{sample}] +\defineoverlay [common] [\composedlayer{common}] + +%D There are three positions. When combined, the sample and +%D text windows overlap, otherwise the lone window is +%D centered. We could have used one layer and reversed the +%D order by setting the \type {direction} parameter, but +%D this approach is more readable. + +\definelayer + [text] + [x=\makeupwidth,y=\makeupheight,location=lt, + hoffset=-\FrameSkip,voffset=-\FrameSkip] + +\definelayer + [sample] + [hoffset=\FrameSkip,voffset=\FrameSkip] + +\definelayer + [common] + [x=.5\makeupwidth,y=.5\makeupheight,location=c] + +%D The topic is put in the lower right corner of the text +%D window. + +\defineoverlay [topic] [\composedlayer{topic}] + +\definelayer + [topic] + [x=\FrameWidth,y=\FrameHeight,location=lt, + hoffset=-\FrameOffset,voffset=-\FrameSkip] + +%D The topic is put in a framed box. That way we can make +%D sure that it gets a background, which looks better when +%D it covers something else. Otherwise we could have stuct +%D to: +%D +%D \starttyping +%D \def\Topic#1% +%D {\setlayer[topic]{\color[PageColor]{\bfb\setstrut#1}}} +%D \stoptyping +%D +%D But, we go for the nice alternative: + +\def\Topic#1% + {\doifsomething{#1} + {\setlayer [topic] + {\bfb\setstrut + \inframed + [frame=off,foregroundcolor=PageColor,offset=0pt, + background=color,backgroundcolor=TextColor] + {#1}}}} + +%D The sample as well as the explanation will be collected in +%D a buffer. That way we can reuse the content. We could +%D have used a box instead, but can we be sure that the content +%D is not adapting itself? So, buffers we use. + +\resetbuffer[sample] +\resetbuffer[text] + +%D Both the sample and explanation are kind of windowed. + +\defineframedtext + [SampleText] + [width=\FrameWidth,height=\FrameHeight,offset=\FrameOffset, + frame=off,align=normal,strut=no,before=,after=, + background={background,nextpage}] + +%D We safe some keying in by combining things in one macro. + +\def\DoSampleText#1#2#3% kind layer overlays + {\setupframedtexts[SampleText][background={background,#3}] + \setlayer[#2] + {\startSampleText[none] + \setups[#1] + \getbuffer[#1] + \stopSampleText}} + +\def\StartSample{\dostartbuffer[sample][StartSample][StopSample]} +\def\StartText {\dostartbuffer[text] [StartText] [StopText]} + +%D The following definitions apply at the outer level. + +\def\StopSample + {\startstandardmakeup + \DoSampleText{sample}{common}{nextpage} + \stopstandardmakeup + \resetbuffer[sample]} + +\def\StopText + {\startstandardmakeup + \DoSampleText{text}{common}{topic,nextpage} + \stopstandardmakeup + \resetbuffer[text]} + +\setupbackgrounds[page][background={color,nextpage}] +\setupbackgrounds[text][background=common] + +%D When we combine sample and text, we get slightly +%D different definitions. As you can see we generate two +%D pages. Watch how we manipulate the order of the +%D overlays and teh nature of the buttons. Here data +%D abstraction really pays off. + +\def\StartIdea + {\bgroup + \let\StopSample\relax + \let\StopText \relax} + +\def\StopIdea% + {\setupbackgrounds[page][background={color,skippage}] + \setupbackgrounds[text][background={text,sample}] + \startstandardmakeup + \DoSampleText{sample}{sample}{previouspage} + \DoSampleText{text} {text} {topic,nextpage} + \stopstandardmakeup + \setupbackgrounds[page][background={color,nextpage}] + \setupbackgrounds[text][background={sample,text}] + \startstandardmakeup + \DoSampleText{sample}{sample}{previouspage} + \DoSampleText{text} {text} {topic,nextpage} + \stopstandardmakeup + \egroup} + +%D The rest of the definitions takes care of the title page. +%D Please don't steal this one for your own documents. + +\defineoverlay[joke] [\useMPgraphic{joke}{n=0}] % not to be changed! + +\startuseMPgraphic{joke}{n} + StartPage ; + path p, q ; numeric w ; pair xy ; + set_grid(OverlayWidth,OverlayHeight,OverlayWidth/8,OverlayHeight/8) ; + if \MPvar{n}=1 : + p := fulldiamond ; fill Page withcolor \MPcolor{TextColor} ; + else : + p := fullsquare ; fill Page withcolor \MPcolor{PageColor} ; + fi ; + forever : + xy := center Page randomized (OverlayWidth,OverlayHeight) ; + if new_on_grid(xpart xy, ypart xy) : + q := (p xyscaled (OverlayWidth/5,OverlayHeight/5)) + randomized (\FrameSkip,\FrameSkip) + shifted xy ; + w := (\FrameSkip) randomized (\FrameSkip/2) ; + draw q withcolor \MPcolor{PageColor} withpen pencircle scaled (1.5w) ; + fill q withcolor \MPcolor{TextColor} ; + draw q withcolor \MPcolor{LineColor} withpen pencircle scaled ( w) ; + fi ; + exitif grid_full ; + endfor ; + StopPage ; +\stopuseMPgraphic + +\defineoverlay[fuzzy][\useMPgraphic{fuzzy}] + +\startuseMPgraphic{fuzzy} + path p ; numeric w ; + p := (fullsquare xyscaled (OverlayWidth,OverlayHeight)) + randomized (\FrameSkip,\FrameSkip) ; + w := (\FrameSkip) randomized (\FrameSkip/2) ; + draw p withcolor \MPcolor{PageColor} withpen pencircle scaled (1.5w) ; + fill p withcolor \MPcolor{TextColor} ; + draw p withcolor \MPcolor{LineColor} withpen pencircle scaled ( w) ; +\stopuseMPgraphic + +%D This time we use a fit window, but with a slightly randomized +%D frame, our trademark so to say. + +\def\StartTitlePage + {\bgroup + \setupbackgrounds[page][background={joke,nextpage}] + \startstandardmakeup + \switchtobodyfont[big] + \setupframedtexts + [SampleText] + [background=fuzzy, + foregroundcolor=PageColor, + width=fit, + height=fit, + align=middle] + \startSampleText[middle] + \bfd\setupinterlinespace + \def\\{\bfb\setupinterlinespace\vfil\def\\{\vfil}}} + +\def\StopTitlePage + {\stopSampleText + \stopstandardmakeup + \egroup} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D Let's nill some error prone presentation macros. + +\let\Subject \Topic +\let\Topics \gobbleoneargument +\let\Subjects \relax + +%D We will avoid \quote {overfull} messages. + +\dontcomplain + +\doifnotmode{demo}{\endinput} + +%D The (rather silly) demo section. + +\starttext + +\setupbodyfont[12pt] + +\TitlePage{Quotes, Quotes\\and more quotes} + +\StartIdea + \StartSample + \input knuth \par + \StopSample + \StartText + \Topic{Tufte} + \input tufte \par + \StopText + \StopIdea + +\StartIdea + \StartSample + \input materie \par + \StopSample + \StartText + \input reich \par + \StopText +\StopIdea + +\StartText + \input tufte \par +\StopText + +\StartIdea + \StartSample + \input knuth \par + \StopSample + \StartText + \input tufte \par + \StopText +\StopIdea + +\stoptext diff --git a/tex/context/modules/mkii/s-pre-10.mkii b/tex/context/modules/mkii/s-pre-10.mkii new file mode 100644 index 000000000..a92e5af01 --- /dev/null +++ b/tex/context/modules/mkii/s-pre-10.mkii @@ -0,0 +1,308 @@ +%D \module +%D [ file=s-pre-10, +%D version=unknown, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 10, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This style is derived from the ninth style, which was +%D used first at \EUROTEX\ 99 and later at \TUG\ 2000. This +%D alternative build up a page. + +\startmode [demo] + \disablemode[demo] \usemodule[pre-09] \enablemode[demo] +\stopmode + +\startnotmode [demo] + \usemodule[pre-09] +\stopnotmode + +%D We use blue colors instead of yellow ones. Since we have +%D used symbolic names, we can easily overload the existing +%D scheme. + +\definecolor[LineColor][r=.40,g=.40,b=1.00] + +%D Here we don't use fixed dimensions, but fit the sample +%D windows and derive the text windows's width from this one. + +\setupframedtexts + [SampleText] + [width=fit,height=fit, + background={background,nextpage}] + +%D The topic goes to the top right corner of the screen which +%D means that it is positioned left down to the reference +%D point. Watch how we make data on this layer (here only +%D the topic but it can be more) persistent. + +\setuplayer + [topic] + [y=0pt,x=\makeupwidth,location=lb,state=repeat, + hoffset=-\FrameSkip,voffset=\FrameSkip] + +%D Clicking on the page brings us back. + +\setupbackgrounds + [page] + [background={previouspage,color,topic}] + +%D All layers end up on the text area. This could have been +%D the page area too since these have the same dimensions. + +\setupbackgrounds + [text] + [background={common,sample,text}] + +%D Because we build up the text window step by step, we will +%D separate the entries by white space. + +\startsetups [always] + \setupwhitespace[big] + \setupblank[big] +\stopsetups + +%D The \type {\Topic} commands can be simplified to: + +\def\Topic#1% + {\resetlayer[topic] + \setlayer[topic]{\bfb\setstrut\color[TextColor]{#1}}} + +%D We also provide a way to erase the topic. + +\def\NoTopic + {\resetlayer[topic]} + +%D We have to redefine the structuring commands to support +%D the resetting of buffer counters. + +\newcounter\TextN + +\def\StartSample + {\doglobal\newcounter\TextN + \dostartbuffer[sample][StartSample][StopSample]} + +\def\StartText + {\doglobal\newcounter\TextN + \dostartbuffer[text][StartText][StopText]} + +\def\StartSubText + {\doglobal\increment\TextN + \dostartbuffer[text-\TextN][StartSubText][StopSubText]} + +\def\StopText + {\startstandardmakeup + \DoSampleText{text}{common}{nextpage} + \stopstandardmakeup} + +\def\StopSubText + {\startstandardmakeup + \DoSampleText{text}{common}{nextpage} + \stopstandardmakeup} + +%D The \type {\DoSampleText} command is adapted to support +%D addition of subtexts (each subtext goes into its own +%D buffer). + +\def\DoSampleText#1#2#3% + {\setupframedtexts[SampleText][background={background,#3}] + \bgroup + \setups[#1]% + \setups[always]% + \setbox\nextbox=\hbox + {\startSampleText[none] + \getbuffer[#1]\par + \doif{#1}{text} + {\dorecurse{\TextN}{\getbuffer[text-\recurselevel]\par}} + \stopSampleText} + \xdef\SampleTextWidth{\the\wd\nextbox} + \setlayer[#2]{\box\nextbox}% + \egroup} + +%D Since we are no longer swapping windows, we end up with a +%D much simplier \type {\Stopidea} macro. We don't reset +%D samples at the inner level. + +\def\StartIdea% + {\bgroup + \let\StopSample \relax + \let\StopText \relax + \let\StopSubText\relax + \def\StartSample{\dostartbuffer[sample][StartSample][StopSample]}} + +\def\StopIdea% + {\startstandardmakeup + \DoSampleText{sample}{sample}{nextpage} + \SetTextWidth + \DoSampleText{text} {text} {nextpage} + \stopstandardmakeup + \egroup} + +%D Here we determine the width of the text window. It is +%D derived from the width of the sample and stays the same +%D within a sequence. + +\def\SetTextWidth + {\ifnum\TextN<1 % yes or no, may change + \scratchdimen=\makeupwidth + \advance\scratchdimen by -\SampleTextWidth + \advance\scratchdimen by \FrameSkip + \xdef\SampleWidth{\the\scratchdimen}% + \fi + \setupframedtexts + [SampleText] + [width=\SampleWidth]} + +%D We use the (already implemented) second alternative of +%D the titlepage graphic. Please don't change this. + +\defineoverlay[joke] [\useMPgraphic{joke}{n=1}] % not to be changed ! + +\doifnotmode{demo}{\endinput} + +%D The demo section. The original presentation uses proper +%D graphics and has better spacing. + +\def\SomeSymbol#1#2{\definedfont[ContextNavigation at #1]\char#2} + +\setupcombinations[distance=\FrameOffset,inbetween=\vskip\FrameOffset] + +\starttext + +\TitlePage{Some Famous Symbols} + +\Topic{Symbols} + +\StartSample + \startcombination[2*2] + {\SomeSymbol{5cm}{1}} {} + {\SomeSymbol{5cm}{3}} {} + {\SomeSymbol{5cm}{2}} {} + {\SomeSymbol{5cm}{4}} {} + \stopcombination +\StopSample + +\Topic{Previous} + +\StartIdea + \StartSample + \SomeSymbol{7cm}{1} + \StopSample + \StartText + This symbol can be used to indicate a hyperlink to a + previous page. + \StopText +\StopIdea + +\StartIdea + \StartSubText + As one can expect there is also a symbol for going to + the next page. + \StopSubText +\StopIdea + +\Topic{Previous} + +\StartIdea + \StartSample + \SomeSymbol{9cm}{2} + \StopSample + \StartText + This symbol is actually just a mirrored version of the + first symbol we showed. + \StopText +\StopIdea + +\NoTopic + +\StartText + Is this nice or not? +\StopText + +\Topic{First and Last} + +\StartSample + \SomeSymbol{11cm}{3} +\StopSample + +\StartSample + \SomeSymbol{11cm}{4} +\StopSample + +\StartIdea + \StartSample + \SomeSymbol{5cm}{3} + \StopSample + \StartText + A few screens back, we saw this symbol. + \StopText +\StopIdea + +\StartIdea + \StartSubText + This symbol represents the beginning of something. + \StopSubText +\StopIdea + +\StartIdea + \StartSample + \SomeSymbol{5cm}{4} + \StopSample + \StartSubText + Just like this one represents an end. + \StopSubText +\StopIdea + +\StartIdea + \StartSubText + They look just like the symbols found on audio and + video players. + \StopSubText +\StopIdea + +\Topic{Summary} + +\StartIdea + \StartSample + \SomeSymbol{6cm}{1} + \StopSample + \StartText + So we have a symbol for previous \unknown + \StopText +\StopIdea + +\StartIdea + \StartSample + \SomeSymbol{6cm}{2} + \StopSample + \StartSubText + \unknown\ and one for next \unknown + \StopSubText +\StopIdea + +\StartIdea + \StartSample + \SomeSymbol{6cm}{3} + \StopSample + \StartSubText + \unknown\ and yet another for first \unknown + \StopSubText +\StopIdea + +\StartIdea + \StartSample + \SomeSymbol{6cm}{4} + \StopSample + \StartSubText + \unknown\ and of course for last. + \StopSubText +\StopIdea + +\stoptext + diff --git a/tex/context/modules/mkii/s-pre-11.mkii b/tex/context/modules/mkii/s-pre-11.mkii new file mode 100644 index 000000000..0c445054f --- /dev/null +++ b/tex/context/modules/mkii/s-pre-11.mkii @@ -0,0 +1,220 @@ +%D \module +%D [ file=s-pre-11, +%D version=1999.08.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 11, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=0cm, + backspace=0cm, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +\setupbodyfont + [14.4pt,lbr] + +\setupcolors + [state=start] + +\setupinteraction + [click=no, + display=new, + state=start] + +\setupinteractionscreen + [option=max] + +\unexpanded\def\SomeShape + {\resetMPdrawing + \startMPdrawing + path p[], q[] ; pair a, b ; + StartPage ; + \stopMPdrawing + \dorecurse{\CurrentTopic} + {\startMPdrawing + initialize_box(\MPpos{topic-\realfolio-\recurselevel}) ; + p[\recurselevel] := tensecircle (wxy,hxy,.25cm) shifted cxy ; + fill p[\recurselevel] withcolor .9white ; + pickup pencircle scaled .25cm ; + if \recurselevel = \CurrentTopic : + draw p[\recurselevel] withcolor \MPcolor{ShowColor} ; + else : + draw p[\recurselevel] withcolor \MPcolor{DoneColor} ; + fi ; + \stopMPdrawing}% + \dorecurse{\CurrentMaxItem} + {\startMPdrawing + initialize_box(\MPpos{item-\realfolio-\recurselevel}) ; + linewidth := .25cm ; + q[\recurselevel] := tensecircle (wxy,hxy,linewidth) shifted cxy ; + fill q[\recurselevel] withcolor .9white ; + pickup pencircle scaled linewidth ; + if \recurselevel = \CurrentMaxItem : + draw q[\recurselevel] withcolor \MPcolor{ShowColor} ; + else : + draw q[\recurselevel] withcolor \MPcolor{DoneColor} ; + fi ; + \stopMPdrawing}% + \dostepwiserecurse{2}{\CurrentTopic}{1} + {\startMPdrawing + draw + rt point 3 of p[\recurselevel-1] -- + lft point 7 of p[\recurselevel] + withcolor \MPcolor{ArrowColor} ; + \stopMPdrawing}% + \dostepwiserecurse{2}{\CurrentMaxItem}{1} + {\startMPdrawing + draw + bot point 9 of q[\recurselevel-1] -- + top point 5 of q[\recurselevel] + withcolor \MPcolor{ArrowColor} ; + \stopMPdrawing}% + \startMPdrawing + draw Page + withpen pencircle scaled .5cm + withcolor \MPcolor{EdgeColor} ; + StopPage ; + \stopMPdrawing + \MPdrawingdonetrue + \getMPdrawing} + +\unexpanded\def\TitlePage#1% + {\startstandardmakeup + \setupalign[middle] + \def\\{\vfil\bfb\setupinterlinespace} + \bfd\setupinterlinespace + \vfil#1\vfil\vfil + \stopstandardmakeup} + +\definecolor[PageColor][r=.5,g=.4,b=.3] +\definecolor[LineColor][r=.7,g=.6,b=.5] + +\definecolor[PageColor] [s=.60] +\definecolor[ShowColor] [r=.40] +\definecolor[EdgeColor] [g=.40] +\definecolor[DoneColor] [r=.40,g=.40] +\definecolor[ArrowColor] [b=.40] +\definecolor[LineColor] [r=.60,g=.60] +\definecolor[GotoColor] [ArrowColor] + +\setupinteraction[color=GotoColor,contrastcolor=GotoColor] + +\defineoverlay [shape] [\SomeShape] +\defineoverlay [next] [\overlaybutton{forward}] % [{nextpage}] + +\setupbackgrounds + [page] + [background={color,next,shape}, + backgroundcolor=PageColor] + +\doglobal\newcounter\CurrentMaxItem +\doglobal\newcounter\CurrentItem +\doglobal\newcounter\CurrentTopic + +\unexpanded\def\StartIdea + {\doglobal\newcounter\CurrentItem} + +\unexpanded\def\StartTopic + {\doglobal\increment\CurrentTopic + \dostartbuffer[topic-\CurrentTopic][StartTopic][StopTopic]} + +\unexpanded\def\StopIdea + {\dorecurse{\CurrentItem} + {\let\CurrentMaxItem\recurselevel + \doStopIdea}} + +\unexpanded\def\doStopIdea + {\startstandardmakeup + \dontcomplain + \vskip.875cm + \hbox to \makeupwidth + {\hfill + \dorecurse{\CurrentTopic} + {\edef\Topic{topic-\realfolio-\recurselevel}% + \hpos + {\Topic} + {\framed + [frame=off,align=middle,offset=.25cm] + {\getbuffer[topic-\recurselevel]}}% + \ifnum\recurselevel<\CurrentTopic + \hskip.875cm + \fi}% + \hfill} + \vskip.875cm + \vfilll + \dorecurse{\CurrentMaxItem} + {\edef\Item{item-\realfolio-\recurselevel} + \hbox to \makeupwidth + {\hfill + \hpos + {\Item} + {\framed + [width=.75\makeupwidth, + frame=off, + align=middle,offset=.125cm] + {\getbuffer[item-\recurselevel]}}% + \hfill} + \vskip.875cm} + \vfilll + \stopstandardmakeup} + +\unexpanded\def\StartItem + {\doglobal\increment\CurrentItem + \dostartbuffer[item-\CurrentItem][StartItem][StopItem]} + +\lefthyphenmin =\maxdimen +\righthyphenmin=\maxdimen + +% \doifnotmode{demo}{\endinput} + +\starttext + +\StartIdea + \StartTopic + A Nice Idea + \StopTopic + \StartItem + \input reich \relax + \StopItem + \StartItem + \input reich \relax + \StopItem + \StartItem + \input reich \relax + \StopItem +\StopIdea + +\StartIdea + \StartTopic + One More Nice Idea + \StopTopic + \StartItem + \input reich \relax + \StopItem + \StartItem + \input reich \relax + \StopItem +\StopIdea + +\StartIdea + \StartTopic + The Last Idea + \StopTopic + \StartItem + \input tufte \relax + \StopItem +\StopIdea + +\stoptext diff --git a/tex/context/modules/mkii/s-pre-14.mkii b/tex/context/modules/mkii/s-pre-14.mkii new file mode 100644 index 000000000..c137df863 --- /dev/null +++ b/tex/context/modules/mkii/s-pre-14.mkii @@ -0,0 +1,263 @@ +%D \module +%D [ file=s-pre-14, +%D version=1999.08.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 14, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D In the process of making a couple of simple styles for +%D \EUROTEX\ 99, I came to this one. The joke is in the +%D pagenumber. This style can be used for short presentations +%D with much text. + +\startmode[asintended] \setupbodyfont[lbr] \stopmode + +\setupbodyfont[14.4pt] + +%D Since we expect text, we can best be very tolerant. + +\setuptolerance + [verytolerant,stretch] + +%D As most styles we choose a large screen page size. + +\setuppapersize + [S6][S6] + +\setuplayout + [width=fit, + rightedge=3cm, + margin=0pt, + rightedgedistance=2cm, + height=middle, + header=0pt, + footer=0pt, + topspace=1cm, + backspace=1cm] + +%D We only use two colors, named \type {One} and \type +%D {Two}: + +\setupcolors + [state=start] + +\definecolor [One] [r=.6,g=.4,b=.4] +\definecolor [Two] [r=.4,g=.6,b=.6] + +%D If you've looked at the demo file, you will have noticed +%D that the background consists of four pieces: two filled +%D rectangles and two half numbers. These are put on th epage +%D using four overlays: + +\setupbackgrounds + [page] + [background={one,two,three,four}] + +%D When we code this in \TEX, we get the following +%D definitions. As an alternative we coudl have used layers +%D but I'm afraid that it would not have led to less code. + +\defineoverlay + [one] + [{\framed + [frame=off,background=color,backgroundcolor=Two, + width=\overlaywidth,height=\overlayheight] + {}}] + +\defineoverlay + [three] + [{\hbox to \overlaywidth + {\hfill\SetOverlayWidth + \framed + [frame=off,background=color,backgroundcolor=One, + width=\overlaywidth,height=\overlayheight] + {}}}] + +%D We could have used the main backgroundcolor instead of +%D overlay \type {one}. + +\definefont[NumberFont][RegularBold at 3cm] + +\defineoverlay + [two] + [{\framed + [frame=off,width=\overlaywidth,height=\overlayheight, + offset=overlay] + {\vfill + \NumberFont\setstrut\SetOverlayWidth + \hbox to \hsize + {\hfill + \setupinteraction[style=,color=]% + \setbox0=\hbox{\strut\One\pagenumber}% + \hbox to 0pt{\hss\gotobox{\box0}[previouspage]\hss}% + \hskip\overlaywidth}}}] + +\defineoverlay + [four] + [{\framed + [frame=off,width=\overlaywidth,height=\overlayheight,offset=overlay] + {\vfill + \hbox to \hsize + {\hfill + \SetOverlayWidth + \framed + [frame=off,width=\overlaywidth,height=\overlayheight,offset=overlay] + {\vfill\NumberFont\setstrut + \setbox0=\hbox{\strut\Two\pagenumber}% + \setbox2=\hbox{\clip[nx=2,ny=1,x=2,y=1]{\copy0}}% + \dp2=\dp0 + \hbox to \hsize{\hbox to 0pt{\hss\hskip.5\wd0\box2\hss}\hfill}}}}}] + +\def\SetOverlayWidth% + {\scratchdimen = \rightedgedistance + \divide\scratchdimen by 2 + \advance\scratchdimen by \rightedgewidth + \advance\scratchdimen by \backspace + \edef\overlaywidth{\the\scratchdimen}} + +%D A much cleaner implementation is the following. If you hate +%D \METAPOST, you can run this style in the specified mode: + +\startnotmode[no-metapost] + +\setupbackgrounds + [page] + [background={number}] + +\defineoverlay[number][\useMPgraphic{number}] + +\startuseMPgraphic{number} + StartPage ; + path Vage ; picture Left, Right ; + x1 = x2 = xpart (llcorner Field[Text][RightEdge] shifted (-RightEdgeDistance/2,0)) ; + y1 = ypart llcorner Page ; + y2 = ypart ulcorner Page ; + Vage := llcorner Page -- z1 -- z2 -- ulcorner Page -- cycle ; + fill Page withcolor \MPcolor {One} ; + fill Vage withcolor \MPcolor {Two} ; + if PageNumber>0 : + defaultfont := "\truefontname{RegularBold}" ; + Left := Right := thelabel("\folio",origin) ysized 3cm ; + clip Right to boundingbox Right shifted (bbwidth(Right)/2,0) ; + draw Left shifted z1 shifted (0,2.25cm) withcolor \MPcolor {One} ; + draw Right shifted z1 shifted (0,2.25cm) withcolor \MPcolor {Two} ; + fi ; + StopPage ; +\stopuseMPgraphic + +\stopnotmode + +%D We use the simple label typesetting present in \METAPOST\ +%D because digits are seldom kerned so real \TEX ing is not +%D needed. As in the previous method, we let the graphics +%D overlap so that we don't get white lines due to rounding +%D problems in viewers. +%D +%D We put a button behind the text (this overlay is calculated +%D each page). + +\defineoverlay + [nextpage] + [\overlaybutton{nextpage}] + +\setupbackgrounds + [text] + [backgroundoffset=.5cm, + background=nextpage] + +%D We still have to turn on interaction mode. + +\setupinteraction + [state=start, + display=new, + menu=on] + +\setupinteraction + [color=, + contrastcolor=] + +%D Next we define structuring commands. + +\definehead[Topic] [chapter] \setuphead[Topic] [style=\bfc] +\definehead[Subject][section] \setuphead[Subject][style=\bfa] + +\setuphead + [Topic,Subject] + [number=no, + after={\blank[big]}] + +%D Because we will provide a menu, we don't offer lists. + +\let\Topics \gobbleoneargument +\let\Subjects\relax + +%D The table of contents goes to the right edge. + +\startinteractionmenu[right] + \setupinteraction + [color=black, + contrastcolor=Two] + \placelist + [Topic] + [alternative=e, + frame=off, + criterium=all] + \vfill +\stopinteractionmenu + +\setuplist + [Topic] + [width=\rightedgewidth, + maxwidth=\rightedgewidth, + style=\bfa] + +%D We safe some space: + +\setupwhitespace + [medium] + +\setupblank + [medium] + +%D In the titlepage, we still use the \TEX\ overlays, +%D so that we don't have to define a second graphic. + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +\def\StartTitlePage% + {\bgroup + \setupbackgrounds[page][background={one,three}] + \startstandardmakeup + \setupalign[middle] + \def\\{\vfil\bfb\setupinterlinespace} + \bfd\setupinterlinespace + \vfil} + +\def\StopTitlePage% + {\vfil\vfil\vfil + \stopstandardmakeup + \egroup} + +%D This is it. + +\doifnotmode{demo}{\endinput} + +\starttext + +\TitlePage{Some Quotes\\(that you probably know by now)} + +\Topic{Tufte} \input tufte +\Topic{Knuth} \input knuth +\Topic{Reich} \input reich +\Topic{Zapf} \input zapf +\Topic{Materie} \input materie +%Topic{Stork} \input stork + +\stoptext diff --git a/tex/context/modules/mkii/s-pre-15.mkii b/tex/context/modules/mkii/s-pre-15.mkii new file mode 100644 index 000000000..d1d8053b6 --- /dev/null +++ b/tex/context/modules/mkii/s-pre-15.mkii @@ -0,0 +1,186 @@ +%D \module +%D [ file=s-pre-15, +%D version=1999.09.01, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 15, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is one of the styles I made for the presentation on +%D the \NTS\ project at Euro\TeX\ 1998. You need balls to let +%D \TEX\ typeset graphics, but this style demonstrates that it +%D can be done. +%D +%D This presentation is meant for presentations that build up +%D an idea stepwise. +%D +%D \starttyping +%D \TitlePage{Do you know \TEX ?} +%D +%D \StartIdea +%D \StartItem We use \TEX\ for typesetting \unknown \StopItem +%D \StartItem mathematical text \unknown \StopItem +%D \StartItem but also for text that has no math \unknown \StopItem +%D \StartItem or presentations like this \unknown \StopItem +%D \StartItem and whatever you can come up with! \StopItem +%D \StopIdea +%D \stoptyping + +%D The basic layout is rather simple and used as much of the +%D screen as possible. + +\setuppapersize + [S6][S6] + +\setuplayout + [backspace=25pt, + topspace=25pt, + width=middle, + height=middle, + header=0pt, + footer=0pt] + +\setupinteraction + [state=start, + display=new, + color=LineColor, + contrastcolor=LineColor, + click=no] + +\setupinteractionscreen + [option=max] + +\startmode[asintended] \setupbodyfont[lbr] \stopmode + +\setupbodyfont[14.4pt] + +%D We use a lot of color. You can remap them if you want +%D different ones. The ideas circulate over the colors. + +\setupcolors + [state=start] + +\definecolor[TextColor][s=.8] +\definecolor[PageColor][s=.6] +\definecolor[LineColor][s=.4] + +\definecolor[red] [r=.4] \definecolor[cyan] [g=.4,b=.4] +\definecolor[green][g=.4] \definecolor[magenta][r=.4,b=.4] +\definecolor[blue] [b=.4] \definecolor[yellow] [r=.4,g=.4] + +\definecolor[linecolor 1][red] \definecolor[linecolor 5][cyan] +\definecolor[linecolor 2][green] \definecolor[linecolor 6][magenta] +\definecolor[linecolor 3][blue] \definecolor[linecolor 4][yellow] + +%D We use variables to make sure that the graphics are reused +%D but unique. + +\setupMPvariables[pageframe][pagecolor=PageColor,linecolor=LineColor] +\setupMPvariables[textframe][textcolor=TextColor,linecolor=LineColor] + +\setupbackgrounds + [page] + [background={pageframe,nextpage}] + +\defineoverlay [pageframe] [\uniqueMPgraphic{pageframe}] +\defineoverlay [textframe] [\uniqueMPgraphic{textframe}] +\defineoverlay [nextpage] [\overlaybutton{forward}] + +\startuniqueMPgraphic{pageframe}{pagecolor,linecolor} + path p ; p := fullsquare xyscaled (OverlayWidth,OverlayHeight) ; + pickup pencircle scaled 10pt ; + fill p withcolor \MPvar{pagecolor} ; + draw p withcolor \MPvar{linecolor} ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{textframe}{textcolor,linecolor} + path p ; p := fullcircle xyscaled (OverlayWidth,OverlayHeight) ; + pickup pencircle scaled 10pt ; + fill p withcolor \MPvar{textcolor} ; + draw p withcolor \MPvar{linecolor} ; +\stopuniqueMPgraphic + +%D The rest of the file implements the nasty part: typesetting +%D text embedded in a graphic. The text is collected in a box +%D so that we can reuse it. + +\newbox\CollectedIdeas +\newcounter\CurrentTopic + +\def\StartItem% + {\setbox\CollectedIdeas=\hbox\bgroup + \ifdim\wd\CollectedIdeas>0pt \unhbox\CollectedIdeas\hskip25pt \fi + \setbox\scratchbox=\hbox\bgroup + \framed + [width=160pt,height=160pt,align=middle,frame=off, + background=textframe,offset=15pt,top=\vfill,bottom=\vfill] + \bgroup} + +\def\StopItem% + {\egroup + \egroup + \setbox\scratchbox=\hbox{\lower.5\ht\scratchbox\box\scratchbox}% + \ht\scratchbox=.5\ht\scratchbox + \dp\scratchbox= \ht\scratchbox + \box\scratchbox + \egroup + \startstandardmakeup + \dontcomplain + \leftskip 0pt plus 50pt + \rightskip 0pt plus 50pt + \parfillskip 0pt + \baselineskip 100pt + \unhcopy\CollectedIdeas + \stopstandardmakeup} + +\def\StartIdea% + {\ifnum\CurrentTopic=6 \doglobal\newcounter\CurrentTopic \fi + \doglobal\increment\CurrentTopic + \definecolor[LineColor][linecolor \CurrentTopic] + \setbox\CollectedIdeas=\null} + +\def\StopIdea% + {} + +\def\StartTitlePage% + {\startstandardmakeup + \setupalign[middle] + \def\\{\vfil\bfb\setupinterlinespace} + \bfd\setupinterlinespace + \vfil} + +\def\StopTitlePage% + {\vfil\vfil + \stopstandardmakeup} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +\doifnotmode{demo}{\endinput} + +%D A simple test on functionality. + +\setupoutput[pdftex] + +\starttext + +\TitlePage{Do you know \TEX ?} + +\startbuffer +\StartIdea + \StartItem We use \TEX\ for typesetting \unknown \StopItem + \StartItem mathematical text \unknown \StopItem + \StartItem but also for text that has no math \unknown \StopItem + \StartItem or presentations like this \unknown \StopItem + \StartItem and whatever you can come up with! \StopItem +\StopIdea +\stopbuffer + +\dorecurse{6}{\getbuffer} + +\stoptext diff --git a/tex/context/modules/mkii/s-pre-19.mkii b/tex/context/modules/mkii/s-pre-19.mkii new file mode 100644 index 000000000..991d311ce --- /dev/null +++ b/tex/context/modules/mkii/s-pre-19.mkii @@ -0,0 +1,347 @@ +%D \module +%D [ file=s-pre-19, +%D version=2000.07.31, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 19, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This style is made in the process or writing the \METAFUN\ +%D manual. It exploits a few tricks, like graphics calculated +%D using positional information. It also uses the (at that +%D moment) new menu list placement alternative. If you forget +%D about the definition of the button shapes, which is +%D complicated in any system, this style is not even that hard +%D to follow. Watch how the left side of the buttons follow +%D the right side of the text graphic. +%D +%D While playing bit with this style, the random alternative +%D made me think of those organic building with non equal +%D windows (we have a few in The Netherlands), so I decided to +%D label this style as \type {pre-organic}. +%D +%D At the end of this file, there is a small test file, so +%D when you process this file with \TEXEXEC\ and the options +%D \type {--mode=demo} and \type {--pdf}, you will get a demo +%D document. + +%D We use one of the standard screen \quote {paper} sizes, and +%D map it onto the same size, so that we get a nicely cropped +%D page. + +\setuppapersize + [S6][S6] + +%D Like in the \METAFUN\ manual, we use the Palatino as main +%D bodyfont. This font is quite readable on even low +%D resolution screens, although I admit that this style is +%D developed using an $1400\times1050$ pixel LCD screen, so I +%D may be biased. + +%\startmode[asintended] \setupbodyfont[ppl] \stopmode + +%D The layout specification sets up a text area and a right +%D edge area where the menus will go. Watch the rather large +%D edge distance. By setting the header and footer dimensions +%D to zero, we automatically get rid of page body ornaments, +%D like the pagenumber. + +\setuplayout + [topspace=48pt, + backspace=48pt, + cutspace=12pt, + width=400pt, + margin=0cm, + rightedge=88pt, + rightedgedistance=48pt, + header=0cm, + footer=0cm, + height=middle] + +%D We use a moderate, about a line height, interparagraph +%D white space. + +\setupwhitespace + [big] + +%D Of course we use colors, since on computer displays they +%D come for free. + +\setupcolors + [state=start] + +\definecolor [red] [r=.75] +\definecolor [yellow] [r=.75,g=.75] +\definecolor [gray] [s=.50] +\definecolor [white] [s=.85] + +\definecolor [PageColor] [yellow] +\definecolor [TextColor] [white] +\definecolor [OrnamentColor] [red] +\definecolor [InteractionColor] [red] +\definecolor [ContrastColor] [gray] + +%D This is an interactive document, so we enable interaction. +%D In this style, we disable the viewer's \quote {highlight a +%D hyperlink when it's clicked on} feature. We will use a +%D menu, so we enable menus. Later we will see the contract +%D color |<|hyperlinks gets that color when we are already on +%D the location|>| in action. + +\setupinteraction + [state=start, + click=off, + color=InteractionColor, + contrastcolor=ContrastColor, + menu=on] + +%D The menu itself is set up as follows. Because we will +%D calculate menubuttons based on their position on the page, +%D we have to keep track of the positions. Therefore, we set +%D the \type {position} variable to \type {yes}. + +\setupinteractionmenu + [right] + [frame=off, + position=yes, + align=middle, + topoffset=-.75cm, + bottomoffset=-.75cm, + color=gray, + contrastcolor=gray, + style=bold, + before=, + after=] + +%D The menu content is rather sober: a list of topics (later +%D we will define the command that generates topic entries), +%D and a close button. + +\startinteractionmenu[right] + \placelist[Topic][alternative=right] + \vfill + \but [CloseDocument] close \\ +\stopinteractionmenu + +%D We have now arived at the more interesting part of the style +%D definition: the graphic that goes in the page background. +%D Because this graphic will change, we define a usable +%D \METAPOST\ graphic. Page backgrounds are recalculated each +%D page, opposite to the other backgrounds that are calculated +%D when a new background is defined, or when repetitive +%D calculation is turned on. + +\setupbackgrounds + [page] + [background=page] + +\defineoverlay + [page] + [\useMPgraphic{page}] + +\setupMPvariables + [page] + [alternative=3] + +\startuseMPgraphic{page} + + \includeMPgraphic{rightsuperbutton} + + StartPage ; + + path p, q ; pickup pencircle scaled 3pt ; + + p := Field[Text][Text] enlarged 36pt superellipsed .90 ; + + fill Page withcolor \MPcolor{PageColor} ; + fill p withcolor \MPcolor{TextColor} ; + draw p withcolor \MPcolor{OrnamentColor} ; + + p := Field[Text][Text] enlarged 48pt superellipsed .90 ; + + def right_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) = + if (pp>0) and (rr>0) : + q := rightsuperbutton(p,xx,yy,RightEdgeWidth,hh) ; + fill q withcolor \MPcolor{TextColor} ; + draw q withcolor if rr=2 : \MPcolor{ContrastColor} + else : \MPcolor{InteractionColor} fi ; + fi ; + enddef ; + + \MPmenubuttons{right} + + StopPage ; +\stopuseMPgraphic + +\startuseMPgraphic{page} + + \includeMPgraphic{rightsuperbutton} + + StartPage ; + + numeric alternative, seed, superness, squeezeness, randomness ; + path p, q ; transform t ; + + alternative := \MPvar{alternative} ; + seed := uniformdeviate 100 ; + + if alternative > 10 : + superness := .85 + ((\realfolio-1)/\lastpage) * .15 ; + squeezeness := 12pt - ((\realfolio-1)/\lastpage) * 10pt ; + else : + superness := .90 ; + squeezeness := 12pt ; + fi ; + + randomness := squeezeness ; + + alternative := alternative mod 10 ; + + t := identity if alternative=3: shifted (9pt,-9pt) fi ; + + % first we draw the shape that surrounds the text + + randomseed := seed ; + + p := Field[Text][Text] enlarged if + alternative = 1 : 36pt superellipsed superness elseif + alternative = 2 : 36pt squeezed squeezeness elseif + alternative = 3 : 36pt randomized randomness else + : 36pt fi ; + pickup pencircle scaled 3pt ; + + fill Page withcolor \MPcolor{PageColor} ; + fill p withcolor \MPcolor{TextColor} ; + draw p withcolor \MPcolor{OrnamentColor} ; + + % we set p to the wider shape from which we will chip off pieces + + randomseed := seed ; + + p := ( Field[Text][Text] enlarged if + alternative = 1 : 48pt superellipsed superness elseif + alternative = 2 : 48pt squeezed squeezeness elseif + alternative = 3 : 36pt randomized randomness else + : 48pt fi ) transformed t ; + + % calls to *_menu_button are generated automatically ... + + vardef right_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) = + save q ; path q ; + if (pp>0) and (rr>0) : + q := rightsuperbutton(p,xx,yy,RightEdgeWidth,hh) ; % \MPw{menu:right:\realfolio} + fill q withcolor \MPcolor{TextColor} ; + draw q withcolor if rr=2 : \MPcolor{ContrastColor} + else : \MPcolor{InteractionColor} fi ; + fi ; + enddef ; + + % ... and inserted when the graphic data is flushed here ... + + \MPmenubuttons{right} + + StopPage ; +\stopuseMPgraphic + +\startuseMPgraphic{rightsuperbutton} + +vardef rightsuperbutton (expr pat, xpos, ypos, wid, hei) = + + save p, ptop, pbot, t, b, edge, shift, width, height ; + path p, ptop, pbot ; pair t, b ; numeric edge, shift, width, height ; + + edge := xpos + wid ; shift := ypos + hei ; + + p := rightpath pat ; + + ptop := ((-infinity,shift)--(edge,shift)) ; + pbot := ((-infinity,shift-hei)--(edge,shift-hei)) ; + + t := p intersection_point ptop ; + b := p intersection_point pbot ; + + p := subpath(0,xpart (p intersectiontimes ptop)) of p ; + p := subpath(xpart (p intersectiontimes pbot),length(p)) of p ; + + (p -- t -- point 1 of ptop & + point 1 of ptop -- point 1 of pbot & + point 1 of pbot -- b + -- cycle) + +enddef ; + +\stopuseMPgraphic + +%D Topics are identified with \type {\Topic}, which is an +%D instance of chapter headings. The number is made invisible. +%D Since it still is a numbered section header, \CONTEXT\ will +%D write the header to the table of contents. + +\definehead + [Topic] + [chapter] + +\setuphead + [Topic] + [number=no] + +%D We will use a bold font in the table of contents. We also +%D force a complete list. + +\setuplist + [Topic] + [criterium=all, + style=bold, + before=, + after=] + +%D The \type {\TitlePage} macro looks horrible, because we +%D want to keep the interface simple: a list of small +%D sentences, separated by \type {\\}. + +\def\StartTitlePage + {\startstandardmakeup + \switchtobodyfont[big] + \def\\{\vfill\bfb\let\\=\par} + \bfd\setupinterlinespace\gray + \vskip.5cm} + +\def\StopTitlePage + {\\\vskip.5cm % the \\ is really needed + \stopstandardmakeup} + +\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D A couple of goodies: + +\def\Subject {\Topic} +\def\Topics #1{} +\def\Subjects {} + +%D For those who want to test: + +\doifnotmode{demo}{\endinput} + +\starttext + +\setupMPvariables[page][alternative=3] + +\TitlePage + {A Few Nice Quotes\\ + A Simple Style Demo\\ + Hans Hagen, August 2000} + + +\Topic {Douglas R. Hofstadter} \input douglas \page +\Topic {Donald E. Knuth} \input knuth \page +\Topic {Edward R. Tufte} \input tufte \page +\Topic {Hermann Zapf} \input zapf \page +%Topic {David F. Stork} \input stork \page + +\stoptext diff --git a/tex/context/modules/mkii/s-pre-61.mkii b/tex/context/modules/mkii/s-pre-61.mkii new file mode 100644 index 000000000..48b9d09a0 --- /dev/null +++ b/tex/context/modules/mkii/s-pre-61.mkii @@ -0,0 +1,275 @@ +%D \module +%D [ file=s-pre-61, +%D version=2004.03.15, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 61, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Optima + +\usemodule[pre-60] + +\doifmodeelse {mkiv} { + \usetypescriptfile[ghz] + \definetypeface[mainface][ss][sans][optima-nova][default] +} { + \usetypescriptfile[type-ghz] + \definetypeface[mainface][ss][sans][optima-nova][default][encoding=\defaultencoding] +} + +\setupbodyfont[mainface,ss,18pt] +\setupinterlinespace[line=3.25ex] + +\setuppapersize + [S6][S6] + +% \setuppapersize +% [SW][SW] + +\setuplayout + [topspace=10pt, + header=30pt, + headerdistance=20pt, + height=middle, + footerdistance=20pt, + footer=0pt, + bottomdistance=20pt, + bottom=20pt, + bottomspace=50pt, + backspace=30pt, + width=middle] + +\setupinteraction + [state=start, + click=off, + menu=on, + style=, + color=interactioncolor, + contrastcolor=interactioncolor] + +\setupinteractionscreen + [option=max] + +\setupinteractionmenu + [bottom] + [color=maincolor, + contrastcolor=maincolor, + style=\tfa, % acceptable + left=\hfill, + middle=, + right=, + height=\bottomheight, + width=2\bottomheight, + offset=overlay, + frame=off] + +\startinteractionmenu[bottom] + \but [firstpage] \symbol[firstpage] \\ + \but [previouspage] \symbol[previouspage] \\ + \but [InvokeStepper] \StartBusy\symbol[PauseRendering]\StopBusy \\ + \but [nextpage] \symbol[nextpage] \\ + \but [lastpage] \symbol[lastpage] \\ + \but [CloseDocument] \symbol[CloseDocument] \\ +\stopinteractionmenu + +% maybe in colo-sjk : \setupcolor[sjk] + +\definecolor [dark] [s=.4] +\definecolor [bright] [s=.9] + +\definecolor [red] [r=.4,g=.2,b=.2] +\definecolor [green] [r=.2,g=.4,b=.2] +\definecolor [blue] [r=.2,g=.2,b=.4] + +\definecolor [cyan] [r=.2,g=.4,b=.4] +\definecolor [magenta][r=.4,g=.2,b=.4] +\definecolor [yellow] [r=.4,g=.4,b=.2] + +\definecolor [pagecolor] [dark] +\definecolor [maincolor] [bright] +\definecolor [textcolor] [red] + +\definecolor [interactioncolor] [r=.8,g=.8,b=.6] + +\setupcolors + [state=start, + textcolor=maincolor] + +\setupbackgrounds + [page] + [background=page, + backgroundcolor=textcolor] + +\setupbackgrounds + [text]% [text] + [background={comments,text,invoke}] + +\definelayer + [text] + [width=\textwidth, + height=\textheight] + +\defineoverlay + [comments] + [{\setlayer[text][preset=middle]{\placecomments}}] + +\defineoverlay[page][\uniqueMPgraphic{page-\ifcase\realpageno\or one\else plus\fi}] + +\startuniqueMPgraphic{page-one} + StartPage ; + fill Page + enlarged 4pt + withcolor \MPcolor{pagecolor} ; + fill Field[Text][Text] + enlarged 10pt +% topenlarged (HeaderHeight+HeaderDistance) + leftenlarged (BackSpace+4pt) + rightenlarged (CutSpace +4pt) + withcolor OverlayColor ; + StopPage ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{page-plus} + StartPage ; + fill Page + enlarged 4pt + withcolor \MPcolor{pagecolor} ; + fill Field[Text][Text] + enlarged 10pt + leftenlarged (BackSpace+4pt) + rightenlarged (CutSpace+4pt) + withcolor OverlayColor ; + StopPage ; +\stopuniqueMPgraphic + +% this needs to be sorted out ! + +\appendtoks + \NormalizeFontHeight \HeadFont {\setstrut\strut\quad} {1.0\headerheight} {SansBold} + \NormalizeFontHeight \TitleFont {\setstrut\strut\quad} {2.0\headerheight} {SansBold} + \NormalizeFontHeight \SubTitleFont {\setstrut\strut\quad} {1.5\headerheight} {SansBold} + \NormalizeFontHeight \SubSubTitleFont {\setstrut\strut\quad} {1.0\headerheight} {SansBold} +\to \everystarttext + +\appendtoks + \NormalizeFontHeight \HeadFont {\setstrut\strut\quad} {1.0\headerheight} {SansBold} + \NormalizeFontHeight \TitleFont {\setstrut\strut\quad} {2.0\headerheight} {SansBold} + \NormalizeFontHeight \SubTitleFont {\setstrut\strut\quad} {1.5\headerheight} {SansBold} + \NormalizeFontHeight \SubSubTitleFont {\setstrut\strut\quad} {1.0\headerheight} {SansBold} +\to \everystoptext + +\setuphead + [chapter] + [placehead=empty, + after={\blank[medium]}, + color=maincolor, + placenumber=no, + style=\HeadFont] + +\setupheadertexts + [\doiftextelse{\currentheadnumber}{\placeheadtext[Topic]}{\placeheadtext[Nopic]}] + [] + +\setuppagenumbering + [location=] + +\definesymbol + [emdash] + [\emdash] + +\setupitemize + [each] + [loose,serried,joinedup,broad] + [symbol=emdash] + +\setupalign + [broad,right] + +\def\doTitlePage#1#2#3% + {\startstandardmakeup[headerstate=high] + \def\\{\def\\{\endgraf\quad\quad}\endgraf\quad\ignorespaces#2}% + #1\setstrut\setupinterlinespace\vfil#3\vfil\vfil + \stopstandardmakeup} + +\def\TitlePage {\doTitlePage\TitleFont\relax} +\def\SubTitlePage{\doTitlePage\TitleFont\SubTitleFont} + +\definehead[Topic][chapter] +\definehead[Nopic][title] + +\def\Topics#1% + {\Nopic[topics]{#1} + \startcolumns + \placelist[Topic] + \stopcolumns} + +\setuplist + [Topic] + [alternative=f, + color=maincolor, + contrastcolor=maincolor, + criterium=all] + +\defineoverlay[topics][\overlaybutton{topics}] + +\setupbackgrounds + [bottom] [text] + [background=topics] + +\continueifinputfile{s-pre-61.tex} + +\starttext + +\TitlePage{Stepwise\\Refinement} + +\Topics{Topics} + +\Topic{Female Artists} + +\StartSteps + +\startitemize +\item Fiona Apple \FlushStep +\item Tori Amos \FlushStep +\item Kate Bush \FlushStep +\item Heather Nova \FlushStep +\item Alanis Morissette \FlushStep +\item Suzanne Vega \FlushStep +\stopitemize + +\StopSteps + +\Topic{Male Composers} + +\StartSteps + +\startitemize +\item John Adams \FlushStep +\item Steve Reich \FlushStep +\item Louis Andriessen \FlushStep +\item Olivier Messiaen \FlushStep +\stopitemize + +\StopSteps + +\Topic{And Some More} + +\StartSteps + +\startitemize +\item Mark Hollis \FlushStep +\item Roger Waters \FlushStep +\item David Gilmore \FlushStep +\item Peter Gabriel \FlushStep +\item Randy Newman \FlushStep +\stopitemize + +\StopSteps + +\stoptext diff --git a/tex/context/modules/mkii/s-pre-62.mkii b/tex/context/modules/mkii/s-pre-62.mkii new file mode 100644 index 000000000..a1a405c23 --- /dev/null +++ b/tex/context/modules/mkii/s-pre-62.mkii @@ -0,0 +1,224 @@ +%D \module +%D [ file=s-pre-62, +%D version=2005.03.04, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 62, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Melior + +\usemodule[pre-60] + +\usetypescriptfile + [type-ghz] + +\doifmodeelse {mkiv} { + + \definetypeface[mainface][rm][serif][melior] [default] + \definetypeface[mainface][tt][mono] [modern] [default][rscale=1.05] + \definetypeface[mainface][ss][serif][melior] [default] + \definetypeface[mainface][mm][math] [palatino][default][rscale=0.95] + +} { + + \definetypeface[mainface][rm][serif][melior] [default][encoding=texnansi] + \definetypeface[mainface][tt][mono] [modern] [default][encoding=texnansi,rscale=1.05] + \definetypeface[mainface][ss][serif][melior] [default][encoding=texnansi] + \definetypeface[mainface][mm][math] [palatino][default][encoding=texnansi,rscale=0.95] + +} + +\setupbodyfont + [mainface,14.4pt] + +\setuppapersize + [S6][S6] + +\setvariables[layout][dx=0,dy=1,nx=2,ny=2,step=64] + +\definemeasure[layoutwd][\dimexpr\paperwidth /\getvariable{layout}{step}\relax] +\definemeasure[layoutht][\dimexpr\paperheight/\getvariable{layout}{step}\relax] + +\setuplayout + [ width=middle, + height=middle, + header=0pt, + footer=0pt, + margin=0pt, + backspace=5\measure{layoutwd}, + topspace=5\measure{layoutht}] + +\definelayout + [step] + [ backspace=\numexpr2+ \getvariable{layout}{dx}\relax\measure{layoutwd}, + cutspace=\numexpr3+\getvariable{layout}{nx}-\getvariable{layout}{dx}\relax\measure{layoutwd}, + topspace=\numexpr2+ \getvariable{layout}{dy}\relax\measure{layoutht}, + bottomspace=\numexpr3+\getvariable{layout}{ny}-\getvariable{layout}{dy}\relax\measure{layoutht}] + +\definecolor[layout:left] [t=.5,a=1,b=1] +\definecolor[layout:right] [t=.5,a=1,r=1] +\definecolor[layout:top] [t=.5,a=1,g=1] +\definecolor[layout:bottom][t=.5,a=1,y=1] +\definecolor[layout:page] [s=.75] + +\definehspace[menu][\measure{layoutwd}] + +\setupinteraction + [state=start, + click=off, + style=, + color=interactioncolor, + contrastcolor=interactioncolor] + +\setupinteractionscreen + [option=max] + +\setupbuttons + [color=maincolor, + contrastcolor=maincolor, + style=\tf, % acceptable + height=2\measure{layoutht}, + width=2\measure{layoutwd}, + offset=overlay, + frame=off] + +\definecolor[interactioncolor][darkgray] +\definecolor[maincolor] [lightgray] + +\setuptexttexts + [] + [\vbox to \textheight{\vfill\hfill\setups{menu:content}}] + +\startsetups menu:content + + \button{\symbol[firstpage]}[firstpage] + \hspace[menu] + \button{\symbol[previouspage]}[previouspage] + \hspace[menu] + \button{\StartBusy\symbol[PauseRendering]\StopBusy}[InvokeStepper] + \hspace[menu] + \button{\symbol[nextpage]}[nextpage] + \hspace[menu] + \button{\symbol[lastpage]}[lastpage] + \hspace[menu] + \button{\symbol[CloseDocument]}[CloseDocument] + +\stopsetups + +\startuseMPgraphic{page}{step} + StartPage ; + numeric dx, dy ; dx := PaperWidth/\MPvar{step} ; dy := PaperHeight/\MPvar{step} ; + fill Page withcolor .5white ; + fill + ulcorner Page -- urcorner Page -- + urcorner Page shifted (0,-TopSpace+dy) -- ulcorner Page shifted (0,-TopSpace+dy) -- cycle + withcolor \MPcolor{layout:top} ; + fill + llcorner Page -- lrcorner Page -- + lrcorner Page shifted (0,BottomSpace-dy) -- llcorner Page shifted (0,BottomSpace-dy) -- cycle + withcolor \MPcolor{layout:bottom} ; + fill + ulcorner Page -- llcorner Page -- + llcorner Page shifted (BackSpace-dx,0) -- ulcorner Page shifted (BackSpace-dx,0) -- cycle + withcolor \MPcolor{layout:left} ; + fill + urcorner Page -- lrcorner Page -- + lrcorner Page shifted (-CutSpace+dx,0) -- urcorner Page shifted (-CutSpace+dx,0) -- cycle + withcolor \MPcolor{layout:right} ; + fill Field[Text][Text] enlarged (dx,dy) withcolor white ; + fill Field[Text][Text] enlarged (dx,dy) withcolor \MPcolor{layout:page} ; + StopPage ; +\stopuseMPgraphic + +\defineoverlay[page][\useMPgraphic{page}{step=\getvariable{layout}{step}}] + +\setupbackgrounds + [page] + [background=page] + +\setupcolors + [state=start] + +\startsetups nextstep + % pagebreak handlers are grouped, so we need to set global + \ifnum\getvariable{layout}{dx}=\getvariable{layout}{nx}\relax + \ifnum\getvariable{layout}{dy}=\getvariable{layout}{ny}\relax + \setxvariables[layout][dy=1] + \else + \setxvariables[layout][dy=\the\numexpr\getvariable{layout}{dy}+1\relax] + \fi + \setxvariables[layout][dx=1] + \else + \setxvariables[layout][dx=\the\numexpr\getvariable{layout}{dx}+1\relax] + \fi + % global anyway + \setuplayout[step] +\stopsetups + +\definefontsynonym[MainTitleFont][SerifBold] + +\definefont[ChapterTitleFont][MainTitleFont sa 2] + +\appendtoks + \NormalizeFontHeight \TitleFont {\setstrut\strut\quad} {4\lineheight} {MainTitleFont} + \NormalizeFontHeight \SubTitleFont {\setstrut\strut\quad} {3\lineheight} {MainTitleFont} + \NormalizeFontHeight \ChapterNumberFont {XVI} {4\lineheight} {MainTitleFont} +\to \everystarttext + +\setupsection + [section-2] + [bodypartconversion=Romannumerals] + +\installpagebreakhandler {step} {\setups{nextstep}} + +\definepagebreak[chapter][yes,step] + +\setuphead + [chapter] + [page=chapter, + command=\MyChapterCommand] + +\definehead[Topic][chapter] +\definehead[Nopic][title] + +\setuphead[chapter,Topic,Nopic] + [numberstyle=\ChapterNumberFont, + textstyle=\ChapterTitleFont, + numbercolor=lightgray, + textcolor=darkgray] + +\def\MyChapterCommand#1#2% + {\hbox \bgroup % we need to nil the strut added by the headplacement + \setupframed[frame=off,lines=4,offset=overlay]% + \rlap{\hskip2\lineheight\framed{\setnostrut#1}}\framed{#2}% + \egroup} + +\setupitemize + [each] + [R,broad] + [stopper=, + color=lightgray] + +\def\doTitlePage#1#2#3% + {\startstandardmakeup[headerstate=high,textstate=stop] + \setupalign[middle] + \def\\{\def\\{\endgraf}\endgraf\vfil\ignorespaces#2}% + \startcolor[darkgray] + #1\setstrut\setupinterlinespace\vfil#3\vfil + \stopcolor + \stopstandardmakeup} + +\def\TitlePage {\doTitlePage\TitleFont\relax} +\def\SubTitlePage{\doTitlePage\TitleFont\SubTitleFont} + +\long\def\StartTitlePage #1\StopTitlePage {\TitlePage {#1}} +\long\def\StartSubTitlePage#1\StopSubTitlePage{\SubTitlePage{#1}} + +\endinput + diff --git a/tex/context/modules/mkii/s-pre-63.mkii b/tex/context/modules/mkii/s-pre-63.mkii new file mode 100644 index 000000000..9ecb2cb1a --- /dev/null +++ b/tex/context/modules/mkii/s-pre-63.mkii @@ -0,0 +1,73 @@ +%D \module +%D [ file=s-pre-63, +%D version=2006.05.11, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 63, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[pre-61,streams] + +\definemeasure[textgap] [\dimexpr24pt\relax] + +\definemeasure[leftwidth] [\dimexpr.25\textwidth-.5\measure{textgap}\relax] +\definemeasure[rightwidth][\dimexpr.75\textwidth-.5\measure{textgap}\relax] + +\definestreamlayer[left] [width=\measure{leftwidth}] +\definestreamlayer[right][width=\measure{rightwidth}] + +\setupbodyfont[12pt] + +\definefont[LeftFont][Normal sa 3] + +\setupheader[style=\tfc,before=\vss,after=\vss] + +\startsetups streamlayer:left:settings + \hsize\measure{leftwidth} + \LeftFont + \setupinterlinespace +\stopsetups + +\startsetups streamlayer:right:settings + \hsize\measure{rightwidth} +\stopsetups + +\definecombination[both][distance=\measure{textgap},location=top] + +\startsetups place:both + \startcombination[both] + {\StartLocalStep\placestreamlayer[left]\StopLocalStep} {} + {\StartLocalStep\placestreamlayer[right]\StopLocalStep} {} + \stopcombination +\stopsetups + +\def\StartPage {\page \StartLocalSteps} +\def\StopPage {\StopLocalSteps \page} + +\def\StartLeft {\startstreamlayer[left]} +\def\StartRight{\startstreamlayer[right]} + +\def\StopLeft {\stopstreamlayer} +\def\StopRight {\stopstreamlayer} + +\def\StartPair {} +\def\StopPair {\setups[place:both]} + +\doifnotmode {demo} {\endinput} + +\setupbodyfont[8pt] \definefont[BigFont][Normal sa 4] + +\starttext + +\StartPage + \StartPair \StartLeft ZAPF \StopLeft \StartRight \input zapf \StopRight \StopPair + \StartPair \StartLeft DAVIS \StopLeft \StartRight \input davis \StopRight \StopPair + \StartPair \StartLeft WARD \StopLeft \StartRight \input ward \StopRight \StopPair +\StopPage + +\stoptext diff --git a/tex/context/modules/mkii/s-pre-64.mkii b/tex/context/modules/mkii/s-pre-64.mkii new file mode 100644 index 000000000..ef4889bbb --- /dev/null +++ b/tex/context/modules/mkii/s-pre-64.mkii @@ -0,0 +1,208 @@ +%D \module +%D [ file=s-pre-64, +%D version=2006.05.11, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 64, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% To be documented, used in 2007 + +\usemodule[s][pre-60] + +\newcounter\shapesynctag +\newdimen\slantedshapedimen +\newdimen\slantedshapestep +\newdimen\slantedshapeleftskip +\newdimen\slantedshapeoffset +\newdimen\slantedshapeextra + +\positioningtrue + +\def\AdaptShape + {\doglobal\increment\shapesynctag + \getnoflines\textheight + \slantedshapestep\dimexpr\slantedshapeleftskip/\noflines\relax + \leftskip\slantedshapeleftskip + \scratchdimen\dimexpr\MPy{text:\MPp\shapesynctag}+\MPh{text:\MPp\shapesynctag}-\topskip-\MPy\shapesynctag\relax + \advance\scratchdimen\slantedshapeextra + \getnoflines\scratchdimen + \slantedshapedimen \noflines \slantedshapestep + \scratchtoks\emptytoks + \dorecurse{30} + {\appendetoks + \the\dimexpr-\slantedshapedimen+\slantedshapeoffset \relax\space + \the\dimexpr \hsize-2\slantedshapeoffset\relax\space + \to\scratchtoks + \advance\slantedshapedimen \slantedshapestep}% + \parshape 30 \the\scratchtoks + \strut\xypos\shapesynctag} + +\def\AdaptShapeX + {\doglobal\increment\shapesynctag + \getnoflines\textheight + \slantedshapestep\dimexpr\slantedshapeleftskip/\noflines\relax + \leftskip\slantedshapeleftskip + \scratchdimen\dimexpr\MPy{text:\MPp\shapesynctag}+\MPh{text:\MPp\shapesynctag}-\topskip-\MPy\shapesynctag\relax + \advance\scratchdimen\slantedshapeextra + \getnoflines\scratchdimen + \slantedshapedimen \noflines \slantedshapestep + \scratchtoks\emptytoks + \dorecurse{30} + {\appendetoks + \the\dimexpr-\slantedshapedimen+\slantedshapeoffset +5cm \relax\space + \the\dimexpr \hsize-2\slantedshapeoffset\relax\space + \to\scratchtoks + \advance\slantedshapedimen \slantedshapestep}% + \parshape 30 \the\scratchtoks + \strut\xypos\shapesynctag} + +\setuppapersize[S6][S6] + +\setupinteraction + [state=start, + click=no] + +\setupinteractionscreen + [option=max] + +\setuplayout + [backspace=12pt, + topspace=24pt, + height=middle, + width=middle, + header=0pt, + footer=0pt] + +\definecolor[maincolor][b=.5] +\definecolor[somecolor][g=.5] +\definecolor[morecolor][r=.5] + +\setupcolors + [textcolor=maincolor, + state=start] + +\setupbackgrounds + [text]% [text] + [background={base,text,invoke}] + +\definelayer + [text] + [width=\textwidth, + height=\textheight] + +\definelayer + [base] + [width=\textwidth, + height=\textheight] + +\definetype [epet] [style=,color=morecolor] +\setuptype [style=,color=somecolor] + +\slantedshapeleftskip150pt +\slantedshapeoffset12pt +\slantedshapeextra10pt + +\startreusableMPgraphic{page} + StartPage ; + fill Page withcolor \MPcolor{maincolor} ; + path p ; p := Field[Text][Text] enlarged 6pt ; + p := + llcorner p shifted (0,-12pt) -- + lrcorner p shifted (-150pt,0) -- + urcorner p shifted (0,12pt) -- + ulcorner p shifted (150pt,0) -- + cycle ; + fill p + withcolor .9white ; + StopPage ; +\stopreusableMPgraphic + +\defineoverlay[page][\reuseMPgraphic{page}] +\setupbackgrounds[page][background=page] + +\setupalign[flushleft] + +\def\StartItem + {\blank[line] + \begingroup + \EveryPar {\AdaptShape}} % beware: \ABBREV aan begin gaat fout + +\def\StopItem + {\endgraf + \endgroup + \blank[line]} + +\def\StartType + {\blank[halfline] + \begingroup + \EveryPar {\AdaptShape} + \dontleavehmode \quad} + +\def\StopType + {\endgraf + \endgroup + \blank[halfline]} + +\def\Title#1% + {\page + \setlayer + [text] + [preset=lefttop, + rotation=90] + {\color[white]{\scale[height=24pt]{\strut#1}}}} + +\def\SetBanner#1% + {\setuplayer[base][state=repeat] + \setlayer[base][preset=rightbottom]{\color[white]{\scale[height=9pt]{\strut#1}}}} + +\let\TitleFont\relax + +\startmode[atpragma] + \definefontfeature[default][method=node,script=latn,language=dflt,liga=yes,onum=yes,kern=yes] + \definefont[TitleFont][palatinosanscom-bold*default at 48pt] + \definefont[MainTextFont][palatinosanscom-regular*default at 12pt] \setupinterlinespace[line=15pt] + \appendtoks + \MainTextFont % hack, as we define a bodyfont at that point (better have a proper typeface) + \to \everystarttext +\stopmode + +\doifnotmode{demo}{\endinput} + +\starttext + +\usemodule[abr-01] + +\SetBanner{tug 2007 san diego} + +\Title {hans hagen} + +\startstandardmakeup \TitleFont \setupinterlinespace[line=3ex] \vfill + +\StartItem \dontleavehmode \quad {\morecolor zapfino, a} \StopItem +\StartItem \dontleavehmode \quad {\morecolor torture test} \StopItem +\StartItem \dontleavehmode \quad {\morecolor for luatex} \StopItem + +\vfill \stopstandardmakeup + +\Title{loading fonts} + +\StartSteps + +\StartItem the \OPENTYPE\ font reader is borrowed from \FONTFORGE\ \FlushStep \StopItem +\StartItem once it was ready, we could look into such a font \FlushStep \StopItem +\StartItem it tooks while to figure out the format due to rather fuzzy specs \FlushStep \StopItem +\StartItem it took us even more time to find out that the loader was flawed \FlushStep \StopItem +\StartItem one reason was that fonts themselves may have bugs or be incomplete \FlushStep \StopItem +\StartItem then we changed to \FONTFORGE\ version 2 \FlushStep \StopItem +\StartItem this made the missing pieces surface in more complex feature handling \FlushStep \StopItem +\StartItem while implementing features the new table format was cleaned up \FlushStep \StopItem + +\StopSteps + +\stoptext diff --git a/tex/context/modules/mkii/s-pre-68.mkii b/tex/context/modules/mkii/s-pre-68.mkii new file mode 100644 index 000000000..c22640efd --- /dev/null +++ b/tex/context/modules/mkii/s-pre-68.mkii @@ -0,0 +1,152 @@ +%D \module +%D [ file=s-pre-68, +%D version=2009.08.28, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 68, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[pre-60,abr-02] + +% style + +\setuppapersize + [S66][S66] + +\setuplayout + [height=middle, + width=middle, + header=0pt, + footer=0pt, + backspace=2cm, + topspace=2cm] + +\setupinteraction + [state=start, + click=no] + +\definecolor[maincolor][r=.4] + +\startreusableMPgraphic{page} + StartPage ; + fill Page enlarged 5mm withcolor \MPcolor{maincolor} ; + StopPage ; +\stopreusableMPgraphic + +\startreusableMPgraphic{next} + fill ultriangle scaled .15PaperWidth withcolor white ; +\stopreusableMPgraphic + +\startreusableMPgraphic{last} + fill boundingbox(ultriangle scaled .15PaperWidth) withcolor white ; +\stopreusableMPgraphic + +\startuniqueMPgraphic{bullit} + fill ultriangle scaled 2ExHeight withcolor white ; +\stopuniqueMPgraphic + +\definelayer + [extra] + [width=\paperwidth, + height=\paperheight] + +\defineoverlay + [page] + [\reuseMPgraphic{page}] + +\setupbackgrounds + [page] + [background={page,extra}] + +\setupcolors + [state=start, + textcolor=white] + +\setuphead + [chapter] + [style=\bfc] + +\definehead[Title][title] + +\definesymbol[MyBullet][\uniqueMPgraphic{bullit}] + +\setupitemgroup[itemize][each][symbol=MyBullet] + +\startmode[asintended] + \usetypescript[cambria] + \setupbodyfont[cambria,14.4pt] +\stopmode + +% interface + +\def\StartItems + {\begingroup + \StartSteps + \startitemize + \def\StartItems{\startitemize\def\StopItems{\stopitemize}}} + +\def\StopItems + {\FlushStep + \stopitemize + \NextPageSymbol + \StopSteps + \endgroup} + +\def\Item + {\def\Item{\FlushStep\item} + \item} + +\def\NextPageSymbol + {\setlayer + [extra] + [preset=rightbottom,offset=2mm] + {\ifnum\realpageno=\lastpage + \reuseMPgraphic{last}% + \else\ifnum\realpageno>1 + \reuseMPgraphic{next}% + \fi\fi + \FlushStep}} + +\def\TitlePage#1#2% + {\startstandardmakeup[bottom=,top=] + \scale[width=\textwidth]{\framed[align=flushleft,foregroundstyle=\bf,frame=off]{#1}} + \vfilll + \hfill\scale[width=.5\textwidth]{\framed[align=flushright,foregroundstyle=\bf,frame=off]{#2}} + \stopstandardmakeup} + +\doifnotmode{demo}{\endinput} + +\starttext + +\TitlePage{I'm running\\out of examples}{Hans Hagen\\Someplace, 2031} + +\Title{Alpha} + +\StartItems +\Item one +\Item two +\Item three +\StopItems + +\Title{Beta} + +\StartItems +\Item four +\Item five +\Item six +\StopItems + +\Title{Gamma} + +\StartItems +\Item seven +\Item eight +\Item nine +\StopItems + +\stoptext diff --git a/tex/context/modules/mkiv/m-asymptote.lua b/tex/context/modules/mkiv/m-asymptote.lua new file mode 100644 index 000000000..de8d032c8 --- /dev/null +++ b/tex/context/modules/mkiv/m-asymptote.lua @@ -0,0 +1,48 @@ +if not modules then modules = { } end modules ['m-asymptote'] = { + version = 1.001, + comment = "companion to m-pstricks.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- See m-asymptote.mkiv for some comment. + +local context = context +local replacesuffix = file.replacesuffix + +moduledata.asymptote = { } + +sandbox.registerrunner { + name = "asymptote prc", + program = "asy", + method = "execute", + template = '-noV -config="" -tex=context -outformat="prc" "%filename%"', + checkers = { filename = "readable" }, +} + +sandbox.registerrunner { + name = "asymptote pdf", + program = "asy", + method = "execute", + template = '-noV -config="" -tex=context -outformat="pdf" "%filename%"', + checkers = { filename = "readable" }, +} + +function moduledata.asympote.process(name,type) + if type == "prc" then + local result = buffers.run(name,false,"asymptote prc","prc") + local jsdata = { js = replacesuffix(result,"js") } + local parset = parametersets[name] + if parset then + -- so we can overload at the tex end + setmetatableindex(parset,jsdata) + else + parametersets[name] = jsdata + end + context(result) + else + local result = buffers.run(name,false,"asymptote pdf","pdf") + context(result) + end +end diff --git a/tex/context/modules/mkiv/m-asymptote.mkiv b/tex/context/modules/mkiv/m-asymptote.mkiv new file mode 100644 index 000000000..c236ceee5 --- /dev/null +++ b/tex/context/modules/mkiv/m-asymptote.mkiv @@ -0,0 +1,143 @@ +%D \module +%D [ file=m-asymptote, +%D version=2017.03.24, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Asymptote, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% \enabletrackers[sandbox,buffers.run] + +%D Currently asymptote assumes \MKII\ but better is to only support \MKIV. A problem +%D is that asymptote has this hard coded while for \CONTEXT\ it's better to stick to +%D something simple: +%D +%D \starttyping +%D \starttext +%D +%D \startasymptotepage +%D some label +%D \stopasymptotepage +%D +%D \startasymptotepage +%D some label +%D \stopasymptotepage +%D +%D \stoptext +%D \stoptyping +%D +%D Which is then run with: +%D +%D \starttyping +%D context --nonstopmode --purge somefile.tex +%D \stoptyping +%D +%D For the moment add "settings.prc=true;" to a graphic that is meant to produce that +%D format. See end of file for some examples. + +\registerctxluafile{m-asymptote}{} + +\unprotect + +\unexpanded\def\asymptote + {\dodoubleempty\module_asymptote} + +\unexpanded\def\module_asymptote[#1][#2]% + {\iffirstargument + \begingroup + \getdummyparameters[#2]% + \edef\lasttypesetbuffer{\ctxlua{moduledata.asympote.process("asymptote:#1","\dummyparameter\c!type")}}% + \externalfigure + [\lasttypesetbuffer]% + [\c!controls=\lasttypesetbuffer,#2]% + \endgroup + \fi} + +\unexpanded\def\startasymptote[#1]% + {\begingroup + \dostartbuffer[asymptote:#1][startasymptote][stopasymptote]} + +\unexpanded\def\stopasymptote + {\endgroup} + +\definefittingpage + [asymptotepage] + [\c!align=\v!normal] + +\protect + +\continueifinputfile{m-asymptote.mkiv} + +\starttext + +\startasymptote[demo-1] +settings.prc=true; + +import graph3; +import palette; + +size(6cm,6cm); +size3(5cm,0); + +currentprojection=orthographic(3,-6,12); +currentlight=light(8,10,2); + +real g(pair z) {return 1-z.x^2-z.y^2;} +real f(pair z) {return -2z.x+2;} + +real x(real t) {return t;} +real y(real t) {return 0;} +real z(real t) {return 1-t^2;} +real a(real t) {return 1;} +real b(real t) {return t;} +real c(real t) {return -t^2;} + +path3 p=graph(x,y,z,-2,2,operator ..); +path3 o=graph(a,b,c,-2,2,operator ..); + +surface r=surface(f,(0,-1),(2,1),nx=3,Spline); +surface s=surface(g,(-2,-2),(2,2),nx=5,Spline); + +path3 q=(-2,-2,-7)--(2,-2,-7)--(2,2,-7)--(-2,2,-7)--cycle; + +draw(q); + +draw(p,blue+thick(),Arrow3); +draw(o,blue+thick(),Arrow3); + +draw(s,lightgray+opacity(0.8),nolight,meshpen=black+thick()); +draw(r,lightgray+opacity(0.8),nolight,meshpen=black+thick()); + +draw((1,0,0)--(2,0,-2),black,Arrow3); +draw((1,0,0)--(1,1,0),black,Arrow3); +\stopasymptote + +\startasymptote[demo-2] +size(6cm,6cm); + +fill((1cm,2cm)--(3cm,3cm)--(4cm,0cm)--cycle); +\stopasymptote + +% see end of grph-inc.mkiv for some more options: + +\startluaparameterset[demo-1] + toolbar = true, + tree = false, + view = 'ortho' +\stopluaparameterset + +\asymptote[demo-1][type=prc,width=5cm,height=5cm,frame=on,display=yes,controls=yes,preview=yes] +\asymptote[demo-2][type=pdf,width=8cm,frame=on] + +% \typebuffer[asymptote:demo-1] + +% \startasymptotepage +% test +% \stopasymptotepage + +\stoptext diff --git a/tex/context/modules/mkiv/m-chart.lua b/tex/context/modules/mkiv/m-chart.lua index f1e7f4cb9..5a9311387 100644 --- a/tex/context/modules/mkiv/m-chart.lua +++ b/tex/context/modules/mkiv/m-chart.lua @@ -10,24 +10,28 @@ if not modules then modules = { } end modules ['x-flow'] = { -- use metapost.graphic(....) directly -- todo: labels +-- todo: named colors -moduledata.charts = moduledata.charts or { } +local type, tonumber, rawget, next = type, tonumber, rawget, next +local gsub, find, lower = string.gsub, string.find, string.lower +local P, S, C, Cc, lpegmatch = lpeg.P, lpeg.S, lpeg.C, lpeg.Cc, lpeg.match -local gsub, match, find, format, lower = string.gsub, string.match, string.find, string.format, string.lower +local formatters = string.formatters local setmetatableindex = table.setmetatableindex -local P, S, C, Cc, lpegmatch = lpeg.P, lpeg.S, lpeg.C, lpeg.Cc, lpeg.match -local report_chart = logs.reporter("chart") +moduledata.charts = moduledata.charts or { } + +local report_chart = logs.reporter("chart") -local variables = interfaces.variables +local variables = interfaces.variables -local v_yes = variables.yes -local v_no = variables.no -local v_none = variables.none -local v_standard = variables.standard -local v_overlay = variables.overlay -local v_round = variables.round -local v_test = variables.test +local v_yes = variables.yes +local v_no = variables.no +local v_none = variables.none +local v_standard = variables.standard +local v_overlay = variables.overlay +local v_round = variables.round +local v_test = variables.test local defaults = { chart = { @@ -252,8 +256,8 @@ end function commands.flow_set_text(align,str) temp.texts[#temp.texts+1] = { - location = align, - text = str, + align = align, + text = str, } end @@ -429,6 +433,7 @@ function commands.flow_set_location(x,y) if type(x) == "string" and not y then x, y = lpegmatch(splitter,x) end + local oldx, oldy = x, y if not x or x == "" then x = last_x elseif type(x) == "number" then @@ -455,6 +460,15 @@ function commands.flow_set_location(x,y) else y = tonumber(y) end + if x < 1 or y < 1 then + report_chart("the cell (%s,%s) ends up at (%s,%s) and gets relocated to (1,1)",oldx or"?", oldy or "?", x,y) + if x < 1 then + x = 1 + end + if y < 1 then + y = 1 + end + end temp.x = x or 1 temp.y = y or 1 temp.realx = x or 1 @@ -504,7 +518,7 @@ local function process_cells(chart,xoffset,yoffset) if shapedata.kind == "line" then local linesettings = settings.line context("flow_shape_line_color := \\MPcolor{%s} ;", linesettings.color) - context("flow_shape_fill_color := \\MPcolor{%s} ;", linesettings.backgroundcolor) + context("flow_shape_fill_color := black ;") context("flow_shape_line_width := %p ; ", linesettings.rulethickness) elseif focus[cell.focus] or focus[cell.name] then local focussettings = settings.focus @@ -567,6 +581,7 @@ local function process_connections(chart,xoffset,yoffset) local settings = chart.settings for i=1,#data do local cell = visible(chart,data[i]) +-- local cell = data[i] if cell then local connections = cell.connections for j=1,#connections do @@ -576,7 +591,7 @@ local function process_connections(chart,xoffset,yoffset) if othercell then -- and visible(chart,data[i]) then local cellx, celly = cell.x, cell.y local otherx, othery, location = othercell.x, othercell.y, connection.location - if otherx > 0 and othery > 0 and cellx > 0 and celly > 0 and connection.location then + if otherx > 0 and othery > 0 and cellx > 0 and celly > 0 and location then local what_cell, where_cell, what_other, where_other = lpegmatch(what,location) if what_cell and where_cell and what_other and where_other then local linesettings = settings.line @@ -597,9 +612,17 @@ local function process_connections(chart,xoffset,yoffset) end end -local texttemplate = "\\setvariables[flowcell:text][x=%s,y=%s,text={%s},align={%s},figure={%s},destination={%s}]" +local f_texttemplate_t = formatters["\\setvariables[flowcell:text][x=%s,y=%s,n=%i,align={%s},figure={%s},overlay={%s},destination={%s}]"] +local f_texttemplate_l = formatters["\\doFLOWlabel{%i}{%i}{%i}"] -local splitter = lpeg.splitat(":") +local splitter = lpeg.splitat(":") +local charttexts = { } -- permits " etc in mp + +function commands.flow_get_text(n) + if n > 0 then + context(charttexts[n]) + end +end local function process_texts(chart,xoffset,yoffset) local data = chart.data @@ -607,41 +630,59 @@ local function process_texts(chart,xoffset,yoffset) if not data then return end + charttexts = { } for i=1,#data do local cell = visible(chart,data[i]) if cell then - local x = cell.x or 1 - local y = cell.y or 1 - local texts = cell.texts - for i=1,#texts do - local text = texts[i] - local data = text.text - local align = validlabellocations[text.align or ""] or text.align or "" - local figure = i == 1 and cell.figure or "" - local destination = i == 1 and cell.destination or "" - context('flow_chart_draw_text(%s,%s,textext("%s")) ;',x,y,format(texttemplate,x,y,data,align,figure,destination)) + local x = cell.x or 1 + local y = cell.y or 1 + local figure = cell.figure or "" + local overlay = cell.overlay or "" + local destination = cell.destination or "" + local texts = cell.texts + local noftexts = #texts + if noftexts > 0 then + for i=1,noftexts do + local text = texts[i] + local data = text.text + local align = text.align or "" + local align = validlabellocations[align] or align + charttexts[#charttexts+1] = data + context('flow_chart_draw_text(%s,%s,textext("%s")) ;',x,y,f_texttemplate_t(x,y,#charttexts,align,figure,overlay,destination)) + if i == 1 then + figure = "" + overlay = "" + destination = "" + end + end + elseif figure ~= "" or overlay ~= "" or destination ~= "" then + context('flow_chart_draw_text(%s,%s,textext("%s")) ;',x,y,f_texttemplate_t(x,y,0,"",figure,overlay,destination)) end local labels = cell.labels for i=1,#labels do - local label = labels[i] - local text = label.text - local location = validlabellocations[label.location or ""] or label.location or "" - if text and location then - context('flow_chart_draw_label(%s,%s,"%s",textext("\\strut %s")) ;',x,y,location,text) + local label = labels[i] + local text = label.text + local location = label.location or "" + local location = validlabellocations[location] or location + if text and text ~= "" then + charttexts[#charttexts+1] = text + context('flow_chart_draw_label(%s,%s,"%s",textext("%s")) ;',x,y,location,f_texttemplate_l(x,y,#charttexts)) end end local exits = cell.exits for i=1,#exits do - local exit = exits[i] - local text = exit.text - local location = validlabellocations[exit.location or ""] - if text and location then + local exit = exits[i] + local text = exit.text + local location = exit.location or "" + local location = validlabellocations[location] or location + if text ~= "" then -- maybe make autoexit an option if location == "l" and x == chart.from_x + 1 or location == "r" and x == chart.to_x - 1 or location == "t" and y == chart.to_y - 1 or location == "b" and y == chart.from_y + 1 then - context('flow_chart_draw_exit(%s,%s,"%s",textext("\\strut %s")) ;',x,y,location,text) + charttexts[#charttexts+1] = text + context('flow_chart_draw_exit(%s,%s,"%s",textext("%s")) ;',x,y,location,f_texttemplate_l(x,y,#charttexts)) end end end @@ -649,10 +690,10 @@ local function process_texts(chart,xoffset,yoffset) for i=1,#connections do local comments = connections[i].comments for j=1,#comments do - local comment = comments[j] - local text = comment.text + local comment = comments[j] + local text = comment.text local location = comment.location or "" - local length = 0 + local length = 0 -- "tl" "tl:*" "tl:0.5" local loc, len = lpegmatch(splitter,location) -- do the following in lpeg if len == "*" then @@ -664,12 +705,13 @@ local function process_texts(chart,xoffset,yoffset) end elseif loc then location = validcommentlocations[loc] or "*" - length = tonumber(len) or 0 + length = tonumber(len) or 0 else location = validcommentlocations[location] or "" end - if text and location then - context('flow_chart_draw_comment(%s,%s,%s,"%s",%s,textext("\\strut %s")) ;',x,y,i,location,length,text) + if text and text ~= "" then + charttexts[#charttexts+1] = text + context('flow_chart_draw_comment(%s,%s,%s,"%s",%s,textext("%s")) ;',x,y,i,location,length,f_texttemplate_l(x,y,#charttexts)) end end end @@ -692,7 +734,6 @@ local function getchart(settings,forced_x,forced_y,forced_nx,forced_ny) print("no such chart",chartname) return end --- chart = table.copy(chart) chart = expanded(chart,settings) local chartsettings = chart.settings.chart local autofocus = chart.settings.chart.autofocus @@ -721,6 +762,14 @@ local function getchart(settings,forced_x,forced_y,forced_nx,forced_ny) if miny == 0 or y > maxy then maxy = y end end end +-- optional: +if x + nx > maxx then + nx = maxx - x + 1 +end +if y + ny > maxy then + ny = maxy - y + 1 +end + -- -- print("1>",x,y,nx,ny) -- print("2>",minx, miny, maxx, maxy) -- check of window should be larger (maybe autofocus + nx/ny?) @@ -837,6 +886,9 @@ local function makechart(chart) context("flow_chart_offset := %p ;",offset) -- context("flow_reverse_y := true ;") + if chartsettings.option == v_test then + context("flow_draw_test_shapes ;") + end process_cells(chart,0,0) process_connections(chart,0,0) process_texts(chart,0,0) @@ -875,9 +927,9 @@ local function splitchart(chart) if done then last_x = to_x end --- if first_x >= to_x then --- break --- end + -- if first_x >= to_x then + -- break + -- end local part_y = 0 local first_y = from_y while true do @@ -887,31 +939,31 @@ local function splitchart(chart) if done then last_y = to_y end --- if first_y >= to_y then --- break --- end + -- if first_y >= to_y then + -- break + -- end -- -local data = chart.data -for i=1,#data do - local cell = data[i] --- inspect(cell) - local cx, cy = cell.x, cell.y - if cx >= first_x and cx <= last_x then - if cy >= first_y and cy <= last_y then - report_chart("part (%s,%s) of %a is split from (%s,%s) -> (%s,%s)",part_x,part_y,name,first_x,first_y,last_x,last_y) - local x = first_x - local y = first_y - local nx = last_x - first_x + 1 - local ny = last_y - first_y + 1 - context.beforeFLOWsplit() - context.handleFLOWsplit(function() - makechart(getchart(settings,x,y,nx,ny)) -- we need to pass frozen settings ! - end) - context.afterFLOWsplit() - break - end - end -end + local data = chart.data + for i=1,#data do + local cell = data[i] + -- inspect(cell) + local cx, cy = cell.x, cell.y + if cx >= first_x and cx <= last_x then + if cy >= first_y and cy <= last_y then + report_chart("part (%s,%s) of %a is split from (%s,%s) -> (%s,%s)",part_x,part_y,name,first_x,first_y,last_x,last_y) + local x = first_x + local y = first_y + local nx = last_x - first_x + 1 + local ny = last_y - first_y + 1 + context.beforeFLOWsplit() + context.handleFLOWsplit(function() + makechart(getchart(settings,x,y,nx,ny)) -- we need to pass frozen settings ! + end) + context.afterFLOWsplit() + break + end + end + end -- if done then break diff --git a/tex/context/modules/mkiv/m-chart.mkvi b/tex/context/modules/mkiv/m-chart.mkvi index a0c8b2244..69d90f47b 100644 --- a/tex/context/modules/mkiv/m-chart.mkvi +++ b/tex/context/modules/mkiv/m-chart.mkvi @@ -15,7 +15,6 @@ % flowsets % autoscaling (bodyfontsteps) % comment -% overlay % % todo: % \useFLOWchart[name][parent][setting,setting][additional settings] @@ -63,8 +62,6 @@ \c!commentoffset=.5\bodyfontsize, \c!exitoffset=\zeropoint, % \c!split=\v!no, - % \c!maxwidth=, - % \c!maxheight=, % \c!option=, % \c!bodyfont=, % \c!dot=, % private option @@ -256,11 +253,11 @@ \unexpanded\def\FLOWcharts {\dodoubleempty\FLOW_charts} -\def\FLOW_charts[#name][#settings] +\def\FLOW_charts[#name][#settings]% {\begingroup \setupFLOWchart[\c!split=\v!yes]% \setupFLOWsplit[#settings]% - \module_charts_process[#name][]% \FLOWchart... + \FLOWchart[#name]% \endgroup} \appendtoks @@ -307,7 +304,7 @@ \unexpanded\def\module_charts_FLOW_include [#name][#settings]{% \begingroup - \getparameters[FLOWi][x=1,y=1,#settings]% + \getparameters[FLOWi][\c!x=1,\c!y=1,#settings]% \ctxcommand{flow_set_include("#name",\number\FLOWix,\number\FLOWiy,\!!bs\detokenize{#settings}\!!es)}% \endgroup \ignorespaces @@ -315,7 +312,8 @@ \setvariables [flowcell:text] - [x=1, + [n=0, + x=1, y=1, text=, align=, @@ -324,8 +322,6 @@ \def\FLOWx{\getvariable{flowcell:text}{x}} % compatibility (for Willi) \def\FLOWy{\getvariable{flowcell:text}{y}} % compatibility (for Willi) -% \c!background={\@@FLOWbackground,\FLOWoverlay}, - \defineoverlay [flowcell:figure] [\overlayfigure{\getvariable{flowcell:text}{figure}}] @@ -335,13 +331,15 @@ \iftrialtypesetting \directsetup{flowcell:text:place:indeed} \else \iflocation - \doifelsenothing {\getvariable{flowcell:text}{destination}} { + \edef\flowcelldestination{\getvariable{flowcell:text}{destination}}% + \ifx\flowcelldestination\empty \directsetup{flowcell:text:place:indeed} - } { + \else % tricky: scaling and moving around is not taken into account - \setupinteraction[\c!color=,\c!contrastcolor=] - \gotobox{\directsetup{flowcell:text:place:indeed}}[\getvariable{flowcell:text}{destination}] - } + \letinteractionparameter\c!color\empty + \letinteractionparameter\c!contrastcolor\empty + \gotobox{\directsetup{flowcell:text:place:indeed}}[\flowcelldestination] + \fi \else \directsetup{flowcell:text:place:indeed} \fi \fi @@ -351,17 +349,41 @@ \startsetups flowcell:text:place:indeed \begingroup \directsetup{flowcell:text:user} - \doifelsenothing {\getvariable{flowcell:text}{figure}} { - \expandcheckedcsname{flowcell:}{\getvariable{flowcell:text}{align}}\empty - {\getvariable{flowcell:text}{text}} - } { - \expandcheckedcsname{flowcell:}{\getvariable{flowcell:text}{align}}\empty - [\c!background=flowcell:figure] - {\getvariable{flowcell:text}{text}} - } + \edef\flowcellfigure {\getvariable{flowcell:text}{figure}}% + \edef\flowcelloverlay{\getvariable{flowcell:text}{overlay}}% + \edef\flowcellalign {\getvariable{flowcell:text}{align}}% + \edef\flowcellindex {\getvariable{flowcell:text}{n}}% + \ifx\flowcellfigure\empty + \ifx\flowcelloverlay\empty + \expandcheckedcsname{flowcell:}\flowcellalign\empty + % {\getvariable{flowcell:text}{text}} + {\getFLOWtext\flowcellindex} + \else + \expandcheckedcsname{flowcell:}\flowcellalign\empty + [\c!background={\flowcelloverlay}] + % {\getvariable{flowcell:text}{text}} + {\getFLOWtext\flowcellindex} + \fi + \else + \expandcheckedcsname{flowcell:}\flowcellalign\empty + [\c!background=flowcell:figure] + % {\getvariable{flowcell:text}{text}} + {\getFLOWtext\flowcellindex} + \fi \endgroup \stopsetups +\unexpanded\def\doFLOWlabel#1#2#3% + {\begingroup + \def\FLOWx{#1}% + \def\FLOWy{#2}% + \strut + \getFLOWtext{#3}% + \endgroup} + +\unexpanded\def\getFLOWtext#1% + {\ifcase#1\else\ctxcommand{flow_get_text(#1)}\fi} + \defineframed % to be discussed: shape or global [flowcell:base] [\c!offset=\v!overlay, % no strut ? diff --git a/tex/context/modules/mkiv/m-educat.mkiv b/tex/context/modules/mkiv/m-educat.mkiv index 93b1a6c5d..e39738e99 100644 --- a/tex/context/modules/mkiv/m-educat.mkiv +++ b/tex/context/modules/mkiv/m-educat.mkiv @@ -47,7 +47,8 @@ {\begingroup \dontcomplain \setupanswerarea - [\c!n=0,\c!m=,#1,\c!location=\v!text]% + [\c!n=0,\c!m=#1,\c!location=\v!text]% + \let\currenttextbackground\v!answerarea \doifelsenothing{\textbackgroundparameter\c!m} {\expandafter\donoanswerspace} {\expandafter\dodoanswerspace}% @@ -110,6 +111,7 @@ \dontcomplain \setupanswerarea [\c!n=0,\c!m=,#1,\c!location=\v!text]% + \let\currenttextbackground\v!answerarea \doifnot{\textbackgroundparameter\c!option}\v!joinedup\softbreak \doifelsenothing{\textbackgroundparameter\c!m} {\expandafter\donostartanswerlines} @@ -156,8 +158,10 @@ #2% \getvalue{\e!stop\e!answerlines}} -\protect \doifnotmode{demo}{\endinput} - +\protect + +\continueifinputfile{m-educat.mkiv} + %D Test materiaal. \starttext diff --git a/tex/context/modules/mkiv/m-graph.mkiv b/tex/context/modules/mkiv/m-graph.mkiv index 62c4ec4cb..8946732d0 100644 --- a/tex/context/modules/mkiv/m-graph.mkiv +++ b/tex/context/modules/mkiv/m-graph.mkiv @@ -25,7 +25,8 @@ \c!method=\s!double] \startMPdefinitions{graph} - if unknown context_grap : input mp-grap.mpiv ; fi ; + loadmodule "grap" ; +% input mp-grap.mpiv ; \stopMPdefinitions \protect @@ -71,8 +72,6 @@ label.rt(formatted("(@j,@j)",(1.23,4.56)),(0cm,-5.0cm)) ; \stopMPpage -\stoptext - % \startMPpage[instance=graph] % draw begingraph(3in,2in); % gdraw "t:/metapost/grphdata/agepop91.d"; @@ -131,3 +130,5 @@ % autogrid(otick.bot,otick.rt); % endgraph; % \stopMPpage + +\stoptext diff --git a/tex/context/modules/mkiv/m-ipsum.mkiv b/tex/context/modules/mkiv/m-ipsum.mkiv index 1c5901d86..7ba78ee2e 100644 --- a/tex/context/modules/mkiv/m-ipsum.mkiv +++ b/tex/context/modules/mkiv/m-ipsum.mkiv @@ -127,6 +127,7 @@ end \startsetups[handler:action:ipsum] \useipsumstyleandcolor\c!style\c!color + % hm, also changes dates \uselanguageparameter\ipsumparameter \ctxlua{moduledata.ipsum.typeset { alternative = "\ipsumparameter\c!alternative", diff --git a/tex/context/modules/mkiv/m-matrix.mkiv b/tex/context/modules/mkiv/m-matrix.mkiv index ccb376e39..f59363e94 100644 --- a/tex/context/modules/mkiv/m-matrix.mkiv +++ b/tex/context/modules/mkiv/m-matrix.mkiv @@ -28,6 +28,9 @@ local formatters = string.formatters local copy = table.copy local insert = table.insert local remove = table.remove +local random = math.random + +local context = context local matrix = { } moduledata.matrix = matrix @@ -67,35 +70,120 @@ end -- todo: define a matrix at the tex end so that we have more control -local fences_p = { - left = "\\left(\\,", - right = "\\,\\right)", +local fences = { + parentheses = { left = "\\left(\\,", right = "\\,\\right)" }, + brackets = { left = "\\left[\\,", right = "\\,\\right]" }, + bars = { left = "\\left|\\,", right = "\\,\\right|" }, } -local fences_b = { - left = "\\left[\\,", - right = "\\,\\right]", -} +-- one can add more fences + +fences.bar = fences.bars +fences.parenthesis = fences.parentheses +fences.bracket = fences.brackets + +-- one can set the template + +matrix.template = "%0.3F" function matrix.typeset(m,options) - local options = settings_to_hash(options or "") - context.startmatrix(options.determinant and fences_b or fences_p) - for i=1, #m do - local mi = m[i] - for j=1,#mi do - context.NC(mi[j]) - end - context.NR() + if type(m) == "table" then + local options = settings_to_hash(options or "") + local whatever = options.determinant == "yes" and fences.bars or fences.parentheses + if options.fences then + whatever = fences[options.fences] or whatever + elseif options.determinant then + -- whatever = fences.brackets + whatever = fences.bars end - context.stopmatrix() + local template = options.template or matrix.template + if template == "yes" then + template = matrix.template + elseif template == "no" then + template = false + elseif tonumber(template) then + template = "%0." .. template .. "F" + end + context.startmatrix(whatever) + for i=1, #m do + local mi = m[i] + for j=1,#mi do + context.NC() + local n = mi[j] + if template and tonumber(n) then + context(template,n) + else + context(mi[j]) + end + end + context.NR() + end + context.stopmatrix() + elseif m then + context(m) + end end -- interchange two rows (i-th, j-th) -function matrix.swap(t,i,j) - t[i], t[j] = t[j], t[i] +-- function matrix.swaprows(t,i,j) +-- if i <= #t and j <= #t then +-- t[i], t[j] = t[j], t[i] +-- return t +-- else +-- return "error: out of bound" +-- end +-- end + +function matrix.swaprows(t,i,j) + local ti = t[i] + if not ti then + return "error: no row i" + end + local tj = t[j] + if not tj then + return "error: no row j" + end + t[i], t[j] = tj, ti + return t +end + +-- interchange two columns (i-th, j-th) + +-- function matrix.swapcolumns(t, i, j) +-- if i <= #t[1] and j <= #t[1] then +-- for k = 1, #t do +-- t[k][i], t[k][j] = t[k][j], t[k][i] +-- end +-- return t +-- else +-- return "error: out of bound" +-- end +-- end + +function matrix.swapcolumns(t, i, j) + local t1 = t[1] + if not t1 then + return "error: no rows" + end + local n = #t1 + if i <= n then + return "error: no row i" + end + if j <= n then + return "error: no row j" + end + for k = 1, #t do + local tk = t[k] + tk[i], tk[j] = tk[j], tk[i] + end + return t end +matrix.swapC = matrix.swapcolumns +matrix.swapR = matrix.swaprows +matrix.swap = matrix.swaprows + -- replace i-th row with factor * (i-th row) function matrix.multiply(m,i,factor) @@ -151,7 +239,7 @@ function matrix.inner(u,v) end local nv = #v if nv ~= nu then - return 0 + return "error: size mismatch" end local result = 0 for i=1,nu do @@ -163,8 +251,8 @@ end -- product of two matrices function matrix.product(m1,m2) - local product = { } if #m1[1] == #m2 then + local product = { } for i=1,#m1 do local m1i = m1[i] local mrow = { } @@ -177,8 +265,10 @@ function matrix.product(m1,m2) end product[i] = mrow end + return product + else + return "error: size mismatch" end - return product end local function uppertri(m,sign) @@ -216,7 +306,7 @@ end matrix.uppertri = uppertri -function matrix.determinant(m) +local function determinant(m) if #m == #m[1] then local d = 1 local t, s = uppertri(m,1) @@ -225,10 +315,12 @@ function matrix.determinant(m) end return s*d else - return 0 + return "error: not a square matrix" end end +matrix.determinant = determinant + local function rowechelon(m,r) local temp = copy(m) local pRow = 1 @@ -293,9 +385,102 @@ end matrix.rowechelon = rowechelon matrix.rowEchelon = rowechelon +-- make matrices until its determinant is not 0 + +function matrix.make(n,m,low,high) + if not n then + n = 10 + end + if not m then + m = 10 + end + if not low then + low = 0 + end + if not high then + high = 100 + end + local t = { } -- make an empty n1 x n2 array + local again = true + for i=1,n do + t[i] = { } + end + while true do + for i=1,n do + local ti = t[i] + for j=1,m do + ti[j] = random(low,high) + end + end + if n ~= m or determinant(t,1) ~= 0 then + return t + end + end +end + +-- extract submatrix by using + +local function submatrix(t,i,j) + local rows = #t + local columns = #t[1] + local sign = 1 -- not used + if i <= rows and j <= columns then + local c = copy(t) + remove(c,i) + for k=1,rows-1 do + remove(c[k],j) + end + return c + else + return "error: out of bound" + end +end + +matrix.submatrix = submatrix + +-- calculating determinant using Laplace Expansion + +function matrix.laplace(t) -- not sure if this is the most effient but + local factors = { 1 } -- it's not used for number crunching anyway + local data = copy(t) + local det = 0 + while #data > 0 do + local mat = { } + local siz = #data[1] + if siz == 0 then + return "error: no determinant" + elseif siz == 1 then + det = data[1][1] + return det + end + for i=1,siz do + mat[i] = data[1] + remove(data,1) + end + local factor = remove(factors,1) + local m1 = mat[1] + if siz == 2 then + local m2 = mat[2] + det = det + factor * (m1[1]*m2[2] - m1[2]*m2[1]) + else + for j=1,#m1 do + local m1j = m1[j] + if m1j ~= 0 then + insert(factors, (-1)^(j+1) * factor * m1j) + local m = submatrix(mat,1,j) + for k, v in next, m do + insert(data,v) + end + end + end + end + end + return det +end + -- solve the linear equation m X = c -local function solve(m,c) +local function solve(m,c) local n = #m if n ~= #c then return copy(m) @@ -393,14 +578,14 @@ moduledata.matrix.typeset(moduledata.matrix.multiply(document.DemoMatrixA, 2, 3) \stopsubject -\startsubject[title={Row 2 + $3 \times r_4$}] +\startsubject[title={Row 2 + $4 \times r_3$}] \startluacode moduledata.matrix.typeset(document.DemoMatrixA) context.blank() moduledata.matrix.sumrow(document.DemoMatrixA, 2, 3, 4) context.blank() -moduledata.matrix.typeset(document.DemoMatrixA) +moduledata.matrix.typeset(document.DemoMatrixA,{ fences = "bars" } ) \stopluacode \stopsubject @@ -445,7 +630,7 @@ local m = { { 0, 0, 2 }, { 2, 2, -6 }, } -context(moduledata.matrix.determinant(m)) +context(moduledata.matrix.determinant(m, "determinant=yes" )) \stopluacode \stopsubject @@ -461,7 +646,8 @@ local m = { } moduledata.matrix.typeset(m) -moduledata.matrix.typeset(moduledata.matrix.rowechelon(m,1)) +context.blank() +moduledata.matrix.typeset(moduledata.matrix.rowechelon(m,1), { determinant = "yes" }) \stopluacode \stopsubject @@ -479,6 +665,14 @@ local m = { local c = { 5, 2, 6, 8 } moduledata.matrix.typeset(moduledata.matrix.solve(m,c)) +context.blank() +moduledata.matrix.typeset(moduledata.matrix.solve(m,c), { template = 6 }) +context.blank() +moduledata.matrix.typeset(moduledata.matrix.solve(m,c), { template = "no" }) +context.blank() +moduledata.matrix.typeset(moduledata.matrix.solve(m,c), { template = "%0.3f" }) +context.blank() +moduledata.matrix.typeset(moduledata.matrix.solve(m,c), { template = "%0.4F" }) \stopluacode \stopsubject diff --git a/tex/context/modules/mkiv/m-punk.mkiv b/tex/context/modules/mkiv/m-punk.mkiv index 331e90d2e..f7e17da83 100644 --- a/tex/context/modules/mkiv/m-punk.mkiv +++ b/tex/context/modules/mkiv/m-punk.mkiv @@ -11,11 +11,6 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\ifx\luaversion\undefined \endinput \fi - -% At some point the font generation code will move into the -% ConTeXt MkIV kernel. - \startluacode local concat = table.concat local chardata = characters.data @@ -242,7 +237,7 @@ end) \definetypeface [punk] [rm] [serif] [punk] [default] \stoptypescript -\endinput +\continueifinputfile{m-punk.mkiv} \usetypescript[punk] diff --git a/tex/context/modules/mkiv/m-scite.mkiv b/tex/context/modules/mkiv/m-scite.mkiv index fd4a3c7a1..a7d9f8b5c 100644 --- a/tex/context/modules/mkiv/m-scite.mkiv +++ b/tex/context/modules/mkiv/m-scite.mkiv @@ -56,11 +56,11 @@ buffers.scite = scite -- context output: -local f_def_color = formatters["\\definecolor[slxc%s][h=%s%s%s]%%"] -local f_fore_none = formatters["\\def\\slx%s#1{{\\slxc%s#1}}%%"] -local f_fore_bold = formatters["\\def\\slx%s#1{{\\slxc%s\\bf#1}}%%"] -local f_none_bold = formatters["\\def\\slx%s#1{{\\bf#1}}%%"] -local f_none_none = formatters["\\def\\slx%s#1{{#1}}%%"] +local f_def_color = formatters["\\definecolor[slxc%s][h=%02X%02X%02X]%%"] +local f_fore_none = formatters["\\unexpanded\\def\\slx%s#1{{\\slxc%s#1}}%%"] +local f_fore_bold = formatters["\\unexpanded\\def\\slx%s#1{{\\slxc%s\\bf#1}}%%"] +local f_none_bold = formatters["\\unexpanded\\def\\slx%s#1{{\\bf#1}}%%"] +local f_none_none = formatters["\\unexpanded\\def\\slx%s#1{{#1}}%%"] local f_texstyled = formatters["\\slx%s{%s}"] local f_hanging = formatters["\\slxb{%s}%s\\slxe"] @@ -90,7 +90,7 @@ local replacer = lpeg.replacer { ["\\"] = "\\slxB ", ["%"] = "\\slxP ", ["~"] = "\\slxT ", - [" "] = "\\slxS ", + [" "] = "\\slxS ", -- can be made more efficient: \\slxF{n} } local colors = nil @@ -99,14 +99,14 @@ local function exportcolors() if not colors then scite.loadscitelexer() local function black(f) - return (f[1] == f[2]) and (f[2] == f[3]) and (f[3] == '00') + return (f[1] == f[2]) and (f[2] == f[3]) and (f[3] == 0) end local result, r = { f_mapping }, 1 for k, v in table.sortedhash(lexer.context.styles) do local fore = v.fore if fore and not black(fore) then r = r + 1 - result[r] = f_def_color(k,fore[1],fore[2],fore[3]) + result[r] = f_def_color(k,fore[1],fore[2] or fore[1],fore[3] or fore[1]) end end r = r + 1 @@ -169,6 +169,10 @@ end local p1 = lpeg.tsplitat(lpeg.patterns.newline) local p2 = lpeg.P("\\slxS ")^1 +local p3 = lpeg.Cs((lpeg.Cp() * lpeg.P(" ") * lpeg.Cp() / function(b,e) return "\\slxF{" .. (e-b-1) .. "}" end + + (1-lpeg.P(" "))^1)^0) + +-- slxb could have a \hskip so then we can replace the slxS's local function indent(str) local l = lpegmatch(p1,str) @@ -181,7 +185,10 @@ local function indent(str) else n = 0 end - l[i] = f_hanging(n,s) +s = lpegmatch(p3,s) -- can be combined + l[i] = f_hanging(n,s) -- "\\slxb{%s}%s\\slxe " +-- print(">",s) +-- print("<",l[i]) end end return concat(l,"\n") @@ -211,10 +218,12 @@ end \unprotect +\newdimen\scitespaceskip + \unexpanded\def\buff_scite_slxb#1% {%\begingroup - \hangindent\dimexpr\numexpr#1+1\relax\emwidth\relax - \hangafter \numexpr\numexpr#1+1\relax} + \hangindent\numexpr#1+2\relax\scitespaceskip + \hangafter 1\relax} \unexpanded\def\buff_scite_slxe {\par @@ -223,7 +232,9 @@ end \unexpanded\def\installscitecommands {\ctxlua{buffers.scite.installcommands()}% \let\installscitecommands\relax - \def\slxS{\fixedspace\allowbreak}% + \scitespaceskip\fontcharwd\font`0\relax + \unexpanded\def\slxS{\hskip\scitespaceskip}% + \unexpanded\def\slxF##1{\hskip##1\scitespaceskip\relax}% \let\slxb\buff_scite_slxb \let\slxe\buff_scite_slxe} @@ -251,7 +262,7 @@ end \raggedright \startcontextcode \startlines - \getbuffer[lex]% + \getbuffer[lex] \stoplines \stopcontextcode \stop} diff --git a/tex/context/modules/mkiv/m-steps.lua b/tex/context/modules/mkiv/m-steps.lua index 8eb481550..ce84866a4 100644 --- a/tex/context/modules/mkiv/m-steps.lua +++ b/tex/context/modules/mkiv/m-steps.lua @@ -8,11 +8,20 @@ if not modules then modules = { } end modules ['x-flow'] = { -- when we can resolve mpcolor at the lua end we will use metapost.graphic(....) directly +local tonumber = tonumber + moduledata.steps = moduledata.steps or { } -local variables = interfaces.variables +local context = context +local variables = interfaces.variables +local formatters = string.formatters +----- mpcolor = attributes.colors.mpnamedcolor +local concat = table.concat + +local report = logs.reporter("stepcharts") +local trace = false -local trace_charts = false +trackers.register("stepcharts",function(v) trace = v end) local defaults = { chart = { @@ -48,179 +57,494 @@ local defaults = { -- maybe: includes -- maybe: flush ranges -local charts = { } +local charts = { } -- not used but we could support nesting +local chart = nil local steps = { } +local count = 0 -function commands.step_start_chart(name) +local function step_start_chart(name,alternative) name = name or "" - steps = { } - charts[name] = { - steps = steps, + steps = table.setmetatableindex(function(t,k) + local v = { -- could be metatable + cell_top = false, + cell_bot = false, + text_top = false, + text_mid = false, + text_bot = false, + start_t = k, + start_m = k, + start_b = k, + cell_ali = false, + } + t[k] = v + return v + end) + count = 0 + chart = { + steps = steps, + count = count, + alternative = alternative, } + charts[name] = chart end -function commands.step_stop_chart() +local function step_stop_chart() + chart.count = count end -function commands.step_make_chart(settings) +local function step_make_chart(settings) local chartsettings = settings.chart if not chartsettings then - print("no chart") + if trace then + report("no chart") + end return end local chartname = chartsettings.name if not chartname then - print("no name given") + if trace then + report("no name given") + end return end local chart = charts[chartname] if not chart then - print("no such chart",chartname) + if trace then + report("no such chart: %s",chartname) + end return end local steps = chart.steps or { } -- table.setmetatableindex(settings,defaults) -- - if trace_charts then - inspect(steps) + if trace then + report(table.serialize(steps,"chartdata")) end -- local textsettings = settings.text local cellsettings = settings.cell local linesettings = settings.line + + local start = nil + local stop = nil + local flush = nil + + if false then + + -- some 2% faster at most, so neglectable as this kind of graphics + -- is hardly used in quantity but it saves mem and tokens in tracing + -- and we lose some aspects, like outer color and so (currently) + + local mpcode = false + + start = function() + mpcode = { } + end + stop = function() + local code = concat(mpcode,"\n") + -- print(code) + metapost.graphic { + -- instance = "metafun", + instance = "steps", + format = "metafun", + data = code, + -- initializations = "", + -- extensions = "", + -- inclusions = "", + definitions = 'loadmodule "step" ;', + -- figure = "", + method = "double", + } + mpcode = false + end + flush = function(fmt,first,...) + if first then + mpcode[#mpcode+1] = formatters[fmt](first,...) + else + mpcode[#mpcode+1] = fmt + end + end + + else + + start = function() context.startMPcode("steps") end + stop = context.stopMPcode + flush = context + + end + -- + start() + flush("step_begin_chart ;") + -- + local alternative = chartsettings.alternative + if not alternative or alternative == "" then + alternative = chart.alternative + end + if not alternative or alternative == "" then + alternative = variables.horizontal + end + local alternative = utilities.parsers.settings_to_hash(alternative) + local vertical = alternative[variables.vertical] + local align = alternative[variables.three] + local category = chartsettings.category -- - context.startMPcode() - context("if unknown context_cell : input mp-step.mpiv ; fi ;") - context("step_begin_chart ;") + flush('chart_category := "%s" ;',category) -- - if chartsettings.alternative == variables.vertical then - context("chart_vertical := true ;") + if vertical then + flush("chart_vertical := true ;") + end + if align then + flush("chart_align := true ;") end -- - context("text_line_color := \\MPcolor{%s} ;", textsettings.framecolor) - context("text_line_width := %p ;", textsettings.rulethickness) - context("text_fill_color := \\MPcolor{%s} ;", textsettings.backgroundcolor) - context("text_offset := %p ;", textsettings.offset) - context("text_distance_set := %p ;", textsettings.distance) + flush("text_line_color := %q ;", textsettings.framecolor) + flush("text_line_width := %p ;", textsettings.rulethickness) + flush("text_fill_color := %q ;", textsettings.backgroundcolor) + flush("text_offset := %p ;", textsettings.offset) + flush("text_distance_set := %p ;", textsettings.distance) -- - context("cell_line_color := \\MPcolor{%s} ;", cellsettings.framecolor) - context("cell_line_width := %p ;", cellsettings.rulethickness) - context("cell_fill_color := \\MPcolor{%s} ;", cellsettings.backgroundcolor) - context("cell_offset := %p ;", cellsettings.offset) - context("cell_distance_x := %p ;", cellsettings.dx) - context("cell_distance_y := %p ;", cellsettings.dy) + flush("cell_line_color := %q ;", cellsettings.framecolor) + flush("cell_line_width := %p ;", cellsettings.rulethickness) + flush("cell_fill_color := %q ;", cellsettings.backgroundcolor) + flush("cell_offset := %p ;", cellsettings.offset) + flush("cell_distance_x := %p ;", cellsettings.dx) + flush("cell_distance_y := %p ;", cellsettings.dy) -- - context("line_line_color := \\MPcolor{%s} ;", linesettings.color) - context("line_line_width := %p ;", linesettings.rulethickness) - context("line_distance := %p ;", linesettings.distance) - context("line_offset := %p ;", linesettings.offset) + flush("line_line_color := %q ;", linesettings.color) + flush("line_line_width := %p ;", linesettings.rulethickness) + flush("line_distance := %p ;", linesettings.distance) + flush("line_offset := %p ;", linesettings.offset) + flush("line_height := %p ;", linesettings.height) -- - for i=1,#steps do + for i=1,chart.count do local step = steps[i] - context("step_begin_cell ;") - if step.cell_top ~= "" then - context('step_cell_top("%s") ;',string.strip(step.cell_top)) + flush("step_begin_cell ;") + local ali = step.cell_ali + local top = step.cell_top + local bot = step.cell_bot + if ali then + local text = ali.text + local shape = ali.shape + flush('step_cell_ali(%s,%s,%s,%q,%q,%p,%i) ;', + tonumber(text.left) or 0, + tonumber(text.middle) or 0, + tonumber(text.right) or 0, + shape.framecolor, + shape.backgroundcolor, + shape.rulethickness, + tonumber(shape.alternative) or 24 + ) end - if step.cell_bot ~= "" then - context('step_cell_bot("%s") ;',string.strip(step.cell_bot)) + if top then + local shape = top.shape + flush('step_cell_top(%s,%q,%q,%p,%i) ;', + tonumber(top.text.top) or 0, + shape.framecolor, + shape.backgroundcolor, + shape.rulethickness, + tonumber(shape.alternative) or 24 + ) end - if step.text_top ~= "" then - context('step_text_top("%s") ;',string.strip(step.text_top)) + if bot then + local shape = bot.shape + flush('step_cell_bot(%s,%q,%q,%p,%i) ;', + tonumber(bot.text.bot) or 0, + shape.framecolor, + shape.backgroundcolor, + shape.rulethickness, + tonumber(shape.alternative) or 24 + ) end - if step.text_mid ~= "" then - context('step_text_mid("%s") ;',string.strip(step.text_mid)) + local top = step.text_top + local mid = step.text_mid + local bot = step.text_bot + local s_t = step.start_t + local s_m = step.start_m + local s_b = step.start_b + if top then + local shape = top.shape + local line = top.line + flush('step_text_top(%s,%q,%q,%p,%i,%q,%p,%i) ;', + tonumber(top.text.top) or 0, + shape.framecolor, + shape.backgroundcolor, + shape.rulethickness, + tonumber(shape.alternative) or 24, + line.color, + line.rulethickness, + tonumber(line.alternative) or 1 + ) end - if step.text_bot ~= "" then - context('step_text_bot("%s") ;',string.strip(step.text_bot)) + if mid then -- used ? + local shape = mid.shape + local line = mid.line + flush('step_text_mid(%s,%q,%q,%p,%i,%q,%p,%i) ;', + tonumber(mid.text.mid) or 0, + shape.framecolor, + shape.backgroundcolor, + shape.rulethickness, + tonumber(shape.alternative) or 24, + line.color, + line.rulethickness, + tonumber(line.alternative) or 1 + ) end - context("step_end_cell ;") + if bot then + local shape = bot.shape + local line = bot.line + flush('step_text_bot(%s,%q,%q,%p,%i,%q,%p,%i) ;', + tonumber(bot.text.bot) or 0, + shape.framecolor, + shape.backgroundcolor, + shape.rulethickness, + tonumber(shape.alternative) or 24, + line.color, + line.rulethickness, + tonumber(line.alternative) or 1 + ) + end + flush('start_t[%i] := %i ;',i,s_t) + flush('start_m[%i] := %i ;',i,s_m) + flush('start_b[%i] := %i ;',i,s_b) + flush("step_end_cell ;") end -- - context("step_end_chart ;") - context.stopMPcode() + flush("step_end_chart ;") + stop() end -function commands.step_cells(top,bot) - steps[#steps+1] = { - cell_top = top or "", - cell_bot = bot or "", - text_top = "", - text_mid = "", - text_bot = "", - } +local function step_cells(spec) + count = count + 1 + local step = steps[count] + step.cell_top = spec + step.cell_bot = spec end -function commands.step_texts(top,bot) - if #steps > 0 then - steps[#steps].text_top = top or "" - steps[#steps].text_bot = bot or "" - end +local function step_cells_three(spec) + count = count + 1 + local step = steps[count] + step.cell_ali = spec end -function commands.step_cell(top) - steps[#steps+1] = { - cell_top = top or "", - cell_bot = "", - text_top = "", - text_mid = "", - text_bot = "", - } +local function step_texts(spec) + if count > 0 then + local step = steps[count] + step.text_top = spec + step.text_bot = spec + end end -function commands.step_text(top) - if #steps > 0 then - steps[#steps].text_top = top or "" - end +local function step_cell(spec) + count = count + 1 + steps[count].cell_top = spec end -function commands.step_textset(left,middle,right) - if #steps > 0 then - steps[#steps].text_top = left or "" - steps[#steps].text_mid = middle or "" - steps[#steps].text_bot = right or "" +local function step_text(spec) + if count > 0 then + local c = count + while true do + local step = steps[c] + if step.text_top then + c = c + 1 + step = steps[c] + else + step.text_top = spec + step.start_b = count + break + end + end end end -function commands.step_start_cell() - steps[#steps+1] = { - cell_top = "", - cell_bot = "", - text_top = "", - text_mid = "", - text_bot = "", - } +local function step_start_cell() + count = count + 1 + local step = steps[count] -- creates end -function commands.step_stop_cell() +local function step_stop_cell() end -function commands.step_text_top(str) - if #steps > 0 then - steps[#steps].text_top = str or "" +local function step_text_top(spec) + if count > 0 then + steps[count].text_top = spec end end -function commands.step_text_mid(str) - if #steps > 0 then - steps[#steps].text_mid = str or "" +local function step_text_mid(spec) + if count > 0 then + steps[count].text_mid = spec end end -function commands.step_text_bot(str) - if #steps > 0 then - steps[#steps].text_bot = str or "" +local function step_text_bot(spec) + if count > 0 then + steps[count].text_bot = spec end end -function commands.step_cell_top(str) - if #steps > 0 then - steps[#steps].cell_top = str or "" +local function step_cell_top(spec) + if count > 0 then + steps[count].cell_top = spec end end -function commands.step_cell_bot(str) - if #steps > 0 then - steps[#steps].cell_bot = str or "" +local function step_cell_bot(spec) + if count > 0 then + steps[count].cell_bot = spec end end + +-- + +interfaces.implement { + name = "step_start_chart", + arguments = { "string", "string" }, + actions = step_start_chart, +} + +interfaces.implement { + name = "step_stop_chart", + actions = step_stop_chart, +} + +interfaces.implement { + name = "step_make_chart", + actions = step_make_chart, + arguments = { + { + { "chart", { + { "category" }, + { "name" }, + { "alternative" }, + } + }, + { "cell", { + { "alternative" }, + { "offset", "dimension" }, + { "rulethickness", "dimension" }, + { "framecolor" }, + { "backgroundcolor" }, + { "dx", "dimension" }, + { "dy", "dimension" }, + } + }, + { "text", { + { "alternative" }, + { "offset", "dimension" }, + { "distance", "dimension" }, + { "rulethickness", "dimension" }, + { "framecolor" }, + { "backgroundcolor" }, + } + }, + { "line", { + { "alternative" }, + { "rulethickness", "dimension" }, + { "height", "dimension" }, + { "distance", "dimension" }, + { "offset", "dimension" }, + { "color" }, + } + } + } + } +} + +local step_spec = { + { + { "text", { + { "top" }, + { "middle" }, + { "mid" }, + { "bot" }, + { "left" }, + { "right" }, + } + }, + { "shape", { + { "rulethickness", "dimension" }, + { "alternative" }, + { "framecolor" }, + { "backgroundcolor" }, + } + }, + { "line", { + { "alternative" }, + { "rulethickness", "dimension" }, + { "color" }, + { "offset", "dimension" }, + } + } + } +} + +interfaces.implement { + name = "step_cell", + arguments = step_spec, + actions = step_cell, +} + +interfaces.implement { + name = "step_text", + arguments = step_spec, + actions = step_text, +} + +interfaces.implement { + name = "step_text_top", + arguments = step_spec, + actions = step_text_top, +} + +interfaces.implement { + name = "step_text_mid", + arguments = step_spec, + actions = step_text_mid, +} + +interfaces.implement { + name = "step_text_bot", + arguments = step_spec, + actions = step_text_bot, +} + +interfaces.implement { + name = "step_cell_top", + arguments = step_spec, + actions = step_cell_top, +} + +interfaces.implement { + name = "step_cell_bot", + arguments = step_spec, + actions = step_cell_bot, +} + +interfaces.implement { + name = "step_start_cell", + actions = step_start_cell, +} + +interfaces.implement { + name = "step_stop_cell", + actions = step_stop_cell, +} + +interfaces.implement { + name = "step_texts", + arguments = step_spec, + actions = step_texts, +} + +interfaces.implement { + name = "step_cells", + arguments = step_spec, + actions = step_cells, +} + +interfaces.implement { + name = "step_cells_three", + arguments = step_spec, + actions = step_cells_three, +} diff --git a/tex/context/modules/mkiv/m-steps.mkvi b/tex/context/modules/mkiv/m-steps.mkvi index c9c5a0636..873015fd6 100644 --- a/tex/context/modules/mkiv/m-steps.mkvi +++ b/tex/context/modules/mkiv/m-steps.mkvi @@ -11,66 +11,71 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -% multiple texts? +% This code is not optimized. \registerctxluafile{m-steps}{} \unprotect +\defineMPinstance + [steps] + [\s!format=metafun, + \s!extensions=\v!yes, + \s!initializations=\v!yes] + %\c!method=\s!double] + +\startMPdefinitions{steps} + loadmodule "step" ; +\stopMPdefinitions + \installcorenamespace {stepcharts} -\installcorenamespace {steptables} \installcorenamespace {stepcells} \installcorenamespace {steptexts} \installcorenamespace {steplines} -\installsimplecommandhandler \??stepcharts {STEPchart} \??stepcharts -\installsimplecommandhandler \??steptables {STEPtable} \??steptables -\installsimplecommandhandler \??stepcells {STEPcell} \??stepcells -\installsimplecommandhandler \??steptexts {STEPtext} \??steptexts -\installsimplecommandhandler \??steplines {STEPline} \??steplines +\installstylisticautosetuphandler \??stepcharts {STEPchart} \??stepcharts +\installstylisticautosetuphandler \??stepcells {STEPcell} \??stepcells +\installstylisticautosetuphandler \??steptexts {STEPtext} \??steptexts +\installstylisticautosetuphandler \??steplines {STEPline} \??steplines \let\setupSTEPcharts\setupSTEPchart -\let\setupSTEPtables\setupSTEPtable +\let\setupSTEPtables\setupSTEPchart % one can define categories so no need \let\setupSTEPcells \setupSTEPcell \let\setupSTEPtexts \setupSTEPtext \let\setupSTEPlines \setupSTEPline +\let\setSTEPchartsparameter\setSTEPchartparameter +\let\setSTEPcellsparameter \setSTEPcellparameter +\let\setSTEPtextsparameter \setSTEPtextparameter +\let\setSTEPlinesparameter \setSTEPlineparameter + % numeric text_text_distance ; text_text_distance := 20pt ; % numeric step_distance ; step_distance := 20pt ; \setupSTEPcharts - [\c!alternative=\v!horizontal, + [%c!alternative=\v!horizontal, % travels with stored so dealt with in lua + %\c!offset=.15\bodyfontsize + %\c!height=2ex \c!before=\blank, \c!after=\blank] -% \c!offset=.15\bodyfontsize -% \c!height=2ex - -% \setupSTEPtables -% [\c!before=\blank, -% \c!after=\blank, -% \c!distance=.25em, -% \c!voffset=1ex, -% \c!method=1, -% \c!width=4em, -% \c!offset=.15\bodyfontsize] \setupSTEPcells - [\c!alternative=1, % TODO -% \c!style=, -% \c!color=, + [\c!alternative=24, + \c!style=, + \c!color=, \c!dx=\bodyfontsize, \c!dy=\bodyfontsize, - \c!background=\v!color, + % \c!background=\v!color, \c!backgroundcolor=STEPbackgroundcolor, \c!rulethickness=.1\bodyfontsize, \c!framecolor=STEPframecolor, \c!offset=.25\bodyfontsize] \setupSTEPtexts - [\c!alternative=1, % TODO -% \c!style=\v!smallbodyfont, -% \c!color=, - \c!background=\v!color, + [\c!alternative=24, + \c!style=\v!smallbodyfont, + \c!color=, + % \c!background=\v!color, \c!backgroundcolor=STEPbackgroundcolor, \c!rulethickness=.1\bodyfontsize, \c!framecolor=STEPframecolor, @@ -78,9 +83,10 @@ \c!offset=.25\bodyfontsize] \setupSTEPlines - [\c!alternative=1, % TODO + [\c!alternative=1, \c!rulethickness=.15\bodyfontsize, - \c!height=3\bodyfontsize, + \c!height=\STEPlineparameter\c!width, + \c!width=3\bodyfontsize, \c!distance=.5\bodyfontsize, \c!offset=.25\bodyfontsize, \c!color=STEPlinecolor] @@ -89,31 +95,78 @@ \definecolor [STEPframecolor] [s=.7] \definecolor [STEPbackgroundcolor] [s=.9] +\newcount\c_module_steps_tag +\newmacro\m_module_steps_category + +\unexpanded\def\setSTEPbox#tag#str% + {\setbox\scratchbox\hbox\bgroup + \begstrut + \ignorespaces + #str% + \removeunwantedspaces + \endstrut + \egroup + \ifzeropt\wd\scratchbox + \let#1\empty + \else + \global\advance\c_module_steps_tag\plusone + \edef#tag{\the\c_module_steps_tag}% + \putboxincache{\??stepcharts\m_module_steps_category}{#tag}\scratchbox + \fi} + \newtoks\everySTEPchart +% we used to save charts but that is tricky with so much delegated to lua +% and mp so now we do support a buffered way only + +\def\module_steps_syncronize + {\let\currentSTEPtext\p_category + \let\currentSTEPcell\p_category + \let\currentSTEPline\p_category + \checkSTEPcellparent + \checkSTEPtextparent + \checkSTEPlineparent} + \unexpanded\def\startSTEPchart {\begingroup \dodoubleempty\module_steps_start_chart} \def\module_steps_start_chart[#name][#settings]% - {\startnointerference - \iffirstargument + {\iffirstargument \doifelseassignment{#name} {\let\currentSTEPchart\empty - \xdef\module_steps_flush_chart{\module_steps_chart[][#name]}} + \let\m_module_steps_category\empty + \setupcurrentSTEPchart[#name]% + \def\module_steps_flush_chart{\module_steps_chart[][#name]}} {\edef\currentSTEPchart{#name}% - \glet\module_steps_flush_chart\relax}% settings are not stored + \setupcurrentSTEPchart[#settings]% + \let\m_module_steps_category\currentSTEPchart + \resetboxesincache{\??stepcharts\m_module_steps_category}% + \doifelse{\STEPchartparameter\c!buffer}\v!no + {\def\module_steps_flush_chart{\STEPchart[#name]}} + {\let\module_steps_flush_chart\relax}}% \else \let\currentSTEPchart\empty - \gdef\module_steps_flush_chart{\module_steps_chart[][]}% + \def\module_steps_flush_chart{\module_steps_chart[][]}% \fi + \edef\p_category{\STEPchartparameter\c!category}% + \let\currentSTEPtext\p_category + \let\currentSTEPcell\p_category + \let\currentSTEPline\p_category + \checkSTEPcellparent + \checkSTEPtextparent + \checkSTEPlineparent \the\everySTEPchart - \ctxcommand{step_start_chart("\currentSTEPchart")}} + \startnointerference + \clf_step_start_chart{\currentSTEPchart}{\STEPchartparameter\c!alternative}} \unexpanded\def\stopSTEPchart - {\ctxcommand{step_stop_chart()}% + {\clf_step_stop_chart \stopnointerference \module_steps_flush_chart + \ifx\m_module_steps_category\empty + \resetboxesincache{\??stepcharts}% + \fi \endgroup} \unexpanded\def\startSTEPtable @@ -123,13 +176,24 @@ \let\stopSTEPtable\stopSTEPchart +\unexpanded\def\startSTEPaligntable + {\begingroup + \setupSTEPchart[\c!alternative={\v!vertical,\v!three}]% + \let\module_steps_cells\module_steps_cells_three % no nesting yet + \dodoubleempty\module_steps_start_chart} + +\let\stopSTEPaligntable\stopSTEPchart + \let\module_steps_flush_chart\relax +% \resetboxesincache\??stepcharts + \unexpanded\def\STEPchart {\dodoubleempty\module_steps_chart} \unexpanded\def\module_steps_chart[#name][#settings]% {\begingroup + \edef\m_module_steps_category{#name}% \setupSTEPchart[#settings]% \ifinsidefloat \makeSTEPchart[#name]% @@ -137,129 +201,300 @@ \STEPchartparameter\c!before \startbaselinecorrection \setlocalhsize - \makeSTEPchart[#name]% + \dontleavehmode\vpack{\makeSTEPchart[#name]}% we need to ensure leftskip \stopbaselinecorrection \STEPchartparameter\c!after \fi \endgroup} \unexpanded\def\makeSTEPchart[#name]% - {\ctxcommand{step_make_chart { - chart = { - name = "#name", - alternative = "\STEPchartparameter\c!alternative", - }, - cell = { - alternative = "\STEPcellparameter\c!alternative", % TODO: shapes - offset = \number\dimexpr\STEPcellparameter\c!offset, - rulethickness = \number\dimexpr\STEPcellparameter\c!rulethickness, - framecolor = "\STEPcellparameter\c!framecolor", - backgroundcolor = "\STEPcellparameter\c!backgroundcolor", - dx = \number\dimexpr\STEPcellparameter\c!dx, - dy = \number\dimexpr\STEPcellparameter\c!dy, - }, - text = { - alternative = "\STEPtextparameter\c!alternative", % TODO: shapes - offset = \number\dimexpr\STEPtextparameter\c!offset, - distance = \number\dimexpr\STEPtextparameter\c!distance, - rulethickness = \number\dimexpr\STEPtextparameter\c!rulethickness, - framecolor = "\STEPtextparameter\c!framecolor", - backgroundcolor = "\STEPtextparameter\c!backgroundcolor", - }, - line = { - alternative = "\STEPlineparameter\c!alternative", % TODO: dash, arrow - rulethickness = \number\dimexpr\STEPlineparameter\c!rulethickness, - height = \number\dimexpr\STEPlineparameter\c!height, - distance = \number\dimexpr\STEPlineparameter\c!distance, - offset = \number\dimexpr\STEPlineparameter\c!offset, - color = "\STEPlineparameter\c!color", - }, - }}} - -\unexpanded\def\startSTEPcell - {\ctxcommand{step_start_cell()}} - -\unexpanded\def\stopSTEPcell - {\ctxcommand{step_stop_cell()}} - -\unexpanded\def\module_steps_cells#top#bot% - {\ctxcommand{step_cells(\!!bs\detokenize{#top}\!!es,\!!bs\detokenize{#bot}\!!es)}} - -\unexpanded\def\module_steps_texts#top#bot% - {\ctxcommand{step_texts(\!!bs\detokenize{#top}\!!es,\!!bs\detokenize{#bot}\!!es)}} - -\unexpanded\def\module_steps_cell#str% - {\ctxcommand{step_cell(\!!bs\detokenize{#str}\!!es)}} - -\unexpanded\def\module_steps_text#str% - {\ctxcommand{step_text(\!!bs\detokenize{#str}\!!es)}} - -\unexpanded\def\module_steps_textset#left#middle#right% - {\ctxcommand{step_textset(\!!bs\detokenize{#left}\!!es,\!!bs\detokenize{#middle}\!!es,\!!bs\detokenize{#right}\!!es)}} - -\unexpanded\def\module_steps_toptext#top% - {\ctxcommand{step_text_top(\!!bs\detokenize{#top}\!!es)}} - -\unexpanded\def\module_steps_bottext#bot% - {\ctxcommand{step_text_bot(\!!bs\detokenize{#bot}\!!es)}} - -\unexpanded\def\module_steps_topcell#top% - {\ctxcommand{step_cell_top(\!!bs\detokenize{#top}\!!es)}} - -\unexpanded\def\module_steps_botcell#bot% - {\ctxcommand{step_cell_bot(\!!bs\detokenize{#bot}\!!es)}} + {\clf_step_make_chart + chart { + category {\??stepcharts\m_module_steps_category} + name {#name} + alternative {\STEPchartparameter\c!alternative} + } + cell { + alternative {\STEPcellparameter\c!alternative} + offset \dimexpr\STEPcellparameter\c!offset\relax + rulethickness \dimexpr\STEPcellparameter\c!rulethickness\relax + framecolor {\STEPcellparameter\c!framecolor} + backgroundcolor {\STEPcellparameter\c!backgroundcolor} + dx \dimexpr\STEPcellparameter\c!dx\relax + dy \dimexpr\STEPcellparameter\c!dy\relax + } + text { + alternative {\STEPtextparameter\c!alternative} + offset \dimexpr\STEPtextparameter\c!offset\relax + distance \dimexpr\STEPtextparameter\c!distance\relax + rulethickness \dimexpr\STEPtextparameter\c!rulethickness\relax + framecolor {\STEPtextparameter\c!framecolor} + backgroundcolor {\STEPtextparameter\c!backgroundcolor} + } + line { + alternative {\STEPlineparameter\c!alternative} + rulethickness \dimexpr\STEPlineparameter\c!rulethickness\relax + height \dimexpr\STEPlineparameter\c!height\relax + distance \dimexpr\STEPlineparameter\c!distance\relax + offset \dimexpr\STEPlineparameter\c!offset\relax + color {\STEPlineparameter\c!color} + } + \relax} + +\unexpanded\def\startSTEPcell{\clf_step_start_cell} +\unexpanded\def\stopSTEPcell {\clf_step_stop_cell} + +\unexpanded\def\module_steps_cells {\dosingleempty\module_steps_cells_indeed} +\unexpanded\def\module_steps_cells_three{\dosingleempty\module_steps_cells_three_indeed} +\unexpanded\def\module_steps_texts {\dosingleempty\module_steps_texts_indeed} +\unexpanded\def\module_steps_cell {\dosingleempty\module_steps_cell_indeed} +\unexpanded\def\module_steps_text {\dosingleempty\module_steps_text_indeed} +\unexpanded\def\module_steps_toptext {\dosingleempty\module_steps_toptext_indeed} +\unexpanded\def\module_steps_bottext {\dosingleempty\module_steps_bottext_indeed} +\unexpanded\def\module_steps_topcell {\dosingleempty\module_steps_topcell_indeed} +\unexpanded\def\module_steps_botcell {\dosingleempty\module_steps_botcell_indeed} + +\def\module_steps_check_cell#category% + {\edef\p_category{#category}% + \ifx\p_category\empty \else + \let\currentSTEPcell\p_category + \let\currentSTEPline\p_category + \checkSTEPcellparent + \checkSTEPlineparent + \fi} + +\def\module_steps_check_text#category% + {\edef\p_category{#category}% + \ifx\p_category\empty \else + \let\currentSTEPtext\p_category + \let\currentSTEPline\p_category + \checkSTEPtextparent + \checkSTEPlineparent + \fi} + +\def\module_steps_pass_data#1#2% + {{ + text { + #2 + } + shape { + rulethickness \dimexpr#1\c!rulethickness\relax + alternative {#1\c!alternative} + framecolor {#1\c!framecolor} + backgroundcolor {#1\c!backgroundcolor} + } + line { + rulethickness \dimexpr\STEPlineparameter\c!rulethickness\relax + alternative {\STEPlineparameter\c!alternative} + color {\STEPlineparameter\c!color} + offset \dimexpr\STEPlineparameter\c!offset\relax + } + }} + +\def\module_steps_cells_indeed[#category]#top#bot% + {\begingroup + \iffirstargument + \module_steps_check_cell{#category}% + \fi + \useSTEPcellstyleandcolor\c!style\c!color + \setSTEPbox\module_steps_tag_a{#top}% + \setSTEPbox\module_steps_tag_b{#bot}% + \clf_step_cells \module_steps_pass_data \STEPcellparameter { + top {\module_steps_tag_a} + bot {\module_steps_tag_b} + } + \endgroup} + +\def\module_steps_cells_three_indeed[#category]#one#two#three% + {\begingroup + \iffirstargument + \module_steps_check_cell{#category}% + \fi + \useSTEPcellstyleandcolor\c!style\c!color + \setSTEPbox\module_steps_tag_a{#one}% + \setSTEPbox\module_steps_tag_b{#two}% + \setSTEPbox\module_steps_tag_c{#three}% + \clf_step_cells_three \module_steps_pass_data \STEPcellparameter { + left {\module_steps_tag_a} + middle {\module_steps_tag_b} + right {\module_steps_tag_c} + }% + \endgroup} + +\def\module_steps_texts_indeed[#category]#top#bot% + {\begingroup + \iffirstargument + \module_steps_check_text{#category}% + \fi + \useSTEPtextstyleandcolor\c!style\c!color + \setSTEPbox\module_steps_tag_a{#top}% + \setSTEPbox\module_steps_tag_b{#bot}% + \clf_step_texts \module_steps_pass_data \STEPtextparameter { + top {\module_steps_tag_a} + bot {\module_steps_tag_b} + }% + \endgroup} + +\def\module_steps_cell_indeed[#category]#str% + {\begingroup + \iffirstargument + \module_steps_check_cell{#category}% + \fi + \useSTEPcellstyleandcolor\c!style\c!color + \setSTEPbox\module_steps_tag_a{#str}% + \clf_step_cell \module_steps_pass_data \STEPcellparameter { + top {\module_steps_tag_a} + }% + \endgroup} + +\def\module_steps_text_indeed[#category]#str% + {\begingroup + \iffirstargument + \module_steps_check_text{#category}% + \fi + \useSTEPtextstyleandcolor\c!style\c!color + \setSTEPbox\module_steps_tag_a{#str}% + \clf_step_text \module_steps_pass_data \STEPtextparameter { + top {\module_steps_tag_a} + }% + \endgroup} + +\def\module_steps_toptext_indeed[#category]#top% + {\begingroup + \iffirstargument + \module_steps_check_text{#category}% + \fi + \useSTEPtextstyleandcolor\c!style\c!color + \setSTEPbox\module_steps_tag_a{#top}% + \clf_step_text_top \module_steps_pass_data \STEPtextparameter { + top {\module_steps_tag_a} + }% + \endgroup} + +\def\module_steps_bottext_indeed[#category]#bot% + {\begingroup + \iffirstargument + \module_steps_check_text{#category}% + \fi + \useSTEPtextstyleandcolor\c!style\c!color + \setSTEPbox\module_steps_tag_a{#bot}% + \clf_step_text_bot \module_steps_pass_data \STEPtextparameter { + bot {\module_steps_tag_a} + }% + \endgroup} + +\def\module_steps_topcell_indeed[#category]#top% + {\begingroup + \iffirstargument + \module_steps_check_cell{#category}% + \fi + \useSTEPcellstyleandcolor\c!style\c!color + \setSTEPbox\module_steps_tag_a{#top}% + \clf_step_cell_top \module_steps_pass_data \STEPcellparameter { + top {\module_steps_tag_a} + }% + \endgroup} + +\def\module_steps_botcell_indeed[#category]#bot% + {\begingroup + \iffirstargument + \module_steps_check_cell{#category}% + \fi + \useSTEPcellstyleandcolor\c!style\c!color + \setSTEPbox\module_steps_tag_a{#bot}% + \clf_step_cell_bot \module_steps_pass_data \STEPcellparameter { + bot {\module_steps_tag_a} + }% + \endgroup} \appendtoks \let\cells \module_steps_cells \let\texts \module_steps_texts \let\cell \module_steps_cell \let\text \module_steps_text - \let\textset\module_steps_textset \let\toptext\module_steps_toptext \let\bottext\module_steps_bottext \let\topcell\module_steps_topcell \let\botcell\module_steps_botcell \to \everySTEPchart -% todo: mapping can be done in lua +% The xml interface: + +\unexpanded\def\setSTEPxmldirective#1#2#3% + {\begincsname setSTEP#1parameter\endcsname{#2}{#3}} + +\xmlinstalldirective{stepchart}{setSTEPxmldirective} \startxmlsetups xml:step:define - \xmlsetsetup{#1} {stepchart|steptable} {xml:step:*} + \xmlsetsetup + {#1} + {stepchart|steptable|stepaligntable|cells|texts|stepcell|cell|text} + {xml:step:*} \stopxmlsetups \xmlregistersetup{xml:step:define} \startxmlsetups xml:step:stepchart - \startSTEPchart - \xmlfilter{#1}{/(cells|texts|stepcell|cell|text)/command(xml:step:*)} + \startSTEPchart[\c!category=\xmlatt{#1}{class}] + \xmlflush{#1} \stopSTEPchart \stopxmlsetups \startxmlsetups xml:step:steptable - \startSTEPtable - \xmlfilter{#1}{/(cells|texts|stepcell|cell|text)/command(xml:step:*)} + \startSTEPtable[\c!category=\xmlatt{#1}{class}] + \xmlflush{#1} \stopSTEPtable \stopxmlsetups +\startxmlsetups xml:step:stepaligntable + \startSTEPaligntable[\c!category=\xmlatt{#1}{class}] + \xmlflush{#1} + \stopSTEPaligntable +\stopxmlsetups + \startxmlsetups xml:step:cells - \cells {\xmltext{#1}{/top}} {\xmltext{#1}{/bot}} + \xmldoifelse {#1} {/c1} { + \cells + [\xmlatt{#1}{class}] + {\xmltext{#1}{/c1}} + {\xmltext{#1}{/c2}} + {\xmltext{#1}{/c3}} + } { + \cells + [\xmlatt{#1}{class}] + {\xmltext{#1}{/top}} + {\xmltext{#1}{/bot}} + } \stopxmlsetups \startxmlsetups xml:step:texts - \texts {\xmltext{#1}{/top}} {\xmltext{#1}{/bot}} + \texts + [\xmlatt{#1}{class}] + {\xmltext{#1}{/top}} + {\xmltext{#1}{/bot}} \stopxmlsetups \startxmlsetups xml:step:stepcell - \cells {\xmltext{#1}{/topcell}} {\xmltext{#1}{/botcell}} - \texts {\xmltext{#1}{/toptext}} {\xmltext{#1}{/bottext}} + \cells + [\xmlatt{#1}{class}] + {\xmltext{#1}{/topcell}} + {\xmltext{#1}{/botcell}} + \texts + [\xmlatt{#1}{class}] + {\xmltext{#1}{/toptext}} + {\xmltext{#1}{/bottext}} \stopxmlsetups \startxmlsetups xml:step:cell - \cell {\xmlflush{#1}} + \cell + [\xmlatt{#1}{class}] + {\xmlflush{#1}} \stopxmlsetups \startxmlsetups xml:step:text - \text {\xmlflush{#1}} + \text + [\xmlatt{#1}{class}] + {\xmlflush{#1}} \stopxmlsetups \protect @@ -268,11 +503,13 @@ \starttext +\setupSTEPcells[demo-1][style=bold] + \startbuffer <stepchart> <cell> some cell </cell> <text> some text </text> - <cell> some cell </cell> + <cell class="demo-1"> some cell </cell> <text> some text </text> <cell> some cell </cell> </stepchart> @@ -280,7 +517,6 @@ \typebuffer \processxmlbuffer - \startbuffer <steptable> <cell> some cell </cell> @@ -304,15 +540,6 @@ \cells {five} {one} \stopSTEPchart -\startSTEPtable - \cell {one} \textset{$x$} {=}{$a+b+c$} - \cell {two} \textset{$c+d$}{=}{$y$} - \cell {three} -\stopSTEPtable - - -\page - \startbuffer <stepchart> <cells> <top> some text </top> <bot> some text </bot> </cells> @@ -379,4 +606,53 @@ \page +\setupSTEPchart + [mytable] + [before={\blank[2*big]}, + after={\blank[2*big]}] + +\starttext + +\startSTEPaligntable[mytable] + \cells {$2c$} {$=$} {$2a+3b$} + \text {with $a=5$} + \cells {$2c$}{$=$} {$10+3b$} + \text {and $b=6$} + \cells {$2c$} {$=$} {$10+18$} + \text {we get} + \cells {$2c$} {$=$} {$28$} + \text {and therefore} + \cells {$c$} {$=$} {$28/2$} + \text {which reduces to} + \cells {$c$} {$=$} {$14$} +\stopSTEPaligntable + +\input tufte + +\STEPchart[mytable] + +\input tufte + +\setupSTEPchart + [mytable] + [buffer=no] + +\startSTEPaligntable[mytable] + \cells {$2c$} {$=$} {$2a+3b$} + \text {with $a=5$} + \cells {$2c$}{$=$} {$10+3b$} + \text {and $b=6$} + \cells {$2c$} {$=$} {$10+18$} + \text {we get} + \cells {$2c$} {$=$} {$28$} + \text {and therefore} + \cells {$c$} {$=$} {$28/2$} + \text {which reduces to} + \cells {$c$} {$=$} {$14$} +\stopSTEPaligntable + +\input tufte + +\STEPchart[mytable] + \stoptext diff --git a/tex/context/modules/mkiv/m-visual.mkiv b/tex/context/modules/mkiv/m-visual.mkiv index 01fae49e2..6ec0a52b0 100644 --- a/tex/context/modules/mkiv/m-visual.mkiv +++ b/tex/context/modules/mkiv/m-visual.mkiv @@ -14,7 +14,8 @@ \unprotect %D Much will probably be replaced by \LUA\ based solutions which is -%D rather trivial and fun doing. +%D rather trivial and fun doing. A lot here makes no sense any more, +%D for instance whatsits are not used. %D This module collect a few more visual debugger features. I %D needed them for manuals and styles. The macros are documented @@ -24,13 +25,18 @@ \definecolor[fakebaselinecolor] [green] \definecolor[fakeparindentcolor][blue] -\newif\iffakebaseline \fakebaselinetrue -\newif\iffaketrigger \faketriggerfalse +\newif \iffakebaseline \fakebaselinetrue +\newif \iffaketrigger \faketriggerfalse +\newdimen \fakerulewidth \fakerulewidth=.2pt \unexpanded\def\fakerule#1% {\strut \begingroup - \directcolored[fakerulecolor]% + \ifx\fakerulecolor\relax + \directcolored[fr\recurselevel c]% + \else + \directcolored[fakerulecolor]% + \fi \iffakebaseline \vrule\s!height1.25\exheight\s!depth-.05\exheight\s!width#1% \kern-#1% @@ -75,7 +81,9 @@ fr8c=darkorange] \unexpanded\def\onlyfakewords#1#2% min max / 10 40 - {\getrandomcount\scratchcounter{\ifcase0#1 10\else#1\fi}{\ifcase0#2 40\else#2\fi}% + {\dontleavehmode + \ifvmode\noindentation\fi + \getrandomcount\scratchcounter{\ifcase0#1 10\else#1\fi}{\ifcase0#2 40\else#2\fi}% \dofakewords\scratchcounter } % no \par @@ -102,7 +110,7 @@ \def\doshowfakewords#1% {\bgroup \setuppalet[fakerule]% - \definecolor[fakerulecolor]% + \let\fakerulecolor\relax \dorecurse{#1} {\getrandomcount\scratchcounter{1}{5}% \dorecurse\scratchcounter @@ -141,19 +149,17 @@ \def\dofakedroppedcaps {\setbox\scratchbox\hpack {\setbox\scratchbox\hpack{W}% - \scratchdimen#1\lineheight - \advance\scratchdimen -\lineheight - \advance\scratchdimen \dp\strutbox + \scratchdimen\dimexpr#1\lineheight-\lineheight+\dp\strutbox\relax \vrule \s!width#1\wd\scratchbox \s!height\ht\scratchbox \s!depth\scratchdimen}% \ht\scratchbox\ht\strutbox \dp\scratchbox\dp\strutbox - \hangindent\wd\scratchbox - \advance\hangindent .5em + \hangindent\dimexpr\wd\scratchbox+.5\emwidth\relax \wd\scratchbox\hangindent - \hangafter-#1\noindent + \hangafter-#1% + \noindent \llap{\fakeparindentcolor\box\scratchbox}}% \fi} @@ -169,13 +175,15 @@ \doifelseinset{#1}{\v!left,\v!right} {\fakewords{2}{4}} {\fakewords{4}{10}}}% - {\doifinset{#1}{\v!left,\v!right} - {\dimen0=.75\dimen0 - \ifdim\dimen0>.6\hsize \dimen0=.5\hsize\fi - \ifdim\dimen0<.3\hsize \dimen0=.3\hsize\fi}% + {\getrandomdimen\scratchdimenone{#3}{#4}% + \getrandomdimen\scratchdimentwo{#5}{#6}% + \doifinset{#1}{\v!left,\v!right} + {\scratchdimenone.75\scratchdimenone + \ifdim\scratchdimenone>.6\hsize \scratchdimenone.5\hsize\fi + \ifdim\scratchdimenone<.3\hsize \scratchdimenone.3\hsize\fi}% \framed - [\c!width=\dimen0, - \c!height=\dimen2, + [\c!width=\scratchdimenone, + \c!height=\scratchdimentwo, \c!frame=\v!off, \c!background=\v!color, \c!backgroundcolor=fakeparindentcolor] @@ -183,25 +191,25 @@ \defrostrandomseed} \unexpanded\def\fakeimage#1#2#3#4% - {\getrandomdimen{\dimen0}{#1}{#3}% - \getrandomdimen{\dimen2}{#2}{#4}% + {\getrandomdimen\scratchdimenone{#1}{#3}% + \getrandomdimen\scratchdimentwo{#2}{#4}% \framed - [\c!width=\dimen0, - \c!height=\dimen2, + [\c!width=\scratchdimenone, + \c!height=\scratchdimentwo, \c!frame=\v!off, \c!background=\v!color, \c!backgroundcolor=fakeparindentcolor] {}} \unexpanded\def\fakeformula - {\dimen0\zeropoint + {\scratchdimenone\zeropoint \getrandomcount\scratchcounter{3}{6}% \dorecurse\scratchcounter - {\getrandomdimen\scratchdimen{0.5em}{1.5em}% - \mathord{\red\fakerule\scratchdimen}% + {\getrandomdimen\scratchdimentwo{0.5\emwidth}{1.5\emwidth}% + \mathord{\red\fakerule\scratchdimentwo}% \ifnum\recurselevel<\scratchcounter+\fi - \advance\scratchdimen\dimen0}% - =\mathinner{\red\fakerule\scratchdimen}} + \advance\scratchdimentwo\scratchdimenone}% + =\mathinner{\red\fakerule\scratchdimentwo}} \unexpanded\def\fakespacingformula {\color[fakebaselinecolor]{\ruledbaseline}\fakeformula} @@ -306,11 +314,10 @@ \scratchdimen#1\relax \dontinterfere \dontcomplain - %boxrulewidth5\testrulewidth #3#4\relax \setbox\scratchbox\normalhbox to \scratchdimen {#2{\ruledhbox to \scratchdimen - {\vrule #5 20\testrulewidth \s!width \zeropoint + {\vrule #5 20\fakerulewidth \s!width \zeropoint \normalhss}}}% \smashbox\scratchbox \normalpenalty\plustenthousand @@ -321,8 +328,7 @@ {\ifdim\hangindent>\zeropoint \ifnum\hangafter<\zerocount \normalhbox - {%boxrulewidth5\testrulewidth - \setbox\scratchbox\ruledhbox to \hangindent + {\setbox\scratchbox\ruledhbox to \hangindent {\scratchdimen\strutht \advance\scratchdimen \strutdp \vrule @@ -354,7 +360,7 @@ \unexpanded\def\ruledpar {\relax \ifhmode - \showparagraphcue{40\testrulewidth}\relax\rightrulefalse\relax\s!height + \showparagraphcue{40\fakerulewidth}\relax\rightrulefalse\relax\s!height \fi \normalpar} @@ -362,7 +368,7 @@ {\relax \normalnoindent \ruledparagraphcues - \showparagraphcue{40\testrulewidth}\llap\leftrulefalse\relax\s!height} + \showparagraphcue{40\fakerulewidth}\llap\leftrulefalse\relax\s!height} \unexpanded\def\ruledindent {\relax @@ -371,7 +377,7 @@ \ifdim\parindent>\zeropoint \showparagraphcue\parindent\relax\relax\relax\s!height \else - \showparagraphcue{40\testrulewidth}\llap\relax\relax\s!height + \showparagraphcue{40\fakerulewidth}\llap\relax\relax\s!height \fi \normalhskip\parindent} @@ -381,10 +387,9 @@ \let\par \normalpar} \unexpanded\def\showimplicits - {\testrulewidth \defaulttestrulewidth - \let\noindent \rulednoindent - \let\indent \ruledindent - \let\par \ruledpar} + {\let\noindent \rulednoindent + \let\indent \ruledindent + \let\par \ruledpar} %D The next few||line examples show the four cues. Keep in %D mind that we only see them when we explicitly open or close @@ -434,8 +439,8 @@ \normalhbox {\strut \vrule - \s!height \testrulewidth - \s!depth \testrulewidth + \s!height \fakerulewidth + \s!depth \fakerulewidth \s!width 120\points} \normalvfill}% \smashbox\scratchbox @@ -452,8 +457,7 @@ \egroup} \unexpanded\def\showbaselines - {\testrulewidth\defaulttestrulewidth - \EveryPar{\ruledbaseline}} + {\EveryPar{\ruledbaseline}} %D \macros %D {showpagebuilder} @@ -504,7 +508,7 @@ {\vss\hpack to 3em{\hss#2\hss}\vss}% \fi}} -\def\colorrangeA#1% +\unexpanded\def\colorrangeA#1% {\vpack {\startcolor[\s!white]% \scratchdimen\dimexpr(-\colormarklength*4+\tractempheight+\tractempdepth)/21\relax @@ -526,7 +530,7 @@ {\vss\hpack to \scratchdimen{\hss#1\hss}\vss}% \fi} -\def\colorrangeB +\unexpanded\def\colorrangeB {\hpack {\startcolor[\s!white]% \scratchdimen\dimexpr(-\colormarklength*\plustwo+\tractempwidth)/11\relax @@ -553,7 +557,7 @@ {\vss\hpack to \scratchdimen{\hss#1\hss}\vss}% \fi} -\def\colorrangeC +\unexpanded\def\colorrangeC {\hpack {\startcolor[\s!white]% \scratchdimen\dimexpr(-\colormarklength*2+\tractempwidth)/14\relax @@ -641,10 +645,10 @@ \let\supernormalmarks \normalmarks % mark may already been superseded \unexpanded\def\showwhatsits - {\protected\def\normalmark {\visualwhatsit100+m\supernormalmark }% - \protected\def\normalmarks{\visualwhatsit100+m\supernormalmarks}% - \protected\def\special {\visualwhatsit0100s\normalspecial }% - \protected\def\write {\visualwhatsit001-w\normalwrite }% + {\unexpanded\def\normalmark {\visualwhatsit100+m\supernormalmark }% + \unexpanded\def\normalmarks{\visualwhatsit100+m\supernormalmarks}% + \unexpanded\def\special {\visualwhatsit0100s\normalspecial }% + \unexpanded\def\write {\visualwhatsit001-w\normalwrite }% \let\immediate\immediatewhatsit \appendtoks\dontshowwhatsits\to\everystoptext} diff --git a/tex/context/modules/mkiv/s-characters-properties.lua b/tex/context/modules/mkiv/s-characters-properties.lua new file mode 100644 index 000000000..dc9fb8f93 --- /dev/null +++ b/tex/context/modules/mkiv/s-characters-properties.lua @@ -0,0 +1,83 @@ +if not modules then modules = { } end modules ['s-characters-properties'] = { + version = 1.001, + comment = "companion to s-characters-properties.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.characters = moduledata.characters or { } +moduledata.characters.properties = moduledata.characters.properties or { } + +local catcodenames = { [0] = + "escape", "begingroup", "endgroup", "mathshift", + "alignment", "endofline", "parameter", "superscript", + "subscript", "ignore", "space", "letter", + "other", "active", "comment", "invalid", +} + +table.swapped(catcodes,catcodes) + +local catcodes = context.catcodes +local getcatcode = tex.getcatcode +local c_context = catcodes.context +local c_tex = catcodes.tex +local c_protect = catcodes.protect +local c_text = catcodes.text +local c_verbatim = catcodes.verbatim + +local context = context +local ctx_NC = context.NC +local ctx_NR = context.NR +local ctx_MR = context.MR +local ctx_ML = context.ML +local ctx_bold = context.bold +local ctx_verbatim = context.verbatim + +function moduledata.characters.properties.showcatcodes(specification) + + local function range(f,l,quit) + if quit then + ctx_MR() + end + for i=f,l do + ctx_NC() + if quit then + ctx_verbatim("%c .. %c",f,l) + else + ctx_verbatim("%c",i) + end + ctx_NC() context(catcodenames[getcatcode(c_tex,i)]) + ctx_NC() context(catcodenames[getcatcode(c_context,i)]) + ctx_NC() context(catcodenames[getcatcode(c_protect,i)]) + ctx_NC() context(catcodenames[getcatcode(c_text,i)]) + ctx_NC() context(catcodenames[getcatcode(c_verbatim,i)]) + ctx_NC() ctx_NR() + if quit then + ctx_MR() + break + end + end + end + + context.starttabulate { "|c|c|c|c|c|c|" } + ctx_ML() + ctx_NC() ctx_bold("ascii") + ctx_NC() ctx_bold("context") + ctx_NC() ctx_bold("tex") + ctx_NC() ctx_bold("protect") + ctx_NC() ctx_bold("text") + ctx_NC() ctx_bold("verbatim") + ctx_NC() ctx_NR() + ctx_ML() + range(32,47) + range(48,57,true) + range(58,64) + range(65,90,true) + range(91,96) + range(97,122,true) + range(123,126) + ctx_ML() + context.stoptabulate() + +end diff --git a/tex/context/modules/mkiv/s-characters-properties.mkiv b/tex/context/modules/mkiv/s-characters-properties.mkiv new file mode 100644 index 000000000..3c486c39c --- /dev/null +++ b/tex/context/modules/mkiv/s-characters-properties.mkiv @@ -0,0 +1,30 @@ +%D \module +%D [ file=s-characters-properties, +%D version=2016.07.24, % moved here +%D title=\CONTEXT\ Style File, +%D subtitle=Character properties, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[characters-properties] + +\registerctxluafile{s-characters-properties}{} + +\installmodulecommandluasingle \showcharactercatcodes {moduledata.characters.properties.showcatcodes} + +\stopmodule + +\continueifinputfile{s-characters-properties.mkiv} + +\usemodule[art-01] + +\starttext + + \showcharactercatcodes + +\stoptext diff --git a/tex/context/modules/mkiv/s-domotica-settings.lua b/tex/context/modules/mkiv/s-domotica-settings.lua new file mode 100644 index 000000000..a564ddf0e --- /dev/null +++ b/tex/context/modules/mkiv/s-domotica-settings.lua @@ -0,0 +1,165 @@ +if not modules then modules = { } end modules ['s-domotica-settings'] = { + version = 1.001, + comment = "companion to s-domotica-settings.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.domotica = moduledata.domotica or { } +moduledata.domotica.settings = moduledata.domotica.settings or { } + +-- bah, no proper wrapper around value|help + +moduledata.zwave = moduledata.zwave or { } +moduledata.hue = moduledata.hue or { } + +local NC = context.NC +local BC = context.BC +local NR = context.NR + +function moduledata.zwave.show_settings(pattern) + + local function show(setting) + + context.starttabulate { "|r|r|r|r|l|p|" } + BC() context("index") + -- BC() context("genre") + -- BC() context("instance") + BC() context("value") + BC() context("min") + BC() context("max") + BC() context("type") + BC() context("label") + BC() NR() + for value in xml.collected(setting,"/Value") do + local at = value.at + NC() context(at.index) + -- NC() context(at.genre) + -- NC() context(at.instance) + NC() context(at.value) + NC() context(at.min) + NC() context(at.max) + NC() context(at.type) + NC() context.escaped(at.label) + NC() NR() + end + context.stoptabulate() + + end + + if string.find(pattern,"%*") then + + local list = dir.glob(pattern) + local last = nil + + for i=1,#list do + + local filename = list[i] + local root = xml.load(filename) + local settings = xml.all(root,"/Product/CommandClass[@id='112']") + + if settings then + + local brand = file.nameonly(file.pathpart(filename)) + local device = file.nameonly(filename) + + if last ~= brand then + context.startchapter { title = brand } + end + + context.startsection { title = device } + for i=1,#settings do + show(settings[i]) + end + context.stopsection() + + if last ~= brand then + last = brand + context.stopchapter() + end + + end + + end + + else + + local root = xml.load(pattern) + local settings = xml.all(root,"/Product/CommandClass[@id='112']") + + if settings then + for i=1,#settings do + show(settings[i]) + end + end + + end + +end + +function moduledata.hue.show_state(filename) + + require("control-common") + require("control-hue") + + local specification = domotica.hue.check(filename) + local instances = specification.instances + + local ctx_NC, ctx_BC, ctx_NR = context.NC, context.BC, context.NR + + for i=1,#instances do + local known = instances[i].knowndevices + + if #instances > 1 then + context.subject("instance %i",i) + end + + context.starttabulate { "|l|c|c|c|c|c|l|" } + ctx_BC() context("light name") + ctx_BC() context("id") + ctx_BC() context("state") + ctx_BC() context("level") + ctx_BC() context("color") + ctx_BC() context("seen") + ctx_BC() context("internal") + ctx_BC() ctx_NR() + for id, entry in table.sortedhash(known.lights) do + if entry.used then + local state = entry.state + local name = entry.name + local internal = entry.internalname + ctx_NC() context(entry.name) + ctx_NC() context(entry.identifier) + ctx_NC() context(state.on and "on " or "off") + ctx_NC() context(state.brightness or 0) + ctx_NC() context(state.temperature or 0) + ctx_NC() context((state.reachable or entry.reachable) and "yes" or "no ") + ctx_NC() if name == internal then context(name) else context.emphasized(internal) end + ctx_NC() ctx_NR() + end + end + context.stoptabulate() + context.starttabulate { "|l|c|c|c|l|" } + ctx_BC() context("sensor name") + ctx_BC() context("id") + ctx_BC() context("seen") + ctx_BC() context("battery") + ctx_BC() context("internal") + ctx_BC() ctx_NR() + for id, entry in table.sortedhash(known.sensors) do + if entry.used then + local state = entry.state + local name = entry.name + local internal = entry.internalname + ctx_NC() context(name) + ctx_NC() context(entry.identifier) + ctx_NC() context((state.reachable or entry.reachable) and "yes" or "no ") + ctx_NC() context(entry.battery or "") + ctx_NC() if name == internal then context(name) else context.emphasized(internal) end + ctx_NC() ctx_NR() + end + end + context.stoptabulate() + end +end diff --git a/tex/context/modules/mkiv/s-domotica-settings.mkiv b/tex/context/modules/mkiv/s-domotica-settings.mkiv new file mode 100644 index 000000000..d32e53830 --- /dev/null +++ b/tex/context/modules/mkiv/s-domotica-settings.mkiv @@ -0,0 +1,26 @@ +%D \module +%D [ file=s-domotica-setting, +%D version=2016.10.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Domotica Helpers, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module is part of some experiments that I do with gadgets that +%D communicate with zwave, zigbee and other (wireless) protocols used in +%D smart home applications. + +% see mtx-context-domotica.tex for usage example(s) + +\startmodule[domotica-settings] + +\registerctxluafile{s-domotica-settings}{} + +% \installmodulecommandluasingle \showopenzwavesettings {.....} + +\stopmodule diff --git a/tex/context/modules/mkiv/s-fonts-coverage.mkiv b/tex/context/modules/mkiv/s-fonts-coverage.mkiv index c09d943bc..305bb9b7b 100644 --- a/tex/context/modules/mkiv/s-fonts-coverage.mkiv +++ b/tex/context/modules/mkiv/s-fonts-coverage.mkiv @@ -38,6 +38,9 @@ [list={texgyrepagella-regular.otf,texgyretermes-regular.otf,texgyrebonum-regular.otf}, pattern=ogonek] +% \showfontcomparison +% [list={texgyrepagella-regular.otf,texgyretermes-regular.otf,nimbusroman-regular.afm}] + \page % $e=mc²$ ${}²$ $²$ $x²ᶞ$ $x⁽²⁺²⁼²⁺²⁾$ $x²⁺²⁼²⁺²$ $x₅²$ $x²₅²$ diff --git a/tex/context/modules/mkiv/s-fonts-emoji.mkiv b/tex/context/modules/mkiv/s-fonts-emoji.mkiv new file mode 100644 index 000000000..59fdda124 --- /dev/null +++ b/tex/context/modules/mkiv/s-fonts-emoji.mkiv @@ -0,0 +1,331 @@ +%D \module +%D [ file=s-fonts-emoji, +%D version=2017.04.26, +%D title=\CONTEXT\ Style File, +%D subtitle=Emoji Helpers, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startluacode +moduledata.emoji = moduledata.emoji or { } + +local find = string.find +local sortedhash = table.sortedhash +local utfvalues = string.utfvalues + +local context = context + +local traverse_id = node.traverse_id +local glyph_code = nodes.nodecodes.glyph + +local descriptions = fonts.hashes.descriptions +local checkedemoji = fonts.symbols.emoji.checked +local compactemoji = characters.emoji.compact +local resolvedemoji = characters.emoji.resolve +local knownemoji = characters.emoji.known + +local function emojisnippets(name) + local d = descriptions[true] + if d then + local e = resolvedemoji(name) + local s = { } + for b in utfvalues(e) do + if not (b == 0x200D or (b >= 0x1F3FB and b <= 0x1F3FF)) then + local t = { } + s[#s+1] = t + local c = d[b] + if c then + c = c.colors + if c then + for i=1,#c do + t[#t+1] = c[i].slot + end + else + t[#t+1] = b + end + end + end + end + return #s > 0 and s or nil + end +end + +local function emojiglyphs(name) + local d = descriptions[true] + if d then + local e = checkedemoji(name) + local s = { } + for n in traverse_id(glyph_code,e) do + local b = n.char + if not (b == 0x200D or (b >= 0x1F3FB and b <= 0x1F3FF)) then + local t = { } + s[#s+1] = t + local c = d[b] + if c then + c = c.colors + if c then + for i=1,#c do + t[#t+1] = c[i].slot + end + else + t[#t+1] = b + end + end + end + end + nodes.flush_list(e) + return #s > 0 and s or nil + end +end + +characters.emojisnippets = emojisnippets +fonts.symbols.emojiglyphs = emojiglyphs + +function moduledata.emoji.showsnippets(name) + local s = emojisnippets(name) + if s then + local ni = #s + for i=1,ni do + local si = s[i] + local nj = #si + for j=1,nj do + context.WrapEmojiSnippet(i,ni,j,nj,si[j]) + end + end + end +end + +function moduledata.emoji.showglyphs(name) + local s = emojiglyphs(name) + if s then + local ni = #s + for i=1,ni do + local si = s[i] + local nj = #si + for j=1,nj do + context.WrapEmojiSnippet(i,ni,j,nj,si[j]) + end + end + end +end + +function moduledata.emoji.showknown(list) + local hash = knownemoji() + local size = 0 + if list then + list = utilities.parsers.settings_to_array(list) + size = #list + if size == 0 then + list = false + else + for i=1,size do + list[i] = string.escapedpattern(list[i]) + end + end + end + for k, v in sortedhash(hash) do + local okay = true + if find(compactemoji(k),"%-s%-t") then + okay = false + elseif list then + okay = false + for i=1,size do + if find(k,list[i]) then + okay = true + break + end + end + end + if okay then + context("\\WrapEmojiPlusText{%s}{%!tex!}",k,v) + end + end +end + +local function convert(t,k) + local v = { } + for i=1,#k do + local p = k[i] + end + return v +end + +function moduledata.emoji.showpalette(list) + local colorpalettes = fonts.hashes.resources[true].colorpalettes + if colorpalettes then + if list then + list = utilities.parsers.settings_to_hash(list) + if not next(list) then + list = false + end + end + context.starttabulate { "||lp|" } + for i=1,#colorpalettes do + if not list or list[tostring(i)] then + local palette = colorpalettes[i] + context.BC() + context.type(i) + context.NC() + for j=1,#palette do + local p = palette[j] + local r, g, b = p[1]/255, p[2]/255, p[3]/255 + local s = attributes.colors.rgbtogray(r,g,b) + context.WrapEmojiColorEntry(j,s,r,g,b) + end + context.NC() + context.NR() + end + end + context.stoptabulate() + end +end + +\stopluacode + +\unexpanded\def\WrapEmojiPlusText#1#2% + {\dontleavehmode\hbox\bgroup + \tttf % determines em + \hpack to 8\emwidth{\setfontid\scratchcounter#2\hss}% + \hpack to 8\emwidth{\setfontid\scratchcounter\checkedemoji{#1}\hss}% + #1% + \egroup\par} + +\unexpanded\def\ShowEmoji + {\dosingleempty\doShowEmoji} + +\unexpanded\def\doShowEmoji[#1]% + {\begingroup + \scratchcounter\fontid\font + \ctxlua{moduledata.emoji.showknown([[#1]])}% + \endgroup} + +\unexpanded\def\WrapEmojiSnippet#1#2#3#4#5% + {\ifnum#3=\plusone + \par + \dontleavehmode\ruledhbox\bgroup + \fi + \ruledhbox to 2\emwidth{\hss\char#5\hss}% + \ifnum#3=#4\relax + \egroup + \par + \fi} + +\unexpanded\def\ShowEmojiSnippets[#1]% + {\ctxlua{moduledata.emoji.showsnippets("#1")}} + +\unexpanded\def\ShowEmojiGlyphs[#1]% + {\ctxlua{moduledata.emoji.showglyphs("#1")}} + +\unexpanded\def\OverlayEmojiSnippet#1#2#3#4#5% + {\setbox\scratchbox\hbox{\color[trace:#3]{\char#5}}% + \ifnum#3=\plusone + \ifnum#1=\plusone + \dontleavehmode\ruledhbox\bgroup + \fi + \hbox\bgroup + \else + \hskip-\wd\scratchbox + \fi + \box\scratchbox + \ifnum#3=#4\relax + \egroup + \ifnum#1=#2\relax + \egroup + \fi + \fi} + +\unexpanded\def\ShowEmojiSnippetsOverlay[#1]% + {\begingroup + \let\WrapEmojiSnippet\OverlayEmojiSnippet + \ctxlua{moduledata.emoji.showsnippets("#1")}% + \endgroup} + +\unexpanded\def\WrapEmojiColorEntry#1#2#3#4#5% + {\dontleavehmode\hpack\bgroup + \definecolor + [dummy] + [r=#3,g=#4,b=#5]% + \backgroundline + [dummy] + {\setbox\scratchbox\hpack to 2\emwidth{\hss\ifdim#2pt<.5pt\white\fi\ttx#1\hss}% + \ht\scratchbox.8\strutht\dp\scratchbox.6\strutdp\box\scratchbox}% + \egroup + \quad} + +\unexpanded\def\ShowEmojiPalettes + {\dosingleempty\doShowEmojiPalettes} + +\unexpanded\def\doShowEmojiPalettes[#1]% + {\ctxlua{moduledata.emoji.showpalette([[#1]])}} + +% \definefontfeature[bandw:overlay][ccmp=yes,dist=yes] +% \definefontfeature[color:overlay][ccmp=yes,dist=yes,colr=yes] +% %definefontfeature[bandw:svg] [ccmp=yes,dist=yes] +% \definefontfeature[color:svg] [ccmp=yes,dist=yes,svg=yes] +% %definefontfeature[bandw:bitmap] [ccmp=yes,dist=yes,sbix=yes] +% \definefontfeature[color:bitmap] [ccmp=yes,dist=yes,sbix=yes] + +\definefontfeature[seguiemj-cl][color:overlay] +\definefontfeature[seguiemj-bw][bandw:overlay] + +% \definefont[MyEmoji] [seguiemj*seguiemj-bw] +% \definefont[MyEmoji] [seguiemj*seguiemj-cl] +% \definefont[MyEmoji] [emojionecolor-svginot*default,svg] +% \definefont[MyEmoji] [emojionemozilla*default,overlay] +% \definefont[MyEmoji] [applecoloremoji*default,bitmap] + +% \definecolor[trace:1][s=0,t=.5,a=1] +% \definecolor[trace:2][s=0,t=.5,a=1] +% \definecolor[trace:3][s=0,t=.5,a=1] +% \definecolor[trace:4][s=0,t=.5,a=1] +% \definecolor[trace:5][s=0,t=.5,a=1] +% \definecolor[trace:6][s=0,t=.5,a=1] + +\continueifinputfile{s-fonts-emoji.mkiv} + +\starttext + +\start + +\definedfont[seguiemj*seguiemj-cl] + +\ShowEmojiSnippets + [family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone] + +\ShowEmojiSnippetsOverlay + [family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone] + +\ShowEmojiGlyphs + [family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone] + +\page + +\ShowEmoji[^man] + +\page + +\definecolor[emoji-base][r=.4] +\definecolor[emoji-gray][s=.5,t=.5,a=1] + +\definefontcolorpalette + [emoji-gray] + [emoji-base,emoji-gray] + +\definefontfeature[seguiemj-cl][ccmp=yes,dist=yes,colr=emoji-gray] + +\definedfont[seguiemj*seguiemj-cl] + +\ShowEmoji + +\page + +\ShowEmojiPalettes[1] + +\stop + +\stoptext diff --git a/tex/context/modules/mkiv/s-fonts-features.lua b/tex/context/modules/mkiv/s-fonts-features.lua index 0a7cf8b13..6f4032948 100644 --- a/tex/context/modules/mkiv/s-fonts-features.lua +++ b/tex/context/modules/mkiv/s-fonts-features.lua @@ -13,6 +13,10 @@ moduledata.fonts.features = moduledata.fonts.features or { } local sortedhash = table.sortedhash +local v_yes = interfaces.variables.yes +local v_no = interfaces.variables.no +local c_name = interfaces.constants.name + local NC, NR, bold = context.NC, context.NR, context.bold function moduledata.fonts.features.showused(specification) @@ -49,12 +53,12 @@ function moduledata.fonts.features.showused(specification) elseif rawget(descriptions,feature) then NC() context(feature) NC() context("+") -- extra - NC() context(descriptions[feature]) + NC() context.escaped(descriptions[feature]) done = true elseif rawget(features,feature) then NC() context(feature) NC() -- otf - NC() context(features[feature]) + NC() context.escaped(features[feature]) done = true else NC() context(feature) @@ -83,6 +87,51 @@ local function collectkerns(tfmdata,feature) local lookuphash = resources.lookuphash local feature = feature or "kern" if sequences then + + if true then + + for i=1,#sequences do + local sequence = sequences[i] + if sequence.features and sequence.features[feature] then + local steps = sequence.steps + for i=1,#steps do + local step = steps[i] + local format = step.format + for unicode, hash in table.sortedhash(step.coverage) do + local kerns = combinations[unicode] + if not kerns then + kerns = { } + combinations[unicode] = kerns + end + for otherunicode, kern in table.sortedhash(hash) do + if format == "pair" then + local f = kern[1] + local s = kern[2] + if f then + if s then + -- todo + else + if not kerns[otherunicode] and f[3] ~= 0 then + kerns[otherunicode] = f[3] + end + end + elseif s then + -- todo + end + elseif format == "kern" then + if not kerns[otherunicode] and kern ~= 0 then + kerns[otherunicode] = kern + end + end + end + end + end + end + end + end + + else -- old loader + for i=1,#sequences do local sequence = sequences[i] if sequence.features and sequence.features[feature] then @@ -107,7 +156,9 @@ local function collectkerns(tfmdata,feature) end end end + end + return combinations end @@ -142,6 +193,7 @@ function moduledata.fonts.features.showallkerns(specification) local tfmdata = fonts.hashes.identifiers[id] local allkerns = collectkerns(tfmdata) local characters = tfmdata.characters + local hfactor = tfmdata.parameters.hfactor if next(allkerns) then for first, pairs in sortedhash(allkerns) do context.par() @@ -150,7 +202,7 @@ function moduledata.fonts.features.showallkerns(specification) -- if not kerns and pairs[second] then -- -- weird -- end - showkernpair(first,kern,second,0) + showkernpair(first,kern*hfactor,second) end context.par() end @@ -159,3 +211,22 @@ function moduledata.fonts.features.showallkerns(specification) context.par() end end + +function moduledata.fonts.features.showfeatureset(specification) + specification = interfaces.checkedspecification(specification) + local name = specification[c_name] + if name then + local s = fonts.specifiers.contextsetups[name] + if s then + local t = table.copy(s) + t.number = nil + if t and next(t) then + context.starttabulate { "|T|T|" } + for k, v in sortedhash(t) do + NC() context(k) NC() context(v == true and v_yes or v == false and v_no or tostring(v)) NC() NR() + end + context.stoptabulate() + end + end + end +end diff --git a/tex/context/modules/mkiv/s-fonts-features.mkiv b/tex/context/modules/mkiv/s-fonts-features.mkiv index b81b53a71..2dca059ff 100644 --- a/tex/context/modules/mkiv/s-fonts-features.mkiv +++ b/tex/context/modules/mkiv/s-fonts-features.mkiv @@ -18,12 +18,13 @@ \installmodulecommandluasingle \showusedfeatures {moduledata.fonts.features.showused} \installmodulecommandluasingle \showallkerns {moduledata.fonts.features.showallkerns} \installmodulecommandluasingle \showbasekerns {moduledata.fonts.features.showbasekerns} +\installmodulecommandluasingle \showfeatureset {moduledata.fonts.features.showfeatureset} -\def\kernpairheight{\strutheight} -\def\kernpairdepth {\strutdepth} +\def\kernpairheight{.8\strutht} +\def\kernpairdepth {.8\strutdp} \def\kernpairwidth {\onepoint} -\unexpanded\def\showkernpair#1#2#3% first second kern +\unexpanded\def\showkernpair#1#2#3% first kern second {\dontleavehmode \hbox \bgroup \scratchdimen#2\scaledpoint diff --git a/tex/context/modules/mkiv/s-fonts-missing.lua b/tex/context/modules/mkiv/s-fonts-missing.lua index 9a75676a9..7db5c2fb8 100644 --- a/tex/context/modules/mkiv/s-fonts-missing.lua +++ b/tex/context/modules/mkiv/s-fonts-missing.lua @@ -10,8 +10,7 @@ moduledata.fonts = moduledata.fonts or { } moduledata.fonts.missing = moduledata.fonts.missing or { } local function legend(id) - local c = fonts.hashes.identifiers[id] - local privates = c.properties.privates + local privates = fonts.helpers.getprivates(id) if privates then local categories = table.swapped(fonts.loggers.category_to_placeholder) context.starttabulate { "|c|l|" } diff --git a/tex/context/modules/mkiv/s-fonts-shapes.lua b/tex/context/modules/mkiv/s-fonts-shapes.lua index 8f872e4bc..ebdf04c22 100644 --- a/tex/context/modules/mkiv/s-fonts-shapes.lua +++ b/tex/context/modules/mkiv/s-fonts-shapes.lua @@ -113,11 +113,8 @@ local function showglyphshape(specification) local tfmdata = fontdata[id] local charnum = tonumber(specification.character) if not charnum then - charnum = fonts.helpers.nametoslot(n) + charnum = fonts.helpers.nametoslot(specification.character) end - context.start() - context.dontleavehmode() - context.obeyMPboxdepth() local characters = tfmdata.characters local descriptions = tfmdata.descriptions local parameters = tfmdata.parameters @@ -130,6 +127,9 @@ local function showglyphshape(specification) local width, italic = (d.width or 0)*factor, (d.italic or 0)*factor local top_accent, bot_accent = (d.top_accent or 0)*factor, (d.bot_accent or 0)*factor local anchors, math = d.anchors, d.math + context.start() + context.dontleavehmode() + context.obeyMPboxdepth() context.startMPcode() context("numeric lw ; lw := .125bp ;") context("pickup pencircle scaled lw ;") @@ -143,7 +143,7 @@ local function showglyphshape(specification) if #v > 0 then local l = { } for kk, vv in ipairs(v) do - local h, k = vv.height, vv.kern + local h, k = vv.height or 0, vv.kern or 0 if h and k then l[#l+1] = formatters["((%s,%s) shifted (%s,%s))"](xsign*k*factor,ysign*h*factor,dx,dy) end @@ -160,7 +160,7 @@ local function showglyphshape(specification) if #v > 0 then local l = { } for kk, vv in ipairs(v) do - local h, k = vv.height, vv.kern + local h, k = vv.height or 0, vv.kern or 0 if h and k then l[#l+1] = formatters["((%s,%s) shifted (%s,%s))"](xsign*k*factor,ysign*h*factor,dx,dy) end @@ -171,7 +171,7 @@ local function showglyphshape(specification) context('label.%s("\\type{%s}",%s shifted (0,2bp)) ;',loc,txt,l[1]) end for kk, vv in ipairs(v) do - local h, k = vv.height, vv.kern + local h, k = vv.height or 0, vv.kern or 0 if h and k then context('label.top("(%s,%s)",%s shifted (0,-2bp));',k,h,l[kk]) end @@ -183,13 +183,13 @@ local function showglyphshape(specification) if kerns then for _, slant in ipairs { slant_1, slant_2 } do for k,v in pairs(kerns) do - if k == "top_right" then + if k == "topright" then slant(v,width+italic,0,k,1,1,"top","ulft") - elseif k == "bottom_right" then + elseif k == "bottomright" then slant(v,width,0,k,1,1,"bot","lrt") - elseif k == "top_left" then + elseif k == "topleft" then slant(v,0,0,k,-1,1,"top","ulft") - elseif k == "bottom_left" then + elseif k == "bottomleft" then slant(v,0,0,k,-1,1,"bot","lrt") end end @@ -257,6 +257,7 @@ local function showglyphshape(specification) context("setbounds currentpicture to boundingbox currentpicture enlarged 1bp ;") context("currentpicture := currentpicture scaled 8 ;") context.stopMPcode() + context.stop() -- elseif c then -- lastdata, lastunicode = nil, nil -- local factor = (7200/7227)/65536 @@ -290,10 +291,9 @@ local function showglyphshape(specification) -- context("currentpicture := currentpicture scaled 8 ;") -- context.stopMPcode() else - lastdata, lastunicode = nil, nil - context("no such shape: 0x%05X",charnum) + -- lastdata, lastunicode = nil, nil + -- context("no such shape: 0x%05X",charnum) end - context.stop() end moduledata.fonts.shapes.showglyphshape = showglyphshape diff --git a/tex/context/modules/mkiv/s-fonts-shapes.mkiv b/tex/context/modules/mkiv/s-fonts-shapes.mkiv index c1e9d61d2..4a0377ada 100644 --- a/tex/context/modules/mkiv/s-fonts-shapes.mkiv +++ b/tex/context/modules/mkiv/s-fonts-shapes.mkiv @@ -11,12 +11,14 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. +%D I will redo this module (using outlines). + \startmodule[fonts-shapes] \registerctxluafile{s-fonts-shapes}{} \installmodulecommandluasingle \showfontshapes {moduledata.fonts.shapes.showlist} -\installmodulecommandluasingle \showglyphshape {moduledata.fonts.shapes.showglypshape} +\installmodulecommandluasingle \showglyphshape {moduledata.fonts.shapes.showglyphshape} \installmodulecommandluatwo \showlastglyphshapefield {moduledata.fonts.shapes.showlastglyphshapefield} \installmodulecommandluasingle \showallglyphshapes {moduledata.fonts.shapes.showallglypshapes} @@ -107,9 +109,10 @@ % \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x1D45D}\stopTEXpage % \page - % \showallglyphshapes[name=name:cambria-math,size=100bp] +\showallglyphshapes[name=name:cambria-math,size=100bp] % \showallglyphshapes[name=name:dejavuserif,size=100bp] -\showallglyphshapes[name=file:brill.otf,size=100bp] +% \showallglyphshapes[name=file:brill.otf,size=100bp] +% \showallglyphshapes[name=file:minionmath-regular.otf,size=100bp] \stoptext diff --git a/tex/context/modules/mkiv/s-fonts-variable.lua b/tex/context/modules/mkiv/s-fonts-variable.lua new file mode 100644 index 000000000..43f5f0d3d --- /dev/null +++ b/tex/context/modules/mkiv/s-fonts-variable.lua @@ -0,0 +1,313 @@ +if not modules then modules = { } end modules ['s-fonts-variable'] = { + version = 1.001, + comment = "companion to s-fonts-variable.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.fonts = moduledata.fonts or { } +moduledata.fonts.variable = moduledata.fonts.variable or { } + +local format = string.format +local stripstring = string.nospaces +local lower = string.lower +local rep = string.rep + +local context = context +local NC, NR, HL, ML = context.NC, context.NR, context.HL, context.ML +local bold, monobold, mono, formattedmono = context.bold, context.monobold, context.mono, context.formatted.mono + +local show_glyphs = false trackers.register("modules.fonts.variables.glyphs", function(v) show_glyphs = v end) +local show_kerns = false trackers.register("modules.fonts.variables.kerns", function(v) show_kerns = v end) + +function moduledata.fonts.variable.showvariations(specification) + + specification = interfaces.checkedspecification(specification) + + local fontfile = specification.font + local maximum = tonumber(specification.max) or 0xFFFF + local fontname = format("testfont-%s",i) + local fontsize = tex.dimen.bodyfontsize + if not fontfile then + return + end + local id, fontdata = fonts.definers.define { + name = fontfile, + -- size = fontsize, + cs = fontname, + } + + if not fontdata then + context.type("no font with name %a found",fontname) + return + end + + local resources = fontdata.resources + + if not resources then + return + end + + local variabledata = resources.variabledata or { } + +-- if not variabledata then +-- return +-- end + +if not fontdata.shared.rawdata.metadata.fullname then + fontdata.shared.rawdata.metadata.fullname = fontdata.shared.rawdata.metadata.fontname +end + + context.starttitle { title = fontdata.shared.rawdata.metadata.fullname } + + local parameters = fontdata.parameters + + context.startsubject { title = "parameters" } + if parameters then + context.starttabulate { "|||" } + NC() monobold("ascender") NC() context("%p",parameters.ascender) NC() NR() + NC() monobold("descender") NC() context("%p",parameters.descender) NC() NR() + NC() monobold("emwidth") NC() context("%p",parameters.em) NC() NR() + NC() monobold("exheight") NC() context("%p",parameters.ex) NC() NR() + NC() monobold("size") NC() context("%p",parameters.size) NC() NR() + NC() monobold("slant") NC() context("%s",parameters.slant) NC() NR() + NC() monobold("space") NC() context("%p",parameters.space) NC() NR() + NC() monobold("shrink") NC() context("%p",parameters.spaceshrink) NC() NR() + NC() monobold("stretch") NC() context("%p",parameters.spacestretch) NC() NR() + NC() monobold("units") NC() context("%s",parameters.units) NC() NR() + context.stoptabulate() + else + context("no parameters") + end + context.stopsubject() + + local features = fontdata.shared.rawdata.resources.features + + context.startsubject { title = "features" } + if features then + local function f(g) + if g then + local t = table.sortedkeys(g) + local n = 0 + for i=1,#t do + if #t[i] <= 4 then + n = n + 1 + t[n] = t[i] + end + end + return table.concat(t," ",1,n) + end + end + context.starttabulate { "||p|" } + NC() monobold("gpos") NC() mono(f(features.gpos)) NC() NR() + NC() monobold("gsub") NC() mono(f(features.gsub)) NC() NR() + context.stoptabulate() + else + context("no features") + end + context.stopsubject() + + local designaxis = variabledata.designaxis + + context.startsubject { title = "design axis" } + if designaxis then + context.starttabulate { "||||c|c|c|c|c|" } + NC() bold("tag") + NC() bold("name") + NC() bold("variant") + NC() bold("flags") + NC() bold("value") + NC() bold("min") + NC() bold("max") + NC() bold("link") + NC() NR() + HL() + for k=1,#designaxis do + local axis = designaxis[k] + local tag = axis.tag + local name = axis.name + local variants = axis.variants + local first = variants and variants[1] + if first then + local haslimits = first.maximum + local haslink = first.link + for i=1,#variants do + local variant = variants[i] + NC() monobold(tag) + NC() context(name) + NC() context(variant.name) + NC() formattedmono("0x%04x",variant.flags) + NC() context(variant.value) + NC() context(variant.minimum or "-") + NC() context(variant.maximum or "-") + NC() context(variant.link or "-") + NC() NR() + tag = nil + name = nil + end + end + end + context.stoptabulate() + else + context("no design axis defined (no \\type{stat} table)") + end + context.stopsubject() + + local axis = variabledata.axis + local instances = variabledata.instances + local list = { } + + context.startsubject { title = "axis" } + if axis then + context.starttabulate { "|||c|c|c|" } + NC() bold("tag") + NC() bold("name") + NC() bold("min") + NC() bold("def") + NC() bold("max") + NC() NR() + HL() + for k=1,#axis do + local a = axis[k] + NC() monobold(a.tag) + NC() context(a.name) + NC() context(a.minimum) + NC() context(a.default) + NC() context(a.maximum) + NC() NR() + list[#list+1] = a.tag + end + context.stoptabulate() + else + context("no axis defined, incomplete \\type{fvar} table") + end + context.stopsubject() + + local collected = { } + + context.startsubject { title = "instances" } + if not instances or #instances == 0 or not list or #list == 0 then + context("no instances defined, incomplete \\type{fvar}/\\type{stat} table") + else + if #axis > 8 then + context.start() + context.switchtobodyfont { "small" } + if #axis > 12 then + context.switchtobodyfont { "small" } + end + end + context.starttabulate { "||" .. rep("c|",#list) .. "|" } + NC() + for i=1,#list do + NC() monobold(list[i]) + end + NC() + local fullname = lower(stripstring(fontdata.shared.rawdata.metadata.fullname)) + formattedmono("%s*",fullname) + NC() NR() + ML() + for k=1,#instances do + local i = instances[k] + NC() monobold(i.subfamily) + local values = i.values + local hash = { } + for k=1,#values do + local v = values[k] + hash[v.axis] = v.value + end + for i=1,#list do + NC() context(hash[list[i]]) + end + NC() + local instance = lower(stripstring(i.subfamily)) + mono(instance) + collected[#collected+1] = fullname .. instance + NC() NR() + end + context.stoptabulate() + if #axis > 8 then + context.stop() + end + end + context.stopsubject() + + local sample = specification.sample + + for i=1,#collected do + + local instance = collected[i] + context.startsubject { title = instance } + context.start() + context.definedfont { "name:" .. instance .. "*default" } + context.start() + if show_glyphs then + context.showglyphs() + end + if show_kerns then + context.showfontkerns() + end + if sample and sample ~= "" then + context(sample) + else + context.input("zapf.tex") + end + context.stop() + context.blank { "big,samepage"} + context.showfontspacing() + context.par() + context.stop() + context.stopsubject() + + if i > maximum then + context.startsubject { title = "And so on" } + context("no more than %i instances are shown",maximum) + context.par() + context.stopsubject() + break + end + end + + -- local function showregions(tag) + -- + -- local regions = variabledata[tag] + -- + -- context.startsubject { title = tag } + -- if regions then + -- context.starttabulate { "|r|c|r|r|r|" } + -- NC() bold("n") + -- NC() bold("axis") + -- NC() bold("start") + -- NC() bold("peak") + -- NC() bold("stop") + -- NC() NR() + -- HL() + -- local designaxis = designaxis or axis + -- for i=1,#regions do + -- local axis = regions[i] + -- for j=1,#axis do + -- local a = axis[j] + -- NC() monobold(i) + -- NC() monobold(designaxis[j].tag) + -- NC() context("%0.3f",a.start) + -- NC() context("%0.3f",a.peak) + -- NC() context("%0.3f",a.stop) + -- NC() NR() + -- i = nil + -- end + -- end + -- context.stoptabulate() + -- else + -- context("no %s defined",tag) + -- end + -- context.stopsubject() + -- + -- end + -- + -- showregions("gregions") + -- showregions("mregions") + -- showregions("hregions") + + context.stoptitle() + +end diff --git a/tex/context/modules/mkiv/s-fonts-variable.mkiv b/tex/context/modules/mkiv/s-fonts-variable.mkiv new file mode 100644 index 000000000..64348b324 --- /dev/null +++ b/tex/context/modules/mkiv/s-fonts-variable.mkiv @@ -0,0 +1,111 @@ +%D \module +%D [ file=s-fonts-variable, +%D version=2017.02.18, +%D title=\CONTEXT\ Style File, +%D subtitle=Show Variable Font Properties , +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% begin info +% +% title : variable information (experimental) +% +% comment : variable fonts contain extra information styles, axis, regions +% status : experimental, used for luatex testing +% +% end info + +\startmodule[fonts-variable] + +\registerctxluafile{s-fonts-variable}{} + +\installmodulecommandluasingle \showfontvariations {moduledata.fonts.variable.showvariations} + +\unexpanded\def\showfontspacing + {\begingroup + \scratchskip \interwordspace plus \interwordstretch minus \interwordshrink + \normalexpanded{\hpack\bgroup + \tttf + sp: \the\scratchskip \hskip\emwidth + es: \the\extraspace\hskip\emwidth + ex: \the\exheight \hskip\emwidth + em: \the\emwidth \hskip\emwidth + \egroup}% + \endgroup} + +\stopmodule + +\continueifinputfile{s-fonts-variable.mkiv} + +\usemodule[art-01] + +\setuphead[section][before={\testpage[5]\blank[2*big]}] + +\enabletrackers[modules.fonts.variables.glyphs] +\enabletrackers[modules.fonts.variables.kerns] + +\starttext + + \startbuffer[zycon] + \char008986\relax\quad + \char009728\relax\quad + \char010031\relax\quad + \char010143\relax\quad + \char011044\relax\quad + \char127773\relax\quad + \char127989\relax\quad + \char128008\relax\quad + \char128021\relax\quad + \char128034\relax\quad + \char128161\relax\quad + \char128274\relax\quad + \char128347\relax\quad + \char128400\relax\quad + \char128692\relax\quad + \char129417\relax\quad + \char129422\relax\quad + \char983040\relax\par + \stopbuffer + +% \showfontvariations +% [font=file:VotoSerifGX.ttf, +% max=6] + + \showfontvariations + [font=file:adobevfprototype.otf] + + \showfontvariations + [font=file:avenirnextvariable.ttf] + + \showfontvariations + [font=file:DecoVar-VF.ttf] + + \showfontvariations + [font=file:VotoSerifGX.ttf, + max=15] + + \showfontvariations + [font=file:Selawik-Variable.ttf] + + \showfontvariations + [font=file:LibreFranklinGX-Romans.ttf] + + \showfontvariations + [font=file:Zycon.ttf, + sample={\getbuffer[zycon]}] + + % \showfontvariations + % [font=file:kairossansvariable.ttf] + + % \showfontvariations + % [font=file:sourcecode-regular.otf] + + % \showfontvariations + % [font=file:AmstelvarAlpha-VF.ttf] + +\stoptext diff --git a/tex/context/modules/mkiv/s-inf-01.mkvi b/tex/context/modules/mkiv/s-inf-01.mkvi index 2c0c1681e..2fda9997a 100644 --- a/tex/context/modules/mkiv/s-inf-01.mkvi +++ b/tex/context/modules/mkiv/s-inf-01.mkvi @@ -39,7 +39,7 @@ "colo%-pan.tex", ".*test.*" } local types = { - "tex", "mkii", "mkiv", "mkvi", "lua" + "tex", "mkii", "mkiv", "mkvi", "lua", -- "mpiv" } local patterns = { "^([a-z][a-z][a-z][a-z])%-[a-z0-9%-]+%.[a-z]+", @@ -150,7 +150,7 @@ for k, v in table.sortedpairs(what) do local c = what == size and comp[k] or nope context.NC() - context("%s~%s~~%s~~%s", + context("\\bf %s~%s~~%s~~%s", (used.mkii[k] and "ii") or "~~", (used.mkiv[k] and "iv") or "~~", (used.mkvi[k] and "vi") or "~~", @@ -197,7 +197,7 @@ \starttexdefinition Top #what#fraction#total#bigones \hbox to 5em{\hss#total}% \enspace - \hbox {#what\ifnum#total=#bigones\else~#bigones\rlap{~+}\fi\hss}% + \hbox {{\bf#what}\ifnum#total=#bigones\else~#bigones\rlap{~+}\fi\hss}% \stoptexdefinition \starttexdefinition Bar #color#size#nobigones#fraction @@ -225,19 +225,26 @@ \stoptexdefinition \starttexdefinition Up #color#width - \scratchdimen#width\dimexpr 16em\relax +% \scratchdimen#width\dimexpr 16em\relax + \scratchdimen#width\dimexpr 40em\relax \ifdim\scratchdimen=\zeropoint \kern1em + \else\ifdim\scratchdimen>13em + \blackrule[color=bar:#color,height=15em,width=1em]% + \hskip-1.1em + \blackrule[color=white,height=14em,width=1.2em]% + \hskip-1.1em + \blackrule[color=bar:#color,height=13em,width=1em]% \else \ifdim\scratchdimen<\onepoint \scratchdimen\onepoint \fi \blackrule[color=bar:#color,height=\scratchdimen,width=1em]% - \fi + \fi\fi \stoptexdefinition \starttexdefinition Show #title#how#what \startTEXpage[offset=1em,width=fit] \hbox{\tttf\strut\currentdate~-~#title} - \par + \blank[line] \ctxlua{document.context_state_\number#how("#what")} \stopTEXpage \stoptexdefinition @@ -249,7 +256,7 @@ {The number of files used in ConTeXt (base modules and styles).} {1}{number} \Show - {The size of (core) files used in ConTeXt (- indicates exclusion of large data files; + indicates inclusion of large data files; comment and spaces removed.)} + {The size of (core) files used in ConTeXt (- : large data files excluded; + : large data files included; comment and spaces removed)} {1}{size} \Show {The relative number of files used in ConTeXt (tex, mkii, mkiv, mkvi, lua).} diff --git a/tex/context/modules/mkiv/s-inf-03.mkiv b/tex/context/modules/mkiv/s-inf-03.mkiv index a253bed77..d2acb7341 100644 --- a/tex/context/modules/mkiv/s-inf-03.mkiv +++ b/tex/context/modules/mkiv/s-inf-03.mkiv @@ -16,7 +16,7 @@ \definefont [TitlePageFont] - [MonoBold at 15pt] + [MonoBold at 14pt] \setupbodyfont [tt,8pt] @@ -25,7 +25,7 @@ \definefont [TitlePageFont] - [MonoBold at 18pt] + [MonoBold at 17pt] \setupbodyfont [tt] @@ -158,13 +158,11 @@ local upper = string.upper local skipglobal = table.tohash { "_G", "_M", "_ENV", "", "context", "modules", "global", "arg", "utf", 1, - "_ptbs_", "_pcol_", "_plib_", "_clib_", "_tlib_", - "kpse", "commands", + "kpse", "commands", "ffi", } local skipkeys = table.tohash { - "_pcol_", "_plib_", "_clib_", "_tlib_", "_bpnf_", "_ptbs_", - "_cldf_", "_cldn_", "_cldo_", + -- "_cldf_", "_cldn_", "_cldo_", "_clmb_", "_clme_", "_clmm_", "_clmn_", "_clma_", "_clmh_", "_G", "_M", "_ENV", "", -- "global", "shortcuts", @@ -215,11 +213,10 @@ local function childtables(key,tab,handler,depth) if marked(v) then t = "data" handler(s,t,depth) + elseif done[v] then + -- logs.report("inf-03","key %a in %a already done",k,v) else -if done[v] then - -- logs.report("inf-03","key %a in %a already done",k,v) -else - done[v] = true + done[v] = true handler(s,t,depth) if variant == 3 then childtables(false,v,handler,depth+1) @@ -229,7 +226,6 @@ else childtables(s,v,handler,depth+1) end end -end else handler(s,t,depth) end @@ -252,7 +248,7 @@ end local function show(title,subtitle,alias,builtin,t,lib,libcolor,glo,glocolor,mark,obsolete) -- todo: table as argument --- print(title,subtitle,alias,builtin,t,lib,libcolor,glo,glocolor,mark,obsolete) + -- print(title,subtitle,alias,builtin,t,lib,libcolor,glo,glocolor,mark,obsolete) local keys = sortedkeys(t) -- no sorted_pairs if #keys > 0 then local fulltitle = title @@ -269,7 +265,7 @@ local function show(title,subtitle,alias,builtin,t,lib,libcolor,glo,glocolor,mar end context.startcolumns { n = 2 } context.starttabulate { "|||" } - local t_obsolete = t.obsolete + local t_obsolete = rawget(t,"obsolete") -- tricky a t.obsolete fails if type(t_obsolete) ~= "table" then t_obsolete = nil end diff --git a/tex/context/modules/mkiv/s-languages-frequencies.lua b/tex/context/modules/mkiv/s-languages-frequencies.lua index 16213a412..4ff5cfe03 100644 --- a/tex/context/modules/mkiv/s-languages-frequencies.lua +++ b/tex/context/modules/mkiv/s-languages-frequencies.lua @@ -31,3 +31,7 @@ function moduledata.languages.frequencies.showlist(specification) end context.stoptabulate() end + +-- function MP.frqc(language,slot) +-- mp.print(languages.frequencies.getdata(language).frequencies[slot]) +-- end diff --git a/tex/context/modules/mkiv/s-languages-hyphenation.lua b/tex/context/modules/mkiv/s-languages-hyphenation.lua index 971ca3d8f..6d3cf3d3e 100644 --- a/tex/context/modules/mkiv/s-languages-hyphenation.lua +++ b/tex/context/modules/mkiv/s-languages-hyphenation.lua @@ -39,6 +39,8 @@ local getdisc = nuts.getdisc local getattr = nuts.getattr local getfont = nuts.getfont local getfield = nuts.getfield +local getlang = nuts.getlang +local setlang = nuts.setlang local setlink = nuts.setlink local setdisc = nuts.setdisc local setfield = nuts.setfield @@ -129,7 +131,7 @@ local function getlanguage(head,l,left,right) local t = { } for n in traverse_by_id(glyph_code,tonut(head)) do t[n] = { - getfield(n,"lang"), + getlang(n), getfield(n,"left"), getfield(n,"right"), } @@ -148,7 +150,7 @@ function moduledata.languages.hyphenation.showhyphens(head) -- somehow assigning -1 fails for n in traverse_by_id(glyph_code,tonut(head)) do cached[n] = { - getfield(n,"lang"), + getlang(n), getfield(n,"left"), getfield(n,"right") } @@ -161,7 +163,7 @@ function moduledata.languages.hyphenation.showhyphens(head) local lmin = s.lefthyphenmin local rmin = s.righthyphenmin for n in next, cached do - setfield(n,"lang",l) + setlang(n,l) setfield(n,"left",lmin) setfield(n,"right",rmin) end @@ -173,7 +175,7 @@ function moduledata.languages.hyphenation.showhyphens(head) mark(head,marked[i],1/16,l/2,l/4,"hyphenation:"..(colorbytag and tags[i] or i)) end for n, d in next, cached do - setfield(n,"lang",d[1]) + setlang(n,d[1]) setfield(n,"left",d[2]) setfield(n,"right",d[3]) end diff --git a/tex/context/modules/mkiv/s-mag-01.mkiv b/tex/context/modules/mkiv/s-mag-01.mkiv new file mode 100644 index 000000000..7191d760c --- /dev/null +++ b/tex/context/modules/mkiv/s-mag-01.mkiv @@ -0,0 +1,505 @@ +%D \module +%D [ file=s-mag-01, +%D version=2016.09.12, % mkiv version of 2002.12.14, +%D title=\CONTEXT\ Style File, +%D subtitle=\CONTEXT\ Magazine Base Style, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This style is used for producing explanationary documents. Don't misuse it for +%D other purposes, since it may confuse users. Don't change the title either, since +%D it provides a way to categorize documents. Numbers are disabled in instances +%D produced outside PRAGMA ADE. +%D +%D The layout setup is such that one has several text areas available: headers and +%D footers, margins and edges as well as the main text area. The surrounding (gray) +%D makes the main page stand out and is suitable for viewing in spread mode. +%D +%D Since this style is under constant construction, messing around with settings +%D will produce unwanted side effects. So, if some feature or settings is needed, +%D let me know. + +% These are reserved for PRAGMA-ADE, don't use them yourself! + +% \setupdocument[main=Tricky] +% \setupdocument[main=Update] +% \setupdocument[main=HOWTO] + +% \setupdocument[main=This Way] % preludes to a/the manual +% \setupdocument[main=A Better Way] % dirty versus clean +% \setupdocument[main=No Way] % how users should not do it +% \setupdocument[main=Your Way] % how users do it +% \setupdocument[main=My Way] % how users do it +% \setupdocument[main=Our Way] % how we do things at pragma +% \setupdocument[main=Their Way] % how to do latex things in context + +\usemodule[narrowtt,scite] + +\definepapersize + [magazine] + [width=\dimexpr\paperwidth-.1\paperwidth\relax, + height=\dimexpr\paperheight-.1\paperheight\relax] + +\setuppapersize + [magazine] + [A4] + +\setupinteractionscreen + [option=doublesided] + +\setupexternalfigures + [location={local,default}] + +\definecolor[OuterColor][s=.3] +\definecolor[InnerColor][s=.8] +\definecolor[MainColor] [s=.2] +\definecolor[TitleColor][s=.9] + +\definecolor[MyRed] [r=.6] +\definecolor[MyGreen][g=.6] +\definecolor[MyBlue] [b=.6] + +\startreusableMPgraphic{middlepaper} + fill OverlayBox + withshademethod "circular" + withshadecenter center (0.5,0.5) + withshadecolors ("InnerColor","OuterColor") ; +\stopreusableMPgraphic + +\startreusableMPgraphic{rightpaper} + fill OverlayBox + withshademethod "circular" + withshadecenter center (0,0.5) + withshadecolors ("InnerColor","OuterColor") ; +\stopreusableMPgraphic + +\startreusableMPgraphic{leftpaper} + fill OverlayBox + withshademethod "circular" + withshadecenter center (1,0.5) + withshadecolors ("InnerColor","OuterColor") ; +\stopreusableMPgraphic + +\startreusableMPgraphic{page} + fill OverlayBox withcolor white ; +\stopreusableMPgraphic + +\startusableMPgraphic{text} + StartPage ; + for i = Header,Text,Footer : + for j = LeftEdge, LeftMargin, Text, RightMargin, RightEdge : + draw Field[i][j] withpen pencircle scaled .5pt ; + endfor ; + endfor ; + StopPage ; + setbounds currentpicture to Field[Text][Text] ; +\stopusableMPgraphic + +\startsetups[paper] + + \doifmodeelse{*makeup} { + \reuseMPgraphic{middlepaper} + } { + \doifoddpageelse { + \reuseMPgraphic{rightpaper} + } { + \reuseMPgraphic{leftpaper}} + } + +\stopsetups + +\defineoverlay[paper] [\setups{paper}] +\defineoverlay[page] [\reuseMPgraphic{page}] +\defineoverlay[text] [\doifmode{frame}{\useMPgraphic{text}}] + +\setupbackgrounds [paper] [background=paper] +\setupbackgrounds [page] [background={page,title}] +\setupbackgrounds [text] [background=text] + +\definelayer + [title] + [state=repeat, + hoffset=-1cm, + voffset=1cm, + width=\paperwidth, + height=\paperheight] + +\setuplayout + [width=middle, + topspace=1.5cm, + height=middle, + header=1.5cm, + footer=1cm, + %grid=yes, + headerdistance=.25cm, + footerdistance=.5cm, + backspace=3cm, + margin=1.5cm, + margindistance=.25cm, + edge=.75cm, + edgedistance=.25cm, + bottomdistance=1.5cm, + bottom=.1\printpaperheight] + +\definelayout + [listing] + [backspace=15mm, + curspace=15mm] + +\definelayout + [makeup] + [topspace=1cm, + backspace=1cm, + header=0pt, + footer=0pt, + bottom=0pt] + +\setuppagenumbering + [alternative=doublesided] + +\setupbodyfont + [pagella,10pt] + +\setuptolerance + [verytolerant,stretch] + +\appendtoks + \setups[papershift]% +\to \beforeeverypage + +\startsetups[papershift] + + \setuppapersize[top=\vskip.5cm,bottom=\vss] + + \doifmodeelse{*makeup} { + \setuppapersize[left=\hfill,right=\hfill] + } { + \doifoddpageelse { + \setuppapersize[right=\hfill] + } { + \setuppapersize[left=\hfill] + } + } + +\stopsetups + +\setupbottomtexts + [\setups{rightbanner}] [] + [] [\setups{leftbanner}] + +\startsetups [leftbanner] + + \definedfont[Regular*default at \the\bottomheight] + + \TitleColor + + \setbox\scratchbox\hbox { + \documentvariable{main} + } + \ht\scratchbox\exheight + \dp\scratchbox\zeropoint + + \definedfont[Regular*default sa 2] + \doifsomething {\documentvariable{number}} { + \doifnot {\documentvariable{number}} {0} { + \#\documentvariable{number} + } + } + \quad + \currentdate + \quad + \scale + [height=.25\bottomheight] + {\box\scratchbox} + \quad + \hbox to 1.5em{\hss\pagenumber\hss} + \quad + \hskip-\backspace + +\stopsetups + +\startsetups [rightbanner] + + \definedfont[Regular*default at \the\bottomheight] + + \TitleColor + + \setbox\scratchbox\hbox { + \documentvariable{main} + } + \ht\scratchbox\exheight + \dp\scratchbox\zeropoint + + \hskip-\backspace + \definedfont[Regular*default sa 2] + \quad + \hbox to 1.5em{\hss\pagenumber\hss} + \quad + \scale + [height=.25\bottomheight] + {\box\scratchbox} + \quad + \currentdate + \quad + \doifmode {atpragma} { + \#\documentvariable{number} + } + +\stopsetups + +\startsetups[titlepage] + + \disablemode[frame] + + \doifmode {atpragma} { + \definecolor[pragmacolor] [r=1,g=.62,b=.06] % (Pantone 138 CV) + \definecolor[OuterColor][.3(\documentvariable{color})] + } + + \setuplayout[makeup] + + \startstandardmakeup[doublesided=no] + + \dontcomplain + + \definelayer + [makeup] + [width=\textwidth, + height=\textheight] + + \setlayerframed [ + makeup + ] [ + corner={left,top}, + location={right,bottom} + ] [ + frame=off, + foregroundcolor=MainColor + ] { + \scale + [width=\makeupwidth] + { + \definedfont[Regular*default sa 10] + \documentvariable{main} + } + } + + \setlayerframed [ + makeup + ] [ + corner={right,top}, + location={left}, + y=.4\textheight + ] [ + frame=off, + foregroundcolor=MainColor, + width=\textwidth, + align=left + ] { + \definedfont[Regular*default sa 2.5] + \setupinterlinespace + \startmode[atpragma] + \strut \ConTeXt\ magazine \#\documentvariable{number}\endgraf + \stopmode + \strut \documentvariable{date} \endgraf + \blank + \strut \documentvariable{title}\endgraf + \doifsomething {\documentvariable{author}} { + \strut \documentvariable{author}\endgraf + } + \doifsomething {\documentvariable{affiliation}} { + \strut \documentvariable{affiliation}\endgraf + } + } + + \setlayerframed [ + makeup + ] [ + corner={right,bottom}, + location={left,top} + ] [ + frame=off, + align=normal, + width=.8\textwidth, + foregroundcolor=MainColor + ] { + \getbuffer[abstract] + } + + \flushlayer[makeup] + + \stopstandardmakeup + + \setuplayout[reset] + +\stopsetups + +\startsetups[cleanup] + + \page + + \setuptexttexts + [margin] + [] [] + +\stopsetups + +\startsetups[listing] + + \page \disablemode[frame] + + \setuptexttexts [][] \setuptexttexts [] + \setupheadertexts[][] \setupheadertexts[source code of this document] + \setupfootertexts[][] \setupfootertexts[] + + \setuplayout[listing] + + \start + + \dontcomplain + + \switchtobodyfont[8pt] + + \scitefile[\jobfilefullname] + + \page + + \stop + + \setuplayout + +\stopsetups + +\startsetups[lastpage] + + \page \disablemode[frame] \page[even] + + \doifoddpageelse { + } { + \setuplayout[makeup] + \startstandardmakeup[doublesided=no,page=] + \stopstandardmakeup + \setuplayout[reset] + } + +\stopsetups + +\startsetups[title] + + \disablemode[frame] + + \setlayerframed [ + title + ] [ + corner={left,top}, + location={left,bottom}, + rotation=90 + ] [ + frame=off, + foregroundcolor=TitleColor + ] { + \definedfont[RegularBold*default sa 2] + \strut\documentvariable{title} + } + + \setlayerframed [ + title + ] [ + corner={right,top}, + rotation=270 + ] [ + frame=off, + foregroundcolor=TitleColor + ] { + \definedfont[RegularBold*default sa 2] + \strut\documentvariable{title} + } + + \doifsomething {\documentvariable{subtitle}} { + \setupheadertexts[\documentvariable{subtitle}] + } + +\stopsetups + +\startbuffer[abstract] + % no abstract +\stopbuffer + +\setuphead + [chapter] + [page=yes, + after={\blank[2*big]}, + color=MainColor, + style=\bfc] + +\setuphead + [section] + [before={\blank[2*big]}, + after=\blank, + color=MainColor, + style=\bfb] + +\setuphead + [subsection] + [before=\blank, + after=, + color=MainColor, + style=\bf] + +\setupwhitespace + [big] + +\definetyping[xtyping] [style=\ttx] +\definetyping[xxtyping][style=\ttxx] + +\definetyping[ntyping] \setuptyping[ntyping][style=\narrowtt] +\definetype [ntype] \setuptype [ntype] [style=\narrowtt] + +\setupdocument + [main={\doifelsemode{atpragma}{This Way}{My Way}}, + %color=pragmacolor, + title={No Title}, + subtitle=, + author={No Author}, + affiliation=, + date={No Date}, + number=0, + before={\setups[titlepage,title]}, + after={\setups[cleanup,listing,lastpage]}] + +\continueifinputfile {s-mag-01.mkiv} + +\startbuffer[abstract] + This is the zero issue of a semi periodical. The associated style can be used + by \CONTEXT\ users to typeset and publish their own issues. +\stopbuffer + +\startdocument + [title={Introduction}, + subtitle={Welcome}, + author={Hans Hagen}, + affiliation=PRAGMA ADE, + date=Januari 2003, + number=0 \MKIV] + +This is the zero issue of a range of \CONTEXT\ related publications, in most +cases short introductions to new functionality. The style may be used by users +for providing similar documents, but preferably not for other purposes, since it +may confuse readers in their expectations. + +We've chosen a layout which is more functional than beautiful. This layout +provides several text areas: headers and footers, margins and edges as well as a +main text area. The surrounding (gray or color) makes the main page (which is +slightly smaller than A4) stand out and is suitable for viewing in spread mode. + +The documents produced at \PRAGMA\ are called {\bf This Way}, user documents gets +the title {\bf My Way}. The \PRAGMA\ issues are numbered. We strongly advise you +not to use the \type {mag-} prefix for your issues, since this may lead to +clashes with files distributed by \PRAGMA. + +\stopdocument diff --git a/tex/context/modules/mkiv/s-math-characters.lua b/tex/context/modules/mkiv/s-math-characters.lua index 8ff3a8660..757e843da 100644 --- a/tex/context/modules/mkiv/s-math-characters.lua +++ b/tex/context/modules/mkiv/s-math-characters.lua @@ -53,8 +53,14 @@ function moduledata.math.characters.showlist(specification) local sorted = { } if type(list) == "string" then sorted = utilities.parsers.settings_to_array(list) + for i=1,#sorted do + sorted[i] = tonumber(sorted[i]) + end elseif type(list) == "table" then sorted = list + for i=1,#sorted do + sorted[i] = tonumber(sorted[i]) + end elseif fillinthegaps then sorted = table.keys(characters) for k, v in next, gaps do diff --git a/tex/context/modules/mkiv/s-math-characters.mkiv b/tex/context/modules/mkiv/s-math-characters.mkiv index 3b273cb6c..e5e0d084f 100644 --- a/tex/context/modules/mkiv/s-math-characters.mkiv +++ b/tex/context/modules/mkiv/s-math-characters.mkiv @@ -56,8 +56,8 @@ \directsetup{s-math-characters:reset} - \unexpanded\def\showmathcharactersstartentry {\blank\begingroup\raggedright} - \unexpanded\def\showmathcharactersstopentry {\endgroup\blank} + \unexpanded\def\showmathcharactersstartentry {\blank\startpacked\raggedright} + \unexpanded\def\showmathcharactersstopentry {\stoppacked\blank} \def\showmathcharactersentryhexdectit##1##2##3% {##1:\space{\char##2}\space\ruledhbox{\char##2}\space##3\par @@ -177,7 +177,7 @@ % \setupbodyfont[stix, 12pt] % \setupbodyfont[xits, 12pt] % \setupbodyfont[lucida, 12pt] - % \setupbodyfont[lucidanova,12pt] + % \setupbodyfont[lucidaot, 12pt] % \setupbodyfont[pagella, 12pt] % \setupbodyfont[bonum, 12pt] diff --git a/tex/context/modules/mkiv/s-math-extensibles.mkiv b/tex/context/modules/mkiv/s-math-extensibles.mkiv index f9ff8547a..cc6fd1b00 100644 --- a/tex/context/modules/mkiv/s-math-extensibles.mkiv +++ b/tex/context/modules/mkiv/s-math-extensibles.mkiv @@ -48,9 +48,9 @@ \def\modulemathextensiblesalternativea#1#2#3% {\NC U+#1 \NC \filledhboxm{\math{\char"#1}} - \NC \hbox{\math{\mathextensible[demo]{"#1}{top}{bottom}}} - \NC \hbox{\math{\mathextensible[demo]{"#1}{}{bottom}}} - \NC \hbox{\math{\mathextensible[demo]{"#1}{top}{}}} + \NC \hbox{\math{\mathstacker[demo]{"#1}{top}{bottom}}} + \NC \hbox{\math{\mathstacker[demo]{"#1}{}{bottom}}} + \NC \hbox{\math{\mathstacker[demo]{"#1}{top}{}}} \NC \nohyphens \veryraggedright #2 \NC\NR} diff --git a/tex/context/modules/mkiv/s-math-repertoire.mkiv b/tex/context/modules/mkiv/s-math-repertoire.mkiv index 230eb513e..91af45dfc 100644 --- a/tex/context/modules/mkiv/s-math-repertoire.mkiv +++ b/tex/context/modules/mkiv/s-math-repertoire.mkiv @@ -13,13 +13,13 @@ \usemodule[s][math-characters] -% context --jit --global --bodyfont=lucidanova --result=math-repertoire-lucidanova s-math-repertoire.mkiv -% context --jit --global --bodyfont=cambria --result=math-repertoire-cambria s-math-repertoire.mkiv -% context --jit --global --bodyfont=xits --result=math-repertoire-xits s-math-repertoire.mkiv -% context --jit --global --bodyfont=modern --result=math-repertoire-modern s-math-repertoire.mkiv -% context --jit --global --bodyfont=pagella --result=math-repertoire-pagella s-math-repertoire.mkiv -% context --jit --global --bodyfont=termes --result=math-repertoire-termes s-math-repertoire.mkiv -% context --jit --global --bodyfont=bonum --result=math-repertoire-bonum s-math-repertoire.mkiv +% context --jit --global --bodyfont=lucidaot --result=math-repertoire-lucidaot s-math-repertoire.mkiv +% context --jit --global --bodyfont=cambria --result=math-repertoire-cambria s-math-repertoire.mkiv +% context --jit --global --bodyfont=xits --result=math-repertoire-xits s-math-repertoire.mkiv +% context --jit --global --bodyfont=modern --result=math-repertoire-modern s-math-repertoire.mkiv +% context --jit --global --bodyfont=pagella --result=math-repertoire-pagella s-math-repertoire.mkiv +% context --jit --global --bodyfont=termes --result=math-repertoire-termes s-math-repertoire.mkiv +% context --jit --global --bodyfont=bonum --result=math-repertoire-bonum s-math-repertoire.mkiv \startmodule[math-repertoire] @@ -473,7 +473,8 @@ % \setupbodyfont[pagella, 12pt] % \setupbodyfont[bonum, 12pt] % \setupbodyfont[schola, 12pt] - \setupbodyfont[dejavu, 12pt] + % \setupbodyfont[dejavu, 12pt] + \setupbodyfont[lucidaot, 12pt] } { diff --git a/tex/context/modules/mkiv/s-pre-17.mkiv b/tex/context/modules/mkiv/s-pre-17.mkiv index 9c46b4ed7..558d5afd2 100644 --- a/tex/context/modules/mkiv/s-pre-17.mkiv +++ b/tex/context/modules/mkiv/s-pre-17.mkiv @@ -52,10 +52,6 @@ \defineoverlay [blowdown] [{\hboxreference[page:\realfolio]{\overlaybutton{page:\realfolio}}}] \defineoverlay [forward] [\overlaybutton{forward}] -\startMPinclusions - input "mp-abck.mpiv" ; -\stopMPinclusions - \startMPpositiongraphic{mppos:connection} path pa, pb, pc ; pair ca, cb ; initialize_box(\MPpos{\MPvar{self}}) ; pa := pxy ; ca := cxy ; diff --git a/tex/context/modules/mkiv/s-present-balls.mkiv b/tex/context/modules/mkiv/s-present-balls.mkiv new file mode 100644 index 000000000..6774b8340 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-balls.mkiv @@ -0,0 +1,194 @@ +%D \module +%D [ file=s-present-balls, % s-pre-15, +%D version=1999.09.01, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Balls, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[present-balls] + +%D This is one of the styles I made for the presentation on the \NTS\ project at +%D Euro\TeX\ 1998. You need balls to let \TEX\ typeset graphics, but this style +%D demonstrates that it can be done. +%D +%D This presentation is meant for presentations that build up an idea stepwise. +%D +%D \starttyping +%D \TitlePage{Do you know \TEX ?} +%D +%D \StartIdea +%D \StartItem We use \TEX\ for typesetting \unknown \StopItem +%D \StartItem mathematical text \unknown \StopItem +%D \StartItem but also for text that has no math \unknown \StopItem +%D \StartItem or presentations like this \unknown \StopItem +%D \StartItem and whatever you can come up with! \StopItem +%D \StopIdea +%D \stoptyping +%D +%D The basic layout is rather simple and used as much of the screen as possible. + +\setuppapersize + [S6][S6] + +\setuplayout + [backspace=25pt, + topspace=25pt, + width=middle, + height=middle, + header=0pt, + footer=0pt] + +\setupinteraction + [state=start, + display=new, + color=LineColor, + contrastcolor=LineColor, + click=no] + +\setupinteractionscreen + [option=max] + +\startmode[asintended,atpragma] \setupbodyfont[lucidaot] \stopmode + +\setupbodyfont[14.4pt] + +%D We use a lot of color. You can remap them if you want different ones. The ideas +%D circulate over the colors. + +\definecolor[TextColor][s=.8] +\definecolor[PageColor][s=.6] +\definecolor[LineColor][s=.4] + +\definecolor[red] [r=.4] \definecolor[cyan] [g=.4,b=.4] +\definecolor[green][g=.4] \definecolor[magenta][r=.4,b=.4] +\definecolor[blue] [b=.4] \definecolor[yellow] [r=.4,g=.4] + +\definecolor[linecolor 1][red] \definecolor[linecolor 5][cyan] +\definecolor[linecolor 2][green] \definecolor[linecolor 6][magenta] +\definecolor[linecolor 3][blue] \definecolor[linecolor 4][yellow] + +%D We use variables to make sure that the graphics are reused but unique. + +\setupMPvariables[pageframe][pagecolor=PageColor,linecolor=LineColor] +\setupMPvariables[textframe][textcolor=TextColor,linecolor=LineColor] + +\setupbackgrounds + [page] + [background={pageframe,nextpage}] + +\defineoverlay [pageframe] [\uniqueMPgraphic{pageframe}] +\defineoverlay [textframe] [\uniqueMPgraphic{textframe}] +\defineoverlay [nextpage] [\overlaybutton{forward}] + +\startuniqueMPgraphic{pageframe}{pagecolor,linecolor} + path p ; p := fullsquare xyscaled (OverlayWidth,OverlayHeight) ; + pickup pencircle scaled 10pt ; + fill p withcolor \MPvar{pagecolor} ; + draw p withcolor \MPvar{linecolor} ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{textframe}{textcolor,linecolor} + path p ; p := fullcircle xyscaled (OverlayWidth,OverlayHeight) ; + pickup pencircle scaled 10pt ; + fill p withcolor \MPvar{textcolor} ; + draw p withcolor \MPvar{linecolor} ; +\stopuniqueMPgraphic + +%D The rest of the file implements the nasty part: typesetting text embedded in a +%D graphic. The text is collected in a box so that we can reuse it. + +\newbox \CollectedIdeas +\newcount\CurrentTopic + +\unexpanded\def\StartItem + {\setbox\CollectedIdeas=\hbox\bgroup + \ifdim\wd\CollectedIdeas>\zeropoint + \unhbox\CollectedIdeas + \hskip25pt + \fi + \setbox\scratchbox=\hbox\bgroup + \framed + [width=160pt, + height=160pt, + align=middle, + frame=off, + background=textframe, + offset=15pt, + top=\vfill, + bottom=\vfill] + \bgroup} + +\unexpanded\def\StopItem + {\egroup + \egroup + \setbox\scratchbox=\hbox{\lower.5\ht\scratchbox\box\scratchbox}% + \ht\scratchbox=.5\ht\scratchbox + \dp\scratchbox= \ht\scratchbox + \box\scratchbox + \egroup + \startstandardmakeup + \dontcomplain + \leftskip 0pt plus 50pt + \rightskip 0pt plus 50pt + \parfillskip 0pt + \baselineskip 100pt + \unhcopy\CollectedIdeas + \stopstandardmakeup} + +\unexpanded\def\StartIdea + {\ifnum\CurrentTopic=6 + \global\CurrentTopic\plusone + \else + \global\advance\CurrentTopic\plusone + \fi + \definecolor[LineColor][linecolor \number\CurrentTopic] + \setbox\CollectedIdeas\null} + +\unexpanded\def\StopIdea + {} + +\unexpanded\def\StartTitlePage + {\startstandardmakeup + \setupalign[middle] + \unexpanded\def\\{\vfil\bfb\setupinterlinespace} + \bfd\setupinterlinespace + \vfil} + +\unexpanded\def\StopTitlePage + {\vfil\vfil + \stopstandardmakeup} + +\unexpanded\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +\startsetups document:start + \StartTitlePage + \documentvariable{title} + \doifsomething {\documentvariable{subtitle}} { + \\ + \documentvariable{subtitle} + } + \doifsomething {\documentvariable{location}} { + \\ + \documentvariable{location} + } + \StopTitlePage +\stopsetups + +\startsetups document:stop + % +\stopsetups + +\stopmodule + +\continueifinputfile{s-present-balls.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-balls-001.tex} diff --git a/tex/context/modules/mkiv/s-present-banner.mkiv b/tex/context/modules/mkiv/s-present-banner.mkiv new file mode 100644 index 000000000..d93c033f2 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-banner.mkiv @@ -0,0 +1,132 @@ + +%D [ file=s-present-banner, +%D version=2016.04.30, % around +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Banner, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This style was made for the Bacho\TeX\ 2016 conference. The banner below +%D the text advances through the title. + +\startmodule[present-banner] + +\definecolor[maincolor] [b=.65] +\definecolor[othercolor][s=.35] + +\startluacode + function mp.Banner(s,mode) + -- local r = tex.count.realpageno + local r = tex.count.realpageno - 1 + local n = #s + local i = mode and 1 or 0 + local t = string.gsub(s,".",function(s) + if s == " " or i > n then + return s + elseif i == r then + i = i + 1 + if mode then + return "\\color[othercolor]{" .. s .. "}" + else + return "\\maincolor " .. s + end + else + i = i + 1 + return s + end + end) + mp.quoted(t) + end +\stopluacode + +\startuseMPgraphic{page} + StartPage ; + fill Page withcolor \MPcolor{maincolor} ; + draw anchored(image ( + % draw textext.top (lua.mp.Banner("\documentvariable{title}",true)) + draw textext.top (lua.mp.Banner("\documentvariable{title}",false)) + xsized (.9PaperWidth) + withcolor white; + ), center bottomboundary Page); + % fill Field[Text][Text] enlarged 10pt withcolor (\MPcolor{maincolor})/1.5 ; + fill Field[Text][Text] enlarged 10pt withcolor .1white ; + StopPage ; +\stopuseMPgraphic + +\setupbackgrounds + [page] + [background=page] + +\defineoverlay + [page] + [\useMPgraphic{page}] + +\setupbodyfont + [lucidaot,10pt] + +\setuppapersize + [S6] + +\setuplayout + [backspace=30pt, + width=middle, + height=middle, + topspace=30pt, + bottomspace=100pt, + header=0pt, + footer=0pt, + margin=0pt] + +\setupcolors + [textcolor=white] + +\setupwhitespace + [big] + +\setuphead + [chapter] + [style=\bfd, + after={\blank[big]}] + +\setuphead + [section] + [style=\bfa, + before=\blank, + after={\blank[medium]}] + +\definehighlight[nb][style=bold] + +\setupitemgroup[itemize][before=,after=] +\setupitemgroup[itemize][packed] + +\setupdocument + [title=Title, + subtitle=Subtitle, + location=\currentdate] + +\startsetups document:start + + \startstandardmakeup + + \raggedcenter + + \dontleavehmode\scale[width=1.00\textwidth]{\documentvariable{title}} \vfil + \dontleavehmode\scale[width=0.75\textwidth]{\documentvariable{subtitle}} \vfil + \dontleavehmode\scale[width=0.45\textwidth]{\documentvariable{location}} \vfil + + \stopstandardmakeup + +\stopsetups + +\stopmodule + +\continueifinputfile{s-present-banner.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{bachotex/2016/bachotex-2016-opentype.tex} diff --git a/tex/context/modules/mkiv/s-present-bars.mkiv b/tex/context/modules/mkiv/s-present-bars.mkiv new file mode 100644 index 000000000..13c09ff3b --- /dev/null +++ b/tex/context/modules/mkiv/s-present-bars.mkiv @@ -0,0 +1,128 @@ +%D \module +%D [ file=s-present-bars, +%D version=2012.07.10, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment bars, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Okay, this one makes me a bit ashamed as it's probably too simple and unattractive but +%D as it was used for a whole bunch of presentations it made it into a module anyway. + +\startmodule[present-bars] + +\setupbodyfont + [dejavu] + +\setuppapersize + [S6] + +\setuplayout + [backspace=12pt, + width=middle, + height=middle, + topspace=12pt, + header=36pt, + footer=36pt, + headerdistance=12pt, + footerdistance=12pt] + +\definecolor + [maincolor] + [darkblue] + +\startreusableMPgraphic{page} + StartPage ; + fill + Page + withcolor \MPcolor{maincolor} ; + fill + Field[Text][Header] + leftenlarged BackSpace + rightenlarged CutSpace + withcolor darkgray ; + fill + Field[Text][Footer] + leftenlarged BackSpace + rightenlarged CutSpace + withcolor darkgray ; + StopPage ; +\stopreusableMPgraphic + +\setupheader + [color=maincolor, + style=bold, + before=\vss, + after=\vss] + +\setupheader + [color=maincolor, + style=bold, + before=\vss, + after=\vss] + +\setupheadertexts + [Breskens 2012] + [\getvariable{document}{title}] + +\setupbackgrounds + [page] + [background=page] + +\defineoverlay + [page] + [\reuseMPgraphic{page}] + +\setupbackgrounds + [footer][text] + [background=goback] + +\defineoverlay + [goback] + [\overlaybutton{PreviousPage}] + +\setuppagenumbering + [location=] + +\setupcolors + [textcolor=white] + +\setvariables + [document] + [maincolor=darkblue, + set=\setups{document:setup}] + +\startsetups document:setup + + \doifsomething {\getvariable{document}{color}} { + + \definecolor[maincolor][\getvariable{document}{color}] + + } + +\stopsetups + +\setupinteraction + [state=start, + click=no] + +\usemodule[abr-01] +\usemodule[pre-60] + +\stopmodule + +\continueifinputfile{s-present-bars.mkiv} + +\usemodule[present-common] + +%\inputpresentationfile{context/2012/context-2012-after-the-cleanup.tex} +%\inputpresentationfile{context/2012/context-2012-the-script.tex} +%\inputpresentationfile{context/2012/context-2012-lexing-sources.tex} +%\inputpresentationfile{context/2012/context-2012-mixed-columns.tex} +%\inputpresentationfile{context/2012/context-2012-visual-debugging.tex} +\inputpresentationfile{context/2012/context-2012-xml-news.tex} diff --git a/tex/context/modules/mkiv/s-present-colorful.mkiv b/tex/context/modules/mkiv/s-present-colorful.mkiv new file mode 100644 index 000000000..ed4b5f7c4 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-colorful.mkiv @@ -0,0 +1,384 @@ +%D \module +%D [ file=s-present-colorful, % was s-pre-04 +%D version=1998.09.06, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Colorful, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[present-general] + +\startmodule[present-colorful] + +%D \macros +%D {setupbodyfont} +%D +%D This is just another environment for typesetting interactive presentations. I +%D wrote this module on behalf of a course I gave for the United Kingdom \TeX\ users +%D group. + +\setupbodyfont[postscript,14.4pt] + +%D \macros +%D {setupcolors,definecolor} +%D +%D I started using dark blue for the navigational elements. In that context, dark +%D red is a logical choice for the contrast color. While playing around with the +%D navigational elements I decided to use the not so dominant color yellow for the +%D status bar. +%D +%D A few days before I wrote this style, the recent acquisition of Mondriaans last +%D painting by the Dutch governement was a hot topic in the Dutch news scenary. +%D Therefore I decided to replace the rather dull title page by something more +%D colorful, in mondriaan colors, but far more random than any of his paintings. For +%D consistence we remap the already defined primary colors. +%D +%D The \MKIV\ version is adapted abit so that the title is better visible. + +\setupcolors [state=start] + +\definecolor [NoneColor] [s=.6] +\definecolor [GotoColor] [b=.6] \definecolor[blue] [GotoColor] +\definecolor [ExitColor] [r=.6] \definecolor[red] [ExitColor] +\definecolor [JumpColor] [s=.6] +\definecolor [UserColor] [g=.6] \definecolor[green] [UserColor] +%definecolor [StepColor] [r=.6,g=.6] \definecolor[yellow][StepColor] +\definecolor [StepColor] [y=.8] \definecolor[yellow][StepColor] + +\definecolor [PageColor] [s=.80] \definecolor[gray] [PageColor] +\definecolor [TextColor] [s=.90] +\definecolor [TitleColor][s=.90] + +%D \macros +%D {setuppapersize} +%D +%D As usual, we take a screen oriented paper size: + +\setuppapersize + [S6][S6] + +%D \macros +%D {setuplayout,setupinteractionscreen} +%D +%D The layout definition fits into this $600\times450$ point area, but the +%D dimensions are somewhat diffused by the text background offset. + +\setuplayout + [width=530pt, + height=400pt, + header=0pt, + footer=0pt, + backspace=15pt, + topspace=15pt, + bottomdistance=15pt, + bottom=10pt, + margin=0pt, + rightedgedistance=15pt, + rightedge=30pt] + +\setupinteractionscreen + [option=max] + +%D \macros +%D {setupbackgrounds} +%D +%D Both the page and the text area have a gray background. The \type {[text,text]} +%D area also has an offset. Later we will see that we have to compensate for that in +%D the navigational areas. + +\setupbackgrounds + [page] + [background=color, + backgroundcolor=PageColor] + +\setupbackgrounds + [text][text] + [background=color, + backgroundcolor=TextColor, + backgroundoffset=5pt] + +%D \macros +%D {setupinteraction} +%D +%D For convenient navigation, we turn on interaction. + +\setupinteraction + [state=start, + menu=on, + color=UserColor, + contrastcolor=NoneColor] + +%D \macros +%D {setupsubpagenumber} +%D +%D When navigating the document, we keep the title page out of sight, therefore we +%D use sub page numbers. + +\setupsubpagenumber + [state=start, + way=bytext] + +%D \macros +%D {setupinteractionmenu} +%D +%D There is only one interaction menu, located in the right edge of the screen. Both +%D offsets enlarge the edge by the same amount as the text background offset. + +\setupinteractionmenu + [right] + [state=start, + frame=off, + strut=no, + offset=0pt, + inbetween=, + bottomoffset=-5pt, + topoffset=-5pt] + +%D \macros +%D {startinteractionmenu} +%D +%D The menu itself is not that spectacular. We use the start||stop alternative for +%D setting the content. The macro \type {\interactioncolor} expands into either the +%D interaction color or the contrast color, the latter only when no jump is +%D possible. + +\startinteractionmenu[right] + \setupinteraction[color=GotoColor] + \but [previoussubpage] \Triangle {90}\hsize\interactioncolor \\ + \vskip10pt + \but [nextsubpage] \Triangle{270}\hsize\interactioncolor \\ + \vfill + \but [PreviousJump] \Triangle{180}\hsize{NoneColor} \\ + \vskip-5pt + \but [NextJump] \Triangle {0}\hsize{NoneColor} \\ +\stopinteractionmenu + +%D \macros +%D {setupinteractionbar} +%D +%D The interaction bar at the bottom is also larger than the normal width of the +%D bottom area. + +\setupinteractionbar + [width=\textwidth, + height=\bottomheight, + distance=10pt, + color=NoneColor, + contrastcolor=StepColor] + +%D \macros +%D {setupbottomtexts} +%D +%D The bar is centered in the middle. + +\setupbottomtexts + [{\interactionbar[alternative=f]}] + +%D We can exit viewing with a close button, located on the rightmost bottom area. + +\unexpanded\def\CloseButton + {\ifnum\realpageno>\plusone + \button + [width=\rightedgewidth, + height=\bottomheight, + offset=overlay, + background=color, + backgroundcolor=ExitColor, + frame=off] + {}% + [CloseDocument]% + \fi} + +\setupbottomtexts + [edge][][\CloseButton] + +%D \macros +%D {definesymbol,setupitemize} +%D +%D Because some prominent things are rectangular or triangular, we prefer some +%D different symbols in itemizations: + +\definesymbol[1][\blacktriangleright] +\definesymbol[2][\blacktriangledown] +\definesymbol[3][\blacktriangleright] +\definesymbol[4][\blacktriangledown] + +\setupitemize[each][color=NoneColor] + +%D \macros +%D {TitlePage,defineoverlay,button,setupalign, +%D setupbackgrounds,setupinteraction,setupinteractionbar, +%D startstandardmakeup,switchtobodyfont,setupinterlinespace} +%D +%D Now the main layout and navigational definitions are done, it makes sense to +%D define and tune some structuring commands. First we build the titlepage. + +\defineoverlay [TitleGraphic] [\useMPgraphic{title}] +\defineoverlay [NextPage] [\overlaybutton{nextpage}] + +\unexpanded\def\StartTitlePage + {\setupbackgrounds[page][background={color,TitleGraphic,NextPage}] + \setupbackgrounds[text][text][background=] + \setupinteraction[menu=off] + \setupinteractionbar[state=stop] + \startpagemakeup + \switchtobodyfont[24pt] + \bfd\setupinterlinespace + \setupalign[middle] + \vfil + \let\\=\vfil + \scale + [factor=max]\bgroup + \framed + [frame=off, + align=middle, + foregroundcolor=TitleColor, + offset=.05\textwidth] + \bgroup} + +\unexpanded\def\StopTitlePage + {\egroup + \egroup + \vfil\vfil\vfil + \stoppagemakeup + \setupinteraction[menu=on] + \setupinteractionbar[state=start] + \setupbackgrounds[page][background=color] + \setupbackgrounds[text][text][background=color]} + +\unexpanded\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D \macros +%D {Topic, Nopic, Subject, +%D definehead, setuphead} +%D +%D We use \type {\Topic} and \type {\Subject} instead of chapters and sections. The +%D \type {\Nopic} alternative is meant for internal use. + +\definehead [Topic] [chapter] +\definehead [Nopic] [title] +\definehead [Subject] [section] + +\setuphead + [Topic,Nopic] + [after={\blank[3*medium]}, + number=no, + style=\bfb, + page=yes, + alternative=middle] + +\setuphead + [Subject] + [after=\blank, + number=no, + page=yes, + continue=no, + style=\bfa] + +%D \macros +%D {Topics, Subjects, +%D setuplist, placelist, startcolumns} +%D +%D This style is meant for the more large presentations, and therefore provided for +%D a list of topics as well as local lists of subjects. When many topics are +%D introduces, the list is typeset in columns. + +\setuplist + [Topic,Subject] + [alternative=g, + interaction=all, + before=, + after=] + +\setuplist + [Topic] + [criterium=all] + +\unexpanded\def\Topics#1% + {\determinelistcharacteristics[Topic] + \ifnum\utilitylistlength>0 + \Nopic[Topics]{#1} + \ifnum\utilitylistlength>12 + \startcolumns + \placelist[Topic] + \stopcolumns + \else + \placelist[Topic] + \fi + \fi} + +\unexpanded\def\Subjects% + {\placelist[Subject]} + +%D Last we define the overlays. Look at the way colors are linked into the macros. + +\setupMPvariables + [triangle] + [width=1cm, + rotation=0, + color=black] + +\startuniqueMPgraphic{triangle}{width,rotation,color} + fill triangle xsized \MPvar{width} rotated \MPvar{rotation} withcolor \MPvar{color} ; +\stopuniqueMPgraphic + +\unexpanded\def\Triangle#1#2#3% + {\uniqueMPgraphic{triangle}{rotation=#1,width=#2,c:color=#3}} + +% \startuseMPgraphic{title} +% path p ; numeric sx, sy, cc ; +% for i=1 upto 250 : +% sx := uniformdeviate 30 ; +% sy := uniformdeviate 30 ; +% cc := round(uniformdeviate 2) ; +% if round(uniformdeviate 1) = 0 : +% p := unitsquare xscaled sx yscaled sy ; +% else : +% p := unittriangle scaled sx rotated (round(uniformdeviate 3) * 90) ; +% fi ; +% p := p shifted (uniformdeviate OverlayWidth,uniformdeviate OverlayHeight) ; +% fill p +% withcolor +% if cc = 0 : "GotoColor" +% elseif cc = 1 : "ExitColor" +% elseif cc = 2 : "StepColor" fi ; +% endfor ; +% \stopuseMPgraphic + +\startuseMPgraphic{title} + path p ; numeric sx, sy, cc ; + fill Page withcolor "StepColor" ; + for i=1 upto 1000 : + sx := 50 + uniformdeviate 50 ; + sy := 50 + uniformdeviate 50 ; + cc := round(uniformdeviate 2) ; + if round(uniformdeviate 1) = 0 : + p := unitsquare xscaled sx yscaled sy ; + else : + p := unittriangle scaled sx rotated (round(uniformdeviate 3) * 90) ; + fi ; + p := p shifted (uniformdeviate OverlayWidth,uniformdeviate OverlayHeight) ; + fill p + withcolor + if cc = 0 : "GotoColor" + elseif cc = 1 : "ExitColor" + elseif cc = 2 : "StepColor" fi ; + draw p + withpen pencircle scaled 1/2 + withcolor white ; + endfor ; +\stopuseMPgraphic + +\stopmodule + +\continueifinputfile{s-present-colorful.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-colorful-001.tex} diff --git a/tex/context/modules/mkiv/s-present-common.mkiv b/tex/context/modules/mkiv/s-present-common.mkiv new file mode 100644 index 000000000..b4b422ca5 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-common.mkiv @@ -0,0 +1,43 @@ +%D \module +%D [ file=s-present-common, +%D version=2016.10.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Common Helpers, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[present-common] + +\startluacode + + -- sources -> presentations + -- tex/context/base/mkiv -> doc/context/presentations + + function commands.inputpresentationfile(name) + local mkivpath = file.pathpart(resolvers.findfile("context.mkiv")) + local filename = file.join(mkivpath,"../presentations",name) + if lfs.isfile(filename) then + context.input(filename) + return + end + filename = file.join(mkivpath,"../../../../doc/context/presentations",name) + if lfs.isfile(filename) then + context.input(filename) + return + end + context.starttext() + context.formatted.type("missing file: %s",name) + context.stoptext() + end + +\stopluacode + +\unexpanded\def\inputpresentationfile#1% + {\ctxcommand{inputpresentationfile("#1")}} + +\stopmodule diff --git a/tex/context/modules/mkiv/s-present-four.mkiv b/tex/context/modules/mkiv/s-present-four.mkiv new file mode 100644 index 000000000..347790e26 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-four.mkiv @@ -0,0 +1,188 @@ +%D \module +%D [ file=s-present-four, +%D version=2011.04.15, % about +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Four, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Just another one-time used Bacho\TEX\ presentation style that I found back +%D when cleaning up old files. It's just simple pages in a shape and this time +%D we hook it into a section command. + +\startmodule[present-four] + +\setupbodyfont + [dejavu,11pt] + +\setupcolors + [textcolor=white] + +\setupalign + [flushleft] + +\startuseMPgraphic{page} + vardef One = + ulcorner Page -- + .75[ulcorner Page, urcorner Page] -- + .60[ulcorner Page, lrcorner Page] -- + .75[ulcorner Page, llcorner Page] -- + cycle + enddef; + vardef One = + ulcorner Page -- + .80[ulcorner Page, urcorner Page] -- + .65[ulcorner Page, lrcorner Page] -- + .80[ulcorner Page, llcorner Page] -- + cycle + enddef; + vardef Two = One rotatedaround(center Page, 90) enddef ; + vardef Three = One rotatedaround(center Page,180) enddef ; + vardef Four = One rotatedaround(center Page,270) enddef ; + StartPage ; + if CurrentLayout = "layout:0" : + fill Two withcolor .25[red,blue] ; + fill Three withcolor .25[blue,yellow] ; + fill Four withcolor .25[yellow,blue] ; + fill One withcolor .5white ; + elseif CurrentLayout = "layout:1" : + fill Two withcolor .25[red,blue] ; + fill Three withcolor .25[blue,yellow] ; + fill Four withcolor .25[yellow,blue] ; + fill One withcolor .25[green,red] ; + elseif CurrentLayout = "layout:2" : + fill One withcolor .25[green,red] ; + fill Two withcolor .25[red,blue] ; + fill Three withcolor .25[blue,yellow] ; + fill Four withcolor .25[yellow,blue] ; + elseif CurrentLayout = "layout:3" : + fill One withcolor .25[green,red] ; + fill Two withcolor .25[red,blue] ; + fill Four withcolor .25[yellow,blue] ; + fill Three withcolor .25[blue,yellow] ; + elseif CurrentLayout = "layout:4" : + fill One withcolor .25[green,red] ; + fill Three withcolor .25[blue,yellow] ; + fill Four withcolor .25[yellow,blue] ; + fill Two withcolor .25[red,blue] ; + fi ; + StopPage ; +\stopuseMPgraphic + +\setupbackgrounds + [page] + [background={page}] + +\setupinteraction + [state=start, + click=no] + +\setupinteractionscreen + [option=max] + +\defineoverlay + [page] + [\useMPgraphic{page}] + +\definepapersize + [mine] + [width=400pt, + height=400pt] + +\setuppapersize + [mine] + +\setuplayout + [header=0pt, + footer=0pt, + margin=0pt, + width=middle, + height=middle] + +% \showframe + +\definelayout + [layout:0] + [backspace=10pt,cutspace=.375\paperwidth, + bottomspace=.35\paperheight,topspace=10pt] + +\definelayout + [layout:1] + [backspace=10pt,cutspace=.375\paperwidth, + bottomspace=.35\paperheight,topspace=10pt] + +\definelayout + [layout:2] + [backspace=.35\paperwidth,cutspace=10pt, + bottomspace=.375\paperheight,topspace=10pt] + +\definelayout + [layout:3] + [backspace=.375\paperwidth,cutspace=10pt, + bottomspace=10pt,topspace=.375\paperheight] + +\definelayout + [layout:4] + [backspace=10pt,cutspace=.375\paperwidth, + bottomspace=10pt,topspace=.35\paperheight] + +\setuptyping + [space=fixed] + +\startluacode + local n = -1 + function documentdata.StartPage() + if n == 4 then + n = 1 + else + n = n + 1 + end + context.setuplayout { string.format("layout:%s",n) } + end + function documentdata.StopPage() + context.page() + end +\stopluacode + +\unexpanded\def\StartPage + {\bgroup + \ctxlua{documentdata.StartPage()}} + +\unexpanded\def\StopPage + {\ctxlua{documentdata.StopPage()} + \egroup} + +\startsetups subject:start + \bgroup + \ctxlua{documentdata.StartPage()} +\stopsetups + +\startsetups subject:stop + \ctxlua{documentdata.StopPage()} + \egroup +\stopsetups + +\setuphead[subject] + [beforesection=\directsetup{subject:start}, + aftersection=\directsetup{subject:stop}] + +\startsetups document:start + \StartPage + \definedfont[SerifBold*default at 48pt] + \setupinterlinespace + \documentvariable{title} + \StopPage +\stopsetups + +\stopmodule + +\continueifinputfile{s-present-four.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{bachotex/2011/bachotex-2011-cld-and-mkvi.tex} diff --git a/tex/context/modules/mkiv/s-present-funny.mkiv b/tex/context/modules/mkiv/s-present-funny.mkiv new file mode 100644 index 000000000..4948766ad --- /dev/null +++ b/tex/context/modules/mkiv/s-present-funny.mkiv @@ -0,0 +1,208 @@ +%D \module +%D [ file=s-present-funny, % was s-pre-03 +%D version=1998.09.06, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Funny, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[present-funny] + +%D This is the third environment for typesetting interactive presentations. I used +%D this style for a talk on \TEX\ and \JAVASCRIPT\ at \TUG98, mainly because I +%D didn't want to use the same style three times. Therefore this is a rather simple, +%D silly style. + +\usemodule[pre-general] + +%D \macros +%D {setupbodyfont} +%D +%D We use a large bodyfont. Combined with the fancy +%D background, this does not leave that much room for text, but +%D presentations should use much text anyway. + +\doifelsemode {asintended} { + \setupbodyfont[ludicaot,14.4pt] +} { + \setupbodyfont[pagella,14.4pt] +} + +%D \macros +%D {setuppapersize,setuplayout,setupinteractionscreen} +%D +%D The page dimensions are set to size \type {S6}, being 600pt by 450pt. We use wide +%D margins and discard headers and footers. We also launch the document full screen. + +\setuppapersize + [S6][S6] + +\setuplayout + [width=middle, + height=middle, + topspace=75pt, + backspace=100pt, + header=0pt, + footer=0pt] + +\setupinteractionscreen + [option=max] + +%D \macros +%D {definecolor} +%D +%D Next, color support is turned on and a dark red color is defined. Other red +%D shades will be derived from this one color. + +\definecolor [PageColor] [black] +\definecolor [BackgroundColor] [s=.85] +\definecolor [OrnamentColor] [r=.75] +\definecolor [PositionColor] [s=.55] + +%D \macros +%D {setupinteraction} +%D +%D We turn on interaction mode and use the same color for hyperlinks and redundant +%D hyperlinks (the ones that point to the current page). + +\setupinteraction + [state=start, + contrastcolor=OrnamentColor, + color=OrnamentColor] + +%D \macros +%D {defineoverlay, setupbackgrounds} +%D +%D The joke in this presentation is the elliptical shape of which the bottom part +%D includes a page indication. + +\defineoverlay + [PageShape][\useMPgraphic{PageShape}] + +\startuseMPgraphic{PageShape} + StartPage ; + path p ; pair pa, pb ; numeric len ; color contrastcolor ; + fill Page withcolor \MPcolor {PageColor} ; + pickup pencircle rotated 45 xscaled 10pt yscaled 20pt ; + p := Page enlarged (-10pt,-15pt) superellipsed .8 ; + p := p shifted (-1.5pt,0) ; % looks better + fill p withcolor \MPcolor{BackgroundColor} ; + draw p withcolor \MPcolor{OrnamentColor} ; + contrastcolor = \MPcolor{PositionColor} ; + if (RealPageNumber > 0) and (NOfPages > 0): + draw point 5 of p withcolor contrastcolor ; + draw point 7 of p withcolor contrastcolor ; + len := 2/NOfPages ; + pa := point (5+len* RealPageNumber ) of p ; + pb := point (5+len*(RealPageNumber-1)) of p ; + draw (p cutafter pa) cutbefore pb + withcolor contrastcolor ; + fi ; + StopPage ; +\stopuseMPgraphic + +%D We use the viewer provided feature to go to the previous or next page. + +\defineoverlay[PrevButton][\overlaybutton{PreviousPage}] +\defineoverlay[NextButton][\overlaybutton{NextPage}] + +\setupbackgrounds + [page] + [background={PageShape,PrevButton}] + +\setupbackgrounds + [text][text] + [background=NextButton] + +% or using hard coded next/prev pages: +% +% \defineoverlay[PrevButton][\overlaybutton{previouspage}] +% \defineoverlay[NextButton][\overlaybutton{nextpage}] +% +% \setupbackgrounds[state=repeat] +% \setupbackground[text][text][background=NextButton] +% +% or simply (using an repeated layer): +% +% \setupbackground[text][background=NextButton] + +%D \macros +%D {definehead, setuphead} +%D +%D Like the other presentation styles, we use \type {\Topic} instead of \type +%D {\chapters}. This time we don't provide an additional sectioning. So we have: +%D +%D \starttyping +%D \TitlePage{How nice} +%D +%D \Topics{This is about ...} +%D +%D \Topic{The first one} +%D +%D \Topic{Another one} +%D \stoptyping + +\definehead [Topic] [chapter] +\definehead [Nopic] [title] + +\setuphead + [Topic,Nopic] + [after={\blank[3*medium]}, + number=no, + style=\bfb, + page=yes, + alternative=middle] + +\setuplist + [Topic] + [alternative=g, + interaction=all, + before=, + after=] + +\let\Subject\Topic + +%D The tables of contents is associated with \type {\Topics}. + +\unexpanded\def\Topics#1% + {\Nopic[Topics]{#1} + \placelist[Topic][criterium=all]} + +\unexpanded\def\Subjects + {} + +%D Instead of \type {\TitlePage}, one can use the pair \type {\StartTitlePage} -- +%D \type {\StopTitlePage}: +%D +%D \starttyping +%D \StartTitlePage +%D A Self Made Title +%D \StopTitlePage +%D \stoptyping + +\unexpanded\def\StartTitlePage + {\startstandardmakeup + \bfd\setupinterlinespace + \setupalign[middle] + \vfil + \def\\{\vfil\bfb\setupinterlinespace}} + +\unexpanded\def\StopTitlePage + {\vfil\vfil\vfil + \stopstandardmakeup} + +\unexpanded\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +\stopmodule + +\continueifinputfile{s-present-funny.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-funny-001.tex} diff --git a/tex/context/modules/mkiv/s-present-fuzzy.mkiv b/tex/context/modules/mkiv/s-present-fuzzy.mkiv new file mode 100644 index 000000000..ee029b0e6 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-fuzzy.mkiv @@ -0,0 +1,225 @@ +%D \module +%D [ file=s-present-fuzzy, % was s-pre-05 +%D version=1998.12.12, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Fuzzy, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[present-general] + +\startmodule[present-fuzzy] + +%D As all styles sofar, this one has the same structuring commands. + +\doifelsemode {asintended} { + \setupbodyfont[ludicaot,14.4pt] +} { + \setupbodyfont[pagella,14.4pt] +} + +\definecolor [BackgroundColor] [s=.95] +\definecolor [OrnamentColor] [r=.6,g=.7,b=.8] + +\setuppapersize + [S6][S6] + +\setuplayout + [width=430pt, + height=400pt, + header=0pt, + footer=0pt, + margin=0pt, + backspace=25pt, + topspace=25pt, + rightedgedistance=20pt, + rightedge=110pt] + +\setupinteractionscreen + [option=max] + +\setupbackgrounds + [state=repeat] + +\setupbackgrounds + [page] + [backgroundcolor=white] + +\setupbackgrounds + [text][text] + [background={HashFrameA,NextPage}, + backgroundoffset=20pt] + +\defineoverlay + [HashFrameA] + [\useMPgraphic{HashFrameA}] + +\defineoverlay + [HashFrameB] + [\useMPgraphic{HashFrameB}] + +\setupinteraction + [state=start, + menu=on, + color=OrnamentColor, + contrastcolor=OrnamentColor] + +%D Watch how we use a list alternative that matches the menu. + +\setupinteractionmenu + [right] + [background=HashFrameB, + style=smallbold, + frame=off, + offset=10pt, + height=35pt, + before=, + after=, + inbetween=\endgraf, + width=\rightedgewidth] + +\startinteractionmenu[right] + \placelist + [Topic] + [criterium=all, + alternative=right, + maxwidth=.8\rightedgewidth, + interaction=all, + before=, + after=] + \vfill + \setupinteractionmenu + [right] + [height=30pt] + \but [CloseDocument] Close \\ +\stopinteractionmenu + +\setupwhitespace + [big] + +\setupblank + [big] + +%D \macros +%D {TitlePage} +%D +%D Now the main layout and navigational definitions are done, it makes sense to +%D define and tune some structuring commands. First we build the titlepage. + +\defineoverlay [TitleGraphic] [\useMPgraphic{TitleGraphic}] +\defineoverlay [NextPage] [\overlaybutton{forward}] + +\unexpanded\def\StartTitlePage + {\setupbackgrounds[page][background={color,TitleGraphic,NextPage}] + \setupbackgrounds[text][text][background=] + \setupinteraction[menu=off] + \setupinteractionbar[state=stop] + \setuplayout[width=550pt,rightedge=0pt] + \startstandardmakeup + \switchtobodyfont[24pt] + \bfd\setupinterlinespace + \setupalign[middle] + \vfil + \let\\=\vfil} + +\unexpanded\def\StopTitlePage + {\vfil\vfil\vfil + \stopstandardmakeup + \setuplayout[width=430pt,rightedge=110pt] + \setupinteraction[menu=on] + \setupinteractionbar[state=start] + \setupbackgrounds[page][background=color] + \setupbackgrounds[text][text][background={HashFrameA,NextPage}]} + +\unexpanded\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D \macros +%D {Topics,Subjects} +%D +%D Because the lists are in the menu, we don't honor list placement macros. + +\unexpanded\def\Topics#1{} +\unexpanded\def\Subjects{} + +%D \macros +%D {Topic, Nopic, Subject} +%D +%D Since this style is meant for rather flat structured documents, only \type +%D {\Topic} makes sense. + +\definehead [Topic] [chapter] +\definehead [Nopic] [title] +\definehead [Subject] [section] + +\setuphead + [Topic, Nopic] + [after={\blank[3*medium]}, + number=no, + style=\tfb, + page=yes, + alternative=middle] + +\setuphead + [Subject] + [after=\blank, + number=no, + page=yes, + continue=no, + style=\tfa] + +%D We use only one kind of base graphic, which is sligthly +%D tuned for the different usage. + +\startMPdefinitions + def random_hash_frame (expr width, height, offset, linewidth ) = + + def delta = ((uniformdeviate .5offset) + .25offset) enddef ; + x1 := offset ; y1 := offset ; x2 := width-offset ; y2 := height-offset ; + + drawoptions(withpen pencircle scaled linewidth withcolor \MPcolor{BackgroundColor}) ; + fill z1--(x2,y1)--z2--(x1,y2)--cycle ; + + drawoptions(withpen pencircle scaled linewidth withcolor \MPcolor{OrnamentColor}) ; + draw (x1-delta,y1)--(x2+delta,y1) ; + draw (x2,y1-delta)--(x2,y2+delta) ; + draw (x2+delta,y2)--(x1-delta,y2) ; + draw (x1,y2+delta)--(x1,y1-delta) ; + + drawoptions(); + setbounds currentpicture to unitsquare xscaled width yscaled height ; + enddef ; +\stopMPdefinitions + +\startuseMPgraphic{HashFrameA} + random_hash_frame(OverlayWidth,OverlayHeight,15pt,2pt) ; +\stopuseMPgraphic + +\startuseMPgraphic{HashFrameB} + random_hash_frame(OverlayWidth,OverlayHeight, 5pt,2pt) ; +\stopuseMPgraphic + +\startuseMPgraphic{TitleGraphic} + numeric offset, width, height ; + for i=1 upto 300 : + offset := uniformdeviate 10pt ; + width := 2*offset + 30pt + uniformdeviate 30pt ; + height := 2*offset + 10pt + uniformdeviate 10pt ; + addto currentpicture also + image(random_hash_frame(width,height,offset,1pt)) shifted + (uniformdeviate OverlayWidth, uniformdeviate OverlayHeight) ; + endfor ; +\stopuseMPgraphic + +\stopmodule + +\continueifinputfile{s-present-fuzzy.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-fuzzy-001.tex} diff --git a/tex/context/modules/mkiv/s-present-green.mkiv b/tex/context/modules/mkiv/s-present-green.mkiv new file mode 100644 index 000000000..e62257ff3 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-green.mkiv @@ -0,0 +1,349 @@ +%D \module +%D [ file=s-present-green, % was s-pre-02 +%D version=1998.04.21, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Green, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[present-green] + +%D Here is another original presentation style, actually the second one we made. +%D Not much adaption was needed for \MKIV. + +\usemodule[pre-general] + +%D \macros +%D {setupbodyfont, switchtobodyfont, setuplayout} +%D +%D At \PRAGMA\ we prefer using the Lucida Bright fonts, but one can of course load +%D another typeface. + +\doifelsemode {asintended} { + \setupbodyfont[ludicaot,14.4pt] +} { + \setupbodyfont[pagella,14.4pt] +} + +\setuplayout + [style=smallbodyfont] + +%D \macros +%D {setuppapersize, setuplayout} +%D +%D The papersize suits the screen dimensions. The layout is rather simple. We use +%D the whole width of the screen and only have navigational tools at the bottom of +%D the screen. + +\setuppapersize + [S6][S6] + +\setuplayout + [backspace=1cm, + topspace=1cm, + margin=0pt, + header=0pt, + footer=0pt, + bottomdistance=.875cm, + bottom=1cm, + width=fit, + height=fit] + +%D \macros +%D {setupwhitespace, setuptyping} +%D +%D We don't have much height, so we use a more cramped spacing. Verbatim text looks +%D better when indented. + +\setupwhitespace + [medium] + +\setuptyping + [margin=standard] + +%D \macros +%D {definecolor} +%D +%D Of course we enable color. We define some logical colors, of which most default +%D to the same green shade. + +\definecolor [BackgroundColor] [r=.8, g=.8, b=.8] +\definecolor [OrnamentColor] [r= 0, g=.7, b=.4] + +%D \macros +%D {setupinteraction, setupinteractionscreen} +%D +%D We still have to enable interaction mode. We go full screen! + +\setupinteraction + [state=start, + color=OrnamentColor, + contrastcolor=OrnamentColor] + +\setupinteractionscreen + [option=max, + width=fit, + height=fit] + +%D \macros +%D {setupitemize} +%D +%D And why not bring some color in itemizations too? + +\setupitemize + [color=OrnamentColor] + +%D \macros +%D {defineoverlay, setupbackgrounds} +%D +%D The navigational elements and the backgrounds are provided by \METAPOST. + +\startuniqueMPgraphic{PageBackground} + fill unitsquare + xyscaled(OverlayWidth,OverlayHeight) + withcolor OverlayColor ; + draw unitsquare + xyscaled(OverlayWidth,OverlayHeight) + enlarged (-2*OverlayLineWidth) + withpen pencircle scaled OverlayLineWidth + withcolor OverlayLineColor ; +\stopuniqueMPgraphic + +\defineoverlay + [PageBackground] + [\uniqueMPgraphic{PageBackground}] + +\setupbackgrounds + [page] + [background=PageBackground, + backgroundcolor=BackgroundColor, + rulethickness=.125cm, + framecolor=OrnamentColor] + +%D \macros +%D {setuptexttexts} +%D +%D By clicking on the text area, one goes to the next page. We hook this feature +%D into the text backgrounds. + +\startuniqueMPgraphic{TextBackground} + draw unitsquare + xyscaled(OverlayWidth,OverlayHeight) + enlarged (4*OverlayLineWidth) + withpen pencircle scaled OverlayLineWidth + withcolor OverlayLineColor ; +\stopuniqueMPgraphic + +\defineoverlay + [TextBackground] + [\uniqueMPgraphic{TextBackground}] + +\defineoverlay + [NextPage] + [\overlaybutton{nextpage}] + +\setupbackgrounds + [text] + [background={TextBackground,NextPage}, + backgroundcolor=BackgroundColor, + rulethickness=.0625cm, + framecolor=OrnamentColor] + +%D \macros +%D {setupinteractionmenu,startinteractionmenu} +%D +%D At the bottom of the screen, we show three buttons. These direct us to the +%D previous or next jump or exit the document. + +\setupMPvariables[RightArrow][height=\bottomheight] +\setupMPvariables[LeftArrow] [height=\bottomheight] +\setupMPvariables[Circle] [height=\bottomheight] +\setupMPvariables[UpArrow] [height=\bottomheight] + +\startuniqueMPgraphic{RightArrow}{height} + fill righttriangle xysized(\MPvar{height},\MPvar{height}) + withpen pencircle scaled (\MPvar{height}/5) + withcolor "OrnamentColor" ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{LeftArrow}{height} + fill lefttriangle xysized(\MPvar{height},\MPvar{height}) + withpen pencircle scaled (\MPvar{height}/5) + withcolor "OrnamentColor" ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{Circle}{height} + fill fullcircle sized \MPvar{height} + withpen pencircle scaled (\MPvar{height}/5) + withcolor "OrnamentColor" ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{UpArrow}{height} + fill uptriangle xysized(\MPvar{height},\MPvar{height}) + withpen pencircle scaled (\MPvar{height}/5) + withcolor "OrnamentColor" ; +\stopuniqueMPgraphic + +\setupinteractionmenu + [bottom] + [state=start, + frame=off, + width=.3\textwidth, + height=\bottomheight] + +\setupinteraction + [menu=on] + +\def\WhateverButton + {\doifreferencefoundelse{Whatever} + {\raw [Whatever] \uniqueMPgraphic{UpArrow} \\} + {}} + +\startinteractionmenu[bottom] + \but [Topics] \\ % secret button + \hfill + \WhateverButton % user specific + \kern2\bottomheight + \raw [previouspage] \uniqueMPgraphic{LeftArrow} \\ + \kern.5\bottomheight + \raw [CloseDocument] \uniqueMPgraphic{Circle} \\ + \kern.5\bottomheight + \raw [nextpage] \uniqueMPgraphic{RightArrow} \\ + \kern.5\bottomheight +\stopinteractionmenu + +%D \macros +%D {TitlePage, Topics, Topic, Subject} +%D +%D A presentation after loading this module looks like: +%D +%D \starttyping +%D \TitlePage {About Whatever\\Topics} +%D +%D \Topics {Todays Talk} +%D +%D \Topic {Some topic} +%D +%D ..... +%D +%D \Topic {Next Topic} +%D +%D ..... +%D \stoptyping + +%D \macros +%D {StartTitlePage, TitlePage} +%D +%D The titlepage is rather simple and can be typeset in two +%D ways: +%D +%D \starttyping +%D \StartTitlePage +%D text \\ text \\ text +%D \StopTitlepage +%D \stoptyping +%D +%D or as one||liner: +%D +%D \starttyping +%D \TitlePage{text\\text\\text} +%D \stoptyping +%D +%D The first alternative can be used for more complicated title pages. + +\unexpanded\def\StartTitlePage + {\startstandardmakeup + \bfd\setupinterlinespace + \setupalign[middle] + \vfil + \let\\=\vfil} + +\unexpanded\def\StopTitlePage + {\vfil\vfil\vfil + \stopstandardmakeup} + +\unexpanded\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D \macros +%D {definehead} +%D +%D The commands \type{\Topic} and \type{\Subject} are defined as copies of head. We +%D use \type{\Nopic} for internal purposes. + +\definehead [Topic] [chapter] +\definehead [Subject] [section] + +\definehead [Nopic] [title] + +%D \macros +%D {setuphead} +%D +%D We use our own command for typesetting the titles. We hide sectionnumbers from +%D viewing. Each topic is followed by a list of subjects that belong to the topic. + +\setuphead + [Topic, Nopic] + [after={\blank[3*medium]}, + number=no, + style=\bfb, + page=yes, + alternative=middle] + +\setuphead + [Subject] + [after=\blank, + number=no, + page=yes, + continue=no, + style=\tfa] + +%D \macros +%D {setuplist} +%D +%D When found, the subject list is automatically placed after the topic head. + +\setuplist + [Topic,Subject] + [alternative=g, + interaction=all, + before=, + after=] + +\setuplist + [Topic] + [criterium=all] + +\unexpanded\def\Topics#1% + {\determinelistcharacteristics[Topic] + \doifmode{*list} + {\Nopic[Topics]{#1} + \startcolumns + \placelist[Topic] + \stopcolumns}} + +\setuplist + [Subject] + [criterium=Topic] + +\unexpanded\def\Subjects + {\determinelistcharacteristics[Subject] + \doifmode{*list} + {\placelist[Subject]}} + +\setuphead + [Topic] + [after={\blank[3*medium]\Subjects}] + +\stopmodule + +\continueifinputfile{s-present-green.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-green-001.tex} diff --git a/tex/context/modules/mkiv/s-present-grow.mkiv b/tex/context/modules/mkiv/s-present-grow.mkiv new file mode 100644 index 000000000..b4971e40f --- /dev/null +++ b/tex/context/modules/mkiv/s-present-grow.mkiv @@ -0,0 +1,171 @@ +%D \module +%D [ file=s-present-grow, % was s-pre-10 +%D version=unknown, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Grow, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This style is derived from the ninth style, which was used first at \EUROTEX\ 99 +%D and later at \TUG\ 2000. This alternative builds up a page. + +\usemodule[present-windows] % not that much used + +\startmodule[present-grow] + +%D We use blue colors instead of yellow ones. Since we have used symbolic names, we +%D can easily overload the existing scheme. + +\definecolor[LineColor][r=.40,g=.40,b=1.00] + +%D Here we don't use fixed dimensions, but fit the sample windows and derive the +%D text windows's width from this one. + +\setupframedtexts + [SampleText] + [width=fit,height=fit, + background={background,nextpage}] + +%D The topic goes to the top right corner of the screen which means that it is +%D positioned left down to the reference point. Watch how we make data on this layer +%D (here only the topic but it can be more) persistent. + +\setuplayer + [topic] + [y=0pt,x=\makeupwidth, + location=lb, + state=repeat, + hoffset=-\FrameSkip, + voffset=\FrameSkip] + +%D Clicking on the page brings us back. + +\setupbackgrounds + [page] + [background={previouspage,color,topic}] + +%D All layers end up on the text area. This could have been the page area too since +%D these have the same dimensions. + +\setupbackgrounds + [text] + [background={common,sample,text}] + +%D We overload this one (\MKIV): + +\defineoverlay [samepage] [\overlaybutton{nextpage}] + +%D Because we build up the text window step by step, we will separate the entries by +%D white space. + +\startsetups [always] + \setupwhitespace[big] + \setupblank[big] +\stopsetups + +%D The \type {\Topic} commands can be simplified to: + +\unexpanded\def\Topic#1% + {\resetlayer[topic] + \setlayer[topic]{\bfb\setstrut\color[TextColor]{#1}}} + +%D We also provide a way to erase the topic. + +\unexpanded\def\NoTopic + {\resetlayer[topic]} + +%D We have to redefine the structuring commands to support the resetting of buffer +%D counters. + +\newcounter\TextN + +\unexpanded\def\StartSample + {\doglobal\newcounter\TextN + \dostartbuffer[sample][StartSample][StopSample]} + +\unexpanded\def\StartText + {\doglobal\newcounter\TextN + \dostartbuffer[text][StartText][StopText]} + +\unexpanded\def\StartSubText + {\doglobal\increment\TextN + \dostartbuffer[text-\TextN][StartSubText][StopSubText]} + +\unexpanded\def\StopText + {\startstandardmakeup + \DoSampleText{text}{common}{nextpage} + \stopstandardmakeup} + +\unexpanded\def\StopSubText + {\startstandardmakeup + \DoSampleText{text}{common}{nextpage} + \stopstandardmakeup} + +%D The \type {\DoSampleText} command is adapted to support addition of subtexts +%D (each subtext goes into its own buffer). + +\unexpanded\def\DoSampleText#1#2#3% + {\setupframedtexts[SampleText][background={background,#3}] + \bgroup + \setups[#1]% + \setups[always]% + \setbox\nextbox=\hbox + {\startSampleText[none] + \getbuffer[#1]\par + \doif{#1}{text} + {\dorecurse{\TextN}{\getbuffer[text-\recurselevel]\par}} + \stopSampleText} + \xdef\SampleTextWidth{\the\wd\nextbox} + \setlayer[#2]{\box\nextbox}% + \egroup} + +%D Since we are no longer swapping windows, we end up with a much simplier \type +%D {\Stopidea} macro. We don't reset samples at the inner level. + +\unexpanded\def\StartIdea + {\bgroup + \let\StopSample \relax + \let\StopText \relax + \let\StopSubText\relax + \def\StartSample{\dostartbuffer[sample][StartSample][StopSample]}} + +\unexpanded\def\StopIdea + {\startstandardmakeup + \DoSampleText{sample}{sample}{nextpage} + \SetTextWidth + \DoSampleText{text} {text} {nextpage} + \stopstandardmakeup + \egroup} + +%D Here we determine the width of the text window. It is derived from the width of +%D the sample and stays the same within a sequence. + +\unexpanded\def\SetTextWidth + {\ifnum\TextN<1 % yes or no, may change + \scratchdimen=\makeupwidth + \advance\scratchdimen by -\SampleTextWidth + \advance\scratchdimen by \FrameSkip + \xdef\SampleWidth{\the\scratchdimen}% + \fi + \setupframedtexts + [SampleText] + [width=\SampleWidth]} + +%D We use the (already implemented) second alternative of the titlepage graphic. +%D Please don't change this. + +\defineoverlay[joke] [\useMPgraphic{joke}{n=1}] % not to be changed ! + +\stopmodule + +\continueifinputfile{s-present-grow.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-grow-001.tex} + diff --git a/tex/context/modules/mkiv/s-present-organic.mkiv b/tex/context/modules/mkiv/s-present-organic.mkiv new file mode 100644 index 000000000..657b786f2 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-organic.mkiv @@ -0,0 +1,335 @@ +%D \module +%D [ file=s-present-organic, % s-pre-19, +%D version=2000.07.31, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Organic, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[present-organic] + +%D This style is made in the process or writing the \METAFUN\ manual. It exploits a +%D few tricks, like graphics calculated using positional information. It also uses +%D the (at that moment) new menu list placement alternative. If you forget about the +%D definition of the button shapes, which is complicated in any system, this style +%D is not even that hard to follow. Watch how the left side of the buttons follow +%D the right side of the text graphic. +%D +%D While playing bit with this style, the random alternative made me think of those +%D organic building with non equal windows (we have a few in The Netherlands), so I +%D decided to label this style as \type {pre-organic}. +%D +%D At the end of this file, there is a small test file, so when you process this +%D file with \TEXEXEC\ and the options \type {--mode=demo} and \type {--pdf}, you +%D will get a demo document. +%D +%D We use one of the standard screen \quote {paper} sizes, and map it onto the same +%D size, so that we get a nicely cropped page. + +\setuppapersize + [S6][S6] + +%D Like in the \METAFUN\ manual, we use the Palatino as main bodyfont. This font is +%D quite readable on even low resolution screens, although I admit that this style +%D is developed using an $1400\times1050$ pixel LCD screen, so I may be biased. + +\setupbodyfont[pagella] + +%D The layout specification sets up a text area and a right edge area where the +%D menus will go. Watch the rather large edge distance. By setting the header and +%D footer dimensions to zero, we automatically get rid of page body ornaments, like +%D the pagenumber. + +\setuplayout + [topspace=48pt, + backspace=48pt, + cutspace=12pt, + width=400pt, + margin=0cm, + rightedge=88pt, + rightedgedistance=48pt, + header=0cm, + footer=0cm, + height=middle] + +%D We use a moderate, about a line height, interparagraph white space. + +\setupwhitespace + [big] + +%D Of course we use colors, since on computer displays they come for free. + +\definecolor [red] [r=.75] +\definecolor [yellow] [r=.75,g=.75] +\definecolor [gray] [s=.50] +\definecolor [white] [s=.85] + +\definecolor [PageColor] [yellow] +\definecolor [TextColor] [white] +\definecolor [OrnamentColor] [red] +\definecolor [InteractionColor] [red] +\definecolor [ContrastColor] [gray] + +%D This is an interactive document, so we enable interaction. In this style, we +%D disable the viewer's \quote {highlight a hyperlink when it's clicked on} feature. +%D We will use a menu, so we enable menus. Later we will see the contract color +%D |<|hyperlinks gets that color when we are already on the location|>| in action. + +\setupinteraction + [state=start, + click=off, + color=InteractionColor, + contrastcolor=ContrastColor, + menu=on] + +%D The menu itself is set up as follows. Because we will calculate menubuttons based +%D on their position on the page, we have to keep track of the positions. Therefore, +%D we set the \type {position} variable to \type {yes}. + +\setupinteractionmenu + [right] + [frame=off, + position=yes, + align=middle, + topoffset=.75cm, % watch out, these are negative in mkii + bottomoffset=.75cm, % watch out, these are negative in mkii + color=gray, + contrastcolor=gray, + style=bold, + before=, + after=] + +%D The menu content is rather sober: a list of topics (later we will define the +%D command that generates topic entries), and a close button. + +\startinteractionmenu[right] + \placelist[Topic][alternative=right] + \vfill + \but [CloseDocument] close \\ +\stopinteractionmenu + +%D We have now arived at the more interesting part of the style definition: the +%D graphic that goes in the page background. Because this graphic will change, we +%D define a usable \METAPOST\ graphic. Page backgrounds are recalculated each page, +%D opposite to the other backgrounds that are calculated when a new background is +%D defined, or when repetitive calculation is turned on. + +\setupbackgrounds + [page] + [background=page] + +\defineoverlay + [page] + [\useMPgraphic{page}] + +\setupMPvariables + [page] + [alternative=3] + +\startuseMPgraphic{page} + + \includeMPgraphic{rightsuperbutton} + + StartPage ; + + path p, q ; pickup pencircle scaled 3pt ; + + p := Field[Text][Text] enlarged 36pt superellipsed .90 ; + + fill Page withcolor \MPcolor{PageColor} ; + fill p withcolor \MPcolor{TextColor} ; + draw p withcolor \MPcolor{OrnamentColor} ; + + p := Field[Text][Text] enlarged 48pt superellipsed .90 ; + + def right_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) = + if (pp>0) and (rr>0) : + q := rightsuperbutton(p,xx,yy,RightEdgeWidth,hh) ; + fill q withcolor \MPcolor{TextColor} ; + draw q withcolor if rr=2 : \MPcolor{ContrastColor} + else : \MPcolor{InteractionColor} fi ; + fi ; + enddef ; + + \MPmenubuttons{right} + + StopPage ; +\stopuseMPgraphic + +\startuseMPgraphic{page} + + \includeMPgraphic{rightsuperbutton} + + StartPage ; + + numeric alternative, seed, superness, squeezeness, randomness ; + path p, q ; transform t ; + + alternative := \MPvar{alternative} ; + seed := uniformdeviate 100 ; + + if alternative > 10 : + superness := .85 + ((\realfolio-1)/max(\lastpage,1)) * .15 ; + squeezeness := 12pt - ((\realfolio-1)/max(\lastpage,1)) * 10pt ; + else : + superness := .90 ; + squeezeness := 12pt ; + fi ; + + randomness := squeezeness ; + + alternative := alternative mod 10 ; + + t := identity if alternative=3: shifted (9pt,-9pt) fi ; + + % first we draw the shape that surrounds the text + + randomseed := seed ; + + p := Field[Text][Text] enlarged if + alternative = 1 : 36pt superellipsed superness elseif + alternative = 2 : 36pt squeezed squeezeness elseif + alternative = 3 : 36pt randomized randomness else + : 36pt fi ; + + pickup pencircle scaled 3pt ; + + fill Page withcolor \MPcolor{PageColor} ; + fill p withcolor \MPcolor{TextColor} ; + draw p withcolor \MPcolor{OrnamentColor} ; + + % we set p to the wider shape from which we will chip off pieces + + randomseed := seed ; + + p := ( Field[Text][Text] enlarged if + alternative = 1 : 48pt superellipsed superness elseif + alternative = 2 : 48pt squeezed squeezeness elseif + alternative = 3 : 36pt randomized randomness else + : 48pt fi ) transformed t ; + + % calls to *_menu_button are generated automatically ... + + vardef right_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) = + save q ; path q ; + if (pp>0) and (rr>0) : + q := rightsuperbutton(p,xx,yy,RightEdgeWidth,hh) ; % \MPw{menu:right:\realfolio} + fill q withcolor \MPcolor{TextColor} ; + draw q withcolor if rr=2 : \MPcolor{ContrastColor} + else : \MPcolor{InteractionColor} fi ; + fi ; + enddef ; + + % ... and inserted when the graphic data is flushed here ... + + \MPmenubuttons{right} + + StopPage ; +\stopuseMPgraphic + +\startuseMPgraphic{rightsuperbutton} + + vardef rightsuperbutton (expr pat, xpos, ypos, wid, hei) = + + save p, ptop, pbot, t, b, edge, shift, width, height ; + path p, ptop, pbot ; pair t, b ; numeric edge, shift, width, height ; + + edge := xpos + wid ; shift := ypos + hei ; + + p := rightpath pat ; + + ptop := ((-infinity,shift)--(edge,shift)) ; + pbot := ((-infinity,shift-hei)--(edge,shift-hei)) ; + + t := p intersection_point ptop ; + b := p intersection_point pbot ; + + p := subpath(0,xpart (p intersectiontimes ptop)) of p ; + p := subpath(xpart (p intersectiontimes pbot),length(p)) of p ; + + (p -- t -- point 1 of ptop & + point 1 of ptop -- point 1 of pbot & + point 1 of pbot -- b + -- cycle) + + enddef ; + +\stopuseMPgraphic + +%D Topics are identified with \type {\Topic}, which is an instance of chapter +%D headings. The number is made invisible. Since it still is a numbered section +%D header, \CONTEXT\ will write the header to the table of contents. + +\definehead + [Topic] + [chapter] + +\setuphead + [Topic] + [number=no] + +%D We will use a bold font in the table of contents. We also force a complete +%D list. + +\setuplist + [Topic] + [criterium=all, + style=bold, + before=, + after=] + +%D The \type {\TitlePage} macro looks horrible, because we want to keep the +%D interface simple: a list of small sentences, separated by \type {\\}. + +\unexpanded\def\StartTitlePage + {\startstandardmakeup + \switchtobodyfont[big] + \def\\{\vfill\bfb\let\\=\par} + \bfd\setupinterlinespace\gray + \vskip.5cm\relax} + +\unexpanded\def\StopTitlePage + {\\ % the \\ is really needed + \vskip.5cm\relax + \stopstandardmakeup} + +\unexpanded\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D A couple of goodies: + +\unexpanded\def\Subject {\Topic} +\unexpanded\def\Topics #1{} +\unexpanded\def\Subjects {} + +\startsetups document:start + \StartTitlePage + \documentvariable{title} + \doifsomething {\documentvariable{subtitle}} { + \\ + \documentvariable{subtitle} + } + \doifsomething {\documentvariable{location}} { + \\ + \documentvariable{location} + } + \StopTitlePage +\stopsetups + +\startsetups document:stop + % +\stopsetups + +\stopmodule + +\continueifinputfile{s-present-organic.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-organic-001.tex} + diff --git a/tex/context/modules/mkiv/s-present-original.mkiv b/tex/context/modules/mkiv/s-present-original.mkiv new file mode 100644 index 000000000..809f7b2cb --- /dev/null +++ b/tex/context/modules/mkiv/s-present-original.mkiv @@ -0,0 +1,397 @@ +%D \module +%D [ file=s-present-original, % was s-pre-01 +%D version=1997.07.22, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Original, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This environment can be used to typeset interactive presentations. This module +%D was first used at the 1997 \TUG\ meeting. The \MKIV\ variant is mostly the same +%D but we adapted the colors a bit. + +\usemodule[present-general] + +\startmodule[present-original] + +%D \macros +%D {language} +%D +%D Because this module is defined in english, we default to the english hyphenation +%D patterns and labels too. This is default anyway. + +\mainlanguage + [en] + +%D \macros +%D {setupbodyfont,setuplayout} +%D +%D For screen reading, a Lucida Bright font looks nice. We use a 14.4 point bodyfont +%D for the main text, but switch back to 12 points for ornaments. + +\doifelsemode {asintended} { + \setupbodyfont[ludicaot,14.4pt] +} { + \setupbodyfont[pagella,14.4pt] +} + +\setuplayout + [style=smallbodyfont] + +\setupalign + [tolerant,stretch] + +%D \macros +%D {definecolor} +%D +%D Screen presentations without color just look dull, so we enable color support. We +%D define ourselves a yellowish backgroundcolor and a not too dark blue +%D interactioncolor. + +% \definecolor [BackgroundColor] [r=1, g=1, b=.7] +% \definecolor [InteractionColor] [r=.1, g=.5, b=.8] +% \definecolor [ContrastColor] [r=.9, g=.5, b=.2] + +\definecolor [BackgroundColor] [r=.7, g=.7, b=.3] +\definecolor [InteractionColor] [r=.1, g=.5, b=.8] +\definecolor [ContrastColor] [r=.9, g=.5, b=.2] + +%D \macros +%D {setuppapersize,setuplayout,setupinteractionscreen} +%D +%D We use a nice large screen, and dedicate the right edge and bottom part to +%D navigational tools. We automatically set the width and height of the page and +%D start up full screen. + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=12pt, + header=0pt, + footer=0pt, + height=402pt, % 450 - 12 - 15 - 12 - 12 + 3 + bottomdistance=15pt, + bottom=12pt, + backspace=12pt, + margin=0pt, + width=fit, + edgedistance=12pt, + rightedge=96pt] + +\setupinteractionscreen + [option=max] + +%D \macros +%D {setupbackgrounds} +%D +%D We set the pagecolor to yellow except the part of the screen that is used to +%D display the running text. By seting the offset to 3pt the text will not touch the +%D yellow parts. We do not set the depth. + +\setupbackgrounds + [page] + [background=color, + backgroundcolor=BackgroundColor] + +\setupbackgrounds + [text][text] + [background=color, + backgroundcolor=white, + backgroundoffset=3pt] + +%D I considered the next setup too, but finaly decided to +%D comment it out. +%D +%D \starttyping +%D \setupbackgrounds +%D [bottom][text] +%D [frame=on, +%D framecolor=white] +%D \stoptyping + +%D \macros +%D {setupinteraction} +%D +%D We did not enable interactive text support yet, so let's do that now. We force +%D page reference to circumvent problems with named destinations in buggy viewers. + +\setupinteraction + [page=yes, + color=InteractionColor, + contrastcolor=ContrastColor, + menu=on, + state=start] + +%D \macros +%D {setupinteractionmenu,startinteractionmenu} +%D +%D At the bottom of the screen we show two navigational bars. At the left we show +%D the subpage bar, at the right we use a non default backward|/|forward bar. + +\setupinteractionmenu + [bottom] + [leftoffset=3pt, + rightoffset=3pt] + +\startinteractionmenu[bottom] + \startcom \InteractionBar \stopcom + \hfill + \startcom \InteractionButtons \stopcom +\stopinteractionmenu + +%D \macros +%D {interactionbar} +%D +%D The left bar gets a white border (on the yellow background). Because we don't +%D want to typeset an empty frame when no subpage bar is shown, we check for the +%D number of subpages. + +\unexpanded\def\InteractionBar + {\ifnum\nofsubpages>\plusone + \framed + [framecolor=white, + rulethickness=1pt, + height=\bottomheight, + strut=no] + {\interactionbar[alternative=f,width=.5\makeupwidth,height=1ex]} + \fi} + +%D \macros +%D {setupinteractionbar, interactionbuttons} +%D +%D The right hand buttons enable us to jump backward and forward, as well as to the +%D previous and next jump. We also enable to close the presentation. + +\setupinteractionbar + [framecolor=white, + rulethickness=1pt, + height=\bottomheight, + strut=no] + +\unexpanded\def\InteractionButtons + {\interactionbuttons + [width=15em, + framecolor=white, + rulethickness=1pt, + height=\bottomheight, + strut=no, + distance=.5em] + [PreviousJump,NextJump, + firstpage, + firstsubpage,previouspage,nextpage,lastsubpage, + lastpage, + CloseDocument]} + +%D \macros +%D {StartTitlePage, TitlePage} +%D +%D The titlepage is rather simple and can be typeset in two ways: +%D +%D \starttyping +%D \StartTitlePage +%D text \\ text \\ text +%D \StopTitlepage +%D \stoptyping +%D +%D or more straightforward: +%D +%D \starttyping +%D \TitlePage{text\\text\\text} +%D \stoptyping +%D +%D The first alternative can be used for more complicated title pages. + +\unexpanded\def\StartTitlePage + {\startstandardmakeup + \bfd + \setupinterlinespace + \setupalign[middle] + \vfil + \let\\=\vfil} + +\unexpanded\def\StopTitlePage + {\vfil\vfil\vfil + \stopstandardmakeup} + +\unexpanded\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D \macros +%D {TitlePage, Topics, Topic, Subject} +%D +%D A presentation after loading this module looks like: +%D +%D \starttyping +%D \TitlePage {About Whatever\\Topics} +%D +%D \Topics {Todays Talk} +%D +%D \Topic {Some topic} +%D +%D \Subject {Alfa} +%D +%D ..... +%D +%D \Subject {Beta} +%D +%D ..... +%D \stoptyping + +%D \macros +%D {definehead} +%D +%D The commands \type{\Topic} and \type{\Subject} are defined as copies of head. We +%D use \type{\Nopic} for internal purposes. + +\definehead [Topic] [chapter] +\definehead [Subject] [section] + +\definehead [Nopic] [title] + +%D \macros +%D {setuphead} +%D +%D Because chapters and sections do not make sense in presentations, we use our own +%D command for typesetting the titles. Sectionnumbers are of course hidden from +%D viewing. Each topic is followed by a list of subjects that belong to the topic. + +\setuphead + [Topic,Nopic,Subject] + [command=\HeadLine, + page=yes, + style=\bfb, + after=\blank, + sectionnumber=no] + +\setuphead + [Topic] + [after=\PlaceSubjectList] + +\setuphead + [Subject] + [continue=no] + +%D \macros +%D {framed, midalined} +%D +%D The command used to typeset the head lines is rather simple. We just center the +%D framed title. The frame macro optimizes the alignment and at the same time +%D enables us to typeset a nice colored rule. + +\unexpanded\def\HeadLine#1#2% + {\midaligned + {\framed + [framecolor=BackgroundColor, + rulethickness=1pt, + width=.8\hsize, + align=middle, + strut=no] + {#2}}} + +%D \macros +%D {setuplist} +%D +%D The subject list is automatically placed. We center each subject line by using +%D one of the default alternatives (g). We could have said: +%D +%D \starttyping +%D \setuplist +%D [Subject] +%D [alternative=none, +%D command=\SubjectListLine, +%D interaction=all] +%D +%D \def\SubjectListLine#1#2#3% +%D {\midaligned{#2}} +%D \stoptyping +%D +%D But why should we complicate things when we can use alternative~\type{g}. The +%D test is only needed if one does not automatically goes a new page with each +%D subject. + +\unexpanded\def\PlaceSubjectList + {\blank + \determinelistcharacteristics[Subject] + \doifmode{*list}{\placelist[Subject]}} + +\setuplist + [Subject,Topic] + [alternative=g, + interaction=all, + before=, + after=] + +% %D \macros +% %D {setuptexttexts} +% %D +% %D The topics will be listed in the right edge, using: +% +% \setuptexttexts +% [edge] +% [][\TopicList] + +%D \macros +%D {setuplist, placelist,startinteractionmenu} +%D +%D The actual topic list is typeset using a \type{\vbox}. We have to specify +%D \type{criteriumcriterium=all} because otherwise no list will be typeset. (By +%D default lists are typeset locally.) + +\startinteractionmenu[right] + \placelist + [Topic] + [alternative=f, % command, % none, + maxwidth=\hsize, + width=\hsize, + offset=0pt, + criterium=all, + align=left, + style=\smallbodyfont\bfx] +\stopinteractionmenu + +\unexpanded\def\Topics#1% temporary hack + {\Nopic{#1} + \placelist[Topic][criterium=all]} + +\unexpanded\def\Subjects + {} + +%D \macros +%D {setupbackgrounds, overlaybutton} +%D +%D During a presentation, we want to use the cursor to point to parts of the text. +%D Furthermore we want to be able to jump to the next page, without the need to move +%D the cursor on buttons. Therefore we make the text part of the screen into an +%D invisible button. +%D +%D In \MKII\ we put a button in he texttextsm here we just use an extra background. + +\defineoverlay[nextpage][\overlaybutton{nextpage}] + +\setupbackgrounds + [text][text] + [background={color,nextpage}] + +%D \macros +%D {setupsubpagenumber} +%D +%D The left bottom navigation bar shows the subpages, which will be counted by text. +%D One can change this in the preentation itself by saying \type {[way=byTopic]}. + +\setupsubpagenumber + [way=bytext, % byTopic, + state=start] + +\stopmodule + +\continueifinputfile{s-present-original.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-original-001.tex} diff --git a/tex/context/modules/mkiv/s-present-ovals.mkiv b/tex/context/modules/mkiv/s-present-ovals.mkiv new file mode 100644 index 000000000..45af6c823 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-ovals.mkiv @@ -0,0 +1,94 @@ +%D \module +%D [ file=s-present-ovals, +%D version=2015.04.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Ovals, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This style was made for some of the font and language related presentations at +%D Bacho\TeX\ 2015. It's a bit boring but it suits simple presentations. It provides +%D no structure as each page content is kind of special. + +\startmodule[s-present-ovals] + +\setuppapersize[S6] + +\definecolor[maincolor] [darkred] +\definecolor[othercolor][maincolor] + +\startuseMPgraphic{page} + + fill Page enlarged 2mm withcolor .5[white,\MPcolor{othercolor}] ; + + if NOfPages > 1 : + + numeric PageFraction ; PageFraction := (RealPageNumber-1) / (NOfPages-1) ; + numeric WidthDelta ; WidthDelta := 2 * PaperWidth / 10 ; + numeric HeightDelta ; HeightDelta := 2 * PaperHeight / 10 ; + numeric WidthOffset ; WidthOffset := WidthDelta + PageFraction*(PaperWidth - 2WidthDelta ) ; + numeric HeightOffset ; HeightOffset := HeightDelta + PageFraction*(PaperHeight - 2HeightDelta) ; + + fill + (ulcorner Page) shifted (WidthOffset,0) .. + (urcorner Page) shifted (0,-HeightOffset) .. + (lrcorner Page) shifted (-WidthOffset,0) .. + (llcorner Page) shifted (0,HeightOffset) .. + cycle withcolor \MPcolor{maincolor} ; + + clip currentpicture to Page ; + + fi ; + +\stopuseMPgraphic + +% e-mess has always been okay by definition which makes it easier to blame generators + +\defineoverlay + [page] + [\useMPgraphic{page}] + +\setupbackgrounds + [page] + [background=page] + +\setupalign + [middle,broad] + +\setupcolors + [textcolor=white] + +\setupbodyfont + [pagella,17.3pt] + +\setuplayout + [height=middle, + width=middle, + topspace=.05\paperheight, + backspace=.15\paperwidth, + header=0pt, + footer=0pt] + +\setupwhitespace + [line] + +\setuphead + [title] + [style=\bfb, + alternative=middle, + before=, + number=no] + +\stopmodule + +\continueifinputfile{s-present-ovals.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{bachotex/2015/bachotex-2015-ligatures.tex} +%inputpresentationfile{bachotex/2015/context-2015-status.tex} diff --git a/tex/context/modules/mkiv/s-present-overlap.mkiv b/tex/context/modules/mkiv/s-present-overlap.mkiv new file mode 100644 index 000000000..053455b4b --- /dev/null +++ b/tex/context/modules/mkiv/s-present-overlap.mkiv @@ -0,0 +1,233 @@ +%D \module +%D [ file=s-present-overlap, % was s-pre-62, +%D version=2005.03.04, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Overlap, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[present-stepwise] + +\startmodule[present-overlap] + +\doifmodeelse {atpragma} { + + \usetypescriptfile + [type-ghz] + + \definetypeface[mainface][rm][serif][melior] [default][encoding=texnansi] + \definetypeface[mainface][tt][mono] [modern] [default][encoding=texnansi,rscale=1.05] + \definetypeface[mainface][ss][serif][melior] [default][encoding=texnansi] + \definetypeface[mainface][mm][math] [palatino][default][encoding=texnansi,rscale=0.95] + + \setupbodyfont + [mainface,14.4pt] + +} { + + \setupbodyfont[dejavu,14.4pt] + +} + +\setuppapersize + [S6][S6] + +\setvariables[layout][dx=0,dy=1,nx=2,ny=2,step=64] + +\definemeasure[layoutwd][\dimexpr\paperwidth /\getvariable{layout}{step}\relax] +\definemeasure[layoutht][\dimexpr\paperheight/\getvariable{layout}{step}\relax] + +\setuplayout + [ width=middle, + height=middle, + header=0pt, + footer=0pt, + margin=0pt, + backspace=5\measured{layoutwd}, + topspace=5\measured{layoutht}] + +\definelayout + [step] + [ backspace=\numexpr2+ \getvariable{layout}{dx}\relax\measured{layoutwd}, + cutspace=\numexpr3+\getvariable{layout}{nx}-\getvariable{layout}{dx}\relax\measured{layoutwd}, + topspace=\numexpr2+ \getvariable{layout}{dy}\relax\measured{layoutht}, + bottomspace=\numexpr3+\getvariable{layout}{ny}-\getvariable{layout}{dy}\relax\measured{layoutht}] + +\definecolor[layout:left] [t=.5,a=1,b=1] +\definecolor[layout:right] [t=.5,a=1,r=1] +\definecolor[layout:top] [t=.5,a=1,g=1] +\definecolor[layout:bottom][t=.5,a=1,y=1] +\definecolor[layout:page] [s=.75] + +\definehspace[menu][\measured{layoutwd}] + +\setupinteraction + [state=start, + click=off, + style=, + color=interactioncolor, + contrastcolor=interactioncolor] + +\setupinteractionscreen + [option=max] + +\setupbuttons + [color=maincolor, + contrastcolor=maincolor, + style=\tf, % acceptable + height=2\measure{layoutht}, + width=2\measure{layoutwd}, + offset=overlay, + frame=off] + +\definecolor[interactioncolor][darkgray] +\definecolor[maincolor] [lightgray] + +\setuptexttexts + [] + [\vbox to \textheight{\vfill\hfill\setups{menu:content}}] + +\startsetups menu:content + + \button{\symbol[firstpage]}[firstpage] + \hspace[menu] + \button{\symbol[previouspage]}[previouspage] + \hspace[menu] + \button{\StartBusy\symbol[PauseRendering]\StopBusy}[InvokeStepper] + \hspace[menu] + \button{\symbol[nextpage]}[nextpage] + \hspace[menu] + \button{\symbol[lastpage]}[lastpage] + \hspace[menu] + \button{\symbol[CloseDocument]}[CloseDocument] + +\stopsetups + +\startuseMPgraphic{page}{step} + StartPage ; + numeric dx ; dx := PaperWidth /\MPvar{step} ; + numeric dy ; dy := PaperHeight/\MPvar{step} ; + fill Page withcolor .5white ; + fill + ulcorner Page -- urcorner Page -- + urcorner Page shifted (0,-TopSpace+dy) -- ulcorner Page shifted (0,-TopSpace+dy) -- cycle + withcolor "layout:top" ; + fill + llcorner Page -- lrcorner Page -- + lrcorner Page shifted (0,BottomSpace-dy) -- llcorner Page shifted (0,BottomSpace-dy) -- cycle + withcolor "layout:bottom" ; + fill + ulcorner Page -- llcorner Page -- + llcorner Page shifted (BackSpace-dx,0) -- ulcorner Page shifted (BackSpace-dx,0) -- cycle + withcolor "layout:left" ; + fill + urcorner Page -- lrcorner Page -- + lrcorner Page shifted (-CutSpace+dx,0) -- urcorner Page shifted (-CutSpace+dx,0) -- cycle + withcolor "layout:right" ; + fill Field[Text][Text] enlarged (dx,dy) withcolor white ; + fill Field[Text][Text] enlarged (dx,dy) withcolor "layout:page" ; + StopPage ; +\stopuseMPgraphic + +\defineoverlay[page][\useMPgraphic{page}{step=\getvariable{layout}{step}}] + +\setupbackgrounds + [page] + [background=page] + +\setupcolors + [state=start] + +\startsetups nextstep + % pagebreak handlers are grouped, so we need to set global + \ifnum\getvariable{layout}{dx}=\getvariable{layout}{nx}\relax + \ifnum\getvariable{layout}{dy}=\getvariable{layout}{ny}\relax + \setxvariables[layout][dy=1] + \else + \setxvariables[layout][dy=\the\numexpr\getvariable{layout}{dy}+1\relax] + \fi + \setxvariables[layout][dx=1] + \else + \setxvariables[layout][dx=\the\numexpr\getvariable{layout}{dx}+1\relax] + \fi + % global anyway + \setuplayout[step] +\stopsetups + +\appendtoks + \definefont[ChapterTitleFont][SerifBold*default sa 2] + \NormalizeFontHeight \SubTitleFont {\setstrut\strut\quad} {3\lineheight} {SerifBold*default} + \NormalizeFontHeight \ChapterNumberFont {XVI} {4\lineheight} {SerifBold*default} +\to \everystarttext + +\setupsection + [section-2] + [bodypartconversion=Romannumerals] + +\installpagebreakhandler {step} {\setups{nextstep}} + +\definepagebreak[chapter][yes,step] + +\setuphead + [chapter] + [page=chapter, + command=\MyChapterCommand, + after=\nowhitespace] + +\definehead[Topic][chapter] +\definehead[Nopic][title] + +\setuphead[chapter,Topic,Nopic] + [numberstyle=\ChapterNumberFont, + textstyle=\ChapterTitleFont, + numbercolor=lightgray, + textcolor=darkgray] + +\unexpanded\def\MyChapterCommand#1#2% + {\hbox \bgroup % we need to nil the strut added by the headplacement + \setupframed[frame=off,lines=3,offset=overlay]% + \rlap{\hskip2\lineheight\framed{\setnostrut#1}}% + \framed{#2}% + \egroup} + +\setupitemize + [each] + [R,broad] + [stopper=, + color=lightgray] + +\startsetups document:start + + \startstandardmakeup[headerstate=high,textstate=stop] + + \setupalign[middle] + + \vfil + \startcolor[darkgray] + \dontleavehmode\scale[width=.9\textwidth]{\bf\setstrut\strut\documentvariable{title}} + \vfil + \dontleavehmode\scale[width=.7\textwidth]{\bf\setstrut\strut\documentvariable{subtitle}} + \vfil \vfil \vfil + \dontleavehmode\scale[width=.5\textwidth]{\bf\setstrut\strut\documentvariable{location}} + \stopcolor + \vfil \vfil \vfil + + \stopstandardmakeup + +\stopsetups + +\stopmodule + +\continueifinputfile{s-present-overlap.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{context/2011/context-2011-mathml-update.tex} +%\inputpresentationfile{context/2011/context-2011-metapost-how-we-adapt.tex} +%\inputpresentationfile{context/2011/context-2011-ebook-export.tex} +%\inputpresentationfile{context/2011/context-2011-sorting-registers.tex} diff --git a/tex/context/modules/mkiv/s-present-phone.mkiv b/tex/context/modules/mkiv/s-present-phone.mkiv new file mode 100644 index 000000000..d041ad822 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-phone.mkiv @@ -0,0 +1,108 @@ +%D \module +%D [ file=s-present-phone, +%D version=2016.04.20, % or about +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Phone, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D The theme of Bacho\TeX\ was \quote {Getting \TEX\ out of the closet}. And, as I'm +%D always a bit sceptical about efforts to get a specialized toolbox like \TEX\ +%D accepted in a large scale generic user base, I decided to give a talk dedicated +%D to Jerzy (the always optimistic organizer). (One can actually wonder if \TEX\ was +%D ever hidden in a closet.) And, because I had to get the attention of some nephew +%D and nieces I took there I gave the presentation without beamer but on my phone. +%D On such a device one just swipes but I still added two buttons. Watch the small +%D full|-|hd|-|ratio paper dimensions and 6 point font size. + +\startmodule[s-present-phone] + +\setupinteraction + [state=start] + +\definepapersize + [phone] + [width=108.0pt, + height=192.0pt] + +\definelayout + [phone] + [backspace=3pt, + topspace=6pt, + bottomspace=3pt, + header=0pt, + footer=0pt, + bottom=10pt, + bottomdistance=5pt, + height=fit, + width=middle] + +\setuplayout + [phone] + +\setuppapersize + [phone] + +\setupbodyfont + [dejavu,ss,6pt] + +\setupalign + [tolerant,flushleft] + +\setupbackgrounds + [page] + [background=color, + backgroundcolor=maincolor] + +\setupbackgrounds + [bottom] + [text] + [background=color, + backgroundcolor=othercolor, + backgroundoffset=\backspace] + +\definecolor[maincolor] [r=.7,g=.3,b=0] +\definecolor[othercolor][r=0,g=.3,b=.7] + +\setupcolors + [textcolor=white] + +\setupinteraction + [menu=on, + color=white, + contrastcolor=white] + +\setupinteractionmenu + [bottom] + [state=start, + style=\ss\bf] + +\setupitemgroup + [itemize] + [inbetween={\blank[medium]}] + +\startinteractionmenu[bottom] + \startgot [previouspage] \textminus \stopgot + \starttxt \getmarking[section] \stoptxt + \startgot [nextpage] \textplus \stopgot +\stopinteractionmenu + +\setuphead + [section] + [page=yes, + before=, + after={\blank[disable]}, + placehead=empty] + +\stopmodule + +\continueifinputfile{s-present-phone.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{bachotex/2016/bachotex-2016-toolbox.tex} diff --git a/tex/context/modules/mkiv/s-present-punk.mkiv b/tex/context/modules/mkiv/s-present-punk.mkiv new file mode 100644 index 000000000..346f7eae8 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-punk.mkiv @@ -0,0 +1,158 @@ +%D \module +%D [ file=s-present-punk, +%D version=2008.04.15, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Punk, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[present-punk] + +%D At the cost of more runtime and a larger output file, we +%D turn on randomization. The instances are cached in the +%D MkIV cache, so successive runs use the same shapes. + +% \usemodule[punk] \usetypescript[punk] \setupbodyfont[punk,20pt] +% +% \EnableRandomPunk + +\setupbodyfont[punknova,20pt] % we now use the opentype variant + +%D We use the regular screen size paper and layout setup. + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=30pt, + backspace=30pt, + width=middle, + height=fit, + header=0pt, + footer=0pt, + bottomdistance=24pt, + bottom=30pt, + bottom=18pt, + top=0pt] + +\setupinterlinespace + [top=height, + line=1.25\bodyfontsize] + +\setupcolors + [state=start, + textcolor=white] + +\setupinteraction + [state=start, + %click=off, + menu=on] + +%D We predefine a few palets. Of course you can define more. + +\definecolor[punkblue] [r=.4,b=.8,g=.4] +\definecolor[punkgreen] [r=.4,b=.4,g=.8] +\definecolor[punkred] [r=.8,b=.4,g=.4] +\definecolor[punkyellow][r=.6,g=.6,b=.2] + +\definepalet [punk-one] [textcolor=punkblue,pagecolor=punkgreen] +\definepalet [punk-two] [textcolor=punkred,pagecolor=punkyellow] +\definepalet [punk-three] [textcolor=punkblue,pagecolor=punkyellow] +\definepalet [punk-one-reverse] [textcolor=punkgreen,pagecolor=punkblue] +\definepalet [punk-two-reverse] [textcolor=punkyellow,pagecolor=punkred] +\definepalet [punk-three-reverse] [textcolor=punkyellow,pagecolor=punkblue] + +\setuppalet[punk-one] + +%D We use a few backgrounds. The hyperlink that invokes the stepper is hooked +%D into the text background. + +\definelayer + [page] + [width=\paperwidth, + height=\paperheight] + +\setupbackgrounds + [page] + [background={color,page}, + backgroundcolor=pagecolor, + setups=pagestuff] + +\setupbackgrounds + [text] + [background={color,invoke}, + backgroundoffset=12pt, + backgroundcolor=textcolor] + +%D We need different symbols for itemized lists. + +\definesymbol[1][\hbox{\lower1ex\hbox{*}}] +\definesymbol[2][\endash] +\definesymbol[3][\letterhash] +\definesymbol[3][>] + +%D We don't want these reversed clicked areas in Acrobat. + +\setupinteraction + [click=no, + color=white, % pagecolor, + contrastcolor=white] % pagecolor, + +%D We define a rather simple navigational panel at the bottom + +\setupinteractionmenu + [bottom] + [color=white, % pagecolor, + contrastcolor=white, % pagecolor, + background=color, + backgroundcolor=textcolor, + frame=off, + height=24pt, + left=\hfill, + middle=\hskip12pt] + +\setupsubpagenumber + [state=start] + +\startinteractionmenu[bottom] + \starttxt + \interactionbar + [alternative=d, + symbol=yes, + color=white, + contrastcolor=textcolor] + \stoptxt + \hfilll + \startbut [previouspage] < < < \stopbut + \startbut [nextpage] > > > \stopbut +\stopinteractionmenu + +%D Instead of the normal symbols we use more punky ones. + +\startsymbolset [punk] + \definesymbol[previous] [\string<\string<] + \definesymbol[somewhere] [\string^\string^] + \definesymbol[next] [\string>\string>] +\stopsymbolset + +\setupinteraction + [symbolset=punk] + +%D Because the font is rather large, we use less whitespace. + +\setuphead + [chapter] + [after={\blank[big]}] + +\stopmodule + +\continueifinputfile{s-present-punk.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-punk-001.tex} diff --git a/tex/context/modules/mkiv/s-present-random.lua b/tex/context/modules/mkiv/s-present-random.lua new file mode 100644 index 000000000..f32d7aaea --- /dev/null +++ b/tex/context/modules/mkiv/s-present-random.lua @@ -0,0 +1,66 @@ +if not modules then modules = { } end modules ['present-random'] = { + version = 1.001, + comment = "companion to s-present-random.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- For the moment we keep the namespace steps because it can become some +-- shared module some day. + +moduledata.steps = moduledata.steps or { } +local steps = moduledata.steps + +local locations = { + 'lefttop', + 'middletop', + 'righttop', + 'middleleft', + 'middle', + 'middleright', + 'leftbottom', + 'middlebottom', + 'rightbottom', +} + +local done, current, previous, n + +function steps.reset_locations() + done, current, previous, n = table.tohash(locations,false), 0, 0, 0 +end + +function steps.next_location(loc) + previous = current + n = n + 1 + loc = loc and loc ~= "" and tonumber(loc) + while true do + current = loc or math.random(1,#locations) + if not done[current] then + done[current] = true + break + end + end +end + +function steps.current_location() + context(locations[current] or "") +end + +function steps.previous_location() + context(locations[previous] or "") +end + +function steps.current_n() + context(current) +end + +function steps.previous_n() + context(previous) +end + +function steps.step() + context(n) +end + +steps.reset_locations() diff --git a/tex/context/modules/mkiv/s-present-random.mkiv b/tex/context/modules/mkiv/s-present-random.mkiv new file mode 100644 index 000000000..5744241fc --- /dev/null +++ b/tex/context/modules/mkiv/s-present-random.mkiv @@ -0,0 +1,215 @@ +%D \module +%D [ file=s-present-random, +%D version=2008.08.05, % updated 2016.10.20 +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Random, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[present-random] + +%D Unfortunately there are not that many viewers that support javascript +%D control over layers. + +% \enablemode[numbers] +% \enablemode[paper] +% \usemodule[present-stepwise] + +\registerctxluafile{s-present-random}{} + +\setupinteraction + [state=start, + click=off] + +\definepapersize + [wide] + [width=900pt, + height=600pt] + +\setuppapersize + [wide] + [wide] + +\setuplayout + [page] + +\setupsorting + [logo] + [style=] + +\startnotmode[paper] + + \setupbackgrounds + [page] + [background=color, + backgroundcolor=black] + +\stopnotmode + +\definelayer + [page] + [width=\paperwidth, + height=\paperheight] + +\definecolor[TopicColor-1][r=.3,g=.4,b=.5] +\definecolor[TopicColor-2][r=.3,g=.5,b=.4] +\definecolor[TopicColor-3][r=.4,g=.3,b=.5] +\definecolor[TopicColor-4][r=.4,g=.5,b=.3] +\definecolor[TopicColor-5][r=.5,g=.3,b=.4] +\definecolor[TopicColor-6][r=.5,g=.4,b=.3] +\definecolor[TopicColor-7][r=.35,g=.35,b=.6] +\definecolor[TopicColor-8][r=.6,g=.35,b=.35] +\definecolor[TopicColor-9][r=.35,g=.6,b=.35] + +\definecolor[TopicColor-0][t=.5,a=1,s=.5] +\definecolor[TopicColor] [s=1] + +\setupcolors + [textcolor=TopicColor] + +\starttexdefinition unexpanded StartTopics + \doifelsemode {paper} { + \disablemode[stepper] + \enablemode[onepagestepper] + } { + \doifelsedefined {NextStep} { + \enablemode[stepper] + \disablemode[onepagestepper] + } { + \disablemode[stepper] + \disablemode[onepagestepper] + } + } + \doifelsemode {onepagestepper} { + \startstandardmakeup[top=,bottom=\vfill] + } { + \setuplayer[state=repeat] + \resetlayer[page] + } + \ctxlua{moduledata.steps.reset_locations()} + \doifmode {interactivestepper} { + \StartLocalSteps + } +\stoptexdefinition + +\starttexdefinition unexpanded StopTopics + \doifmode {interactivestepper} { + \StopLocalSteps + } + \doifelsemode {onepagestepper} { + \flushlayer[page] + \stopstandardmakeup + } { + \resetlayer[page] + } +\stoptexdefinition + +\starttexdefinition unexpanded StartTopic + \dosingleempty\doStartTopic +\stoptexdefinition + +\starttexdefinition unexpanded doStartTopic [#1] + \doifmode {interactivestepper} { + \NextStep + } + \ctxlua{moduledata.steps.next_location("#1")} + \doifmode {paper} { + \doifnothing {#1} { + \ifcase\ctxlua{moduledata.steps.previous_n()}\else + \setlayer + [page] + [preset=\ctxlua{moduledata.steps.previous_location()}] + \bgroup + \doifmode {interactivestepper} { + \startviewerlayer[\StepLayer] + } + \framed + [offset=20pt, + strut=no, + align=normal, + frame=off, + height=\dimexpr\paperheight/3\relax, + width=\dimexpr\paperwidth/3\relax, + background=color, + backgroundcolor=TopicColor-0] + {} + \doifmode {interactivestepper} { + \stopviewerlayer + } + \egroup + \fi + } + } + \setlayer + [page] + [preset=\ctxlua{moduledata.steps.current_location()}] + \bgroup + \doifmode {interactivestepper} { + \startviewerlayer[\StepLayer] + } + \framed + [offset=20pt, + strut=no, + align=\expdoifelse{#1}{}{normal}{middle,lohi}, + align=\expdoifelse{#1}{}{flushleft,verytolerant}{middle,lohi}, + frame=off, + height=\dimexpr\paperheight/3\relax, + width=\dimexpr\paperwidth/3\relax, + background=color, + backgroundcolor=TopicColor-\ctxlua{moduledata.steps.current_n()}] + \bgroup + \ignorespaces +\stoptexdefinition + +\starttexdefinition unexpanded StopTopic + \removeunwantedspaces + \egroup + \doifmode {interactivestepper} { + \stopviewerlayer + } + \egroup + \doifmode {numbers} { + \setlayerframed + [page] + [preset=\ctxlua{moduledata.steps.current_location()}] + [height=\dimexpr\paperheight/3\relax, + width=\dimexpr\paperwidth/3\relax, + frame=off, + foregroundstyle=\bfa, + align={flushright,low}] + \bgroup + \doifmode {interactivestepper} { + \startviewerlayer[\StepLayer] + } + \ctxlua{moduledata.steps.step()}\kern\strutdepth + \doifmode {interactivestepper} { + \stopviewerlayer + } + \egroup + } + \doifnotmode {onepagestepper} { + \startstandardmakeup[top=,bottom=\vfill] + \flushlayer[page] + \stopstandardmakeup + } +\stoptexdefinition + +\definefont[TitleFont][SansBold*default at 60pt] +\definefont[TempFont] [SansBold*default at 12pt] + +\let\StartText\starttext % for old times sake +\let\StopText \stoptext % for old times sake + +\stopmodule + +\continueifinputfile{s-present-random.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-random-001.tex} + diff --git a/tex/context/modules/mkiv/s-present-shaded.mkiv b/tex/context/modules/mkiv/s-present-shaded.mkiv new file mode 100644 index 000000000..df6ab9c5c --- /dev/null +++ b/tex/context/modules/mkiv/s-present-shaded.mkiv @@ -0,0 +1,161 @@ +%D \module +%D [ file=s-present-shaded, +%D version=2014.04.30, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Shaded Content, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D As usual, this style was made for a Bacho\TeX\ conference. It doesn't do anything +%D special apart from progressively changing the shaded backgrounds. You can +%D redefine the colors \type {maincolor} and \type {othercolor} to suit your taste. + +\startmodule[present-shaded] + +\setuppapersize[S6] + +\setuplayout + [cutspace=120pt, + rightmargin=100pt, + margindistance=10pt, + rightmargin=0pt, + margindistance=0pt, + rightedge=100pt, + edgedistance=12.5pt, + backspace=10pt, + topspace=10pt, + bottomspace=10pt, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +\setupbodyfont + [dejavu] + +\setuplist + [chapter] + [before=, + after=, + inbetween=\vskip5pt, + inbetween=\vfill, + alternative=e, + width=\hsize, + height=\measure{menu-item-height}, + style=bold, + frame=off, + background=color, + backgroundcolor=\structurelistuservariable{color}, + criterium=text] + +\setupcolors + [textcolor=white] + +\setupinteraction + [state=start, + menu=on, + color=white, + click=off, + contrastcolor=white] + +\setupinteractionmenu + [right] + [topoffset=5pt, + bottomoffset=5pt] + +\startinteractionmenu[right] + \placelist[chapter] +\stopinteractionmenu + +\definecolor[maincolor] [b=.4] +\definecolor[othercolor][s=.4] + +\definecolor[verydark][s=.2] +\definecolor[lessdark][1.5(verydark)] + +% we need some extra counter values: \getstructurenumber{self} + +\setupmodule + [n=\the\numexpr\lastpage-\plusone\relax] + +\appendtoks + \dorecurse {\moduleparameter{present-shaded}{n}} { + \definecolor[shade:#1][\luaexpr{.8*#1/\moduleparameter{present-shaded}{n}}(maincolor,othercolor)] + } +\to \everystarttext + +\setupbackgrounds + [page] + [background=color, + backgroundoffset=5pt, + backgroundcolor=verydark] + +\setupbackgrounds + [text] + [background={invoke,color}, + backgroundoffset=5pt, + backgroundcolor=\namedstructureuservariable{chapter}{color}] + +\definemeasure + [menu-item-height] + [(\textheight-\numexpr\moduleparameter{present-shaded}{n}-1\relax\dimexpr5pt\relax)/\moduleparameter{present-shaded}{n}] + +\setupitemgroup + [itemize] + [packed] + +\setuphead + [chapter] + [number=no, + style=\bfc] + +\setuphead + [section] + [number=no, + style=\bf, + before=\blank, + after=\blank] + +\setupdocument + [title=Title, + subtitle=Subtitle, + location=\currentdate] + +\startsetups document:start + + \setupbackgrounds + [text] + [backgroundcolor=lessdark] + + \startstandardmakeup + + \setupalign[middle] + + \vfil + \dontleavehmode \scale[width=.8\textwidth] {\documentvariable{title}} + \vfil + \dontleavehmode \scale[width=.6\textwidth] {\documentvariable{subtitle}} + \vfil \vfil \vfil + \dontleavehmode \scale[width=.4\textwidth] {\documentvariable{location}} + \vfil + + \stopstandardmakeup + + \setupbackgrounds + [text] + [backgroundcolor=\namedstructureuservariable{chapter}{color}] + +\stopsetups + +\stopmodule + +\continueifinputfile{s-present-shaded.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-shaded-001.tex} diff --git a/tex/context/modules/mkiv/s-present-simple.mkiv b/tex/context/modules/mkiv/s-present-simple.mkiv new file mode 100644 index 000000000..4fadf1f9f --- /dev/null +++ b/tex/context/modules/mkiv/s-present-simple.mkiv @@ -0,0 +1,151 @@ +%D \module +%D [ file=s-present-simple, % was: s-pre-68, +%D version=2009.08.28, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Simple, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[present-stepwise] + +\startmodule[present-simple] + +% style + +\setuppapersize + [S66][S66] + +\setuplayout + [height=middle, + width=middle, + header=0pt, + footer=0pt, + backspace=2cm, + topspace=2cm] + +\setupinteraction + [state=start, + click=no] + +\definecolor[maincolor][r=.4] + +\startreusableMPgraphic{page} + StartPage ; + fill Page enlarged 5mm withcolor "maincolor" ; + StopPage ; +\stopreusableMPgraphic + +\startreusableMPgraphic{next} + fill ultriangle scaled .15PaperWidth withcolor white ; +\stopreusableMPgraphic + +\startreusableMPgraphic{last} + fill boundingbox(ultriangle scaled .15PaperWidth) withcolor white ; +\stopreusableMPgraphic + +\startuniqueMPgraphic{bullit} + fill ultriangle scaled 2ExHeight withcolor white ; +\stopuniqueMPgraphic + +\definelayer + [extra] + [width=\paperwidth, + height=\paperheight] + +\defineoverlay + [page] + [\reuseMPgraphic{page}] + +\setupbackgrounds + [page] + [background={page,extra}] + +\setupcolors + [state=start, + textcolor=white] + +\setuphead + [chapter] + [style=\bfc] + +\definehead + [Title] + [title] + +\definesymbol + [MyBullet] + [\uniqueMPgraphic{bullit}] + +\setupitemgroup + [itemize] + [each] + [symbol=MyBullet] + +\doifelsemode {asintended,atpragma} { + \setupbodyfont[cambria,14.4pt] +} { + \setupbodyfont[pagella,14.4pt] +} + +% interface + +\unexpanded\def\StartItems + {\begingroup + \StartSteps + \startitemize + \unexpanded\def\StartItems{\startitemize\unexpanded\def\StopItems{\stopitemize}}} + +\unexpanded\def\StopItems + {\FlushStep + \stopitemize + \NextPageSymbol + \StopSteps + \endgroup} + +\unexpanded\def\Item + {\unexpanded\def\Item{\FlushStep\item} + \item} + +\unexpanded\def\NextPageSymbol + {\setlayer + [extra] + [preset=rightbottom,offset=2mm] + {\ifnum\realpageno=\lastpage\relax + \reuseMPgraphic{last}% + \else\ifnum\realpageno>\plusone + \reuseMPgraphic{next}% + \fi\fi + \FlushStep}} + +\unexpanded\def\TitlePage#1#2% + {\startstandardmakeup[bottom=,top=] + \scale[width=\textwidth]{\framed[align=flushleft,foregroundstyle=\bf,frame=off]{#1}} + \vfilll + \hfill\scale[width=.5\textwidth]{\framed[align=flushright,foregroundstyle=\bf,frame=off]{#2}} + \stopstandardmakeup} + +\unexpanded\def\StartTopic#1% + {\Title{#1}} + +\unexpanded\def\StopTopic + {\page} + +\startsetups document:start + \TitlePage + {\documentvariable{title}} + {\documentvariable{author}\\ + \documentvariable{location}} +\stopsetups + +\stopmodule + +\continueifinputfile{s-present-simple.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-simple-001.tex} diff --git a/tex/context/modules/mkiv/s-present-slanted.mkiv b/tex/context/modules/mkiv/s-present-slanted.mkiv new file mode 100644 index 000000000..a68e0cd8e --- /dev/null +++ b/tex/context/modules/mkiv/s-present-slanted.mkiv @@ -0,0 +1,206 @@ +%D \module +%D [ file=s-present-slanted, % was: s-pre-64, +%D version=2006.05.11, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Slanted, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This style is kept as reference (but can be usedof course). It was used at the +%D TUG conference in San Diego in 2007 (the very early days if \LUATEX\ and \MKIV). +%D +%D This was one of he four presentations, each with a different style. The other +%D styles were quite ok but I just lack time (ane motivation) to generalize them, + +\usemodule[s][pre-60] + +\newcounter\shapesynctag +\newdimen \slantedshapedimen +\newdimen \slantedshapestep +\newdimen \slantedshapeleftskip +\newdimen \slantedshapeoffset +\newdimen \slantedshapeextra +\newdimen \slantedshapedelta + +\positioningtrue + +\unexpanded\def\AdaptShape + {\doglobal\increment\shapesynctag + \getnoflines\textheight + \slantedshapestep\dimexpr\slantedshapeleftskip/\noflines\relax + \leftskip\slantedshapeleftskip + \scratchdimen\dimexpr + \MPy{text:\MPp\shapesynctag} + +\MPh{text:\MPp\shapesynctag} + -\topskip + -\MPy\shapesynctag + +\slantedshapeextra + \relax + \getnoflines\scratchdimen + \slantedshapedimen \noflines \slantedshapestep + \scratchtoks\emptytoks + \dorecurse{30} + {\appendetoks + \the\dimexpr + -\slantedshapedimen + +\slantedshapeoffset + +\slantedshapedelta + \relax + \space + \the\dimexpr + \hsize + -2\slantedshapeoffset + \relax + \space + \to\scratchtoks + \advance\slantedshapedimen \slantedshapestep}% + \parshape 30 \the\scratchtoks + \strut\xypos\shapesynctag} + +\setuppapersize[S6][S6] + +\setupinteraction + [state=start, + click=no] + +\setupinteractionscreen + [option=max] + +\setuplayout + [backspace=12pt, + topspace=24pt, + height=middle, + width=middle, + header=0pt, + footer=0pt] + +\definecolor[maincolor][b=.5] +\definecolor[somecolor][g=.5] +\definecolor[morecolor][r=.5] + +\setupcolors + [textcolor=maincolor] + +\setupbodyfont + [pagella] + +\setupbackgrounds + [text]% [text] + [background={base,text,invoke}] + +\definelayer + [text] + [width=\textwidth, + height=\textheight] + +\definelayer + [base] + [width=\textwidth, + height=\textheight] + +\definetype [epet] [style=,color=morecolor] +\setuptype [style=,color=somecolor] +\slantedshapeleftskip150pt +\slantedshapeoffset 12pt +\slantedshapeextra 10pt + +\startreusableMPgraphic{page} + StartPage ; + fill Page withcolor \MPcolor{maincolor} ; + path p ; p := Field[Text][Text] enlarged 6pt ; + p := + llcorner p shifted (0,-12pt) -- + lrcorner p shifted (-150pt,0) -- + urcorner p shifted (0,12pt) -- + ulcorner p shifted (150pt,0) -- + cycle ; + fill p + withcolor .9white ; + StopPage ; +\stopreusableMPgraphic + +\defineoverlay + [page] + [\reuseMPgraphic{page}] + +\setupbackgrounds + [page] + [background=page] + +\setupalign + [flushleft] + +\unexpanded\def\StartItem + {\blank[line] + \begingroup + \EveryPar {\AdaptShape}} % beware: \ABBREV aan begin gaat fout + +\unexpanded\def\StopItem + {\endgraf + \endgroup + \blank[line]} + +\unexpanded\def\StartType + {\blank[halfline] + \begingroup + \EveryPar {\AdaptShape} + \dontleavehmode \quad} + +\unexpanded\def\StopType + {\endgraf + \endgroup + \blank[halfline]} + +\unexpanded\def\StartTopic#1% + {\page + \setlayer + [text] + [preset=lefttop, + rotation=90] + {\color[white]{\scale[height=24pt]{\strut#1}}}} + +\unexpanded\def\StopTopic + {\page} + +\startsetups document:start + \ifdefined\TitleFont \else + \definedfont[TitleFont][Bold*default sa 4] + \fi + \ifdefined\MainTextFont + \MainTextFont + \fi + \Banner{\documentvariable{location}} + \StartTopic{\documentvariable{author}} + \startstandardmakeup + \TitleFont + \setupinterlinespace[line=3ex] + \vfill + \def\docommand##1{\StartItem\dontleavehmode\quad{\morecolor##1}\StopItem} + \processcommacommand[\documentvariable{title}]\docommand + \vfill + \stopstandardmakeup + \StopTopic +\stopsetups + +\startsetups document:stop +\stopsetups + +\unexpanded\def\Banner#1% + {\setuplayer + [base] + [state=repeat] + \setlayer + [base] + [preset=rightbottom] + {\color[white]{\scale[height=9pt]{\strut#1}}}} + +\continueifinputfile{s-present-slanted.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{tug/2007/tug-2007-fonts.tex} diff --git a/tex/context/modules/mkiv/s-present-split.mkiv b/tex/context/modules/mkiv/s-present-split.mkiv new file mode 100644 index 000000000..48be7ca81 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-split.mkiv @@ -0,0 +1,191 @@ +%D \module +%D [ file=s-present-split, % s-pre-14, +%D version=1999.08.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Split, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D In the process of making a couple of simple styles for \EUROTEX\ 99, I came to +%D this one. The joke is in the pagenumber. This style can be used for short +%D presentations with much text. + +\startmodule[present-split] + +\startmode[asintended,atpragma] \setupbodyfont[lucidaot] \stopmode + +\setupbodyfont[14.4pt] + +%D Since we expect text, we can best be very tolerant. + +\setuptolerance + [verytolerant,stretch] + +%D As most styles we choose a large screen page size. + +\setuppapersize + [S6][S6] + +\setuplayout + [width=fit, + rightedge=3cm, + margin=0pt, + rightedgedistance=2cm, + height=middle, + header=0pt, + footer=0pt, + topspace=1cm, + backspace=1cm] + +%D We only use two colors, named \type {ColorOne} and \type {ColorTwo}: + +\definecolor [ColorOne] [r=.6,g=.4,b=.4] +\definecolor [ColorTwo] [r=.4,g=.6,b=.6] + +%D If you've looked at the demo file, you will have noticed that the background +%D consists of four pieces: two filled rectangles and two half numbers. In older +%D versions these are put on the page using four overlays, here we use a much +%D cleaner implementation is the following. If you hate \METAPOST, you can run +%D this style in the specified mode: + +\setupbackgrounds + [page] + [background={number}] + +\defineoverlay[number][\useMPgraphic{number}] + +\startuseMPgraphic{number} + StartPage ; + picture Left, Right ; + numeric Shift ; Shift := -TextWidth - BackSpace - RightEdgeDistance/2 ; + fill Page withcolor "ColorOne" ; + fill Page leftenlarged Shift withcolor "ColorTwo" ; + if RealPageNumber > 1 : + Left := Right := textext("\bf\folio") ysized 3cm ; + clip Right to boundingbox Right shifted ( bbwidth(Right)/2,0) ; + clip Left to boundingbox Left shifted (-bbwidth(Left) /2,0) ; + draw Left shifted (-Shift,2.25cm) withcolor "ColorTwo" ; + draw Right shifted (-Shift,2.25cm) withcolor "ColorOne" ; + fi ; + StopPage ; +\stopuseMPgraphic + +%D We use the simple label typesetting present in \METAPOST\ because digits are +%D seldom kerned so real \TEX ing is not needed. As in the previous method, we let +%D the graphics overlap so that we don't get white lines due to rounding problems in +%D viewers. +%D +%D We put a button behind the text (this overlay is calculated each page). + +\defineoverlay + [nextpage] + [\overlaybutton{nextpage}] + +\setupbackgrounds + [text] + [backgroundoffset=.5cm, + background=nextpage] + +%D We still have to turn on interaction mode. + +\setupinteraction + [state=start, + display=new, + menu=on] + +\setupinteraction + [color=, + contrastcolor=] + +%D Next we define structuring commands. + +\definehead[Topic] [chapter] \setuphead[Topic] [style=\bfc] +\definehead[Subject][section] \setuphead[Subject][style=\bfa] + +\setuphead + [Topic,Subject] + [number=no, + after={\blank[big]}] + +%D Because we will provide a menu, we don't offer lists. + +\let\Topics \gobbleoneargument +\let\Subjects\relax + +%D The table of contents goes to the right edge. + +\startinteractionmenu[right] + \setupinteraction + [color=black, + contrastcolor=Two] + \placelist + [Topic] + [alternative=e, + frame=off, + criterium=all] + \vfill +\stopinteractionmenu + +\setuplist + [Topic] + [width=\rightedgewidth, + maxwidth=\rightedgewidth, + style=\bfa] + +%D We safe some space: + +\setupwhitespace + [medium] + +\setupblank + [medium] + +%D In the titlepage, we still use the \TEX\ overlays, so that we don't have to +%D define a second graphic. + +\unexpanded\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +\unexpanded\def\StartTitlePage + {\startstandardmakeup + \setupalign[middle] + \unexpanded\def\\{\vfil\bfb\setupinterlinespace} + \bfd\setupinterlinespace + \vfil} + +\unexpanded\def\StopTitlePage + {\vfil\vfil\vfil + \stopstandardmakeup} + +\startsetups document:start + \StartTitlePage + \documentvariable{title} + \doifsomething {\documentvariable{subtitle}} { + \\ + \documentvariable{subtitle} + } + \doifsomething {\documentvariable{location}} { + \\ + \documentvariable{location} + } + \StopTitlePage +\stopsetups + +\startsetups document:stop + % +\stopsetups + +\stopmodule + +%D This is it. + +\continueifinputfile{s-present-split.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-split-001.tex} diff --git a/tex/context/modules/mkiv/s-present-stack.mkiv b/tex/context/modules/mkiv/s-present-stack.mkiv new file mode 100644 index 000000000..4cc75404f --- /dev/null +++ b/tex/context/modules/mkiv/s-present-stack.mkiv @@ -0,0 +1,194 @@ +%D \module +%D [ file=s-present-stack, % was s-pre-11 +%D version=1999.08.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Stack, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[present-stack] + +%D This is ancient but shows a few tricks so we keep it around in \MKIV\ +%D anyway. + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=0cm, + backspace=0cm, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +\doifelsemode {asintended} { + \setupbodyfont[ludicaot,14.4pt] +} { + \setupbodyfont[pagella,14.4pt] +} + +\setupinteraction + [click=no, + display=new, + state=start] + +\setupinteractionscreen + [option=max] + +\unexpanded\def\SomeShape + {\resetMPdrawing + \startMPdrawing + path p[], q[] ; pair a, b ; + StartPage ; + \stopMPdrawing + \dorecurse{\CurrentTopic} + {\startMPdrawing + initialize_box(\MPpos{topic-\realfolio-\recurselevel}) ; + p[\recurselevel] := tensecircle (wxy,hxy,.25cm) shifted cxy ; + fill p[\recurselevel] withcolor .9white ; + pickup pencircle scaled .25cm ; + if \recurselevel = \CurrentTopic : + draw p[\recurselevel] withcolor \MPcolor{ShowColor} ; + else : + draw p[\recurselevel] withcolor \MPcolor{DoneColor} ; + fi ; + \stopMPdrawing}% + \dorecurse{\CurrentMaxItem} + {\startMPdrawing + initialize_box(\MPpos{item-\realfolio-\recurselevel}) ; + linewidth := .25cm ; + q[\recurselevel] := tensecircle (wxy,hxy,linewidth) shifted cxy ; + fill q[\recurselevel] withcolor .9white ; + pickup pencircle scaled linewidth ; + if \recurselevel = \CurrentMaxItem : + draw q[\recurselevel] withcolor \MPcolor{ShowColor} ; + else : + draw q[\recurselevel] withcolor \MPcolor{DoneColor} ; + fi ; + \stopMPdrawing}% + \dostepwiserecurse{2}{\CurrentTopic}{1} + {\startMPdrawing + draw + rt point 3 of p[\recurselevel-1] -- + lft point 7 of p[\recurselevel] + withcolor \MPcolor{ArrowColor} ; + \stopMPdrawing}% + \dostepwiserecurse{2}{\CurrentMaxItem}{1} + {\startMPdrawing + draw + bot point 9 of q[\recurselevel-1] -- + top point 5 of q[\recurselevel] + withcolor \MPcolor{ArrowColor} ; + \stopMPdrawing}% + \startMPdrawing + draw Page + withpen pencircle scaled .5cm + withcolor \MPcolor{EdgeColor} ; + StopPage ; + \stopMPdrawing + \MPdrawingdonetrue + \getMPdrawing} + +\unexpanded\def\TitlePage#1% + {\startstandardmakeup + \setupalign[middle] + \def\\{\vfil\bfb\setupinterlinespace} + \bfd\setupinterlinespace + \vfil#1\vfil\vfil + \stopstandardmakeup} + +\definecolor[PageColor][r=.5,g=.4,b=.3] +\definecolor[LineColor][r=.7,g=.6,b=.5] + +\definecolor[PageColor] [s=.60] +\definecolor[ShowColor] [r=.40] +\definecolor[EdgeColor] [g=.40] +\definecolor[DoneColor] [r=.40,g=.40] +\definecolor[ArrowColor] [b=.40] +\definecolor[LineColor] [r=.60,g=.60] +\definecolor[GotoColor] [ArrowColor] + +\setupinteraction + [color=GotoColor, + contrastcolor=GotoColor] + +\defineoverlay [shape] [\SomeShape] +\defineoverlay [next] [\overlaybutton{forward}] % [{nextpage}] + +\setupbackgrounds + [page] + [background={color,next,shape}, + backgroundcolor=PageColor] + +\doglobal\newcounter\CurrentMaxItem +\doglobal\newcounter\CurrentItem +\doglobal\newcounter\CurrentTopic + +\unexpanded\def\StartIdea + {\doglobal\newcounter\CurrentItem} + +\unexpanded\def\StartTopic + {\doglobal\increment\CurrentTopic + \dostartbuffer[topic-\CurrentTopic][StartTopic][StopTopic]} + +\unexpanded\def\StopIdea + {\dorecurse{\CurrentItem} + {\let\CurrentMaxItem\recurselevel + \doStopIdea}} + +\unexpanded\def\doStopIdea + {\startstandardmakeup + \dontcomplain + \vskip.875cm + \hbox to \makeupwidth + {\hfill + \dorecurse{\CurrentTopic} + {\edef\Topic{topic-\realfolio-\recurselevel}% + \hpos + {\Topic} + {\framed + [frame=off,align=middle,offset=.25cm] + {\getbuffer[topic-\recurselevel]}}% + \ifnum\recurselevel<\CurrentTopic + \hskip.875cm + \fi}% + \hfill} + \vskip.875cm + \vfilll + \dorecurse{\CurrentMaxItem} + {\edef\Item{item-\realfolio-\recurselevel} + \hbox to \makeupwidth + {\hfill + \hpos + {\Item} + {\framed + [width=.75\makeupwidth, + frame=off, + align=middle,offset=.125cm] + {\getbuffer[item-\recurselevel]}}% + \hfill} + \vskip.875cm} + \vfilll + \stopstandardmakeup} + +\unexpanded\def\StartItem + {\doglobal\increment\CurrentItem + \dostartbuffer[item-\CurrentItem][StartItem][StopItem]} + +\setupalign + [nothyphenated] + +\stopmodule + +\continueifinputfile{s-present-stack.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-stack-001.tex} + diff --git a/tex/context/modules/mkiv/s-present-stepper.mkiv b/tex/context/modules/mkiv/s-present-stepper.mkiv new file mode 100644 index 000000000..3dd8d9dcd --- /dev/null +++ b/tex/context/modules/mkiv/s-present-stepper.mkiv @@ -0,0 +1,227 @@ +%D \module +%D [ file=s-present-stepper, % was s-pre-61 +%D version=2004.03.15, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Stepper, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Optima + +\startmodule[present-stepper] + +\usemodule[pre-60] + +\doifmodeelse {atpragma,asintended} { + \usetypescriptfile[ghz] + \definetypeface[mainface][ss][sans][optima-nova][default] +} { + \usetypescriptfile[type-ghz] + \definetypeface[mainface][ss][sans][optima-nova][default][encoding=\defaultencoding] +} + +\setupbodyfont[mainface,ss,18pt] + +\setupinterlinespace + [line=3.25ex] + +\setuppapersize + [S6][S6] + +% \setuppapersize +% [SW][SW] + +\setuplayout + [topspace=10pt, + header=30pt, + headerdistance=20pt, + height=middle, + footerdistance=20pt, + footer=0pt, + bottomdistance=20pt, + bottom=20pt, + bottomspace=50pt, + backspace=30pt, + width=middle] + +\setupinteraction + [state=start, + click=off, + menu=on, + style=, + color=interactioncolor, + contrastcolor=interactioncolor] + +\setupinteractionscreen + [option=max] + +\setupinteractionmenu + [bottom] + [color=maincolor, + contrastcolor=maincolor, + style=\tfa, % acceptable + left=\hfill, + middle=, + right=, + height=\bottomheight, + width=2\bottomheight, + offset=overlay, + frame=off] + +\startinteractionmenu[bottom] + \but [firstpage] \symbol[firstpage] \\ + \but [previouspage] \symbol[previouspage] \\ + \but [InvokeStepper] \StartBusy\symbol[PauseRendering]\StopBusy \\ + \but [nextpage] \symbol[nextpage] \\ + \but [lastpage] \symbol[lastpage] \\ + \but [CloseDocument] \symbol[CloseDocument] \\ +\stopinteractionmenu + +% maybe in colo-sjk : \setupcolor[sjk] + +\definecolor [dark] [s=.4] +\definecolor [bright] [s=.9] + +\definecolor [red] [r=.4,g=.2,b=.2] +\definecolor [green] [r=.2,g=.4,b=.2] +\definecolor [blue] [r=.2,g=.2,b=.4] + +\definecolor [cyan] [r=.2,g=.4,b=.4] +\definecolor [magenta] [r=.4,g=.2,b=.4] +\definecolor [yellow] [r=.4,g=.4,b=.2] + +\definecolor [pagecolor] [dark] +\definecolor [maincolor] [bright] +\definecolor [textcolor] [red] + +\definecolor [interactioncolor] [r=.8,g=.8,b=.6] + +\setupcolors + [textcolor=maincolor] + +\setupbackgrounds + [page] + [background=page, + backgroundcolor=textcolor] + +\setupbackgrounds + [text]% [text] + [background={comments,text,invoke}] + +\definelayer + [text] + [width=\textwidth, + height=\textheight] + +\defineoverlay + [comments] + [{\setlayer[text][preset=middle]{\placecomments}}] + +\defineoverlay[page][\uniqueMPgraphic{page-\ifcase\realpageno\or one\else plus\fi}] + +\startuniqueMPgraphic{page-one} + StartPage ; + fill Page + enlarged 4pt + withcolor \MPcolor{pagecolor} ; + fill Field[Text][Text] + enlarged 10pt + % topenlarged (HeaderHeight+HeaderDistance) + leftenlarged (BackSpace+4pt) + rightenlarged (CutSpace +4pt) + withcolor OverlayColor ; + StopPage ; +\stopuniqueMPgraphic + +\startuniqueMPgraphic{page-plus} + StartPage ; + fill Page + enlarged 4pt + withcolor \MPcolor{pagecolor} ; + fill Field[Text][Text] + enlarged 10pt + leftenlarged (BackSpace+4pt) + rightenlarged (CutSpace+4pt) + withcolor OverlayColor ; + StopPage ; +\stopuniqueMPgraphic + +\startsetups fonts:normalize + \definefont[HeadFont] [SansBold*default ht \the\dimexpr0.750\headerheight\relax] + \definefont[TitleFont] [SansBold*default ht \the\dimexpr1.500\headerheight\relax] + \definefont[SubTitleFont] [SansBold*default ht \the\dimexpr0.375\headerheight\relax] + \definefont[SubSubTitleFont] [SansBold*default ht \the\dimexpr0.750\headerheight\relax] +\stopsetups + +\setuphead + [chapter] + [placehead=empty, + after={\blank[medium]}, + color=maincolor, + placenumber=no, + style=\HeadFont] + +\setupheadertexts + [\doiftextelse{\currentheadnumber}{\placeheadtext[Topic]}{\placeheadtext[Nopic]}] + [] + +\setuppagenumbering + [location=] + +\definesymbol + [emdash] + [\emdash] + +\setupitemize + [each] + [loose,serried,joinedup,broad] + [symbol=emdash] + +\setupalign + [broad,right] + +\def\doTitlePage#1#2#3% + {\setups[fonts:normalize] + \resetsetups[fonts:normalize] + \startstandardmakeup[headerstate=high] + \def\\{\def\\{\endgraf\quad\quad}\endgraf\quad\ignorespaces#2}% + #1\setstrut\setupinterlinespace\vfil#3\vfil\vfil + \stopstandardmakeup} + +\unexpanded\def\TitlePage {\doTitlePage\TitleFont\relax} +\unexpanded\def\SubTitlePage{\doTitlePage\TitleFont\SubTitleFont} + +\definehead[Topic][chapter] +\definehead[Nopic][title] + +\unexpanded\def\Topics#1% + {\Nopic[topics]{#1} + \startcolumns + \placelist[Topic] + \stopcolumns} + +\setuplist + [Topic] + [alternative=f, + color=maincolor, + contrastcolor=maincolor, + criterium=all] + +\defineoverlay[topics][\overlaybutton{topics}] + +\setupbackgrounds + [bottom] [text] + [background=topics] + +\stopmodule + +\continueifinputfile{s-present-stepper.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-stepper-001.tex} diff --git a/tex/context/modules/mkiv/s-present-stepwise.mkiv b/tex/context/modules/mkiv/s-present-stepwise.mkiv new file mode 100644 index 000000000..bc781c499 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-stepwise.mkiv @@ -0,0 +1,216 @@ +%D \module +%D [ file=s-present-stepwise, % was s-pre-60 +%D version=2004.03.15, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Stepwise, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% use lua instead of global mess + +\startmodule[present-stepwise] + +\unprotect + +\startmode[paper,print] + \let\StartSteps\relax + \let\StopSteps \relax + \let\FlushStep \relax + \let\ResetStep \relax + \let\StartBusy \relax + \let\StopBusy \relax + \endinput +\stopmode + +\newcount\c_module_pre_steps_current +\newcount\c_module_pre_steps_maximum +\newcount\c_module_pre_steps_nesting_step +\newcount\c_module_pre_steps_nesting_steps +\newcount\c_module_pre_steps_nesting_busy + +\def\StepCounter {\the\c_module_pre_steps_current} +\def\StepMaximum {\the\c_module_pre_steps_maximum} +\def\StepLayer {step:\the\c_module_pre_steps_current} +\def\NextStepLayer {step:\the\numexpr\c_module_pre_steps_current+\plusone\relax} +\def\FirstStepLayer{step:1} + +\useJSscripts[stp] + +\startsetups[set-stepper] + + \ifnum\getvariable{stepper}{nofsteps}>\c_module_pre_steps_maximum + + \dostepwiserecurse {\numexpr\c_module_pre_steps_maximum+\plusone\relax} {\getvariable{stepper}{nofsteps}} {1} { + \doifnotmode{nosteps,nostep} { + \expanded{\defineviewerlayer[step:\recurselevel][state=stop,scope=global]} + } + } + + \global\c_module_pre_steps_maximum\getvariable{stepper}{nofsteps}\relax + + \fi + +\stopsetups + +\setvariables + [stepper] + [set=\setups{set-stepper}, + nofsteps=50] + +\defineviewerlayer[step:busy][state=start] + +\definereference [SetupStepper] [JS(SetupStepper{step,\StepMaximum})] +\definereference [ResetStepper] [JS(ResetStepper)] +\definereference [CheckStepper] [JS(CheckStepper{\StepCounter})] +\definereference [InvokeStepper] [JS(InvokeStepper)] + +% todo: roll back blank + +\unexpanded\def\ResetStep + {\iftrialtypesetting\else + \global\c_module_pre_steps_current\zerocount + \fi} + +\unexpanded\def\NextStep + {\iftrialtypesetting\else + \global\advance\c_module_pre_steps_current\plusone + \fi} + +\unexpanded\def\PrevStep + {\iftrialtypesetting\else + \global\advance\c_module_pre_steps_current\minusone + \fi} + +\unexpanded\def\FlushStep + {\iftrialtypesetting\else + \StopStep + \NextStep + \StartStep + \fi} + +\unexpanded\def\StartStep + {\iftrialtypesetting\else + \global\advance\c_module_pre_steps_nesting_step\plusone + \ifcase\c_module_pre_steps_nesting_step\or + \startviewerlayer[\StepLayer]% + \fi + \fi + \ignorespaces} + +\unexpanded\def\StopStep + {\removeunwantedspaces + \iftrialtypesetting\else + \ifcase\c_module_pre_steps_nesting_step\or + \stopviewerlayer + \fi + \global\advance\c_module_pre_steps_nesting_step\minusone + \fi} + +\unexpanded\def\StartSteps + {\iftrialtypesetting\else + \global\advance\c_module_pre_steps_nesting_steps\plusone + \ifcase\c_module_pre_steps_nesting_steps\or + \ResetStep + \NextStep + \StartStep + \fi + \fi} + +\unexpanded\def\StopSteps + {\iftrialtypesetting\else + \ifcase\c_module_pre_steps_nesting_steps\or + \StopStep + \PrevStep + \fi + \global\advance\c_module_pre_steps_nesting_steps\minusone + \fi} + +\unexpanded\def\StartBusy + {\iftrialtypesetting\else + \global\advance\c_module_pre_steps_nesting_busy\plusone + \ifcase\c_module_pre_steps_nesting_busy\or + \startviewerlayer[step:busy] + \fi + \fi + \ignorespaces} + +\unexpanded\def\StopBusy + {\removeunwantedspaces + \iftrialtypesetting\else + \ifcase\c_module_pre_steps_nesting_busy\or + \stopviewerlayer + \fi + \global\advance\c_module_pre_steps_nesting_busy\minusone + \fi} + +%D Handy: + +\unexpanded\def\StartLocalSteps + {\ResetStep} + +\unexpanded\def\StopLocalSteps + {} + +\unexpanded\def\StartLocalStep + {\NextStep + \StartStep} + +\unexpanded\def\StopLocalStep + {\StopStep} + +\appendtoks + \ResetStep +\to \everyaftershipout + +\setupinteraction + [%openaction=SetupStepper, + closeaction=ResetStepper, + openpageaction=CheckStepper, + closepageaction=ResetStepper] + +\defineoverlay[invoke][\overlaybutton{InvokeStepper}] + +\setupbackgrounds + [text] + [background=invoke] + +% bonus + +\useMPlibrary[nav] + +\definepalet + [navplus] + [attach=interactioncolor, + comment=interactioncolor] + +\setupcomment + [symbol={comment-normal,comment-down}, + textlayer=\StepLayer, + option=buffer, + height=\textheight, + width=\textwidth, + margin=0pt] + +\setupattachments + [symbol={attach-normal,attach-down}, + textlayer=\StepLayer] + +%D used as (given some definitions): +%D +%D \starttyping +%D \StartLocalSteps +%D \startcombination[both] +%D {\StartLocalStep\placestreamlayer[left]\StopLocalStep} {} +%D {\StartLocalStep\placestreamlayer[right]\StopLocalStep} {} +%D \stopcombination +%D \StopLocalSteps +%D \stoptyping + +\protect + +\stopmodule diff --git a/tex/context/modules/mkiv/s-present-tiles.mkiv b/tex/context/modules/mkiv/s-present-tiles.mkiv index b68a34ef4..566a610a4 100644 --- a/tex/context/modules/mkiv/s-present-tiles.mkiv +++ b/tex/context/modules/mkiv/s-present-tiles.mkiv @@ -11,15 +11,18 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -%D The Bacho\TeX\ 2013 style. +%D In this style the table of contents is a bunch of rectangular blobs. The layout +%D adapts itself upto 25 pages. This style was made for Bacho\TeX\ 2013. + +\startmodule[present-tiles] \setupbodyfont[pagella,14.4pt] \setuppapersize[S6][S6] -\definecolor[primarycolor] [.50(darkblue,darkgreen)] -\definecolor[secondarycolor][.25(darkblue,darkyellow)] -\definecolor[mixedcolor] [s=.35] +\definecolor[maincolor] [.50(darkblue,darkgreen)] +\definecolor[othercolor][.25(darkblue,darkyellow)] +\definecolor[mixedcolor][s=.35] \setupcolors [textcolor=white] @@ -88,7 +91,7 @@ background=color, frame=off, foregroundstyle=MyTopicListFont, - backgroundcolor=primarycolor, + backgroundcolor=maincolor, foregroundcolor=white] \setupwhitespace @@ -171,7 +174,7 @@ frame=off] \defineframed[nb] [bb] [empty=yes] -\defineframed[rb] [bb] [backgroundcolor=white,foregroundcolor=secondarycolor] +\defineframed[rb] [bb] [backgroundcolor=white,foregroundcolor=othercolor] \defineframed[db] [bb] [backgroundcolor=mixedcolor,foregroundcolor=white] \definepushbutton [prev] @@ -235,7 +238,7 @@ align={flushleft,lohi}, background=color, backgroundcolor=white, - foregroundcolor=secondarycolor] + foregroundcolor=othercolor] \startsetups [document:titlepage] @@ -245,12 +248,12 @@ \setupbackgrounds [page] [background={color,menupage}, - backgroundcolor=secondarycolor] + backgroundcolor=othercolor] \setupbackgrounds [text] [background={color,menupage}, - backgroundcolor=secondarycolor] + backgroundcolor=othercolor] \starttopicmakeup[reference=homepage] @@ -277,12 +280,12 @@ \setupbackgrounds [page] [background={color,homepage}, - backgroundcolor=secondarycolor] + backgroundcolor=othercolor] \setupbackgrounds [text] [background={color,menupage}, - backgroundcolor=secondarycolor] + backgroundcolor=othercolor] \startcontentmakeup[reference=menupage] @@ -296,23 +299,33 @@ [page] % [background={color,menupage}, [background={color,invoke}, - backgroundcolor=primarycolor] + backgroundcolor=maincolor] \setupbackgrounds [text] % [background={color,nextpage,setbuttons,buttons}, [background={color,setbuttons,buttons}, - backgroundcolor=secondarycolor] + backgroundcolor=othercolor] \stopsetups \setupdocument [before=\directsetup{document:titlepage}] -\continueifinputfile{s-present-tiles.mkiv} - -\startdocument[title=Whatever We\\Want Here,subtitle=Whatever We\\Want There] +\stopmodule - \dorecurse{12}{\starttopic[title=Topic #1]\input tufte \stoptopic} +\continueifinputfile{s-present-tiles.mkiv} -\stopdocument +\usemodule[present-common] + +%inputpresentationfile{examples/present-tiles-001.tex} +%inputpresentationfile{context/2013/context-2013-speed.tex} +\inputpresentationfile{context/2013/context-2013-math.tex} +%inputpresentationfile{bachotex/2013/bachotex-2013-bits.tex} +%inputpresentationfile{bachotex/2013/bachotex-2013-bits.pdf} +%inputpresentationfile{bachotex/2013/bachotex-2013-luatex.tex} +%inputpresentationfile{bachotex/2013/bachotex-2013-luatex.pdf} +%inputpresentationfile{bachotex/2013/bachotex-2013-sense.tex} +%inputpresentationfile{bachotex/2013/bachotex-2013-sense.pdf} +%inputpresentationfile{bachotex/2013/bachotex-2013-speed.tex} +%inputpresentationfile{bachotex/2013/bachotex-2013-speed.pdf} diff --git a/tex/context/modules/mkiv/s-present-windows.mkiv b/tex/context/modules/mkiv/s-present-windows.mkiv new file mode 100644 index 000000000..22d6fdba1 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-windows.mkiv @@ -0,0 +1,350 @@ +%D \module +%D [ file=s-resent-windows, % was s-pre-09 +%D version=unknown, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Windows, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[present-windows] + +%D I made this style when I had to give a presentation on the \MAPS\ bibliography +%D production for several user group meetings. This style is rather tuned for +%D combinations of examples and explanations. The colors match the \MAPS\ +%D bibliography colors. + +\doifelsemode {asintended} { + \setupbodyfont[ludicaot,14.4pt] +} { + \setupbodyfont[pagella,14.4pt] +} + +%D A couple of years later, in 2001 this style was documented and made public. While +%D documenting, I also changed box building on top of overlays into the now +%D available layer positioning. So, this styles demonstrates quite some tricks. +%D +%D I'm sure that nowadays it can be done with less code but therei sno real need to +%D rewrite history. + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=0cm, + backspace=0cm, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +%D Local environments can be set by using the setups commands. For downward +%D compatibility, we keep supporting the \type {\...Settings} hooks. Using local +%D environments is seldom needed. + +\let\TextSettings \empty +\let\SampleSettings\empty + +\startsetups [text] \TextSettings \stopsetups +\startsetups [sample] \SampleSettings \stopsetups + +%D The dimensions are kind of fixed. + +\def\FrameWidth {448pt} +\def\FrameHeight {348pt} +\def\FrameOffset {24pt} +\def\FrameSkip {12pt} + +%D But they {\em can} and {\em will} be changed. + +\def\FrameWidth {408pt} +\def\FrameHeight {318pt} + +%D The funny values come from the $3:4$ display aspect ratio. + +\definecolor[PageColor] [s=.40] +\definecolor[TextColor] [s=.90] +\definecolor[InteractionColor][r=.40] +\definecolor[LineColor] [r=.60,g=.60] + +%D Of course we go interactive and since we will probably open other documents, we +%D make sure that the viewer opens a new window. + +\setupinteraction + [color=InteractionColor, + contrastcolor=LineColor, + display=new, + state=start] + +\setupinteractionscreen + [option=max] + +%D Before we come to the real macros, we do a little bit of tuning. + +\setupitemize + [1][packed] + +\setuptyping + [blank=medium] + +%D Apart from the titlepage, the page gets a simple colored background. Later we +%D will activate the background. + +\setupbackgrounds + [page] + [backgroundcolor=PageColor] + +%D Everything gets frames by a nice \METAPOST\ frame. + +\defineoverlay [background] [\uniqueMPgraphic{background}] + +\startuniqueMPgraphic{background} + pickup pencircle scaled (1.5*\FrameSkip) ; + draw OverlayBox withcolor "PageColor" ; + pickup pencircle scaled \FrameSkip ; + fill OverlayBox withcolor "TextColor" ; + draw OverlayBox withcolor "LineColor" ; +\stopuniqueMPgraphic + +%D We will present samples and explanation pair||wise, so we need a hyperlink that +%D skips a page. Contrary to \MKII\ we put the next button in the page background and +%D the two windows get buttons that toggle between them. This is easier. + +\defineoverlay [nextpage] [\overlaybutton{nextpage}] +\defineoverlay [previouspage] [\overlaybutton{previouspage}] +\defineoverlay [skippage] [\overlaybutton{realpage(\number\numexpr\realpageno+2\relax)}] +\defineoverlay [samepage] [\overlaybutton{realpage(\number\numexpr\realpageno \relax)}] + +%D Layers are normally used to position multiple content on a specific overlay. Here +%D we will use them to position only and since the samples and text will swap place, +%D we will use quite a few layers. + +\defineoverlay [text] [\composedlayer{text}] +\defineoverlay [sample] [\composedlayer{sample}] +\defineoverlay [common] [\composedlayer{common}] + +%D There are three positions. When combined, the sample and text windows overlap, +%D otherwise the lone window is centered. We could have used one layer and reversed +%D the order by setting the \type {direction} parameter, but this approach is more +%D readable. + +\definelayer + [text] + [x=\makeupwidth, + y=\makeupheight, + location=lt, + hoffset=-\FrameSkip, + voffset=-\FrameSkip] + +\definelayer + [sample] + [hoffset=\FrameSkip, + voffset=\FrameSkip] + +\definelayer + [common] + [x=.5\makeupwidth, + y=.5\makeupheight, + location=c] + +%D The topic is put in the lower right corner of the text window. + +\defineoverlay [topic] [\composedlayer{topic}] + +\definelayer + [topic] + [x=\FrameWidth, + y=\FrameHeight, + location=lt, + hoffset=-\FrameOffset, + voffset=-\FrameSkip] + +%D The topic is put in a framed box. That way we can make sure that it gets a +%D background, which looks better when it covers something else. Otherwise we could +%D have stuck to: +%D +%D \starttyping +%D \def\Topic#1% +%D {\setlayer[topic]{\color[PageColor]{\bfb\setstrut#1}}} +%D \stoptyping +%D +%D But, we go for the nice alternative: + +\unexpanded\def\Topic#1% + {\doifsomething{#1} + {\setlayer [topic] + {\bfb\setstrut + \inframed + [frame=off, + foregroundcolor=PageColor, + offset=0pt, + background=color, + backgroundcolor=TextColor] + {#1}}}} + +%D The sample as well as the explanation will be collected in a buffer. That way we +%D can reuse the content. We could have used a box instead, but can we be sure that +%D the content is not adapting itself? So, buffers we use. + +\resetbuffer[sample] +\resetbuffer[text] + +%D Both the sample and explanation are kind of windowed. + +\defineframedtext + [SampleText] + [width=\FrameWidth, + height=\FrameHeight, + offset=\FrameOffset, + frame=off, + align=normal, + strut=no, + before=, + after=, + background=background] + +%D We safe some keying in by combining things in one macro. + +\unexpanded\def\DoSampleText#1#2#3% kind layer overlays + {\setupframedtexts[SampleText][background={background,#3}] + \setlayer[#2] + {\startSampleText[none] + \setups[#1] + \getbuffer[#1] + \stopSampleText}} + +\unexpanded\def\StartSample{\dostartbuffer[sample][StartSample][StopSample]} +\unexpanded\def\StartText {\dostartbuffer[text] [StartText] [StopText]} + +%D The following definitions apply at the outer level. + +\unexpanded\def\StopSample + {\startstandardmakeup + \DoSampleText{sample}{common}{samepage} + \stopstandardmakeup + \resetbuffer[sample]} + +\unexpanded\def\StopText + {\startstandardmakeup + \DoSampleText{text}{common}{topic,samepage} + \stopstandardmakeup + \resetbuffer[text]} + +\setupbackgrounds[page][background={color,nextpage}] +\setupbackgrounds[text][background=common] + +%D When we combine sample and text, we get slightly different definitions. As you +%D can see we generate two pages. Watch how we manipulate the order of the overlays +%D and teh nature of the buttons. Here some abstraction really pays off. + +\unexpanded\def\StartIdea + {\bgroup + \let\StopSample\relax + \let\StopText \relax} + +\unexpanded\def\StopIdea + {\setupbackgrounds[page][background={color,skippage}] + \setupbackgrounds[text][background={text,sample}] + \startstandardmakeup + \DoSampleText{sample}{sample}{nextpage} + \DoSampleText{text} {text} {topic,nextpage} + \stopstandardmakeup + \setupbackgrounds[page][background={color,nextpage}] + \setupbackgrounds[text][background={sample,text}] + \startstandardmakeup + \DoSampleText{sample}{sample}{previouspage} + \DoSampleText{text} {text} {topic,previouspage} + \stopstandardmakeup + \egroup} + +%D The rest of the definitions takes care of the title page. Please don't steal this +%D one for your own documents. + +\defineoverlay[joke] [\useMPgraphic{joke}{n=0}] % not to be changed! + +\startuseMPgraphic{joke}{n} + StartPage ; + path p, q ; numeric w ; pair xy ; + set_grid(OverlayWidth,OverlayHeight,OverlayWidth/8,OverlayHeight/8) ; + if \MPvar{n}=1 : + p := fulldiamond ; fill Page withcolor \MPcolor{TextColor} ; + else : + p := fullsquare ; fill Page withcolor \MPcolor{PageColor} ; + fi ; + forever : + xy := center Page randomized (OverlayWidth,OverlayHeight) ; + if new_on_grid(xpart xy, ypart xy) : + q := (p xyscaled (OverlayWidth/5,OverlayHeight/5)) + randomized (\FrameSkip,\FrameSkip) + shifted xy ; + w := (\FrameSkip) randomized (\FrameSkip/2) ; + draw q withcolor \MPcolor{PageColor} withpen pencircle scaled (1.5w) ; + fill q withcolor \MPcolor{TextColor} ; + draw q withcolor \MPcolor{LineColor} withpen pencircle scaled ( w) ; + fi ; + exitif grid_full ; + endfor ; + StopPage ; +\stopuseMPgraphic + +\defineoverlay[fuzzy][\useMPgraphic{fuzzy}] + +\startuseMPgraphic{fuzzy} + path p ; numeric w ; + p := (fullsquare xyscaled (OverlayWidth,OverlayHeight)) + randomized (\FrameSkip,\FrameSkip) ; + w := (\FrameSkip) randomized (\FrameSkip/2) ; + draw p withcolor \MPcolor{PageColor} withpen pencircle scaled (1.5w) ; + fill p withcolor \MPcolor{TextColor} ; + draw p withcolor \MPcolor{LineColor} withpen pencircle scaled ( w) ; +\stopuseMPgraphic + +%D This time we use a fit window, but with a slightly randomized frame, our +%D trademark so to say. + +\unexpanded\def\StartTitlePage + {\bgroup + \setupbackgrounds[page][background={joke,nextpage}] + \startstandardmakeup + \switchtobodyfont[big] + \setupframedtexts + [SampleText] + [background=fuzzy, + foregroundcolor=PageColor, + width=fit, + height=fit, + align=middle] + \startSampleText[middle] + \bfd\setupinterlinespace + \def\\{\bfb\setupinterlinespace\vfil\def\\{\vfil}}} + +\unexpanded\def\StopTitlePage + {\stopSampleText + \stopstandardmakeup + \egroup} + +\unexpanded\def\TitlePage#1% + {\StartTitlePage#1\StopTitlePage} + +%D Let's nil some error prone presentation macros. + +\let\Subject \Topic +\let\Topics \gobbleoneargument +\let\Subjects \relax + +%D We will avoid \quote {overfull} messages. + +\dontcomplain + +\stopmodule + +\continueifinputfile{s-present-windows.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-windows-001.tex} + diff --git a/tex/context/modules/mkiv/s-present-wobbling.mkiv b/tex/context/modules/mkiv/s-present-wobbling.mkiv new file mode 100644 index 000000000..e61b262f4 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-wobbling.mkiv @@ -0,0 +1,339 @@ +%D \module +%D [ file=s-prent-wobbling, +%D version=2010.04.28, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Wobbling, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This a bit old stuyls and I should adapt it a bit but as it sort of works ok I'll +%D not do that now. + +\startmodule[present-wobbling] + +%setuppapersize[S6][S6] +\setuppapersize[SM][SM] + +\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[pagella] + +\definecolor[maincolor] [blue] +\definecolor[extracolor][green] + +% \definecolor[maincolor] [red] +% \definecolor[extracolor][blue] + +\startMPdefinitions + picture MySoFar ; MySoFar := nullpicture ; + path MyLastOne ; MyLastOne := origin -- cycle ; + path MyLeftSteps, MyRightSteps ; + boolean MyPageDone ; MyPageDone := false ; + + vardef MySmallShape(expr parent) = + path p ; 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 "maincolor" withtransparency(1,.25) ; ) ; + enddef ; + + vardef MyDrawOne = + fill MyLastOne withcolor black ; + fill MyLastOne withcolor "maincolor" withtransparency(1,.25) ; + 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 ; + +\stopMPdefinitions + +\startuseMPgraphic{initialization} + StartPage ; + MySoFar := image(fill Page enlarged 12pt withcolor "maincolor" withtransparency(1,.25) ;) ; + MyMakeOne ; + MySetSteps ; + StopPage ; +\stopuseMPgraphic + +\appendtoks + \startnointerference + \useMPgraphic{initialization} + \stopnointerference +\to \everystarttext + +\unexpanded\def\TitleCommand#1% + {\framed + [frame=off, + offset=overlay, + align=flushleft, + foregroundcolor=white, + foregroundstyle={\tfd}, + bottom=\vskip2\lineheight] + {\setupinterlinespace + \setupwhitespace[halfline]% + %\showstruts + \begstrut + #1% + \endstrut}} + +\unexpanded\def\TopicCommand#1% + {\color[white]{\tfb#1}} + +\startuseMPgraphic{page} + StartPage ; + MyDrawPage ; + MyDrawOne ; + MySetSteps ; + if RealPageNumber == 1 : + MyDrawTitle(textext("\TitleCommand{\documentvariable{title}}")) ; + MyDrawText (textext("\TopicCommand{\documentvariable{topic}}")) ; + fi ; + % + % 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} + path p ; p := MySmallShape(unitsquare scaled (.6*LineHeight)) ; + fill p withcolor white ; + fill p withcolor "extracolor" withtransparency(1,.25) ; +\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 { mpx = "metafun", data = "clip currentpicture to MyLeftSteps ;" } + local rightpath = metapost.getclippath { mpx = "metafun", data = "clip currentpicture to MyRightSteps ;" } + local shape = { } + for i=1,#leftpath do + local left = leftpath[i].x_coord + local right = rightpath[i].x_coord + local hsize = right - left - (texdimen.backspace + texdimen.cutspace)*number.dimenfactors.bp + shape[#shape+1] = string.format("%sbp %sbp",left,hsize) + end + -- print(table.serialize(shape)) + -- context.parshape(string.format("%s %s ",#shape,table.concat(shape," "))) + context("\\parshape %s %s ",#shape,table.concat(shape," ")) + end +\stopluacode + +\nopenalties \dontcomplain + +\setupwhitespace[none] + +\startsetups document:start + \bgroup + \let\crlf\endgraf % \par in a mp textext doesn't work well + \startstandardmakeup + % dummy page + \stopstandardmakeup + \egroup +\stopsetups + +\unexpanded\def\StartText#1#2% for old times sake + {\startdocument[title={#1},subtitle={#2}]} + +\unexpanded\def\StopText + {\stopdocument + \setupdocument[title=,topic=]} + +\unexpanded\def\StartItems#1% + {\setupdocument[topic={#1}] + \startstandardmakeup[top=,bottom=\vss] + \startelement[items][title={#1}]% + \ctxlua{document.SetParShape()} + \StartSteps} + +\unexpanded\def\StopItems + {\StopSteps + \stopelement + \stopstandardmakeup} + +\unexpanded\def\StartItem + {\dontleavehmode + \startelement[item]% + \llap{\symbol[mysymbol]\quad}% graphic + \ignorespaces} + +\unexpanded\def\StopItem + {\removeunwantedspaces + \nobreak + \crlf + \stopelement + \crlf + \FlushStep} + +\unexpanded\def\ShapeParagraph + {\ctxlua{document.SetParShape()}} + +% no parshape yet + +\unexpanded\def\StartParagraphs#1% + {\setupdocument[topic={#1}] + \startstandardmakeup[top=,bottom=\vss] + %\ctxlua{document.SetParShape()} + \startelement[paragraphs]% + \StartSteps} + +\unexpanded\def\StopParagraphs + {\StopSteps + \stopelement + \stopstandardmakeup} + +\unexpanded\def\StartParagraph + {\startelement[paragraph]} + +\unexpanded\def\StopParagraph + {\par + \stopelement + \FlushStep} + +% experiment .. likely to change + +\setelementexporttag[items] [nature][display] +\setelementexporttag[item] [nature][mixed] +\setelementexporttag[paragraphs][nature][display] +\setelementexporttag[paragraph] [nature][mixed] + +\stopmodule + +\continueifinputfile{s-present-wobbling.mkiv} + +\usemodule[present-common] + +%inputpresentationfile{bachotex/2010/bachotex-2010-clash.tex} +\inputpresentationfile{bachotex/2010/bachotex-2010-move.tex} diff --git a/tex/context/modules/mkiv/s-syntax.mkiv b/tex/context/modules/mkiv/s-syntax.mkiv index 96312f771..d9492af3e 100644 --- a/tex/context/modules/mkiv/s-syntax.mkiv +++ b/tex/context/modules/mkiv/s-syntax.mkiv @@ -31,7 +31,7 @@ \unexpanded\def\module_syntax_Tex #1{\Sugar{\type{#1}}} \unexpanded\def\module_syntax_Literal #1{\Sugar{\type{#1}}} \unexpanded\def\module_syntax_Syntax #1{\strut\kern-.25em{#1}\kern-.25em} -\unexpanded\def\module_syntax_Next {\crlf\hbox to 2em{}\nobreak} +\unexpanded\def\module_syntax_Next {\par\strut\kern4em} % {\crlf\hbox to 2em{}\nobreak} \unexpanded\def\module_syntax_Whatever #1{\Sugar{\mathematics{(\hbox{#1})}}} \unexpanded\def\module_syntax_Quote #1{\Sugar{\quote{#1}}} \unexpanded\def\module_syntax_Or {\Sugar{\module_syntax_Indent{\mathematics{\vert}}}} @@ -70,6 +70,7 @@ \let\L \module_syntax_Literal \let\S \module_syntax_Something \let\M \module_syntax_Means + \let\N \module_syntax_Next \let\O \module_syntax_Or \let\Q \module_syntax_Quote \let\LB \module_syntax_Lbrace diff --git a/tex/context/modules/mkiv/s-xml-analyzers.lua b/tex/context/modules/mkiv/s-xml-analyzers.lua index c356d4c37..6e7f7f2ba 100644 --- a/tex/context/modules/mkiv/s-xml-analyzers.lua +++ b/tex/context/modules/mkiv/s-xml-analyzers.lua @@ -11,6 +11,8 @@ moduledata.xml.analyzers = moduledata.xml.analyzers or { } local next, type = next, type local utfvalues = string.utfvalues +local formatters = string.formatters +local setmetatableindex = table.setmetatableindex local context = context local NC, NR, HL, FL, LL, SL, TB = context.NC, context.NR, context.HL, context.TB, context.FL, context.LL, context.SL local sortedhash, sortedkeys, concat, sequenced = table.sortedhash, table.sortedkeys, table.concat, table.sequenced @@ -43,28 +45,29 @@ local function analyze(filename) attr = { } ents = { } - table.setmetatableindex(tags,function(t,k) + local function att(t,k) + local v = setmetatableindex("number") + t[k] = v + return v + end + + local function add(t,k) local v = { n = 0, - attributes = { }, - children = { }, + attributes = setmetatableindex(att), + children = setmetatableindex(add), } t[k] = v return v - end) + end - table.setmetatableindex(char,function(t,k) - t[k] = 0 - return 0 - end) + setmetatableindex(tags,add) - table.setmetatableindex(attr,function(t,k) - char[k] = char[k] or 0 - t[k] = 0 - return 0 - end) + setmetatableindex(ents,"number") + setmetatableindex(char,"number") - table.setmetatableindex(ents,function(t,k) + setmetatableindex(attr,function(t,k) + char[k] = char[k] or 0 t[k] = 0 return 0 end) @@ -85,24 +88,25 @@ local function analyze(filename) local tg = e.tg local tag = tags[tg] tag.n = tag.n + 1 + local children = parent and tags[parent].children[tg] + local childatt = children and children.attributes + if children then + children.n = children.n + 1 + end if at then local attributes = tag.attributes for k, v in next, at do local a = attributes[k] - if a then - a[v] = (a[v] or 0) + 1 - else - attributes[k] = { [v] = 1 } + a[v] = a[v] + 1 + if childatt then + local a = childatt[k] + a[v] = a[v] + 1 end for s in utfvalues(v) do attr[s] = attr[s] + 1 end end end - if parent then - local children = tags[parent].children - children[tg] = (children[tg] or 0) + 1 - end if dt then for i=1,#dt do local d = dt[i] @@ -119,7 +123,11 @@ local function analyze(filename) end for i=1,#filename do - local root = xml.load(filename[i]) + local name = filename[i] + local root = xml.load(name) + -- + logs.report("xml analyze","loaded: %s",name) + -- collect(root) -- local names = root.statistics.entities.names @@ -128,10 +136,10 @@ local function analyze(filename) end end - table.setmetatableindex(tags,nil) - table.setmetatableindex(char,nil) - table.setmetatableindex(attr,nil) - table.setmetatableindex(ents,nil) + setmetatableindex(tags,nil) + setmetatableindex(char,nil) + setmetatableindex(attr,nil) + setmetatableindex(ents,nil) end @@ -153,16 +161,20 @@ function moduledata.xml.analyzers.structure(filename) NC() context.bold("element") NC() context.darkred(name) NC() NR() NC() context.bold("frequency") NC() context(data.n) NC() NR() if next(children) then - NC() context.bold("children") NC() context.puretext(sequenced(children)) NC() NR() + local t = { } + for k, v in next, children do + t[k] = v.n + end + NC() context.bold("children") NC() context.puretext(sequenced(t)) NC() NR() end if next(attributes) then NC() context.bold("attributes") NC() context.puretext.darkgreen(concat(sortedkeys(attributes)," ")) NC() NR() for attribute, values in sortedhash(attributes) do local n = table.count(values) if attribute == "id" or attribute == "xml:id" or n > maxnofattributes then - NC() context(attribute) NC() context("%s different values",n) NC() NR() + NC() context("@%s",attribute) NC() context("%s different values",n) NC() NR() else - NC() context(attribute) NC() context.puretext(sequenced(values)) NC() NR() + NC() context("@%s",attribute) NC() context.puretext(sequenced(values)) NC() NR() end end end @@ -195,4 +207,121 @@ function moduledata.xml.analyzers.entities(filename) context.stoptabulate() end +local f_parent_s = formatters["xml:%s"] +local f_parent_n = formatters["\\startxmlsetups xml:%s\n \\xmlflush{#1}\n\\stopxmlsetups"] +local f_parent_a = formatters["\\startxmlsetups xml:%s\n %% @ % t\n \\xmlflush{#1}\n\\stopxmlsetups"] +local f_child_s = formatters["xml:%s:%s"] +local f_child_n = formatters["\\startxmlsetups xml:%s:%s\n \\xmlflush{#1}\n\\stopxmlsetups"] +local f_child_a = formatters["\\startxmlsetups xml:%s:%s\n %% @ % t\n \\xmlflush{#1}\n\\stopxmlsetups"] + +local f_template = formatters [ [[ +%% file: %s + +%% Beware, these are all (first level) setups. If you have a complex document +%% it often makes sense to use \\xmlfilter or similar local filter options. + +%% presets + +\startxmlsetup xml:presets:all + \xmlsetsetups {#1} { + %s + } +\stopxmlsetups + +%% setups + +%s +]] ] + +function moduledata.xml.analyzers.allsetups(filename,usedname) + analyze(filename) + local result = { } + local setups = { } + for name, data in table.sortedhash(tags) do + local children = data.children + local attributes = data.attributes + if next(attributes) then + result[#result+1] = f_parent_a(name,sortedkeys(attributes)) + else + result[#result+1] = f_parent_n(name) + end + setups[#setups+1] = f_parent_s(name) + if next(children) then + for k, v in sortedhash(children) do + local attributes = v.attributes + if next(attributes) then + result[#result+1] = f_child_a(name,k,sortedkeys(attributes)) + else + result[#result+1] = f_child_n(name,k) + end + setups[#setups+1] = f_child_s(name,k) + end + end + end + table.sort(setups) + -- + if type(filename) == "table" then + filename = concat(filename," | ") + end + -- + usedname = usedname or "xml-analyze-template.tex" + -- + io.savedata(usedname,f_template(filename,concat(setups,"|\n "),concat(result,"\n\n"))) + logs.report("xml analyze","presets saved in: %s",usedname) +end + +-- example: + +-- local t = { } +-- local x = xml.load("music-collection.xml") +-- for c in xml.collected(x,"//*") do +-- if not c.special and not t[c.tg] then +-- t[c.tg] = true +-- end +-- end +-- inspect(table.sortedkeys(t)) + +-- xml.finalizers.taglist = function(collected) +-- local t = { } +-- for i=1,#collected do +-- local c = collected[i] +-- if not c.special then +-- local tg = c.tg +-- if tg and not t[tg] then +-- t[tg] = true +-- end +-- end +-- end +-- return t +-- end +-- local x = xml.load("music-collection.xml") +-- inspect(table.sortedkeys(xml.applylpath(x,"//*/taglist()"))) + +-- xml.finalizers.taglist = function(collected,parenttoo) +-- local t = { } +-- for i=1,#collected do +-- local c = collected[i] +-- if not c.special then +-- local tg = c.tg +-- if tg and not t[tg] then +-- t[tg] = true +-- end +-- if parenttoo then +-- local p = c.__p__ +-- if p and not p.special then +-- local tg = p.tg .. ":" .. tg +-- if tg and not t[tg] then +-- t[tg] = true +-- end +-- end +-- end +-- end +-- end +-- return t +-- end + +-- local x = xml.load("music-collection.xml") +-- inspect(table.sortedkeys(xml.applylpath(x,"//*/taglist()"))) +-- local x = xml.load("music-collection.xml") +-- inspect(table.sortedkeys(xml.applylpath(x,"//*/taglist(true)"))) diff --git a/tex/context/modules/mkiv/s-xml-analyzers.mkiv b/tex/context/modules/mkiv/s-xml-analyzers.mkiv index af11fc984..4104f023a 100644 --- a/tex/context/modules/mkiv/s-xml-analyzers.mkiv +++ b/tex/context/modules/mkiv/s-xml-analyzers.mkiv @@ -18,6 +18,7 @@ \installmodulecommandluasingle \showxmlstructure {moduledata.xml.analyzers.structure} \installmodulecommandluasingle \showxmlcharacters {moduledata.xml.analyzers.characters} \installmodulecommandluasingle \showxmlentities {moduledata.xml.analyzers.entities} +\installmodulecommandluasingle \showxmlallsetups {moduledata.xml.analyzers.allsetups} \stopmodule @@ -33,6 +34,9 @@ \starttext - \showxmlcharacters[\FileName] + \showxmlstructure [\FileName] \page + \showxmlentities [\FileName] \page + \showxmlcharacters[\FileName] \page + \showxmlallsetups [\FileName] \page \stoptext diff --git a/tex/context/modules/mkiv/x-asciimath.lua b/tex/context/modules/mkiv/x-asciimath.lua index e0a4a714b..677d3519b 100644 --- a/tex/context/modules/mkiv/x-asciimath.lua +++ b/tex/context/modules/mkiv/x-asciimath.lua @@ -295,8 +295,8 @@ local reserved = { ["sigma"] = { true, "σ" }, ["tau"] = { true, "τ" }, ["upsilon"] = { true, "υ" }, - ["phi"] = { true, "φ" }, - ["varphi"] = { true, "ϕ" }, + ["phi"] = { true, "ϕ" }, + ["varphi"] = { true, "φ" }, ["chi"] = { true, "χ" }, ["psi"] = { true, "ψ" }, ["omega"] = { true, "ω" }, @@ -1274,6 +1274,15 @@ local function collapse_bars(t) i = i + 1 end if l then + -- problem: we can have a proper nesting +local d = false +for i=1,m do + if find(t[i],"\\left") then + d = true + break + end +end +if not d then local tt = { s_lnothing } -- space fools final checker local tm = 1 for i=1,m do @@ -1290,6 +1299,7 @@ local function collapse_bars(t) tt[tm] = s_rnothing -- space fools final checker m = tm t = tt +end elseif m < n then for i=n,m+1,-1 do t[i] = nil @@ -1739,7 +1749,7 @@ collapse = function(t,level) -- steps t = collapse_matrices (t) if trace_detail then show_state(t,level,"matrices") end t = collapse_bars (t) if trace_detail then show_state(t,level,"bars") end -t = collapse_stupids (t) if trace_detail then show_state(t,level,"stupids") end + t = collapse_stupids (t) if trace_detail then show_state(t,level,"stupids") end t = collapse_pairs (t) if trace_detail then show_state(t,level,"pairs") end t = collapse_parentheses(t) if trace_detail then show_state(t,level,"parentheses") end t = collapse_signs (t) if trace_detail then show_state(t,level,"signs") end diff --git a/tex/context/modules/mkiv/x-asciimath.mkiv b/tex/context/modules/mkiv/x-asciimath.mkiv index d3a629c81..5c96d4f8a 100644 --- a/tex/context/modules/mkiv/x-asciimath.mkiv +++ b/tex/context/modules/mkiv/x-asciimath.mkiv @@ -299,7 +299,7 @@ %D This will become an extra. -\showframe +\starttext \setups[asciimath:layout] @@ -312,10 +312,12 @@ % % \ShowAsciiMathSave[e:/temporary/asciimath/asciimath.lua] % \stoptext -\starttext -\unexpanded\def\MyAsciiMath#1{\startformula\asciimath{#1}\stopformula} -\startlines -\MyAsciiMath{x^2 / 10 // z_12^34 / 20} +\subject{Some tests} + +% \unexpanded\def\MyAsciiMath#1{\startformula\asciimath{#1}\stopformula} +% +% \startlines +% \MyAsciiMath{x^2 / 10 // z_12^34 / 20} % \MyAsciiMath{{:{:x^2:} / 10:} // {:{:z_12^34 :} / 20:}} % \MyAsciiMath{x^2+y_1+z_12^34} % \MyAsciiMath{sin^-1(x)} @@ -399,38 +401,82 @@ % \MyAsciiMath{x^ (-1 1/2) =1/x^ (1 1/2)=1/ (x^1*x^ (1/2)) =1/ (xsqrt(x))} % \MyAsciiMath{x^2(10 -x)>2 x^2} % \MyAsciiMath{x^4>x} -\stoplines - -\setupasciimath[splitmethod=3,symbol={{,}}] - -\startlines -\asciimath{sqrt 1} -\asciimath{sqrt 1.2} -\asciimath{sqrt 1.2} -\asciimath{1} -\asciimath{12} -\asciimath{123} -\asciimath{1234} -\asciimath{12345} -\asciimath{123456} -\asciimath{1234567} -\asciimath{12345678} -\asciimath{123456789} -\asciimath{1.1} -\asciimath{12.12} -\asciimath{1234.123} -\asciimath{1234.1234} -\asciimath{12345.1234} -\asciimath{1234.12345} -\asciimath{12345.12345} -\asciimath{123456.123456} -\asciimath{1234567.1234567} -\asciimath{12345678.12345678} -\asciimath{123456789.123456789} -\asciimath{0.1234} -\asciimath{1234.0} -\asciimath{1234.00} -\asciimath{0.123456789} -\stoplines +% \stoplines + +% \setupasciimath[splitmethod=3,symbol={{,}}] +% +% \startlines +% \asciimath{sqrt 1} +% \asciimath{sqrt 1.2} +% \asciimath{sqrt 1.2} +% \asciimath{1} +% \asciimath{12} +% \asciimath{123} +% \asciimath{1234} +% \asciimath{12345} +% \asciimath{123456} +% \asciimath{1234567} +% \asciimath{12345678} +% \asciimath{123456789} +% \asciimath{1.1} +% \asciimath{12.12} +% \asciimath{1234.123} +% \asciimath{1234.1234} +% \asciimath{12345.1234} +% \asciimath{1234.12345} +% \asciimath{12345.12345} +% \asciimath{123456.123456} +% \asciimath{1234567.1234567} +% \asciimath{12345678.12345678} +% \asciimath{123456789.123456789} +% \asciimath{0.1234} +% \asciimath{1234.0} +% \asciimath{1234.00} +% \asciimath{0.123456789} +% \stoplines + +% \definemixedcolumns[asciimath][n=3,balance=yes] +% +% \startluacode +% local asciimath = moduledata.asciimath +% local variables = { "w", "x", "y", "z", "p", "q", "r" } +% local constants = { "a", "b", "c" } +% local functions = { "g", "h", "i" } +% local iterators = { "i", "j", "k" } +% local vectors = { "A", "B", "C", "D", "E", "P", "Q", "R" } +% local reserved = { } +% local reserved = { +% -- "vdots","ddots","oint", +% "grad", "prod", "prop", "sube", "supe", "sum", +% "vvv", "nnn", "uuu", "sub", "sup", +% "iff", "int", "del", +% "sinh", "cosh", "tanh", "sin", "cos", "tan", "csc", "sec", "cot", +% "atan", "asin", "acos", "arctan", "arcsin", "arccos", +% "log", "ln", "det", "lim", "mod", "gcd", -- "lcm", +% "min", "max", +% "xx", "in", "ox", "vv", "nn", "uu", "oo", "bb", +% "not", "and", "or", "if", +% "AA", "EE", "TT", +% "sqrt", "root", "frac", "stackrel", +% "hat", "overbar", "underline", "vec", +% "dx", "dy", "dz", +% } +% for c=1,#constants do +% for r=1,#reserved do +% context.startmixedcolumns { "asciimath" } +% for v1=1,#variables do +% for v2=1,#variables do +% local str = constants[c] .. variables[v1] .. reserved[r] .. variables[v2] +% context.type(str) +% context.quad() +% commands.asciimath(str) +% context.par() +% end +% end +% context.stopmixedcolumns() +% context.blank() +% end +% end +% \stopluacode \stoptext diff --git a/tex/context/modules/mkiv/x-html.mkiv b/tex/context/modules/mkiv/x-html.mkiv index e1806eb9e..723872dfd 100644 --- a/tex/context/modules/mkiv/x-html.mkiv +++ b/tex/context/modules/mkiv/x-html.mkiv @@ -148,9 +148,11 @@ % % we can also use \xmlmap for border etc +% \registerctxluafile{lxml-css}{1.001} + \starttexdefinition cssgetsinglepadding #1 \ctxlua { - context((moduledata.css.padding( + context((xml.css.padding( "#1", \number\dimexpr0.1ex, \number\dimexpr0.01\hsize, diff --git a/tex/context/modules/mkiv/x-math-svg.mkvi b/tex/context/modules/mkiv/x-math-svg.mkvi new file mode 100644 index 000000000..4645f75d8 --- /dev/null +++ b/tex/context/modules/mkiv/x-math-svg.mkvi @@ -0,0 +1,65 @@ +%D \module +%D [ file=x-math-svg, +%D version=2014.09.19, +%D title=\CONTEXT\ XML Modules, +%D subtitle=\MATHML\ to \SVG, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt XML Macros / MathML to SVG Converter} + +\usemodule[x][mathml] + +\registerctxluafile{x-math-svg}{} + +\starttexdefinition MakeSVGMath #index#page#mode + \setbox\scratchbox\hbox\bgroup + \xmlprocessbuffer{main}{math-#page}{} + \egroup + \ctxlua { + moduledata.svgmath.register(#index, #page, { + mode = "#mode", + width = \number\wd\scratchbox, + height = \number\ht\scratchbox, + depth = \number\dp\scratchbox, + } ) + } + \startTEXpage + \box\scratchbox + \stopTEXpage +\stoptexdefinition + +\starttexdefinition ReuseSVGMath #index#page + \ctxlua { + moduledata.svgmath.register(#index,#page) + } +\stoptexdefinition + +% assume the same font .. what to do with size + +\startluacode + + local svgstyle = document.arguments.svgstyle or "" + + if type(svgstyle) == "string" and svgstyle ~= "" then + context.environment { svgstyle } + else + context.setupbodyfont { "pagella" } + end + +\stopluacode + +% \continueifinputfile{x-math-svg.mkvi} + +\starttext + + \startluacode + moduledata.svgmath.process(environment.arguments.inputfile) + \stopluacode + +\stoptext diff --git a/tex/context/modules/mkiv/x-mathml.lua b/tex/context/modules/mkiv/x-mathml.lua index 7d0b42d21..9650afab8 100644 --- a/tex/context/modules/mkiv/x-mathml.lua +++ b/tex/context/modules/mkiv/x-mathml.lua @@ -187,6 +187,7 @@ local i_replacements = { ["true"] = "{\\mathrm true}", ["declare"] = "{\\mathrm declare}", ["as"] = "{\\mathrm as}", + } -- we could use a metatable or when accessing fallback on the diff --git a/tex/context/modules/mkiv/x-mathml.mkiv b/tex/context/modules/mkiv/x-mathml.mkiv index a5be5ddb0..50d31da0e 100644 --- a/tex/context/modules/mkiv/x-mathml.mkiv +++ b/tex/context/modules/mkiv/x-mathml.mkiv @@ -1,6 +1,6 @@ %D \module %D [ file=x-mathml, -%D version=2008.05.29, +%D version=2008.05.29, (evolved from pre 2000 code) %D title=\CONTEXT\ XML Modules, %D subtitle=\MATHML, %D author=Hans Hagen, @@ -13,20 +13,14 @@ % \xmlfilter{#1}{/*/name()} -> \xmltag -% This module is under construction and will be cleaned up. We use a funny mix of -% xml, tex and lua. I could rewrite the lot but it also shows how context evolves. +% This implementation looks like a hack ... this is because we deal with all weird +% cases we ran into, including abuse that was supposed to render ok (even if it +% didn't in other renderers) .. it was simply expected to work that way. % -% I might end up with a lua-only implementation some day. I must find a good reason -% to spend time on it. In fact, it might even be more messy. -% -% no m:text strip (needs checking, maybe nbsp is mandate -% -% todo: more will be moved to lua (less hassle) -% todo: move left/right to the lua end -% -% this implememation looks like a hack ... this is because we deal with all weird cases we -% ran into, including abuse that was supposed to render ok (even if it didn't in other -% renderers) .. it was simply expected to work that way. +% So, consider this module to be under constant construction and clean up. We still +% use a funny mix of xml, tex and lua. I could rewrite the lot but it also shows how +% context evolves. I might end up with a lua-only implementation some day, but I must +% find a real good reason to spend time on it as so far it never paid back. \writestatus{loading}{ConTeXt XML Macros / MathML Renderer} @@ -210,7 +204,7 @@ %D The second implementation expanded the whole math sequence %D into an internal \TEX\ representation. This is a rather clean %D and fast process. Filtering and testing takes place by -%D redefining teh internal representation macros. +%D redefining the internal representation macros. %D %D The third implementation may look a bit more messy in some %D respects. This is because in \TEX\ it's not that trivial to @@ -1855,9 +1849,13 @@ \let\mmlfrac\frac \xmlmapvalue {mml:l} {+} {\let\mmlfrac\sfrac} +\xmlmapvalue {mml:d} {true} {\displaystyle} +\xmlmapvalue {mml:d} {false} {\textstyle} % or whatever + % todo: displaystyle=true/false (or whatever else shows up) \starttexdefinition setmmlmathstyle #1 + \xmlval{mml:d}{\xmlatt{#1}{displaystyle}}\empty % was: \mmmr \xmlval{mml:s}{\xmlatt{#1}{mathvariant}}\empty % was: \mmmr \stoptexdefinition @@ -2042,7 +2040,11 @@ \expanded{\doifelseinset {mml:enclose:radical} {\mmlmenclosenotation}} { \sqrt{\xmlflush{#1}} } { - \xmlflush{#1} + \expanded{\doifelseinset {mml:enclose:rule} {\mmlmenclosenotation}} { + \overline{\strut\xmlflush{#1}} + } { + \xmlflush{#1} + } } } } @@ -2270,9 +2272,9 @@ \def\mmlextensible#1{\ctxmodulemathml{extensible(\!!bs#1\!!es)}} -\definemathtriplet [\v!mathematics] [mmlovertriplet] % or will we use a special instance -\definemathtriplet [\v!mathematics] [mmlundertriplet] % or will we use a special instance -\definemathtriplet [\v!mathematics] [mmldoubletriplet] % or will we use a special instance +\definemathtriplet [\v!mathematics] [mmlovertriplet] % or will we use a special instance +\definemathtriplet [\v!mathematics] [mmlundertriplet] % or will we use a special instance +\definemathtriplet [\v!mathematics] [mmldoubletriplet] % or will we use a special instance % common to munder/mover/munderover : will become core helper (speed up too) @@ -2321,9 +2323,15 @@ \startxmlsetups mml:mover \edef\mmlbasetoken{\mmlextensible{\xmlraw{#1}{/mml:*[1]}}}% /text() - \doifelseutfmathfiller\mmlbasetoken \mmloverbasefiller \mmloveraccentchecker {#1} + \doifelseutfmathlimop\mmlbasetoken + {\mmllimopover{#1}} + {\doifelseutfmathfiller\mmlbasetoken \mmloverbasefiller \mmloveraccentchecker {#1}} \stopxmlsetups +\starttexdefinition mmllimopover #1 + \mmlbasetoken ^{\mmlfencedsecond{#1}} +\stoptexdefinition + % munder \starttexdefinition unexpanded mmlunderbelow #1 @@ -2353,9 +2361,15 @@ \startxmlsetups mml:munder \edef\mmlbasetoken{\mmlextensible{\xmlraw{#1}{/mml:*[1]}}}% /text() - \doifelseutfmathfiller\mmlbasetoken \mmlunderbasefiller \mmlunderaccentchecker {#1} + \doifelseutfmathlimop\mmlbasetoken + {\mmllimopunder{#1}} + {\doifelseutfmathfiller\mmlbasetoken \mmlunderbasefiller \mmlunderaccentchecker {#1}} \stopxmlsetups +\starttexdefinition mmllimopunder #1 + \mmlbasetoken _{\mmlfencedsecond{#1}} +\stoptexdefinition + % munderover \starttexdefinition unexpanded mmlunderoveraccentcheckerUO #1 @@ -2414,11 +2428,18 @@ \edef\mmlbasecommand{e\utfmathcommandfiller\mmlbasetoken}% \mmlexecuteifdefined\mmlbasecommand \relax {\mmlfencedthird{#1}} {\mmlfencedsecond{#1}} \stoptexdefinition + \startxmlsetups mml:munderover \edef\mmlbasetoken{\mmlextensible{\xmlraw{#1}{/mml:*[1]}}}% /text() - \doifelseutfmathfiller\mmlbasetoken \mmlunderoverbasefiller \mmlunderoveraccentchecker {#1} + \doifelseutfmathlimop\mmlbasetoken + {\mmllimopunderover{#1}} + {\doifelseutfmathfiller\mmlbasetoken \mmlunderoverbasefiller \mmlunderoveraccentchecker {#1}} \stopxmlsetups +\starttexdefinition mmllimopunderover #1 + \mmlbasetoken ^{\mmlfencedthird{#1}}_{\mmlfencedsecond{#1}} +\stoptexdefinition + % tables (mml:mtable, mml:mtr, mml:mlabledtr, mml:mtd) \startxmlsetups mml:mtable % some more attributes need to be supported @@ -2430,7 +2451,7 @@ \stopxmlsetups \startxmlsetups mml:mcolumn - \ctxmodulemathml{mcolumn("#1")} + \vbox{\ctxmodulemathml{mcolumn("#1")}}% needs checking \stopxmlsetups \def\mmlsetfakewidth#1{\setbox\scratchbox\hbox{#1}\scratchdimen\wd\scratchbox} diff --git a/tex/context/modules/mkiv/x-setups-basics.mkiv b/tex/context/modules/mkiv/x-setups-basics.mkiv index 4a7859c7f..1c0eb8346 100644 --- a/tex/context/modules/mkiv/x-setups-basics.mkiv +++ b/tex/context/modules/mkiv/x-setups-basics.mkiv @@ -25,6 +25,8 @@ %D Currently we load the \XML\ file and when not in the english interface we just %D remap the relevant words to their translation. +%D Todo: use lua instead of synonyms + \unprotect \defineregister @@ -45,7 +47,7 @@ [\c!width=\hsize, \c!height=\v!fit, \c!align=\v!right, - \c!offset=0.75\emwidth] + \c!offset=0.75\emwidth] % \exheight \popmacro\setuptext @@ -69,7 +71,8 @@ \unexpanded\def\setupalwcolor{} \unexpanded\def\setupoptcolor{darkgray} -\unexpanded\def\setupvarword#1{{\sl\detokenize{#1}}} +% \unexpanded\def\setupvarword#1{{\sl\detokenize{#1}}} +\unexpanded\def\setupvarword#1{\detokenize{#1}} \unexpanded\def\setupintword#1{\WORD{\detokenize{#1}}} \unexpanded\def\setuptxtword#1{\detokenize{#1}} @@ -119,16 +122,68 @@ } \stopxmlsetups +\startxmlsetups xml:setups:assemblename:instance + \doifelse {\xmlatt{#1}{type}} {environment} { + \doifsomethingelse {\xmlatt{#1}{begin}} { + \edef\currentSETUPprefix{\xmllastatt}% + } { + \let\currentSETUPprefix\e!start + } + } { + \let\currentSETUPprefix\empty + } +% \edef\currentSETUPname{\xmlatt{#1}{name}} + \let\currentSETUPgenerated\empty + \doifelsenothing {\xmlatt{#1}{variant}} { + \let\currentSETUPvariant\empty + } { + \def\currentSETUPvariant{:\xmllastatt} + } + \edef\currentSETUPfullname { + \currentSETUPprefix + \currentSETUPname + \currentSETUPvariant + \currentSETUPgenerated + } +\stopxmlsetups + +% \startxmlsetups xml:setups:register +% \doifelse {\xmlatt{#1}{variant}} {instance} { +% \def\docommand##1% +% {\def\currentSETUPname{##1}% +% \xmlsetup{#1}{xml:setups:assemblename:instance} +% \expanded{\texcommand[stp:x:\currentSETUPfullname]{{#1}{##1}}}}% +% \processcommacommand[\clf_getinstances{#1}]\docommand +% } { +% \xmlsetup{#1}{xml:setups:assemblename} +% % not really needed if we just use setups +% \expanded{\texcommand[stp:x:\currentSETUPfullname]{{#1}{}}} +% } +% \stopxmlsetups + \startxmlsetups xml:setups:register + \doif {\xmlatt{#1}{variant}} {instance} { + \def\docommand##1% + {\xmlsetup{#1}{xml:setups:assemblename:instance} + \expanded{\texcommand[stp:x:\currentSETUPfullname:##1]{{#1}{##1}}}}% + \processcommacommand[\clf_getinstances{#1}]\docommand + } \xmlsetup{#1}{xml:setups:assemblename} % not really needed if we just use setups - \expanded{\texcommand[stp:x:\currentSETUPfullname]{#1}} + \expanded{\texcommand[stp:x:\currentSETUPfullname]{{#1}{}}} \stopxmlsetups \startluacode local find, gsub = string.find, string.gsub + local xmlcollected = xml.collected + local xmlcount = xml.count + local xmlfirst = xml.first + + local lxmlgetid = lxml.getid + local lxmlflush = lxml.flush + local context = context local setupvarword = context.formatted.setupvarword @@ -146,12 +201,11 @@ setups.definitions = definitions function xml.functions.setups_define(id) - local x = lxml.getid(id) - for c in xml.collected(x,"cd:interface/cd:define") do + local x = lxmlgetid(id) + for c in xmlcollected(x,"cd:interface/cd:define") do definitions[c.at.name] = c end - - for c in xml.collected(x,"cd:interface/cd:interface") do + for c in xmlcollected(x,"cd:interface/cd:interface") do c.at.file = c.__f__ c.at["xmlns:cd"] = nil -- c.dt[#c.dt+1] = " " @@ -166,22 +220,23 @@ local commands = interfaces.complete.commands local elements = interfaces.complete.elements - local function replace(pattern,attribute,one,two) - for e in xml.collected(x,pattern) do - local t = e.at[attribute] + local function replace(pattern,attribute,one,two,three) + for e in xmlcollected(x,pattern) do + local a = e.at + local t = a[attribute] if t then - local c = one[t] or (two and two[t]) + local c = one[t] or (two and two[t]) or (three and three[t]) if c then local v = c[interface] if v then - e.at[attribute] = v + a[attribute] = v end end end end end - replace('cd:command', 'name', commands, elements) + replace('cd:command', 'name', commands, elements, variables) replace('cd:string', 'value', commands, elements) replace('cd:variable' , 'value', variables) @@ -191,19 +246,74 @@ replace('cd:variable', 'type', variables) replace('cd:inherit', 'name', commands, elements) + replace('cd:instances/cd:constant', 'value', variables) end if tex.modes["setups:save"] and environment.currentrun == 1 then - local s = tostring(x) - s = gsub(s,"\n*%s*(</cd:interface>)%s+(<cd:interface)", "\n\n %1\n\n %2") - s = gsub(s,"\n*%s*(</cd:interface>)%s+(</cd:interface>)","\n\n %1\n\n %2") - io.savedata("context-"..interface..".xml",s) + -- + -- the reload is a hack .. we could make a handler instead + -- + local filename = "context-" .. interface .. ".xml" + local xmlroot = x + local xmlblob = tostring(xmlroot) + io.savedata(filename,xmlblob) + xmlroot = xml.load(filename) + -- + local definitions = { } + for e in xml.collected(xmlroot,"cd:interface/cd:define") do + definitions[e.at.name] = e.dt + end + local function resolve(root) + for e in xmlcollected(root,"*") do + if e.tg == "resolve" then + local name = e.at.name or "" + local resolved = definitions[name] + if resolved then + e.__p__.dt[e.ni] = resolved + resolve(resolved) + -- logs.report("setups","resolved: %a",name) + else + logs.report("setups","unable to resolve: %a",name) + end + end + end + end + resolve(xmlroot) + for e in xml.collected(xmlroot,"cd:interface/cd:define") do + e.__p__.dt[e.ni] = "" + end + xml.delete(xmlroot,"/cd:interface/cd:interface/cd:interface/..") + -- + xmlblob = xml.tostring(xmlroot) + io.savedata(filename,xmlblob) + xmlroot = xml.load(filename) + -- + local spacer = utilities.strings.newrepeater(" ") + local function simplify(dt,n) + local nt, nn = { }, 0 + for i=1,#dt do + local d = dt[i] + if d.special then + -- + elseif type(d) ~= "string" then + d.dt = simplify(d.dt,n+1) + nn = nn + 1 nt[nn] = "\n" .. spacer[n] + nn = nn + 1 nt[nn] = d + nn = nn + 1 nt[nn] = "\n" .. spacer[n-1] + end + end + return nn == 0 and "" or nt + end + xmlroot.dt = simplify(xmlroot.dt,0) + -- + xmlblob = "<?xml version='1.0'?>\n<!-- expanded and compacted i-context.xml -->\n" .. xml.tostring(xmlroot) + xmlblob = gsub(xmlblob,"\n *\n","\n") + io.savedata(filename,xmlblob) end - end function moduledata.setups.resolved(name) - lxml.flush(definitions[name]) + lxmlflush(definitions[name]) end function xml.finalizers.s_count(collected) @@ -213,7 +323,7 @@ local tg = c.tg if tg == "resolve" then local d = definitions[c.at.name] - n = n + xml.count(d,"/*") + n = n + xmlcount(d,"/*") elseif tg == "delimiter" then -- skip else @@ -223,13 +333,30 @@ context(n) end + local function getinstances(id) + local t = { } + local x = lxmlgetid(id) + local r = xmlfirst(x,"/instances/resolve") + if r then + local x = setups.definitions[r.at.name] + for c in xmlcollected(x,"constant") do + t[#t+1] = c.at.value + end + else + for c in xmlcollected(x,"/instances/constant") do + t[#t+1] = c.at.value + end + end + return t + end + interfaces.implement { name = "getsetupstring", actions = function(s) local g = getsetupstring(s) if not find(s,"^cd:") then setuptxtword(g) - elseif find(s,"%-.$") then + elseif find(s,"%-.$") then -- singular | plural setupvarword(g) else setupintword(g) -- cap @@ -246,6 +373,12 @@ arguments = "string", } + interfaces.implement { + name = "getinstances", + actions = { getinstances, function(t) context("%,t",t) end }, + overload = true, + arguments = { "string" }, + } \stopluacode % <?xml version="1.0" encoding="UTF-8"?> @@ -297,13 +430,20 @@ \let \m_cmd_current_hash \empty \let \m_cmd_current_file \empty +% todo: use different names (and a backward compatible extra module then) + \unexpanded\def\basicsetup{\c_cmd_kind\zerocount\cmd_show_setup} \unexpanded\def\shortsetup{\c_cmd_kind\plusone \cmd_show_setup} \unexpanded\def\setup {\c_cmd_kind\plustwo \cmd_show_setup} \unexpanded\def\showsetup {\c_cmd_kind\plustwo \cmd_show_setup} \unexpanded\def\showsetupinlist#1#2#3% - {\c_cmd_kind\plustwo\xmlsetup{#3}{xml:setups:typeset}\par} + {%(#1)(#2)(#3)\par + \edef\m_cmd_instance{\secondoftwoarguments#3}% + \c_cmd_kind\plustwo + \xmlsetup{\firstoftwoarguments#3}{xml:setups:typeset} + \let\m_cmd_instance\empty + \par} \installtextracker {cmd.showsetup} @@ -327,7 +467,12 @@ \fi \startelement[setup][name=#1]% \startelement[noexport][comment={setup definition #1}]% - \xmlsetup{\rawsynonymname{texcommand}{stp:x:#1}}{xml:setups:typeset} + \edef\cmd_id{\rawsynonymname{texcommand}{stp:x:#1}}% + \ifx\cmd_id\empty + missing: stp:x:#1 + \else + \xmlsetup{\expandafter\firstoftwoarguments\cmd_id}{xml:setups:typeset} + \fi \stopelement \stopelement} @@ -358,8 +503,16 @@ \xmlatt{#1}{value} \stopxmlsetups +\startxmlsetups xml:setups:make:instance + \ifx\m_cmd_instance\empty + \setupintfont{\xmlatt{#1}{value}} + \else + \m_cmd_instance + \fi +\stopxmlsetups + \startxmlsetups xml:setups:make:variable - \xmlatt{#1}{value} + \setupintfont{\xmlatt{#1}{value}} \stopxmlsetups \let\m_cmd_current_hash\empty @@ -368,6 +521,7 @@ \let\m_cmd_name \empty \let\m_cmd_start \empty \let\m_cmd_stop \empty +\let\m_cmd_instance \empty \startxmlsetups xml:setups:make:prepare \edef\m_cmd_current_hash{\xmlatt{#1}{hash}} @@ -375,7 +529,7 @@ \xmldoifelseempty{#1}{/sequence} { \edef\m_cmd_name{\xmlatt{#1}{name}} } { - \edef\m_cmd_name{\xmlfilter{#1}{/sequence/(string|variable)/command(xml:setups:make:*)}} + \edef\m_cmd_name{\xmlfilter{#1}{/sequence/(string|variable|instance)/command(xml:setups:make:*)}} } \doifelse {\xmlatt{#1}{type}} {environment} { \doifsomethingelse {\xmlatt{#1}{begin}} { @@ -474,17 +628,23 @@ \stopxmlsetups \startxmlsetups xml:setups:instance - \xmlatt{#1}{value}\enspace + \doifelse {\xmltag{#1}} {resolve} { + \ctxlua{lxml.command(moduledata.setups.definitions['\xmlatt{#1}{name}'],"constant","xml:setups:instance")} + } { + \xmlatt{#1}{value}\enskip % we need a break + } \stopxmlsetups \startxmlsetups xml:setups:typeset:instances - \xmldoif{#1}{/instances} { - \godown[.75\lineheight] - {\ttbf instances:} - \enspace - \xmlfilter{#1}{/instances/constant/command(xml:setups:instance)} - \removeunwantedspaces - } + \ifx\m_cmd_instance\empty + \xmldoif{#1}{/instances} { + \godown[.75\lineheight] + {\ttbf instances:} + \enspace + \xmlfilter{#1}{/instances/(constant|resolve)/command(xml:setups:instance)} + \removeunwantedspaces + } + \fi \stopxmlsetups \startxmlsetups xml:setups:typeset:yes @@ -742,26 +902,35 @@ \unexpanded\def\show_setup_any#1#2% {\bgroup \global\advance\c_cmd_current_argument\plusone + \doifelse{\xmlatt{#1}{optional}}{yes}\donetrue\donefalse \setbox0=\hbox - {\doifelse{\xmlatt{#1}{list}}{yes} + {\ifdone\sl\fi + \doifelse{\xmlatt{#1}{list}}{yes} {\getsetupstring{cd:#2-l}}% {\getsetupstring{cd:#2-s}}}% \setbox2=\hbox to \wd0 {\hss - \raise1.25\exheight\hbox - {\txx\ifcase\c_cmd_maximum_argument \relax - \or*\else\the\c_cmd_current_argument - \fi}% + \ifcase\c_cmd_kind\else + \ifcase\c_cmd_maximum_argument \relax + \or + \raise1.25\exheight\hbox + {\txx *}% + \else + \raise1.25\exheight\hbox + {\txx\the\c_cmd_current_argument}% + \fi + \fi \hss}% \setbox4=\hbox to \wd0 {\hss - \lower2\exheight\hbox - \bgroup - \txx - \doif {\xmlatt{#1}{optional}} {yes} - {\getsetupstring{cd:optional}}% - \egroup - \hss}% + \ifdone + \lower2\exheight\hbox + \bgroup + \txx + \getsetupstring{cd:optional}% + \egroup + \hss + \fi}% \ht2\ht\strutbox \dp4\dp\strutbox \hskip.5\emwidth @@ -871,9 +1040,10 @@ } \blank[\v!big,\v!samepage] \starttabulate[|l|p|] + % no /interface here \xmlall {#1} - {/interface/command[@name=='\currentsetupparametercommand' or @handler=='\currentsetupparametercommand']/arguments/assignments/parameter/command(xml:setups:parameters:value)} + {interface/command[@name=='\currentsetupparametercommand' or @handler=='\currentsetupparametercommand']/arguments/assignments/parameter/command(xml:setups:parameters:value)} \ifnum\noftabulaterows = \zerocount \NC \parameterkey{no specific settings} \NC \NC \NR \fi @@ -903,6 +1073,15 @@ \let\cmdshortsetup\shortsetup \let\cmdfullsetup \showsetup +\unexpanded\def\cmd_with_instance#1#2#3% + {\edef\m_cmd_instance{#3}% + #1{#2}% + \let\m_cmd_instance\empty} + +\unexpanded\def\cmdbasicsetupinstance{\cmd_with_instance\cmdbasicsetup} +\unexpanded\def\cmdshortsetupinstance{\cmd_with_instance\cmdshortsetup} +\unexpanded\def\cmdfullsetupinstance {\cmd_with_instance\cmdfullsetup } + % bonus \definefloat @@ -912,7 +1091,13 @@ [definition] [align=flushright] -\unexpanded\def\showdefinition#1% +\unexpanded\def\showdefinition + {\doifelsenextoptional\cmd_show_definition_yes\cmd_show_definition_nop} + +\unexpanded\def\cmd_show_definition_nop#1% + {\cmd_show_definition_yes[#1]} + +\unexpanded\def\cmd_show_definition_yes[#1]% {\placedefinition[here][definition:#1]{\tex{#1}}{\showsetup{#1}}} \unexpanded\def\definition[#1]% diff --git a/tex/context/modules/mkiv/x-setups-overview.mkiv b/tex/context/modules/mkiv/x-setups-overview.mkiv index 8cfe14439..c0047f13a 100644 --- a/tex/context/modules/mkiv/x-setups-overview.mkiv +++ b/tex/context/modules/mkiv/x-setups-overview.mkiv @@ -14,6 +14,8 @@ % context --interface=en --global --result=setup-en x-setups-overview.mkiv +% \enablemode[setups:save] + \usemodule[setups-basics] \unprotect diff --git a/tex/context/modules/mkiv/x-setups-proofing.mkiv b/tex/context/modules/mkiv/x-setups-proofing.mkiv index e40ee2ad1..5583b8861 100644 --- a/tex/context/modules/mkiv/x-setups-proofing.mkiv +++ b/tex/context/modules/mkiv/x-setups-proofing.mkiv @@ -17,9 +17,6 @@ \unprotect -\loadsetups - [\jobname.xml] - \setupbodyfont [10pt] @@ -45,6 +42,8 @@ \loadsetups[i-common-definitions] + \loadsetups[\jobname.xml] + \placeeverysetup \stoptext diff --git a/tex/context/modules/mkiv/x-steps.mkiv b/tex/context/modules/mkiv/x-steps.mkiv index 29b3f7eaa..02b4cda77 100644 --- a/tex/context/modules/mkiv/x-steps.mkiv +++ b/tex/context/modules/mkiv/x-steps.mkiv @@ -18,6 +18,8 @@ \usemodule[m][steps] +\endinput + \unprotect \installcorenamespace {xmlstepchart} @@ -46,40 +48,40 @@ \xmlregistersetup{xml:ct:define} -\startxmlsetups xml:ct:prep - \expanded{\prep[\xmltoparameters{#1}]}{\xmlflush{#1}} -\stopxmlsetups +% \startxmlsetups xml:ct:prep +% \normalexpanded{\prep[\xmltoparameters{#1}]}{\xmlflush{#1}} +% \stopxmlsetups \startxmlsetups xml:ct:text - \expanded{\text[\xmltoparameters{#1}]}{\xmlflush{#1}} + \normalexpanded{\text[\xmltoparameters{#1}]}{\xmlflush{#1}} \stopxmlsetups \startxmlsetups xml:ct:texts - \expanded{\texts[\xmltoparameters{#1}]}{\xmltext{#1}{/top}} {\xmltext{#1}{/bot}} + \normalexpanded{\texts[\xmltoparameters{#1}]}{\xmltext{#1}{/top}} {\xmltext{#1}{/bot}} \stopxmlsetups \startxmlsetups xml:ct:cell - \expanded{\cell[\xmltoparameters{#1}]}{\xmlflush{#1}} + \normalexpanded{\cell[\xmltoparameters{#1}]}{\xmlflush{#1}} \stopxmlsetups \startxmlsetups xml:ct:cells - \expanded{\cells[\xmltoparameters{#1}]}{\xmltext{#1}{/top}} {\xmltext{#1}{/bot}} + \normalexpanded{\cells[\xmltoparameters{#1}]}{\xmltext{#1}{/top}} {\xmltext{#1}{/bot}} \stopxmlsetups \startxmlsetups xml:ct:lines - \expanded{\startlines[\xmltoparameters{#1}]} + \normalexpanded{\startlines[\xmltoparameters{#1}]} \xmlflush{#1} \stoplines \stopxmlsetups \startxmlsetups xml:ct:steptable - \expanded{\startSTEPtable[\xmltoparameters{#1}]} + \normalexpanded{\startSTEPtable[\xmltoparameters{#1}]} \xmlflush{#1} \stopSTEPtable \stopxmlsetups \startxmlsetups xml:ct:stepchart - \expanded{\startSTEPchart[\xmltoparameters{#1}]} + \normalexpanded{\startSTEPchart[\xmltoparameters{#1}]} \xmlflush{#1} \stopSTEPchart \stopxmlsetups diff --git a/tex/context/sample/common/carrol.tex b/tex/context/sample/common/carrol.tex new file mode 100644 index 000000000..1b653d69c --- /dev/null +++ b/tex/context/sample/common/carrol.tex @@ -0,0 +1,5 @@ +The fraction of fossil olfactory receptor genes is significantly +higher in all species with full color vision. This suggests that +the evolution of trichromatic vision --- which allows these +primates to detect food, mates, and danger with visual cues --- +has reduced their reliance on the sense of smell. diff --git a/tex/context/sample/common/douglas.tex b/tex/context/sample/common/douglas.tex index 838c6d24d..0aa9486e6 100644 --- a/tex/context/sample/common/douglas.tex +++ b/tex/context/sample/common/douglas.tex @@ -4,7 +4,7 @@ of his forthcoming books|=|from the typesetting and layout down to the very shapes of the letters! Seldom has an author had anything remotely like this power to control the final appearance of his or her work. Knuth's \TEX\ -typesetting system has become well|-|known and as available in +typesetting system has become well|-|known and is available in many countries around the world. By contrast, his \METAFONT\ system for designing families of typefaces has not become as well known or as available. diff --git a/tex/context/sample/common/khatt-en.tex b/tex/context/sample/common/khatt-en.tex index f994513e7..52891af25 100644 --- a/tex/context/sample/common/khatt-en.tex +++ b/tex/context/sample/common/khatt-en.tex @@ -1,4 +1,4 @@ -ʿAlī ibn Abī Ṭālib said to his scribe ʿUbaydullāh ibn Abī Rāfiʿ: -your inkwell before you, sharpen the edge of your pen, make sure +ʿAlī ibn Abī Ṭālib said to his scribe ʿUbaydullāh ibn Abī Rāfiʿ: Set +down your inkwell before you, sharpen the edge of your pen, make sure there is open space between the lines, and set your letter|-|spacing closely. Now {\em that} is the way to make the script shine! diff --git a/tex/context/sample/common/knuth.tex b/tex/context/sample/common/knuth.tex index 30b6310cc..2f6a2f8e7 100644 --- a/tex/context/sample/common/knuth.tex +++ b/tex/context/sample/common/knuth.tex @@ -13,4 +13,4 @@ But a system cannot be successful if it is too strongly influenced by a single person. Once the initial design is complete and fairly robust, the real test begins as people with many different viewpoints undertake their own -experiments. +experiments. diff --git a/tex/context/sample/common/samples.tex b/tex/context/sample/common/samples.tex index 0201ab318..8d1477e1c 100644 --- a/tex/context/sample/common/samples.tex +++ b/tex/context/sample/common/samples.tex @@ -48,6 +48,8 @@ used in testing bibliographic references and citations. \NC waltham.tex \NC David Waltham \NC Lucky Planet, why earth is exceptional and what that means for life in the universe, Icon Books Ltd, London, 2014, p. 168 \NC \NR +\NC sapolsky.tex \NC Robert M. Sapolsky \NC Why Zebras Don't Have Ulsters, means for life in the universe, + St Martin's Press, 2004 \NC \NR \stoptabulate % Tufte: This quote will always produce hyphenated text, apart from the content, diff --git a/tex/context/sample/common/sapolsky.tex b/tex/context/sample/common/sapolsky.tex new file mode 100644 index 000000000..37c3ae4f3 --- /dev/null +++ b/tex/context/sample/common/sapolsky.tex @@ -0,0 +1,11 @@ +Agriculture is a fairly recent human invention, and in many ways it was one of +the great stupid moves of all time. Hunter|-|gatherers have thousands of wild +sources of food to subsist on. Agriculture changed that all, generating an +overwhelming reliance on a few dozen domesticated food sources, making you +extremely vulnerable to the next famine, the next locust infestation, the next +potato blight. Agriculture allowed for stockpiling of surplus resources and thus, +inevitably, the unequal stockpiling of them --- stratification of society and +the invention of classes. Thus, it allowed for the invention of poverty. I think +that the punch line of the primate|-|human difference is that when humans +invented poverty, they came up with a way of subjugating the low|-|ranking like +nothing ever seen before in the primate world. diff --git a/tex/context/test/mkiv/pdf-a2a.mkiv b/tex/context/test/mkiv/pdf-a2a.mkiv new file mode 100644 index 000000000..eea567f34 --- /dev/null +++ b/tex/context/test/mkiv/pdf-a2a.mkiv @@ -0,0 +1,40 @@ +% PDF/A-2a + +\enabletrackers[structure.tags,backend.tags] + +\setupbackend + [format=PDF/A-2a, + intent=sRGB IEC61966-2.1, % use <info> entry here; otherwise problems with predefined default profile + profile=sRGB.icc, % use <filename> here + level=0] + +\setuptagging[state=start] + +\setupcolors[cmyk=no] +\definecolor[rgbblack][b=0.01] +\definecolor[transtest][r=1,g=1,t=.5] + +\placebookmarks[chapter][all][force=yes] + +\starttext + +\starttextcolor[rgbblack] + +\startchapter[title=aa,bookmark=bb,list=cc,marking=dd] + +Test it + +\stopchapter + +\stoptextcolor + +\hbox\bgroup + \blackrule[width=1cm,height=1cm,color=red] + \blackrule[width=1cm,height=1cm,color=green] + \blackrule[width=1cm,height=1cm,color=blue] + \blackrule[width=1cm,height=1cm,color=rgbblack] + \blackrule[width=1cm,height=1cm,color=transtest]\hskip-.5cm + \blackrule[width=1cm,height=1cm,color=transtest] +\egroup + +\stoptext diff --git a/tex/context/test/mkiv/pdf-a3a.mkiv b/tex/context/test/mkiv/pdf-a3a.mkiv new file mode 100644 index 000000000..e7bba6fd8 --- /dev/null +++ b/tex/context/test/mkiv/pdf-a3a.mkiv @@ -0,0 +1,43 @@ +% PDF/A-3a + +\nopdfcompression + + +\enabletrackers[structure.tags,backend.tags] + +\setupbackend + [format=PDF/A-3a, + intent=sRGB IEC61966-2.1, % use <info> entry here; otherwise problems with predefined default profile + profile=sRGB.icc, % use <filename> here + level=0] + +\setuptagging[state=start] + +\setupcolors[cmyk=no] +\definecolor[rgbblack][b=0.01] +\definecolor[transtest][r=1,g=1,t=.5] + +\placebookmarks[chapter][all][force=yes] + +\starttext + +\starttextcolor[rgbblack] + +\startchapter[title=aa,bookmark=bb,list=cc,marking=dd] + +Test it + +\stopchapter + +\stoptextcolor + +\hbox\bgroup + \blackrule[width=1cm,height=1cm,color=red] + \blackrule[width=1cm,height=1cm,color=green] + \blackrule[width=1cm,height=1cm,color=blue] + \blackrule[width=1cm,height=1cm,color=rgbblack] + \blackrule[width=1cm,height=1cm,color=transtest]\hskip-.5cm + \blackrule[width=1cm,height=1cm,color=transtest] +\egroup + +\stoptext diff --git a/tex/generic/context/luatex/luatex-basics-gen.lua b/tex/generic/context/luatex/luatex-basics-gen.lua index 2a68b1c18..2be55ccea 100644 --- a/tex/generic/context/luatex/luatex-basics-gen.lua +++ b/tex/generic/context/luatex/luatex-basics-gen.lua @@ -97,6 +97,7 @@ local remapper = { -- fea = "font feature files", -- no longer supported pfb = "type1 fonts", -- needed for vector loading afm = "afm", + enc = "enc files", } function resolvers.findfile(name,fileformat) @@ -257,45 +258,84 @@ function caches.is_writable(path,name) return fullname and file.is_writable(fullname) end -function caches.loaddata(paths,name) - for i=1,#paths do - local data = false - local luaname, lucname = makefullname(paths[i],name) - if lucname and not lfs.isfile(lucname) and type(caches.compile) == "function" then - -- in case we used luatex and luajittex mixed ... lub or luc file - texio.write(string.format("(compiling luc: %s)",lucname)) - data = loadfile(luaname) - if data then - data = data() - end - if data then - caches.compile(data,luaname,lucname) - return data - end - end - if lucname and lfs.isfile(lucname) then -- maybe also check for size +-- function caches.loaddata(paths,name) +-- for i=1,#paths do +-- local data = false +-- local luaname, lucname = makefullname(paths[i],name) +-- if lucname and not lfs.isfile(lucname) and type(caches.compile) == "function" then +-- -- in case we used luatex and luajittex mixed ... lub or luc file +-- texio.write(string.format("(compiling luc: %s)",lucname)) +-- data = loadfile(luaname) +-- if data then +-- data = data() +-- end +-- if data then +-- caches.compile(data,luaname,lucname) +-- return data +-- end +-- end +-- if lucname and lfs.isfile(lucname) then -- maybe also check for size +-- texio.write(string.format("(load luc: %s)",lucname)) +-- data = loadfile(lucname) +-- if data then +-- data = data() +-- end +-- if data then +-- return data +-- else +-- texio.write(string.format("(loading failed: %s)",lucname)) +-- end +-- end +-- if luaname and lfs.isfile(luaname) then +-- texio.write(string.format("(load lua: %s)",luaname)) +-- data = loadfile(luaname) +-- if data then +-- data = data() +-- end +-- if data then +-- return data +-- end +-- end +-- end +-- end + +function caches.loaddata(readables,name,writable) + for i=1,#readables do + local path = readables[i] + local loader = false + local luaname, lucname = makefullname(path,name) + if lfs.isfile(lucname) then texio.write(string.format("(load luc: %s)",lucname)) - data = loadfile(lucname) - if data then - data = data() + loader = loadfile(lucname) + end + if not loader and lfs.isfile(luaname) then + -- can be different paths when we read a file database from disk + local luacrap, lucname = makefullname(writable,name) + texio.write(string.format("(compiling luc: %s)",lucname)) + if lfs.isfile(lucname) then + loader = loadfile(lucname) end - if data then - return data + caches.compile(data,luaname,lucname) + if lfs.isfile(lucname) then + texio.write(string.format("(load luc: %s)",lucname)) + loader = loadfile(lucname) else texio.write(string.format("(loading failed: %s)",lucname)) end - end - if luaname and lfs.isfile(luaname) then - texio.write(string.format("(load lua: %s)",luaname)) - data = loadfile(luaname) - if data then - data = data() - end - if data then - return data + if not loader then + texio.write(string.format("(load lua: %s)",luaname)) + loader = loadfile(luaname) + else + texio.write(string.format("(loading failed: %s)",luaname)) end end + if loader then + loader = loader() + collectgarbage("step") + return loader + end end + return false end function caches.savedata(path,name,data) diff --git a/tex/generic/context/luatex/luatex-basics-nod.lua b/tex/generic/context/luatex/luatex-basics-nod.lua index e7b5ab24f..5571a82ba 100644 --- a/tex/generic/context/luatex/luatex-basics-nod.lua +++ b/tex/generic/context/luatex/luatex-basics-nod.lua @@ -71,7 +71,7 @@ nodes.nodecodes = nodecodes nodes.glyphcodes = glyphcodes nodes.disccodes = disccodes -local free_node = node.free +local flush_node = node.flush_node local remove_node = node.remove local new_node = node.new local traverse_id = node.traverse_id @@ -95,7 +95,7 @@ function nodes.remove(head, current, free_too) head, current = remove_node(head,current) if t then if free_too then - free_node(t) + flush_node(t) t = nil else t.next, t.prev = nil, nil @@ -128,12 +128,14 @@ nodes.setattr = setfield nodes.tostring = node.tostring or tostring nodes.copy = node.copy +nodes.copy_node = node.copy nodes.copy_list = node.copy_list nodes.delete = node.delete nodes.dimensions = node.dimensions nodes.end_of_math = node.end_of_math nodes.flush_list = node.flush_list nodes.flush_node = node.flush_node +nodes.flush = node.flush_node nodes.free = node.free nodes.insert_after = node.insert_after nodes.insert_before = node.insert_before @@ -149,7 +151,6 @@ nodes.first_glyph = node.first_glyph nodes.has_glyph = node.has_glyph or node.first_glyph nodes.current_attr = node.current_attr -nodes.do_ligature_n = node.do_ligature_n nodes.has_field = node.has_field nodes.last_node = node.last_node nodes.usedlist = node.usedlist @@ -170,6 +171,8 @@ nodes.mlist_to_hlist = node.mlist_to_hlist -- we can go nuts (e.g. experimental); this split permits us us keep code -- used elsewhere stable but at the same time play around in context +-- much of this will go away + local direct = node.direct local nuts = { } nodes.nuts = nuts @@ -200,16 +203,39 @@ nuts.setattr = setfield nuts.getfont = direct.getfont nuts.setfont = direct.setfont nuts.getsubtype = direct.getsubtype -nuts.setsubtype = direct.setsubtype or function(n,s) setfield(n,"subtype",s) end +nuts.setsubtype = direct.setsubtype nuts.getchar = direct.getchar nuts.setchar = direct.setchar nuts.getdisc = direct.getdisc nuts.setdisc = direct.setdisc nuts.setlink = direct.setlink nuts.getlist = direct.getlist -nuts.setlist = direct.setlist or function(n,l) setfield(n,"list",l) end -nuts.getleader = direct.getleader -nuts.setleader = direct.setleader or function(n,l) setfield(n,"leader",l) end +nuts.setlist = direct.setlist + +nuts.getoffsets = direct.getoffsets or + function(n) + return getfield(n,"xoffset"), getfield(n,"yoffset") + end +nuts.setoffsets = direct.setoffsets or + function(n,x,y) + if x then setfield(n,"xoffset",x) end + if y then setfield(n,"xoffset",y) end + end + +nuts.getleader = direct.getleader or function(n) return getfield(n,"leader") end +nuts.setleader = direct.setleader or function(n,l) setfield(n,"leader",l) end +nuts.getcomponents = direct.getcomponents or function(n) return getfield(n,"components") end +nuts.setcomponents = direct.setcomponents or function(n,c) setfield(n,"components",c) end +nuts.getkern = direct.getkern or function(n) return getfield(n,"kern") end +nuts.setkern = direct.setkern or function(n,k) setfield(n,"kern",k) end +nuts.getdir = direct.getkern or function(n) return getfield(n,"dir") end +nuts.setdir = direct.setkern or function(n,d) setfield(n,"dir",d) end +nuts.getwidth = direct.getwidth or function(n) return getfield(n,"width") end +nuts.setwidth = direct.setwidth or function(n,w) return setfield(n,"width",w) end +nuts.getheight = direct.getheight or function(n) return getfield(n,"height") end +nuts.setheight = direct.setheight or function(n,h) return setfield(n,"height",h) end +nuts.getdepth = direct.getdepth or function(n) return getfield(n,"depth") end +nuts.setdepth = direct.setdepth or function(n,d) return setfield(n,"depth",d) end if not direct.is_glyph then local getchar = direct.getchar @@ -253,9 +279,12 @@ nuts.insert_before = direct.insert_before nuts.insert_after = direct.insert_after nuts.delete = direct.delete nuts.copy = direct.copy +nuts.copy_node = direct.copy nuts.copy_list = direct.copy_list nuts.tail = direct.tail nuts.flush_list = direct.flush_list +nuts.flush_node = direct.flush_node +nuts.flush = direct.flush nuts.free = direct.free nuts.remove = direct.remove nuts.is_node = direct.is_node @@ -308,3 +337,128 @@ end nodes.setprop = nodes.setproperty nodes.getprop = nodes.getproperty + +-- a few helpers (we need to keep 'm in sync with context) .. some day components +-- might go so here we isolate them + +local setprev = nuts.setprev +local setnext = nuts.setnext +local getnext = nuts.getnext +local setlink = nuts.setlink +local getfield = nuts.getfield +local setfield = nuts.setfield +local getcomponents = nuts.getcomponents +local setcomponents = nuts.setcomponents + +local find_tail = nuts.tail +local flush_list = nuts.flush_list +local flush_node = nuts.flush_node +local traverse_id = nuts.traverse_id +local copy_node = nuts.copy_node + +local glyph_code = nodes.nodecodes.glyph + +function nuts.set_components(target,start,stop) + local head = getcomponents(target) + if head then + flush_list(head) + head = nil + end + if start then + setprev(start) + else + return nil + end + if stop then + setnext(stop) + end + local tail = nil + while start do + local c = getcomponents(start) + local n = getnext(start) + if c then + if head then + setlink(tail,c) + else + head = c + end + tail = find_tail(c) + setcomponents(start) + flush_node(start) + else + if head then + setlink(tail,start) + else + head = start + end + tail = start + end + start = n + end + setcomponents(target,head) + -- maybe also upgrade the subtype but we don't use it anyway + return head +end + +nuts.get_components = nuts.getcomponents + +function nuts.take_components(target) + local c = getcomponents(target) + setcomponents(target) + -- maybe also upgrade the subtype but we don't use it anyway + return c +end + +function nuts.count_components(n,marks) + local components = getcomponents(n) + if components then + if marks then + local i = 0 + for g in traverse_id(glyph_code,components) do + if not marks[getchar(g)] then + i = i + 1 + end + end + return i + else + return count(glyph_code,components) + end + else + return 0 + end +end + +function nuts.copy_no_components(g,copyinjection) + local components = getcomponents(g) + if components then + setcomponents(g) + local n = copy_node(g) + if copyinjection then + copyinjection(n,g) + end + setcomponents(g,components) + -- maybe also upgrade the subtype but we don't use it anyway + return n + else + local n = copy_node(g) + if copyinjection then + copyinjection(n,g) + end + return n + end +end + +function nuts.copy_only_glyphs(current) + local head = nil + local previous = nil + for n in traverse_id(glyph_code,current) do + n = copy_node(n) + if head then + setlink(previous,n) + else + head = n + end + previous = n + end + return head +end diff --git a/tex/generic/context/luatex/luatex-core.lua b/tex/generic/context/luatex/luatex-core.lua new file mode 100644 index 000000000..16df01707 --- /dev/null +++ b/tex/generic/context/luatex/luatex-core.lua @@ -0,0 +1,210 @@ +-- if not modules then modules = { } end modules ['luatex-core'] = { +-- version = 1.001, +-- comment = 'companion to luatex', +-- author = 'Hans Hagen & Luigi Scarso', +-- copyright = 'LuaTeX Development Team', +-- } + +LUATEXCOREVERSION = 1.002 + +-- This file overloads some Lua functions. The readline variants provide the same +-- functionality as LuaTeX <= 1.04 and doing it this way permits us to keep the +-- original io libraries clean. Performance is probably even a bit better now. + +local type, next, getmetatable, require = type, next, getmetatable, require +local find, gsub = string.find, string.gsub + +local io_open = io.open +local io_popen = io.popen +local io_line = io.lines + +local fio_readline = fio.readline +local fio_checkpermission = fio.checkpermission +local fio_recordfilename = fio.recordfilename + +local mt = getmetatable(io.stderr) +local mt_lines = mt.lines +local saferoption = status.safer_option +local shellescape = status.shell_escape -- 0 (disabled) 1 (anything) 2 (restricted) +local kpseused = status.kpse_used -- 0 1 + +io.saved_open = io_open -- can be protected +io.saved_popen = io_popen -- can be protected +io.saved_lines = io_lines -- always readonly +mt.saved_lines = mt_lines -- always readonly + +local function luatex_io_open(name,how) + if not how then + how = 'r' + end + local f = io_open(name,how) + if f then + if type(how) == 'string' and find(how,'w') then + fio_recordfilename(name,'w') + else + fio_recordfilename(name,'r') + end + end + return f +end + +local function luatex_io_open_readonly(name,how) + if how then + how = 'r' + else + how = gsub(how,'[^rb]','') + if how == '' then + how = 'r' + end + end + local f = io_open(name,how) + if f then + fio_recordfilename(name,'r') + end + return f +end + +local function luatex_io_popen(name,...) + local okay, found = fio_checkpermission(name) + if okay and found then + return io_popen(found,...) + end +end + +local function luatex_io_lines(name) + local f = io_open(name,'r') + if f then + return function() + return fio_readline(f) + end + end +end + +local function luatex_io_readline(f) + return function() + return fio_readline(f) + end +end + +io.lines = luatex_io_lines +mt.lines = luatex_io_readline + +-- We assume management to be provided by the replacement of kpse. This is the +-- case in ConTeXt. + +if kpseused == 1 then + + io.open = luatex_io_open + io.popen = luatex_io_popen + +end + +if saferoption == 1 then + + os.execute = nil + os.spawn = nil + os.exec = nil + os.setenv = nil + os.tempdir = nil + + io.popen = nil + io.open = nil + + os.rename = nil + os.remove = nil + + io.tmpfile = nil + io.output = nil + + lfs.chdir = nil + lfs.lock = nil + lfs.touch = nil + lfs.rmdir = nil + lfs.mkdir = nil + + io.saved_popen = nil + io.saved_open = luatex_io_open_readonly + +end + +if saferoption == 1 or shellescape ~= 1 then + + ffi = require('ffi') + for k, v in next, ffi do + if k ~= 'gc' then + ffi[k] = nil + end + end + ffi = nil + +end + +-- os.[execute|os.spawn|os.exec] already are shellescape aware) + + +if md5 then + + local sum = md5.sum + local gsub = string.gsub + local format = string.format + local byte = string.byte + + function md5.sumhexa(k) + return (gsub(sum(k), ".", function(c) + return format("%02x",byte(c)) + end)) + end + + function md5.sumHEXA(k) + return (gsub(sum(k), ".", function(c) + return format("%02X",byte(c)) + end)) + end + +end + +if utilities and utilities.merger and utilities.merger.compact then + + local byte, format, gmatch = string.byte, string.format, string.gmatch + local concat = table.concat + + local data = gsub(io.loaddata('luatex-core.lua'),'if%s+utilities.*','') + local t = { } + local r = { } + local n = 0 + local d = gsub(data,'\r\n','\n') -- be nice for unix + local s = utilities.merger.compact(d) -- no comments and less spaces + + t[#t+1] = '/* generated from and by luatex-core.lua */' + t[#t+1] = '' + -- t[#t+1] = format('/*\n\n%s\n\n*/',d) + -- t[#t+1] = '' + t[#t+1] = '#include "lua.h"' + t[#t+1] = '#include "lauxlib.h"' + t[#t+1] = '' + t[#t+1] = 'int load_luatex_core_lua (lua_State * L);' + t[#t+1] = '' + t[#t+1] = 'int load_luatex_core_lua (lua_State * L)' + t[#t+1] = '{' + t[#t+1] = ' static unsigned char luatex_core_lua[] = {' + for c in gmatch(d,'.') do + if n == 16 then + n = 1 + t[#t+1] = ' ' .. concat(r,', ') .. ',' + else + n = n + 1 + end + r[n] = format('0x%02x',byte(c)) + end + n = n + 1 + r[n] = '0x00' + t[#t+1] = ' ' .. concat(r,', ',1,n) + t[#t+1] = ' };' + -- t[#t+1] = format('unsigned int luatex_core_lua_len = 0x%x;',#d+1) + t[#t+1] = ' return luaL_dostring(L, (const char*) luatex_core_lua);' + t[#t+1] = '}' + + io.savedata('luatex-core.c',concat(t,'\n')) + io.savedata('luatex-core-stripped.lua',s) + +end diff --git a/tex/generic/context/luatex/luatex-core.tex b/tex/generic/context/luatex/luatex-core.tex new file mode 100644 index 000000000..2e7c7d5d4 --- /dev/null +++ b/tex/generic/context/luatex/luatex-core.tex @@ -0,0 +1,30 @@ +\starttext + +\startluacode + + local report = logs.reporter("core") + + report("kpse used : %i",status.kpse_used) + report("shell escape : %i",status.shell_escape) + report("shell restricted : %i",status.shell_restricted) + report("safer option : %i",status.safer_option) + + if false then + + for l in io.open("luatex-core.lua"):lines() do + print(l) + end + + for l in io.lines("luatex-core.lua") do + print(l) + end + + end + +\stopluacode + +\startTEXpage[foregroundstyle=mono,offset=10pt] + LUATEXCOREVERSION: \cldcontext{LUATEXCOREVERSION} +\stopTEXpage + +\stoptext diff --git a/tex/generic/context/luatex/luatex-fonts-demo-vf-1.lua b/tex/generic/context/luatex/luatex-fonts-demo-vf-1.lua index 13acd16ca..793526f7b 100644 --- a/tex/generic/context/luatex/luatex-fonts-demo-vf-1.lua +++ b/tex/generic/context/luatex/luatex-fonts-demo-vf-1.lua @@ -1,3 +1,11 @@ +if not modules then modules = { } end modules ['luatex-fonts-demo-vf-1'] = { + version = 1.001, + comment = "companion to luatex-*.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + local identifiers = fonts.hashes.identifiers return function(specification) diff --git a/tex/generic/context/luatex/luatex-fonts-demo-vf-4.lua b/tex/generic/context/luatex/luatex-fonts-demo-vf-4.lua index 00fc636a1..92ce4ffcb 100644 --- a/tex/generic/context/luatex/luatex-fonts-demo-vf-4.lua +++ b/tex/generic/context/luatex/luatex-fonts-demo-vf-4.lua @@ -1,3 +1,10 @@ +if not modules then modules = { } end modules ['luatex-fonts-demo-vf-4'] = { + version = 1.001, + comment = "companion to luatex-*.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} return function(specification) local t = { } diff --git a/tex/generic/context/luatex/luatex-fonts-enc.lua b/tex/generic/context/luatex/luatex-fonts-enc.lua index 2e1c6a466..c076d5947 100644 --- a/tex/generic/context/luatex/luatex-fonts-enc.lua +++ b/tex/generic/context/luatex/luatex-fonts-enc.lua @@ -11,19 +11,66 @@ if context then os.exit() end -local fonts = fonts -fonts.encodings = { } -fonts.encodings.agl = { } -fonts.encodings.known = { } +local fonts = fonts +local encodings = { } +fonts.encodings = encodings +encodings.agl = { } +encodings.known = { } -setmetatable(fonts.encodings.agl, { __index = function(t,k) +setmetatable(encodings.agl, { __index = function(t,k) if k == "unicodes" then texio.write(" <loading (extended) adobe glyph list>") local unicodes = dofile(resolvers.findfile("font-age.lua")) - fonts.encodings.agl = { unicodes = unicodes } + encodings.agl = { unicodes = unicodes } return unicodes else return nil end end }) +-- adapted for generic + +encodings.cache = containers.define("fonts", "enc", encodings.version, true) + +function encodings.load(filename) + local name = file.removesuffix(filename) + local data = containers.read(encodings.cache,name) + if data then + return data + end + local vector, tag, hash, unicodes = { }, "", { }, { } + local foundname = resolvers.findfile(filename,'enc') + if foundname and foundname ~= "" then + local ok, encoding, size = resolvers.loadbinfile(foundname) + if ok and encoding then + encoding = string.gsub(encoding,"%%(.-)\n","") + local unicoding = encodings.agl.unicodes + local tag, vec = string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def") + local i = 0 + for ch in string.gmatch(vec,"/([%a%d%.]+)") do + if ch ~= ".notdef" then + vector[i] = ch + if not hash[ch] then + hash[ch] = i + else + -- duplicate, play safe for tex ligs and take first + end + local u = unicoding[ch] + if u then + unicodes[u] = i + end + end + i = i + 1 + end + end + end + local data = { + name = name, + tag = tag, + vector = vector, + hash = hash, + unicodes = unicodes + } + return containers.write(encodings.cache, name, data) +end + diff --git a/tex/generic/context/luatex/luatex-fonts-ext.lua b/tex/generic/context/luatex/luatex-fonts-ext.lua index b60d04512..7d9c58ccb 100644 --- a/tex/generic/context/luatex/luatex-fonts-ext.lua +++ b/tex/generic/context/luatex/luatex-fonts-ext.lua @@ -12,7 +12,7 @@ if context then end local fonts = fonts -local otffeatures = fonts.constructors.newfeatures("otf") +local otffeatures = fonts.constructors.features.otf -- A few generic extensions. @@ -270,3 +270,60 @@ otffeatures.register { node = reencode, } } + +local function ignore(tfmdata,key,value) + if value then + tfmdata.mathparameters = nil + end +end + +otffeatures.register { + name = "ignoremathconstants", + description = "ignore math constants table", + initializers = { + base = ignore, + node = ignore, + } +} + +local setmetatableindex = table.setmetatableindex + +local function additalictowidth(tfmdata,key,value) + local characters = tfmdata.characters + local resources = tfmdata.resources + local additions = { } + local private = resources.private + for unicode, old_c in next, characters do + -- maybe check for math + local oldwidth = old_c.width + local olditalic = old_c.italic + if olditalic and olditalic ~= 0 then + private = private + 1 + local new_c = { + width = oldwidth + olditalic, + height = old_c.height, + depth = old_c.depth, + commands = { + { "slot", 1, private }, + { "right", olditalic }, + }, + } + setmetatableindex(new_c,old_c) + characters[unicode] = new_c + additions[private] = old_c + end + end + for k, v in next, additions do + characters[k] = v + end + resources.private = private +end + +otffeatures.register { + name = "italicwidths", + description = "add italic to width", + manipulators = { + base = additalictowidth, + -- node = additalictowidth, -- only makes sense for math + } +} diff --git a/tex/generic/context/luatex/luatex-fonts-lig.lua b/tex/generic/context/luatex/luatex-fonts-lig.lua new file mode 100644 index 000000000..c5347aa19 --- /dev/null +++ b/tex/generic/context/luatex/luatex-fonts-lig.lua @@ -0,0 +1,2067 @@ +-- this file is generated by context + +fonts.handlers.otf.addfeature { + ["dataset"]={ + { + ["data"]={ + ["À"]={ "A", "̀" }, + ["Á"]={ "A", "́" }, + ["Â"]={ "A", "̂" }, + ["Ã"]={ "A", "̃" }, + ["Ä"]={ "A", "̈" }, + ["Å"]={ "A", "̊" }, + ["Ç"]={ "C", "̧" }, + ["È"]={ "E", "̀" }, + ["É"]={ "E", "́" }, + ["Ê"]={ "E", "̂" }, + ["Ë"]={ "E", "̈" }, + ["Ì"]={ "I", "̀" }, + ["Í"]={ "I", "́" }, + ["Î"]={ "I", "̂" }, + ["Ï"]={ "I", "̈" }, + ["Ñ"]={ "N", "̃" }, + ["Ò"]={ "O", "̀" }, + ["Ó"]={ "O", "́" }, + ["Ô"]={ "O", "̂" }, + ["Õ"]={ "O", "̃" }, + ["Ö"]={ "O", "̈" }, + ["Ù"]={ "U", "̀" }, + ["Ú"]={ "U", "́" }, + ["Û"]={ "U", "̂" }, + ["Ü"]={ "U", "̈" }, + ["Ý"]={ "Y", "́" }, + ["à"]={ "a", "̀" }, + ["á"]={ "a", "́" }, + ["â"]={ "a", "̂" }, + ["ã"]={ "a", "̃" }, + ["ä"]={ "a", "̈" }, + ["å"]={ "a", "̊" }, + ["ç"]={ "c", "̧" }, + ["è"]={ "e", "̀" }, + ["é"]={ "e", "́" }, + ["ê"]={ "e", "̂" }, + ["ë"]={ "e", "̈" }, + ["ì"]={ "i", "̀" }, + ["í"]={ "i", "́" }, + ["î"]={ "i", "̂" }, + ["ï"]={ "i", "̈" }, + ["ñ"]={ "n", "̃" }, + ["ò"]={ "o", "̀" }, + ["ó"]={ "o", "́" }, + ["ô"]={ "o", "̂" }, + ["õ"]={ "o", "̃" }, + ["ö"]={ "o", "̈" }, + ["ù"]={ "u", "̀" }, + ["ú"]={ "u", "́" }, + ["û"]={ "u", "̂" }, + ["ü"]={ "u", "̈" }, + ["ý"]={ "y", "́" }, + ["ÿ"]={ "y", "̈" }, + ["Ā"]={ "A", "̄" }, + ["ā"]={ "a", "̄" }, + ["Ă"]={ "A", "̆" }, + ["ă"]={ "a", "̆" }, + ["Ą"]={ "A", "̨" }, + ["ą"]={ "a", "̨" }, + ["Ć"]={ "C", "́" }, + ["ć"]={ "c", "́" }, + ["Ĉ"]={ "C", "̂" }, + ["ĉ"]={ "c", "̂" }, + ["Ċ"]={ "C", "̇" }, + ["ċ"]={ "c", "̇" }, + ["Č"]={ "C", "̌" }, + ["č"]={ "c", "̌" }, + ["Ď"]={ "D", "̌" }, + ["ď"]={ "d", "̌" }, + ["Ē"]={ "E", "̄" }, + ["ē"]={ "e", "̄" }, + ["Ĕ"]={ "E", "̆" }, + ["ĕ"]={ "e", "̆" }, + ["Ė"]={ "E", "̇" }, + ["ė"]={ "e", "̇" }, + ["Ę"]={ "E", "̨" }, + ["ę"]={ "e", "̨" }, + ["Ě"]={ "E", "̌" }, + ["ě"]={ "e", "̌" }, + ["Ĝ"]={ "G", "̂" }, + ["ĝ"]={ "g", "̂" }, + ["Ğ"]={ "G", "̆" }, + ["ğ"]={ "g", "̆" }, + ["Ġ"]={ "G", "̇" }, + ["ġ"]={ "g", "̇" }, + ["Ģ"]={ "G", "̧" }, + ["ģ"]={ "g", "̧" }, + ["Ĥ"]={ "H", "̂" }, + ["ĥ"]={ "h", "̂" }, + ["Ĩ"]={ "I", "̃" }, + ["ĩ"]={ "i", "̃" }, + ["Ī"]={ "I", "̄" }, + ["ī"]={ "i", "̄" }, + ["Ĭ"]={ "I", "̆" }, + ["ĭ"]={ "i", "̆" }, + ["Į"]={ "I", "̨" }, + ["į"]={ "i", "̨" }, + ["İ"]={ "I", "̇" }, + ["Ĵ"]={ "J", "̂" }, + ["ĵ"]={ "j", "̂" }, + ["Ķ"]={ "K", "̧" }, + ["ķ"]={ "k", "̧" }, + ["Ĺ"]={ "L", "́" }, + ["ĺ"]={ "l", "́" }, + ["Ļ"]={ "L", "̧" }, + ["ļ"]={ "l", "̧" }, + ["Ľ"]={ "L", "̌" }, + ["ľ"]={ "l", "̌" }, + ["Ń"]={ "N", "́" }, + ["ń"]={ "n", "́" }, + ["Ņ"]={ "N", "̧" }, + ["ņ"]={ "n", "̧" }, + ["Ň"]={ "N", "̌" }, + ["ň"]={ "n", "̌" }, + ["Ō"]={ "O", "̄" }, + ["ō"]={ "o", "̄" }, + ["Ŏ"]={ "O", "̆" }, + ["ŏ"]={ "o", "̆" }, + ["Ő"]={ "O", "̋" }, + ["ő"]={ "o", "̋" }, + ["Ŕ"]={ "R", "́" }, + ["ŕ"]={ "r", "́" }, + ["Ŗ"]={ "R", "̧" }, + ["ŗ"]={ "r", "̧" }, + ["Ř"]={ "R", "̌" }, + ["ř"]={ "r", "̌" }, + ["Ś"]={ "S", "́" }, + ["ś"]={ "s", "́" }, + ["Ŝ"]={ "S", "̂" }, + ["ŝ"]={ "s", "̂" }, + ["Ş"]={ "S", "̧" }, + ["ş"]={ "s", "̧" }, + ["Š"]={ "S", "̌" }, + ["š"]={ "s", "̌" }, + ["Ţ"]={ "T", "̧" }, + ["ţ"]={ "t", "̧" }, + ["Ť"]={ "T", "̌" }, + ["ť"]={ "t", "̌" }, + ["Ũ"]={ "U", "̃" }, + ["ũ"]={ "u", "̃" }, + ["Ū"]={ "U", "̄" }, + ["ū"]={ "u", "̄" }, + ["Ŭ"]={ "U", "̆" }, + ["ŭ"]={ "u", "̆" }, + ["Ů"]={ "U", "̊" }, + ["ů"]={ "u", "̊" }, + ["Ű"]={ "U", "̋" }, + ["ű"]={ "u", "̋" }, + ["Ų"]={ "U", "̨" }, + ["ų"]={ "u", "̨" }, + ["Ŵ"]={ "W", "̂" }, + ["ŵ"]={ "w", "̂" }, + ["Ŷ"]={ "Y", "̂" }, + ["ŷ"]={ "y", "̂" }, + ["Ÿ"]={ "Y", "̈" }, + ["Ź"]={ "Z", "́" }, + ["ź"]={ "z", "́" }, + ["Ż"]={ "Z", "̇" }, + ["ż"]={ "z", "̇" }, + ["Ž"]={ "Z", "̌" }, + ["ž"]={ "z", "̌" }, + ["Ơ"]={ "O", "̛" }, + ["ơ"]={ "o", "̛" }, + ["Ư"]={ "U", "̛" }, + ["ư"]={ "u", "̛" }, + ["Ǎ"]={ "A", "̌" }, + ["ǎ"]={ "a", "̌" }, + ["Ǐ"]={ "I", "̌" }, + ["ǐ"]={ "i", "̌" }, + ["Ǒ"]={ "O", "̌" }, + ["ǒ"]={ "o", "̌" }, + ["Ǔ"]={ "U", "̌" }, + ["ǔ"]={ "u", "̌" }, + ["Ǖ"]={ "Ü", "̄" }, + ["ǖ"]={ "ü", "̄" }, + ["Ǘ"]={ "Ü", "́" }, + ["ǘ"]={ "ü", "́" }, + ["Ǚ"]={ "Ü", "̌" }, + ["ǚ"]={ "ü", "̌" }, + ["Ǜ"]={ "Ü", "̀" }, + ["ǜ"]={ "ü", "̀" }, + ["Ǟ"]={ "Ä", "̄" }, + ["ǟ"]={ "ä", "̄" }, + ["Ǡ"]={ "Ȧ", "̄" }, + ["ǡ"]={ "ȧ", "̄" }, + ["Ǣ"]={ "Æ", "̄" }, + ["ǣ"]={ "æ", "̄" }, + ["Ǧ"]={ "G", "̌" }, + ["ǧ"]={ "g", "̌" }, + ["Ǩ"]={ "K", "̌" }, + ["ǩ"]={ "k", "̌" }, + ["Ǫ"]={ "O", "̨" }, + ["ǫ"]={ "o", "̨" }, + ["Ǭ"]={ "Ǫ", "̄" }, + ["ǭ"]={ "ǫ", "̄" }, + ["Ǯ"]={ "Ʒ", "̌" }, + ["ǯ"]={ "ʒ", "̌" }, + ["ǰ"]={ "j", "̌" }, + ["Ǵ"]={ "G", "́" }, + ["ǵ"]={ "g", "́" }, + ["Ǹ"]={ "N", "̀" }, + ["ǹ"]={ "n", "̀" }, + ["Ǻ"]={ "Å", "́" }, + ["ǻ"]={ "å", "́" }, + ["Ǽ"]={ "Æ", "́" }, + ["ǽ"]={ "æ", "́" }, + ["Ǿ"]={ "Ø", "́" }, + ["ǿ"]={ "ø", "́" }, + ["Ȁ"]={ "A", "̏" }, + ["ȁ"]={ "a", "̏" }, + ["Ȃ"]={ "A", "̑" }, + ["ȃ"]={ "a", "̑" }, + ["Ȅ"]={ "E", "̏" }, + ["ȅ"]={ "e", "̏" }, + ["Ȇ"]={ "E", "̑" }, + ["ȇ"]={ "e", "̑" }, + ["Ȉ"]={ "I", "̏" }, + ["ȉ"]={ "i", "̏" }, + ["Ȋ"]={ "I", "̑" }, + ["ȋ"]={ "i", "̑" }, + ["Ȍ"]={ "O", "̏" }, + ["ȍ"]={ "o", "̏" }, + ["Ȏ"]={ "O", "̑" }, + ["ȏ"]={ "o", "̑" }, + ["Ȑ"]={ "R", "̏" }, + ["ȑ"]={ "r", "̏" }, + ["Ȓ"]={ "R", "̑" }, + ["ȓ"]={ "r", "̑" }, + ["Ȕ"]={ "U", "̏" }, + ["ȕ"]={ "u", "̏" }, + ["Ȗ"]={ "U", "̑" }, + ["ȗ"]={ "u", "̑" }, + ["Ș"]={ "S", "̦" }, + ["ș"]={ "s", "̦" }, + ["Ț"]={ "T", "̦" }, + ["ț"]={ "t", "̦" }, + ["Ȟ"]={ "H", "̌" }, + ["ȟ"]={ "h", "̌" }, + ["Ȧ"]={ "A", "̇" }, + ["ȧ"]={ "a", "̇" }, + ["Ȩ"]={ "E", "̧" }, + ["ȩ"]={ "e", "̧" }, + ["Ȫ"]={ "Ö", "̄" }, + ["ȫ"]={ "ö", "̄" }, + ["Ȭ"]={ "Õ", "̄" }, + ["ȭ"]={ "õ", "̄" }, + ["Ȯ"]={ "O", "̇" }, + ["ȯ"]={ "o", "̇" }, + ["Ȱ"]={ "Ȯ", "̄" }, + ["ȱ"]={ "ȯ", "̄" }, + ["Ȳ"]={ "Y", "̄" }, + ["ȳ"]={ "y", "̄" }, + ["̈́"]={ "̈", "́" }, + ["΅"]={ "¨", "́" }, + ["Ά"]={ "Α", "́" }, + ["Έ"]={ "Ε", "́" }, + ["Ή"]={ "Η", "́" }, + ["Ί"]={ "Ι", "́" }, + ["Ό"]={ "Ο", "́" }, + ["Ύ"]={ "Υ", "́" }, + ["Ώ"]={ "Ω", "́" }, + ["ΐ"]={ "ϊ", "́" }, + ["Ϊ"]={ "Ι", "̈" }, + ["Ϋ"]={ "Υ", "̈" }, + ["ά"]={ "α", "́" }, + ["έ"]={ "ε", "́" }, + ["ή"]={ "η", "́" }, + ["ί"]={ "ι", "́" }, + ["ΰ"]={ "ϋ", "́" }, + ["ϊ"]={ "ι", "̈" }, + ["ϋ"]={ "υ", "̈" }, + ["ό"]={ "ο", "́" }, + ["ύ"]={ "υ", "́" }, + ["ώ"]={ "ω", "́" }, + ["ϓ"]={ "ϒ", "́" }, + ["ϔ"]={ "ϒ", "̈" }, + ["Ѐ"]={ "Е", "̀" }, + ["Ё"]={ "Е", "̈" }, + ["Ѓ"]={ "Г", "́" }, + ["Ї"]={ "І", "̈" }, + ["Ќ"]={ "К", "́" }, + ["Ѝ"]={ "И", "̀" }, + ["Ў"]={ "У", "̆" }, + ["Й"]={ "И", "̆" }, + ["й"]={ "и", "̆" }, + ["ѐ"]={ "е", "̀" }, + ["ё"]={ "е", "̈" }, + ["ѓ"]={ "г", "́" }, + ["ї"]={ "і", "̈" }, + ["ќ"]={ "к", "́" }, + ["ѝ"]={ "и", "̀" }, + ["ў"]={ "у", "̆" }, + ["Ѷ"]={ "Ѵ", "̏" }, + ["ѷ"]={ "ѵ", "̏" }, + ["Ӂ"]={ "Ж", "̆" }, + ["ӂ"]={ "ж", "̆" }, + ["Ӑ"]={ "А", "̆" }, + ["ӑ"]={ "а", "̆" }, + ["Ӓ"]={ "А", "̈" }, + ["ӓ"]={ "а", "̈" }, + ["Ӗ"]={ "Е", "̆" }, + ["ӗ"]={ "е", "̆" }, + ["Ӛ"]={ "Ә", "̈" }, + ["ӛ"]={ "ә", "̈" }, + ["Ӝ"]={ "Ж", "̈" }, + ["ӝ"]={ "ж", "̈" }, + ["Ӟ"]={ "З", "̈" }, + ["ӟ"]={ "з", "̈" }, + ["Ӣ"]={ "И", "̄" }, + ["ӣ"]={ "и", "̄" }, + ["Ӥ"]={ "И", "̈" }, + ["ӥ"]={ "и", "̈" }, + ["Ӧ"]={ "О", "̈" }, + ["ӧ"]={ "о", "̈" }, + ["Ӫ"]={ "Ө", "̈" }, + ["ӫ"]={ "ө", "̈" }, + ["Ӭ"]={ "Э", "̈" }, + ["ӭ"]={ "э", "̈" }, + ["Ӯ"]={ "У", "̄" }, + ["ӯ"]={ "у", "̄" }, + ["Ӱ"]={ "У", "̈" }, + ["ӱ"]={ "у", "̈" }, + ["Ӳ"]={ "У", "̋" }, + ["ӳ"]={ "у", "̋" }, + ["Ӵ"]={ "Ч", "̈" }, + ["ӵ"]={ "ч", "̈" }, + ["Ӹ"]={ "Ы", "̈" }, + ["ӹ"]={ "ы", "̈" }, + ["آ"]={ "ا", "ٓ" }, + ["أ"]={ "ا", "ٔ" }, + ["ؤ"]={ "و", "ٔ" }, + ["إ"]={ "ا", "ٕ" }, + ["ئ"]={ "ي", "ٔ" }, + ["ۀ"]={ "ە", "ٔ" }, + ["ۂ"]={ "ہ", "ٔ" }, + ["ۓ"]={ "ے", "ٔ" }, + ["ऩ"]={ "न", "़" }, + ["ऱ"]={ "र", "़" }, + ["ऴ"]={ "ळ", "़" }, + ["क़"]={ "क", "़" }, + ["ख़"]={ "ख", "़" }, + ["ग़"]={ "ग", "़" }, + ["ज़"]={ "ज", "़" }, + ["ड़"]={ "ड", "़" }, + ["ढ़"]={ "ढ", "़" }, + ["फ़"]={ "फ", "़" }, + ["य़"]={ "य", "़" }, + ["ো"]={ "ে", "া" }, + ["ৌ"]={ "ে", "ৗ" }, + ["ড়"]={ "ড", "়" }, + ["ঢ়"]={ "ঢ", "়" }, + ["য়"]={ "য", "়" }, + ["ਲ਼"]={ "ਲ", "਼" }, + ["ਸ਼"]={ "ਸ", "਼" }, + ["ਖ਼"]={ "ਖ", "਼" }, + ["ਗ਼"]={ "ਗ", "਼" }, + ["ਜ਼"]={ "ਜ", "਼" }, + ["ਫ਼"]={ "ਫ", "਼" }, + ["ୈ"]={ "େ", "ୖ" }, + ["ୋ"]={ "େ", "ା" }, + ["ୌ"]={ "େ", "ୗ" }, + ["ଡ଼"]={ "ଡ", "଼" }, + ["ଢ଼"]={ "ଢ", "଼" }, + ["ஔ"]={ "ஒ", "ௗ" }, + ["ொ"]={ "ெ", "ா" }, + ["ோ"]={ "ே", "ா" }, + ["ௌ"]={ "ெ", "ௗ" }, + ["ై"]={ "ె", "ౖ" }, + ["ೀ"]={ "ಿ", "ೕ" }, + ["ೇ"]={ "ೆ", "ೕ" }, + ["ೈ"]={ "ೆ", "ೖ" }, + ["ೊ"]={ "ೆ", "ೂ" }, + ["ೋ"]={ "ೊ", "ೕ" }, + ["ൊ"]={ "െ", "ാ" }, + ["ോ"]={ "േ", "ാ" }, + ["ൌ"]={ "െ", "ൗ" }, + ["ේ"]={ "ෙ", "්" }, + ["ො"]={ "ෙ", "ා" }, + ["ෝ"]={ "ො", "්" }, + ["ෞ"]={ "ෙ", "ෟ" }, + ["གྷ"]={ "ག", "ྷ" }, + ["ཌྷ"]={ "ཌ", "ྷ" }, + ["དྷ"]={ "ད", "ྷ" }, + ["བྷ"]={ "བ", "ྷ" }, + ["ཛྷ"]={ "ཛ", "ྷ" }, + ["ཀྵ"]={ "ཀ", "ྵ" }, + ["ཱི"]={ "ཱ", "ི" }, + ["ཱུ"]={ "ཱ", "ུ" }, + ["ྲྀ"]={ "ྲ", "ྀ" }, + ["ླྀ"]={ "ླ", "ྀ" }, + ["ཱྀ"]={ "ཱ", "ྀ" }, + ["ྒྷ"]={ "ྒ", "ྷ" }, + ["ྜྷ"]={ "ྜ", "ྷ" }, + ["ྡྷ"]={ "ྡ", "ྷ" }, + ["ྦྷ"]={ "ྦ", "ྷ" }, + ["ྫྷ"]={ "ྫ", "ྷ" }, + ["ྐྵ"]={ "ྐ", "ྵ" }, + ["ဦ"]={ "ဥ", "ီ" }, + ["ᬆ"]={ "ᬅ", "ᬵ" }, + ["ᬈ"]={ "ᬇ", "ᬵ" }, + ["ᬊ"]={ "ᬉ", "ᬵ" }, + ["ᬌ"]={ "ᬋ", "ᬵ" }, + ["ᬎ"]={ "ᬍ", "ᬵ" }, + ["ᬒ"]={ "ᬑ", "ᬵ" }, + ["ᬻ"]={ "ᬺ", "ᬵ" }, + ["ᬽ"]={ "ᬼ", "ᬵ" }, + ["ᭀ"]={ "ᬾ", "ᬵ" }, + ["ᭁ"]={ "ᬿ", "ᬵ" }, + ["ᭃ"]={ "ᭂ", "ᬵ" }, + ["Ḁ"]={ "A", "̥" }, + ["ḁ"]={ "a", "̥" }, + ["Ḃ"]={ "B", "̇" }, + ["ḃ"]={ "b", "̇" }, + ["Ḅ"]={ "B", "̣" }, + ["ḅ"]={ "b", "̣" }, + ["Ḇ"]={ "B", "̱" }, + ["ḇ"]={ "b", "̱" }, + ["Ḉ"]={ "Ç", "́" }, + ["ḉ"]={ "ç", "́" }, + ["Ḋ"]={ "D", "̇" }, + ["ḋ"]={ "d", "̇" }, + ["Ḍ"]={ "D", "̣" }, + ["ḍ"]={ "d", "̣" }, + ["Ḏ"]={ "D", "̱" }, + ["ḏ"]={ "d", "̱" }, + ["Ḑ"]={ "D", "̧" }, + ["ḑ"]={ "d", "̧" }, + ["Ḓ"]={ "D", "̭" }, + ["ḓ"]={ "d", "̭" }, + ["Ḕ"]={ "Ē", "̀" }, + ["ḕ"]={ "ē", "̀" }, + ["Ḗ"]={ "Ē", "́" }, + ["ḗ"]={ "ē", "́" }, + ["Ḙ"]={ "E", "̭" }, + ["ḙ"]={ "e", "̭" }, + ["Ḛ"]={ "E", "̰" }, + ["ḛ"]={ "e", "̰" }, + ["Ḝ"]={ "Ȩ", "̆" }, + ["ḝ"]={ "ȩ", "̆" }, + ["Ḟ"]={ "F", "̇" }, + ["ḟ"]={ "f", "̇" }, + ["Ḡ"]={ "G", "̄" }, + ["ḡ"]={ "g", "̄" }, + ["Ḣ"]={ "H", "̇" }, + ["ḣ"]={ "h", "̇" }, + ["Ḥ"]={ "H", "̣" }, + ["ḥ"]={ "h", "̣" }, + ["Ḧ"]={ "H", "̈" }, + ["ḧ"]={ "h", "̈" }, + ["Ḩ"]={ "H", "̧" }, + ["ḩ"]={ "h", "̧" }, + ["Ḫ"]={ "H", "̮" }, + ["ḫ"]={ "h", "̮" }, + ["Ḭ"]={ "I", "̰" }, + ["ḭ"]={ "i", "̰" }, + ["Ḯ"]={ "Ï", "́" }, + ["ḯ"]={ "ï", "́" }, + ["Ḱ"]={ "K", "́" }, + ["ḱ"]={ "k", "́" }, + ["Ḳ"]={ "K", "̣" }, + ["ḳ"]={ "k", "̣" }, + ["Ḵ"]={ "K", "̱" }, + ["ḵ"]={ "k", "̱" }, + ["Ḷ"]={ "L", "̣" }, + ["ḷ"]={ "l", "̣" }, + ["Ḹ"]={ "Ḷ", "̄" }, + ["ḹ"]={ "ḷ", "̄" }, + ["Ḻ"]={ "L", "̱" }, + ["ḻ"]={ "l", "̱" }, + ["Ḽ"]={ "L", "̭" }, + ["ḽ"]={ "l", "̭" }, + ["Ḿ"]={ "M", "́" }, + ["ḿ"]={ "m", "́" }, + ["Ṁ"]={ "M", "̇" }, + ["ṁ"]={ "m", "̇" }, + ["Ṃ"]={ "M", "̣" }, + ["ṃ"]={ "m", "̣" }, + ["Ṅ"]={ "N", "̇" }, + ["ṅ"]={ "n", "̇" }, + ["Ṇ"]={ "N", "̣" }, + ["ṇ"]={ "n", "̣" }, + ["Ṉ"]={ "N", "̱" }, + ["ṉ"]={ "n", "̱" }, + ["Ṋ"]={ "N", "̭" }, + ["ṋ"]={ "n", "̭" }, + ["Ṍ"]={ "Õ", "́" }, + ["ṍ"]={ "õ", "́" }, + ["Ṏ"]={ "Õ", "̈" }, + ["ṏ"]={ "õ", "̈" }, + ["Ṑ"]={ "Ō", "̀" }, + ["ṑ"]={ "ō", "̀" }, + ["Ṓ"]={ "Ō", "́" }, + ["ṓ"]={ "ō", "́" }, + ["Ṕ"]={ "P", "́" }, + ["ṕ"]={ "p", "́" }, + ["Ṗ"]={ "P", "̇" }, + ["ṗ"]={ "p", "̇" }, + ["Ṙ"]={ "R", "̇" }, + ["ṙ"]={ "r", "̇" }, + ["Ṛ"]={ "R", "̣" }, + ["ṛ"]={ "r", "̣" }, + ["Ṝ"]={ "Ṛ", "̄" }, + ["ṝ"]={ "ṛ", "̄" }, + ["Ṟ"]={ "R", "̱" }, + ["ṟ"]={ "r", "̱" }, + ["Ṡ"]={ "S", "̇" }, + ["ṡ"]={ "s", "̇" }, + ["Ṣ"]={ "S", "̣" }, + ["ṣ"]={ "s", "̣" }, + ["Ṥ"]={ "Ś", "̇" }, + ["ṥ"]={ "ś", "̇" }, + ["Ṧ"]={ "Š", "̇" }, + ["ṧ"]={ "š", "̇" }, + ["Ṩ"]={ "Ṣ", "̇" }, + ["ṩ"]={ "ṣ", "̇" }, + ["Ṫ"]={ "T", "̇" }, + ["ṫ"]={ "t", "̇" }, + ["Ṭ"]={ "T", "̣" }, + ["ṭ"]={ "t", "̣" }, + ["Ṯ"]={ "T", "̱" }, + ["ṯ"]={ "t", "̱" }, + ["Ṱ"]={ "T", "̭" }, + ["ṱ"]={ "t", "̭" }, + ["Ṳ"]={ "U", "̤" }, + ["ṳ"]={ "u", "̤" }, + ["Ṵ"]={ "U", "̰" }, + ["ṵ"]={ "u", "̰" }, + ["Ṷ"]={ "U", "̭" }, + ["ṷ"]={ "u", "̭" }, + ["Ṹ"]={ "Ũ", "́" }, + ["ṹ"]={ "ũ", "́" }, + ["Ṻ"]={ "Ū", "̈" }, + ["ṻ"]={ "ū", "̈" }, + ["Ṽ"]={ "V", "̃" }, + ["ṽ"]={ "v", "̃" }, + ["Ṿ"]={ "V", "̣" }, + ["ṿ"]={ "v", "̣" }, + ["Ẁ"]={ "W", "̀" }, + ["ẁ"]={ "w", "̀" }, + ["Ẃ"]={ "W", "́" }, + ["ẃ"]={ "w", "́" }, + ["Ẅ"]={ "W", "̈" }, + ["ẅ"]={ "w", "̈" }, + ["Ẇ"]={ "W", "̇" }, + ["ẇ"]={ "w", "̇" }, + ["Ẉ"]={ "W", "̣" }, + ["ẉ"]={ "w", "̣" }, + ["Ẋ"]={ "X", "̇" }, + ["ẋ"]={ "x", "̇" }, + ["Ẍ"]={ "X", "̈" }, + ["ẍ"]={ "x", "̈" }, + ["Ẏ"]={ "Y", "̇" }, + ["ẏ"]={ "y", "̇" }, + ["Ẑ"]={ "Z", "̂" }, + ["ẑ"]={ "z", "̂" }, + ["Ẓ"]={ "Z", "̣" }, + ["ẓ"]={ "z", "̣" }, + ["Ẕ"]={ "Z", "̱" }, + ["ẕ"]={ "z", "̱" }, + ["ẖ"]={ "h", "̱" }, + ["ẗ"]={ "t", "̈" }, + ["ẘ"]={ "w", "̊" }, + ["ẙ"]={ "y", "̊" }, + ["ẛ"]={ "ſ", "̇" }, + ["Ạ"]={ "A", "̣" }, + ["ạ"]={ "a", "̣" }, + ["Ả"]={ "A", "̉" }, + ["ả"]={ "a", "̉" }, + ["Ấ"]={ "Â", "́" }, + ["ấ"]={ "â", "́" }, + ["Ầ"]={ "Â", "̀" }, + ["ầ"]={ "â", "̀" }, + ["Ẩ"]={ "Â", "̉" }, + ["ẩ"]={ "â", "̉" }, + ["Ẫ"]={ "Â", "̃" }, + ["ẫ"]={ "â", "̃" }, + ["Ậ"]={ "Ạ", "̂" }, + ["ậ"]={ "ạ", "̂" }, + ["Ắ"]={ "Ă", "́" }, + ["ắ"]={ "ă", "́" }, + ["Ằ"]={ "Ă", "̀" }, + ["ằ"]={ "ă", "̀" }, + ["Ẳ"]={ "Ă", "̉" }, + ["ẳ"]={ "ă", "̉" }, + ["Ẵ"]={ "Ă", "̃" }, + ["ẵ"]={ "ă", "̃" }, + ["Ặ"]={ "Ạ", "̆" }, + ["ặ"]={ "ạ", "̆" }, + ["Ẹ"]={ "E", "̣" }, + ["ẹ"]={ "e", "̣" }, + ["Ẻ"]={ "E", "̉" }, + ["ẻ"]={ "e", "̉" }, + ["Ẽ"]={ "E", "̃" }, + ["ẽ"]={ "e", "̃" }, + ["Ế"]={ "Ê", "́" }, + ["ế"]={ "ê", "́" }, + ["Ề"]={ "Ê", "̀" }, + ["ề"]={ "ê", "̀" }, + ["Ể"]={ "Ê", "̉" }, + ["ể"]={ "ê", "̉" }, + ["Ễ"]={ "Ê", "̃" }, + ["ễ"]={ "ê", "̃" }, + ["Ệ"]={ "Ẹ", "̂" }, + ["ệ"]={ "ẹ", "̂" }, + ["Ỉ"]={ "I", "̉" }, + ["ỉ"]={ "i", "̉" }, + ["Ị"]={ "I", "̣" }, + ["ị"]={ "i", "̣" }, + ["Ọ"]={ "O", "̣" }, + ["ọ"]={ "o", "̣" }, + ["Ỏ"]={ "O", "̉" }, + ["ỏ"]={ "o", "̉" }, + ["Ố"]={ "Ô", "́" }, + ["ố"]={ "ô", "́" }, + ["Ồ"]={ "Ô", "̀" }, + ["ồ"]={ "ô", "̀" }, + ["Ổ"]={ "Ô", "̉" }, + ["ổ"]={ "ô", "̉" }, + ["Ỗ"]={ "Ô", "̃" }, + ["ỗ"]={ "ô", "̃" }, + ["Ộ"]={ "Ọ", "̂" }, + ["ộ"]={ "ọ", "̂" }, + ["Ớ"]={ "Ơ", "́" }, + ["ớ"]={ "ơ", "́" }, + ["Ờ"]={ "Ơ", "̀" }, + ["ờ"]={ "ơ", "̀" }, + ["Ở"]={ "Ơ", "̉" }, + ["ở"]={ "ơ", "̉" }, + ["Ỡ"]={ "Ơ", "̃" }, + ["ỡ"]={ "ơ", "̃" }, + ["Ợ"]={ "Ơ", "̣" }, + ["ợ"]={ "ơ", "̣" }, + ["Ụ"]={ "U", "̣" }, + ["ụ"]={ "u", "̣" }, + ["Ủ"]={ "U", "̉" }, + ["ủ"]={ "u", "̉" }, + ["Ứ"]={ "Ư", "́" }, + ["ứ"]={ "ư", "́" }, + ["Ừ"]={ "Ư", "̀" }, + ["ừ"]={ "ư", "̀" }, + ["Ử"]={ "Ư", "̉" }, + ["ử"]={ "ư", "̉" }, + ["Ữ"]={ "Ư", "̃" }, + ["ữ"]={ "ư", "̃" }, + ["Ự"]={ "Ư", "̣" }, + ["ự"]={ "ư", "̣" }, + ["Ỳ"]={ "Y", "̀" }, + ["ỳ"]={ "y", "̀" }, + ["Ỵ"]={ "Y", "̣" }, + ["ỵ"]={ "y", "̣" }, + ["Ỷ"]={ "Y", "̉" }, + ["ỷ"]={ "y", "̉" }, + ["Ỹ"]={ "Y", "̃" }, + ["ỹ"]={ "y", "̃" }, + ["ἀ"]={ "α", "̓" }, + ["ἁ"]={ "α", "̔" }, + ["ἂ"]={ "ἀ", "̀" }, + ["ἃ"]={ "ἁ", "̀" }, + ["ἄ"]={ "ἀ", "́" }, + ["ἅ"]={ "ἁ", "́" }, + ["ἆ"]={ "ἀ", "͂" }, + ["ἇ"]={ "ἁ", "͂" }, + ["Ἀ"]={ "Α", "̓" }, + ["Ἁ"]={ "Α", "̔" }, + ["Ἂ"]={ "Ἀ", "̀" }, + ["Ἃ"]={ "Ἁ", "̀" }, + ["Ἄ"]={ "Ἀ", "́" }, + ["Ἅ"]={ "Ἁ", "́" }, + ["Ἆ"]={ "Ἀ", "͂" }, + ["Ἇ"]={ "Ἁ", "͂" }, + ["ἐ"]={ "ε", "̓" }, + ["ἑ"]={ "ε", "̔" }, + ["ἒ"]={ "ἐ", "̀" }, + ["ἓ"]={ "ἑ", "̀" }, + ["ἔ"]={ "ἐ", "́" }, + ["ἕ"]={ "ἑ", "́" }, + ["Ἐ"]={ "Ε", "̓" }, + ["Ἑ"]={ "Ε", "̔" }, + ["Ἒ"]={ "Ἐ", "̀" }, + ["Ἓ"]={ "Ἑ", "̀" }, + ["Ἔ"]={ "Ἐ", "́" }, + ["Ἕ"]={ "Ἑ", "́" }, + ["ἠ"]={ "η", "̓" }, + ["ἡ"]={ "η", "̔" }, + ["ἢ"]={ "ἠ", "̀" }, + ["ἣ"]={ "ἡ", "̀" }, + ["ἤ"]={ "ἠ", "́" }, + ["ἥ"]={ "ἡ", "́" }, + ["ἦ"]={ "ἠ", "͂" }, + ["ἧ"]={ "ἡ", "͂" }, + ["Ἠ"]={ "Η", "̓" }, + ["Ἡ"]={ "Η", "̔" }, + ["Ἢ"]={ "Ἠ", "̀" }, + ["Ἣ"]={ "Ἡ", "̀" }, + ["Ἤ"]={ "Ἠ", "́" }, + ["Ἥ"]={ "Ἡ", "́" }, + ["Ἦ"]={ "Ἠ", "͂" }, + ["Ἧ"]={ "Ἡ", "͂" }, + ["ἰ"]={ "ι", "̓" }, + ["ἱ"]={ "ι", "̔" }, + ["ἲ"]={ "ἰ", "̀" }, + ["ἳ"]={ "ἱ", "̀" }, + ["ἴ"]={ "ἰ", "́" }, + ["ἵ"]={ "ἱ", "́" }, + ["ἶ"]={ "ἰ", "͂" }, + ["ἷ"]={ "ἱ", "͂" }, + ["Ἰ"]={ "Ι", "̓" }, + ["Ἱ"]={ "Ι", "̔" }, + ["Ἲ"]={ "Ἰ", "̀" }, + ["Ἳ"]={ "Ἱ", "̀" }, + ["Ἴ"]={ "Ἰ", "́" }, + ["Ἵ"]={ "Ἱ", "́" }, + ["Ἶ"]={ "Ἰ", "͂" }, + ["Ἷ"]={ "Ἱ", "͂" }, + ["ὀ"]={ "ο", "̓" }, + ["ὁ"]={ "ο", "̔" }, + ["ὂ"]={ "ὀ", "̀" }, + ["ὃ"]={ "ὁ", "̀" }, + ["ὄ"]={ "ὀ", "́" }, + ["ὅ"]={ "ὁ", "́" }, + ["Ὀ"]={ "Ο", "̓" }, + ["Ὁ"]={ "Ο", "̔" }, + ["Ὂ"]={ "Ὀ", "̀" }, + ["Ὃ"]={ "Ὁ", "̀" }, + ["Ὄ"]={ "Ὀ", "́" }, + ["Ὅ"]={ "Ὁ", "́" }, + ["ὐ"]={ "υ", "̓" }, + ["ὑ"]={ "υ", "̔" }, + ["ὒ"]={ "ὐ", "̀" }, + ["ὓ"]={ "ὑ", "̀" }, + ["ὔ"]={ "ὐ", "́" }, + ["ὕ"]={ "ὑ", "́" }, + ["ὖ"]={ "ὐ", "͂" }, + ["ὗ"]={ "ὑ", "͂" }, + ["Ὑ"]={ "Υ", "̔" }, + ["Ὓ"]={ "Ὑ", "̀" }, + ["Ὕ"]={ "Ὑ", "́" }, + ["Ὗ"]={ "Ὑ", "͂" }, + ["ὠ"]={ "ω", "̓" }, + ["ὡ"]={ "ω", "̔" }, + ["ὢ"]={ "ὠ", "̀" }, + ["ὣ"]={ "ὡ", "̀" }, + ["ὤ"]={ "ὠ", "́" }, + ["ὥ"]={ "ὡ", "́" }, + ["ὦ"]={ "ὠ", "͂" }, + ["ὧ"]={ "ὡ", "͂" }, + ["Ὠ"]={ "Ω", "̓" }, + ["Ὡ"]={ "Ω", "̔" }, + ["Ὢ"]={ "Ὠ", "̀" }, + ["Ὣ"]={ "Ὡ", "̀" }, + ["Ὤ"]={ "Ὠ", "́" }, + ["Ὥ"]={ "Ὡ", "́" }, + ["Ὦ"]={ "Ὠ", "͂" }, + ["Ὧ"]={ "Ὡ", "͂" }, + ["ὰ"]={ "α", "̀" }, + ["ὲ"]={ "ε", "̀" }, + ["ὴ"]={ "η", "̀" }, + ["ὶ"]={ "ι", "̀" }, + ["ὸ"]={ "ο", "̀" }, + ["ὺ"]={ "υ", "̀" }, + ["ὼ"]={ "ω", "̀" }, + ["ᾀ"]={ "ἀ", "ͅ" }, + ["ᾁ"]={ "ἁ", "ͅ" }, + ["ᾂ"]={ "ἂ", "ͅ" }, + ["ᾃ"]={ "ἃ", "ͅ" }, + ["ᾄ"]={ "ἄ", "ͅ" }, + ["ᾅ"]={ "ἅ", "ͅ" }, + ["ᾆ"]={ "ἆ", "ͅ" }, + ["ᾇ"]={ "ἇ", "ͅ" }, + ["ᾈ"]={ "Ἀ", "ͅ" }, + ["ᾉ"]={ "Ἁ", "ͅ" }, + ["ᾊ"]={ "Ἂ", "ͅ" }, + ["ᾋ"]={ "Ἃ", "ͅ" }, + ["ᾌ"]={ "Ἄ", "ͅ" }, + ["ᾍ"]={ "Ἅ", "ͅ" }, + ["ᾎ"]={ "Ἆ", "ͅ" }, + ["ᾏ"]={ "Ἇ", "ͅ" }, + ["ᾐ"]={ "ἠ", "ͅ" }, + ["ᾑ"]={ "ἡ", "ͅ" }, + ["ᾒ"]={ "ἢ", "ͅ" }, + ["ᾓ"]={ "ἣ", "ͅ" }, + ["ᾔ"]={ "ἤ", "ͅ" }, + ["ᾕ"]={ "ἥ", "ͅ" }, + ["ᾖ"]={ "ἦ", "ͅ" }, + ["ᾗ"]={ "ἧ", "ͅ" }, + ["ᾘ"]={ "Ἠ", "ͅ" }, + ["ᾙ"]={ "Ἡ", "ͅ" }, + ["ᾚ"]={ "Ἢ", "ͅ" }, + ["ᾛ"]={ "Ἣ", "ͅ" }, + ["ᾜ"]={ "Ἤ", "ͅ" }, + ["ᾝ"]={ "Ἥ", "ͅ" }, + ["ᾞ"]={ "Ἦ", "ͅ" }, + ["ᾟ"]={ "Ἧ", "ͅ" }, + ["ᾠ"]={ "ὠ", "ͅ" }, + ["ᾡ"]={ "ὡ", "ͅ" }, + ["ᾢ"]={ "ὢ", "ͅ" }, + ["ᾣ"]={ "ὣ", "ͅ" }, + ["ᾤ"]={ "ὤ", "ͅ" }, + ["ᾥ"]={ "ὥ", "ͅ" }, + ["ᾦ"]={ "ὦ", "ͅ" }, + ["ᾧ"]={ "ὧ", "ͅ" }, + ["ᾨ"]={ "Ὠ", "ͅ" }, + ["ᾩ"]={ "Ὡ", "ͅ" }, + ["ᾪ"]={ "Ὢ", "ͅ" }, + ["ᾫ"]={ "Ὣ", "ͅ" }, + ["ᾬ"]={ "Ὤ", "ͅ" }, + ["ᾭ"]={ "Ὥ", "ͅ" }, + ["ᾮ"]={ "Ὦ", "ͅ" }, + ["ᾯ"]={ "Ὧ", "ͅ" }, + ["ᾰ"]={ "α", "̆" }, + ["ᾱ"]={ "α", "̄" }, + ["ᾲ"]={ "ὰ", "ͅ" }, + ["ᾳ"]={ "α", "ͅ" }, + ["ᾴ"]={ "ά", "ͅ" }, + ["ᾶ"]={ "α", "͂" }, + ["ᾷ"]={ "ᾶ", "ͅ" }, + ["Ᾰ"]={ "Α", "̆" }, + ["Ᾱ"]={ "Α", "̄" }, + ["Ὰ"]={ "Α", "̀" }, + ["ᾼ"]={ "Α", "ͅ" }, + ["῁"]={ "¨", "͂" }, + ["ῂ"]={ "ὴ", "ͅ" }, + ["ῃ"]={ "η", "ͅ" }, + ["ῄ"]={ "ή", "ͅ" }, + ["ῆ"]={ "η", "͂" }, + ["ῇ"]={ "ῆ", "ͅ" }, + ["Ὲ"]={ "Ε", "̀" }, + ["Ὴ"]={ "Η", "̀" }, + ["ῌ"]={ "Η", "ͅ" }, + ["῍"]={ "᾿", "̀" }, + ["῎"]={ "᾿", "́" }, + ["῏"]={ "᾿", "͂" }, + ["ῐ"]={ "ι", "̆" }, + ["ῑ"]={ "ι", "̄" }, + ["ῒ"]={ "ϊ", "̀" }, + ["ῖ"]={ "ι", "͂" }, + ["ῗ"]={ "ϊ", "͂" }, + ["Ῐ"]={ "Ι", "̆" }, + ["Ῑ"]={ "Ι", "̄" }, + ["Ὶ"]={ "Ι", "̀" }, + ["῝"]={ "῾", "̀" }, + ["῞"]={ "῾", "́" }, + ["῟"]={ "῾", "͂" }, + ["ῠ"]={ "υ", "̆" }, + ["ῡ"]={ "υ", "̄" }, + ["ῢ"]={ "ϋ", "̀" }, + ["ῤ"]={ "ρ", "̓" }, + ["ῥ"]={ "ρ", "̔" }, + ["ῦ"]={ "υ", "͂" }, + ["ῧ"]={ "ϋ", "͂" }, + ["Ῠ"]={ "Υ", "̆" }, + ["Ῡ"]={ "Υ", "̄" }, + ["Ὺ"]={ "Υ", "̀" }, + ["Ῥ"]={ "Ρ", "̔" }, + ["῭"]={ "¨", "̀" }, + ["ῲ"]={ "ὼ", "ͅ" }, + ["ῳ"]={ "ω", "ͅ" }, + ["ῴ"]={ "ώ", "ͅ" }, + ["ῶ"]={ "ω", "͂" }, + ["ῷ"]={ "ῶ", "ͅ" }, + ["Ὸ"]={ "Ο", "̀" }, + ["Ὼ"]={ "Ω", "̀" }, + ["ῼ"]={ "Ω", "ͅ" }, + ["↚"]={ "←", "̸" }, + ["↛"]={ "→", "̸" }, + ["↮"]={ "↔", "̸" }, + ["⇍"]={ "⇐", "̸" }, + ["⇎"]={ "⇔", "̸" }, + ["⇏"]={ "⇒", "̸" }, + ["∄"]={ "∃", "̸" }, + ["∉"]={ "∈", "̸" }, + ["∌"]={ "∋", "̸" }, + ["∤"]={ "∣", "̸" }, + ["∦"]={ "∥", "̸" }, + ["≁"]={ "∼", "̸" }, + ["≄"]={ "≃", "̸" }, + ["≇"]={ "≅", "̸" }, + ["≉"]={ "≈", "̸" }, + ["≠"]={ "=", "̸" }, + ["≢"]={ "≡", "̸" }, + ["≭"]={ "≍", "̸" }, + ["≮"]={ "<", "̸" }, + ["≯"]={ ">", "̸" }, + ["≰"]={ "≤", "̸" }, + ["≱"]={ "≥", "̸" }, + ["≴"]={ "≲", "̸" }, + ["≵"]={ "≳", "̸" }, + ["≸"]={ "≶", "̸" }, + ["≹"]={ "≷", "̸" }, + ["⊀"]={ "≺", "̸" }, + ["⊁"]={ "≻", "̸" }, + ["⊄"]={ "⊂", "̸" }, + ["⊅"]={ "⊃", "̸" }, + ["⊈"]={ "⊆", "̸" }, + ["⊉"]={ "⊇", "̸" }, + ["⊬"]={ "⊢", "̸" }, + ["⊭"]={ "⊨", "̸" }, + ["⊮"]={ "⊩", "̸" }, + ["⊯"]={ "⊫", "̸" }, + ["⋠"]={ "≼", "̸" }, + ["⋡"]={ "≽", "̸" }, + ["⋢"]={ "⊑", "̸" }, + ["⋣"]={ "⊒", "̸" }, + ["⋪"]={ "⊲", "̸" }, + ["⋫"]={ "⊳", "̸" }, + ["⋬"]={ "⊴", "̸" }, + ["⋭"]={ "⊵", "̸" }, + ["⫝̸"]={ "⫝", "̸" }, + ["が"]={ "か", "゙" }, + ["ぎ"]={ "き", "゙" }, + ["ぐ"]={ "く", "゙" }, + ["げ"]={ "け", "゙" }, + ["ご"]={ "こ", "゙" }, + ["ざ"]={ "さ", "゙" }, + ["じ"]={ "し", "゙" }, + ["ず"]={ "す", "゙" }, + ["ぜ"]={ "せ", "゙" }, + ["ぞ"]={ "そ", "゙" }, + ["だ"]={ "た", "゙" }, + ["ぢ"]={ "ち", "゙" }, + ["づ"]={ "つ", "゙" }, + ["で"]={ "て", "゙" }, + ["ど"]={ "と", "゙" }, + ["ば"]={ "は", "゙" }, + ["ぱ"]={ "は", "゚" }, + ["び"]={ "ひ", "゙" }, + ["ぴ"]={ "ひ", "゚" }, + ["ぶ"]={ "ふ", "゙" }, + ["ぷ"]={ "ふ", "゚" }, + ["べ"]={ "へ", "゙" }, + ["ぺ"]={ "へ", "゚" }, + ["ぼ"]={ "ほ", "゙" }, + ["ぽ"]={ "ほ", "゚" }, + ["ゔ"]={ "う", "゙" }, + ["ゞ"]={ "ゝ", "゙" }, + ["ガ"]={ "カ", "゙" }, + ["ギ"]={ "キ", "゙" }, + ["グ"]={ "ク", "゙" }, + ["ゲ"]={ "ケ", "゙" }, + ["ゴ"]={ "コ", "゙" }, + ["ザ"]={ "サ", "゙" }, + ["ジ"]={ "シ", "゙" }, + ["ズ"]={ "ス", "゙" }, + ["ゼ"]={ "セ", "゙" }, + ["ゾ"]={ "ソ", "゙" }, + ["ダ"]={ "タ", "゙" }, + ["ヂ"]={ "チ", "゙" }, + ["ヅ"]={ "ツ", "゙" }, + ["デ"]={ "テ", "゙" }, + ["ド"]={ "ト", "゙" }, + ["バ"]={ "ハ", "゙" }, + ["パ"]={ "ハ", "゚" }, + ["ビ"]={ "ヒ", "゙" }, + ["ピ"]={ "ヒ", "゚" }, + ["ブ"]={ "フ", "゙" }, + ["プ"]={ "フ", "゚" }, + ["ベ"]={ "ヘ", "゙" }, + ["ペ"]={ "ヘ", "゚" }, + ["ボ"]={ "ホ", "゙" }, + ["ポ"]={ "ホ", "゚" }, + ["ヴ"]={ "ウ", "゙" }, + ["ヷ"]={ "ワ", "゙" }, + ["ヸ"]={ "ヰ", "゙" }, + ["ヹ"]={ "ヱ", "゙" }, + ["ヺ"]={ "ヲ", "゙" }, + ["ヾ"]={ "ヽ", "゙" }, + ["יִ"]={ "י", "ִ" }, + ["ײַ"]={ "ײ", "ַ" }, + ["שׁ"]={ "ש", "ׁ" }, + ["שׂ"]={ "ש", "ׂ" }, + ["שּׁ"]={ "שּ", "ׁ" }, + ["שּׂ"]={ "שּ", "ׂ" }, + ["אַ"]={ "א", "ַ" }, + ["אָ"]={ "א", "ָ" }, + ["אּ"]={ "א", "ּ" }, + ["בּ"]={ "ב", "ּ" }, + ["גּ"]={ "ג", "ּ" }, + ["דּ"]={ "ד", "ּ" }, + ["הּ"]={ "ה", "ּ" }, + ["וּ"]={ "ו", "ּ" }, + ["זּ"]={ "ז", "ּ" }, + ["טּ"]={ "ט", "ּ" }, + ["יּ"]={ "י", "ּ" }, + ["ךּ"]={ "ך", "ּ" }, + ["כּ"]={ "כ", "ּ" }, + ["לּ"]={ "ל", "ּ" }, + ["מּ"]={ "מ", "ּ" }, + ["נּ"]={ "נ", "ּ" }, + ["סּ"]={ "ס", "ּ" }, + ["ףּ"]={ "ף", "ּ" }, + ["פּ"]={ "פ", "ּ" }, + ["צּ"]={ "צ", "ּ" }, + ["קּ"]={ "ק", "ּ" }, + ["רּ"]={ "ר", "ּ" }, + ["שּ"]={ "ש", "ּ" }, + ["תּ"]={ "ת", "ּ" }, + ["וֹ"]={ "ו", "ֹ" }, + ["בֿ"]={ "ב", "ֿ" }, + ["כֿ"]={ "כ", "ֿ" }, + ["פֿ"]={ "פ", "ֿ" }, + ["𑂚"]={ "𑂙", "𑂺" }, + ["𑂜"]={ "𑂛", "𑂺" }, + ["𑂫"]={ "𑂥", "𑂺" }, + ["𑄮"]={ "𑄱", "𑄧" }, + ["𑄯"]={ "𑄲", "𑄧" }, + ["𑍋"]={ "𑍇", "𑌾" }, + ["𑍌"]={ "𑍇", "𑍗" }, + ["𑒻"]={ "𑒹", "𑒺" }, + ["𑒼"]={ "𑒹", "𑒰" }, + ["𑒾"]={ "𑒹", "𑒽" }, + ["𑖺"]={ "𑖸", "𑖯" }, + ["𑖻"]={ "𑖹", "𑖯" }, + ["𝅗𝅥"]={ "𝅗", "𝅥" }, + ["𝅘𝅥"]={ "𝅘", "𝅥" }, + ["𝅘𝅥𝅮"]={ "𝅘𝅥", "𝅮" }, + ["𝅘𝅥𝅯"]={ "𝅘𝅥", "𝅯" }, + ["𝅘𝅥𝅰"]={ "𝅘𝅥", "𝅰" }, + ["𝅘𝅥𝅱"]={ "𝅘𝅥", "𝅱" }, + ["𝅘𝅥𝅲"]={ "𝅘𝅥", "𝅲" }, + ["𝆹𝅥"]={ "𝆹", "𝅥" }, + ["𝆺𝅥"]={ "𝆺", "𝅥" }, + ["𝆹𝅥𝅮"]={ "𝆹𝅥", "𝅮" }, + ["𝆺𝅥𝅮"]={ "𝆺𝅥", "𝅮" }, + ["𝆹𝅥𝅯"]={ "𝆹𝅥", "𝅯" }, + ["𝆺𝅥𝅯"]={ "𝆺𝅥", "𝅯" }, + }, + }, + { + ["data"]={ + ["À"]={ "A", "̀" }, + ["Á"]={ "A", "́" }, + ["Â"]={ "A", "̂" }, + ["Ã"]={ "A", "̃" }, + ["Ä"]={ "A", "̈" }, + ["Å"]={ "A", "̊" }, + ["Ç"]={ "C", "̧" }, + ["È"]={ "E", "̀" }, + ["É"]={ "E", "́" }, + ["Ê"]={ "E", "̂" }, + ["Ë"]={ "E", "̈" }, + ["Ì"]={ "I", "̀" }, + ["Í"]={ "I", "́" }, + ["Î"]={ "I", "̂" }, + ["Ï"]={ "I", "̈" }, + ["Ñ"]={ "N", "̃" }, + ["Ò"]={ "O", "̀" }, + ["Ó"]={ "O", "́" }, + ["Ô"]={ "O", "̂" }, + ["Õ"]={ "O", "̃" }, + ["Ö"]={ "O", "̈" }, + ["Ù"]={ "U", "̀" }, + ["Ú"]={ "U", "́" }, + ["Û"]={ "U", "̂" }, + ["Ü"]={ "U", "̈" }, + ["Ý"]={ "Y", "́" }, + ["à"]={ "a", "̀" }, + ["á"]={ "a", "́" }, + ["â"]={ "a", "̂" }, + ["ã"]={ "a", "̃" }, + ["ä"]={ "a", "̈" }, + ["å"]={ "a", "̊" }, + ["ç"]={ "c", "̧" }, + ["è"]={ "e", "̀" }, + ["é"]={ "e", "́" }, + ["ê"]={ "e", "̂" }, + ["ë"]={ "e", "̈" }, + ["ì"]={ "i", "̀" }, + ["í"]={ "i", "́" }, + ["î"]={ "i", "̂" }, + ["ï"]={ "i", "̈" }, + ["ñ"]={ "n", "̃" }, + ["ò"]={ "o", "̀" }, + ["ó"]={ "o", "́" }, + ["ô"]={ "o", "̂" }, + ["õ"]={ "o", "̃" }, + ["ö"]={ "o", "̈" }, + ["ù"]={ "u", "̀" }, + ["ú"]={ "u", "́" }, + ["û"]={ "u", "̂" }, + ["ü"]={ "u", "̈" }, + ["ý"]={ "y", "́" }, + ["ÿ"]={ "y", "̈" }, + ["Ā"]={ "A", "̄" }, + ["ā"]={ "a", "̄" }, + ["Ă"]={ "A", "̆" }, + ["ă"]={ "a", "̆" }, + ["Ą"]={ "A", "̨" }, + ["ą"]={ "a", "̨" }, + ["Ć"]={ "C", "́" }, + ["ć"]={ "c", "́" }, + ["Ĉ"]={ "C", "̂" }, + ["ĉ"]={ "c", "̂" }, + ["Ċ"]={ "C", "̇" }, + ["ċ"]={ "c", "̇" }, + ["Č"]={ "C", "̌" }, + ["č"]={ "c", "̌" }, + ["Ď"]={ "D", "̌" }, + ["ď"]={ "d", "̌" }, + ["Ē"]={ "E", "̄" }, + ["ē"]={ "e", "̄" }, + ["Ĕ"]={ "E", "̆" }, + ["ĕ"]={ "e", "̆" }, + ["Ė"]={ "E", "̇" }, + ["ė"]={ "e", "̇" }, + ["Ę"]={ "E", "̨" }, + ["ę"]={ "e", "̨" }, + ["Ě"]={ "E", "̌" }, + ["ě"]={ "e", "̌" }, + ["Ĝ"]={ "G", "̂" }, + ["ĝ"]={ "g", "̂" }, + ["Ğ"]={ "G", "̆" }, + ["ğ"]={ "g", "̆" }, + ["Ġ"]={ "G", "̇" }, + ["ġ"]={ "g", "̇" }, + ["Ģ"]={ "G", "̧" }, + ["ģ"]={ "g", "̧" }, + ["Ĥ"]={ "H", "̂" }, + ["ĥ"]={ "h", "̂" }, + ["Ĩ"]={ "I", "̃" }, + ["ĩ"]={ "i", "̃" }, + ["Ī"]={ "I", "̄" }, + ["ī"]={ "i", "̄" }, + ["Ĭ"]={ "I", "̆" }, + ["ĭ"]={ "i", "̆" }, + ["Į"]={ "I", "̨" }, + ["į"]={ "i", "̨" }, + ["İ"]={ "I", "̇" }, + ["Ĵ"]={ "J", "̂" }, + ["ĵ"]={ "j", "̂" }, + ["Ķ"]={ "K", "̧" }, + ["ķ"]={ "k", "̧" }, + ["Ĺ"]={ "L", "́" }, + ["ĺ"]={ "l", "́" }, + ["Ļ"]={ "L", "̧" }, + ["ļ"]={ "l", "̧" }, + ["Ľ"]={ "L", "̌" }, + ["ľ"]={ "l", "̌" }, + ["Ń"]={ "N", "́" }, + ["ń"]={ "n", "́" }, + ["Ņ"]={ "N", "̧" }, + ["ņ"]={ "n", "̧" }, + ["Ň"]={ "N", "̌" }, + ["ň"]={ "n", "̌" }, + ["Ō"]={ "O", "̄" }, + ["ō"]={ "o", "̄" }, + ["Ŏ"]={ "O", "̆" }, + ["ŏ"]={ "o", "̆" }, + ["Ő"]={ "O", "̋" }, + ["ő"]={ "o", "̋" }, + ["Ŕ"]={ "R", "́" }, + ["ŕ"]={ "r", "́" }, + ["Ŗ"]={ "R", "̧" }, + ["ŗ"]={ "r", "̧" }, + ["Ř"]={ "R", "̌" }, + ["ř"]={ "r", "̌" }, + ["Ś"]={ "S", "́" }, + ["ś"]={ "s", "́" }, + ["Ŝ"]={ "S", "̂" }, + ["ŝ"]={ "s", "̂" }, + ["Ş"]={ "S", "̧" }, + ["ş"]={ "s", "̧" }, + ["Š"]={ "S", "̌" }, + ["š"]={ "s", "̌" }, + ["Ţ"]={ "T", "̧" }, + ["ţ"]={ "t", "̧" }, + ["Ť"]={ "T", "̌" }, + ["ť"]={ "t", "̌" }, + ["Ũ"]={ "U", "̃" }, + ["ũ"]={ "u", "̃" }, + ["Ū"]={ "U", "̄" }, + ["ū"]={ "u", "̄" }, + ["Ŭ"]={ "U", "̆" }, + ["ŭ"]={ "u", "̆" }, + ["Ů"]={ "U", "̊" }, + ["ů"]={ "u", "̊" }, + ["Ű"]={ "U", "̋" }, + ["ű"]={ "u", "̋" }, + ["Ų"]={ "U", "̨" }, + ["ų"]={ "u", "̨" }, + ["Ŵ"]={ "W", "̂" }, + ["ŵ"]={ "w", "̂" }, + ["Ŷ"]={ "Y", "̂" }, + ["ŷ"]={ "y", "̂" }, + ["Ÿ"]={ "Y", "̈" }, + ["Ź"]={ "Z", "́" }, + ["ź"]={ "z", "́" }, + ["Ż"]={ "Z", "̇" }, + ["ż"]={ "z", "̇" }, + ["Ž"]={ "Z", "̌" }, + ["ž"]={ "z", "̌" }, + ["Ơ"]={ "O", "̛" }, + ["ơ"]={ "o", "̛" }, + ["Ư"]={ "U", "̛" }, + ["ư"]={ "u", "̛" }, + ["Ǎ"]={ "A", "̌" }, + ["ǎ"]={ "a", "̌" }, + ["Ǐ"]={ "I", "̌" }, + ["ǐ"]={ "i", "̌" }, + ["Ǒ"]={ "O", "̌" }, + ["ǒ"]={ "o", "̌" }, + ["Ǔ"]={ "U", "̌" }, + ["ǔ"]={ "u", "̌" }, + ["Ǖ"]={ "Ü", "̄" }, + ["ǖ"]={ "ü", "̄" }, + ["Ǘ"]={ "Ü", "́" }, + ["ǘ"]={ "ü", "́" }, + ["Ǚ"]={ "Ü", "̌" }, + ["ǚ"]={ "ü", "̌" }, + ["Ǜ"]={ "Ü", "̀" }, + ["ǜ"]={ "ü", "̀" }, + ["Ǟ"]={ "Ä", "̄" }, + ["ǟ"]={ "ä", "̄" }, + ["Ǡ"]={ "Ȧ", "̄" }, + ["ǡ"]={ "ȧ", "̄" }, + ["Ǣ"]={ "Æ", "̄" }, + ["ǣ"]={ "æ", "̄" }, + ["Ǧ"]={ "G", "̌" }, + ["ǧ"]={ "g", "̌" }, + ["Ǩ"]={ "K", "̌" }, + ["ǩ"]={ "k", "̌" }, + ["Ǫ"]={ "O", "̨" }, + ["ǫ"]={ "o", "̨" }, + ["Ǭ"]={ "Ǫ", "̄" }, + ["ǭ"]={ "ǫ", "̄" }, + ["Ǯ"]={ "Ʒ", "̌" }, + ["ǯ"]={ "ʒ", "̌" }, + ["ǰ"]={ "j", "̌" }, + ["Ǵ"]={ "G", "́" }, + ["ǵ"]={ "g", "́" }, + ["Ǹ"]={ "N", "̀" }, + ["ǹ"]={ "n", "̀" }, + ["Ǻ"]={ "Å", "́" }, + ["ǻ"]={ "å", "́" }, + ["Ǽ"]={ "Æ", "́" }, + ["ǽ"]={ "æ", "́" }, + ["Ǿ"]={ "Ø", "́" }, + ["ǿ"]={ "ø", "́" }, + ["Ȁ"]={ "A", "̏" }, + ["ȁ"]={ "a", "̏" }, + ["Ȃ"]={ "A", "̑" }, + ["ȃ"]={ "a", "̑" }, + ["Ȅ"]={ "E", "̏" }, + ["ȅ"]={ "e", "̏" }, + ["Ȇ"]={ "E", "̑" }, + ["ȇ"]={ "e", "̑" }, + ["Ȉ"]={ "I", "̏" }, + ["ȉ"]={ "i", "̏" }, + ["Ȋ"]={ "I", "̑" }, + ["ȋ"]={ "i", "̑" }, + ["Ȍ"]={ "O", "̏" }, + ["ȍ"]={ "o", "̏" }, + ["Ȏ"]={ "O", "̑" }, + ["ȏ"]={ "o", "̑" }, + ["Ȑ"]={ "R", "̏" }, + ["ȑ"]={ "r", "̏" }, + ["Ȓ"]={ "R", "̑" }, + ["ȓ"]={ "r", "̑" }, + ["Ȕ"]={ "U", "̏" }, + ["ȕ"]={ "u", "̏" }, + ["Ȗ"]={ "U", "̑" }, + ["ȗ"]={ "u", "̑" }, + ["Ș"]={ "S", "̦" }, + ["ș"]={ "s", "̦" }, + ["Ț"]={ "T", "̦" }, + ["ț"]={ "t", "̦" }, + ["Ȟ"]={ "H", "̌" }, + ["ȟ"]={ "h", "̌" }, + ["Ȧ"]={ "A", "̇" }, + ["ȧ"]={ "a", "̇" }, + ["Ȩ"]={ "E", "̧" }, + ["ȩ"]={ "e", "̧" }, + ["Ȫ"]={ "Ö", "̄" }, + ["ȫ"]={ "ö", "̄" }, + ["Ȭ"]={ "Õ", "̄" }, + ["ȭ"]={ "õ", "̄" }, + ["Ȯ"]={ "O", "̇" }, + ["ȯ"]={ "o", "̇" }, + ["Ȱ"]={ "Ȯ", "̄" }, + ["ȱ"]={ "ȯ", "̄" }, + ["Ȳ"]={ "Y", "̄" }, + ["ȳ"]={ "y", "̄" }, + ["̈́"]={ "̈", "́" }, + ["΅"]={ "¨", "́" }, + ["Ά"]={ "Α", "́" }, + ["Έ"]={ "Ε", "́" }, + ["Ή"]={ "Η", "́" }, + ["Ί"]={ "Ι", "́" }, + ["Ό"]={ "Ο", "́" }, + ["Ύ"]={ "Υ", "́" }, + ["Ώ"]={ "Ω", "́" }, + ["ΐ"]={ "ϊ", "́" }, + ["Ϊ"]={ "Ι", "̈" }, + ["Ϋ"]={ "Υ", "̈" }, + ["ά"]={ "α", "́" }, + ["έ"]={ "ε", "́" }, + ["ή"]={ "η", "́" }, + ["ί"]={ "ι", "́" }, + ["ΰ"]={ "ϋ", "́" }, + ["ϊ"]={ "ι", "̈" }, + ["ϋ"]={ "υ", "̈" }, + ["ό"]={ "ο", "́" }, + ["ύ"]={ "υ", "́" }, + ["ώ"]={ "ω", "́" }, + ["ϓ"]={ "ϒ", "́" }, + ["ϔ"]={ "ϒ", "̈" }, + ["Ѐ"]={ "Е", "̀" }, + ["Ё"]={ "Е", "̈" }, + ["Ѓ"]={ "Г", "́" }, + ["Ї"]={ "І", "̈" }, + ["Ќ"]={ "К", "́" }, + ["Ѝ"]={ "И", "̀" }, + ["Ў"]={ "У", "̆" }, + ["Й"]={ "И", "̆" }, + ["й"]={ "и", "̆" }, + ["ѐ"]={ "е", "̀" }, + ["ё"]={ "е", "̈" }, + ["ѓ"]={ "г", "́" }, + ["ї"]={ "і", "̈" }, + ["ќ"]={ "к", "́" }, + ["ѝ"]={ "и", "̀" }, + ["ў"]={ "у", "̆" }, + ["Ѷ"]={ "Ѵ", "̏" }, + ["ѷ"]={ "ѵ", "̏" }, + ["Ӂ"]={ "Ж", "̆" }, + ["ӂ"]={ "ж", "̆" }, + ["Ӑ"]={ "А", "̆" }, + ["ӑ"]={ "а", "̆" }, + ["Ӓ"]={ "А", "̈" }, + ["ӓ"]={ "а", "̈" }, + ["Ӗ"]={ "Е", "̆" }, + ["ӗ"]={ "е", "̆" }, + ["Ӛ"]={ "Ә", "̈" }, + ["ӛ"]={ "ә", "̈" }, + ["Ӝ"]={ "Ж", "̈" }, + ["ӝ"]={ "ж", "̈" }, + ["Ӟ"]={ "З", "̈" }, + ["ӟ"]={ "з", "̈" }, + ["Ӣ"]={ "И", "̄" }, + ["ӣ"]={ "и", "̄" }, + ["Ӥ"]={ "И", "̈" }, + ["ӥ"]={ "и", "̈" }, + ["Ӧ"]={ "О", "̈" }, + ["ӧ"]={ "о", "̈" }, + ["Ӫ"]={ "Ө", "̈" }, + ["ӫ"]={ "ө", "̈" }, + ["Ӭ"]={ "Э", "̈" }, + ["ӭ"]={ "э", "̈" }, + ["Ӯ"]={ "У", "̄" }, + ["ӯ"]={ "у", "̄" }, + ["Ӱ"]={ "У", "̈" }, + ["ӱ"]={ "у", "̈" }, + ["Ӳ"]={ "У", "̋" }, + ["ӳ"]={ "у", "̋" }, + ["Ӵ"]={ "Ч", "̈" }, + ["ӵ"]={ "ч", "̈" }, + ["Ӹ"]={ "Ы", "̈" }, + ["ӹ"]={ "ы", "̈" }, + ["آ"]={ "ا", "ٓ" }, + ["أ"]={ "ا", "ٔ" }, + ["ؤ"]={ "و", "ٔ" }, + ["إ"]={ "ا", "ٕ" }, + ["ئ"]={ "ي", "ٔ" }, + ["ۀ"]={ "ە", "ٔ" }, + ["ۂ"]={ "ہ", "ٔ" }, + ["ۓ"]={ "ے", "ٔ" }, + ["ऩ"]={ "न", "़" }, + ["ऱ"]={ "र", "़" }, + ["ऴ"]={ "ळ", "़" }, + ["क़"]={ "क", "़" }, + ["ख़"]={ "ख", "़" }, + ["ग़"]={ "ग", "़" }, + ["ज़"]={ "ज", "़" }, + ["ड़"]={ "ड", "़" }, + ["ढ़"]={ "ढ", "़" }, + ["फ़"]={ "फ", "़" }, + ["य़"]={ "य", "़" }, + ["ো"]={ "ে", "া" }, + ["ৌ"]={ "ে", "ৗ" }, + ["ড়"]={ "ড", "়" }, + ["ঢ়"]={ "ঢ", "়" }, + ["য়"]={ "য", "়" }, + ["ਲ਼"]={ "ਲ", "਼" }, + ["ਸ਼"]={ "ਸ", "਼" }, + ["ਖ਼"]={ "ਖ", "਼" }, + ["ਗ਼"]={ "ਗ", "਼" }, + ["ਜ਼"]={ "ਜ", "਼" }, + ["ਫ਼"]={ "ਫ", "਼" }, + ["ୈ"]={ "େ", "ୖ" }, + ["ୋ"]={ "େ", "ା" }, + ["ୌ"]={ "େ", "ୗ" }, + ["ଡ଼"]={ "ଡ", "଼" }, + ["ଢ଼"]={ "ଢ", "଼" }, + ["ஔ"]={ "ஒ", "ௗ" }, + ["ொ"]={ "ெ", "ா" }, + ["ோ"]={ "ே", "ா" }, + ["ௌ"]={ "ெ", "ௗ" }, + ["ై"]={ "ె", "ౖ" }, + ["ೀ"]={ "ಿ", "ೕ" }, + ["ೇ"]={ "ೆ", "ೕ" }, + ["ೈ"]={ "ೆ", "ೖ" }, + ["ೊ"]={ "ೆ", "ೂ" }, + ["ೋ"]={ "ೊ", "ೕ" }, + ["ൊ"]={ "െ", "ാ" }, + ["ോ"]={ "േ", "ാ" }, + ["ൌ"]={ "െ", "ൗ" }, + ["ේ"]={ "ෙ", "්" }, + ["ො"]={ "ෙ", "ා" }, + ["ෝ"]={ "ො", "්" }, + ["ෞ"]={ "ෙ", "ෟ" }, + ["གྷ"]={ "ག", "ྷ" }, + ["ཌྷ"]={ "ཌ", "ྷ" }, + ["དྷ"]={ "ད", "ྷ" }, + ["བྷ"]={ "བ", "ྷ" }, + ["ཛྷ"]={ "ཛ", "ྷ" }, + ["ཀྵ"]={ "ཀ", "ྵ" }, + ["ཱི"]={ "ཱ", "ི" }, + ["ཱུ"]={ "ཱ", "ུ" }, + ["ྲྀ"]={ "ྲ", "ྀ" }, + ["ླྀ"]={ "ླ", "ྀ" }, + ["ཱྀ"]={ "ཱ", "ྀ" }, + ["ྒྷ"]={ "ྒ", "ྷ" }, + ["ྜྷ"]={ "ྜ", "ྷ" }, + ["ྡྷ"]={ "ྡ", "ྷ" }, + ["ྦྷ"]={ "ྦ", "ྷ" }, + ["ྫྷ"]={ "ྫ", "ྷ" }, + ["ྐྵ"]={ "ྐ", "ྵ" }, + ["ဦ"]={ "ဥ", "ီ" }, + ["ᬆ"]={ "ᬅ", "ᬵ" }, + ["ᬈ"]={ "ᬇ", "ᬵ" }, + ["ᬊ"]={ "ᬉ", "ᬵ" }, + ["ᬌ"]={ "ᬋ", "ᬵ" }, + ["ᬎ"]={ "ᬍ", "ᬵ" }, + ["ᬒ"]={ "ᬑ", "ᬵ" }, + ["ᬻ"]={ "ᬺ", "ᬵ" }, + ["ᬽ"]={ "ᬼ", "ᬵ" }, + ["ᭀ"]={ "ᬾ", "ᬵ" }, + ["ᭁ"]={ "ᬿ", "ᬵ" }, + ["ᭃ"]={ "ᭂ", "ᬵ" }, + ["Ḁ"]={ "A", "̥" }, + ["ḁ"]={ "a", "̥" }, + ["Ḃ"]={ "B", "̇" }, + ["ḃ"]={ "b", "̇" }, + ["Ḅ"]={ "B", "̣" }, + ["ḅ"]={ "b", "̣" }, + ["Ḇ"]={ "B", "̱" }, + ["ḇ"]={ "b", "̱" }, + ["Ḉ"]={ "Ç", "́" }, + ["ḉ"]={ "ç", "́" }, + ["Ḋ"]={ "D", "̇" }, + ["ḋ"]={ "d", "̇" }, + ["Ḍ"]={ "D", "̣" }, + ["ḍ"]={ "d", "̣" }, + ["Ḏ"]={ "D", "̱" }, + ["ḏ"]={ "d", "̱" }, + ["Ḑ"]={ "D", "̧" }, + ["ḑ"]={ "d", "̧" }, + ["Ḓ"]={ "D", "̭" }, + ["ḓ"]={ "d", "̭" }, + ["Ḕ"]={ "Ē", "̀" }, + ["ḕ"]={ "ē", "̀" }, + ["Ḗ"]={ "Ē", "́" }, + ["ḗ"]={ "ē", "́" }, + ["Ḙ"]={ "E", "̭" }, + ["ḙ"]={ "e", "̭" }, + ["Ḛ"]={ "E", "̰" }, + ["ḛ"]={ "e", "̰" }, + ["Ḝ"]={ "Ȩ", "̆" }, + ["ḝ"]={ "ȩ", "̆" }, + ["Ḟ"]={ "F", "̇" }, + ["ḟ"]={ "f", "̇" }, + ["Ḡ"]={ "G", "̄" }, + ["ḡ"]={ "g", "̄" }, + ["Ḣ"]={ "H", "̇" }, + ["ḣ"]={ "h", "̇" }, + ["Ḥ"]={ "H", "̣" }, + ["ḥ"]={ "h", "̣" }, + ["Ḧ"]={ "H", "̈" }, + ["ḧ"]={ "h", "̈" }, + ["Ḩ"]={ "H", "̧" }, + ["ḩ"]={ "h", "̧" }, + ["Ḫ"]={ "H", "̮" }, + ["ḫ"]={ "h", "̮" }, + ["Ḭ"]={ "I", "̰" }, + ["ḭ"]={ "i", "̰" }, + ["Ḯ"]={ "Ï", "́" }, + ["ḯ"]={ "ï", "́" }, + ["Ḱ"]={ "K", "́" }, + ["ḱ"]={ "k", "́" }, + ["Ḳ"]={ "K", "̣" }, + ["ḳ"]={ "k", "̣" }, + ["Ḵ"]={ "K", "̱" }, + ["ḵ"]={ "k", "̱" }, + ["Ḷ"]={ "L", "̣" }, + ["ḷ"]={ "l", "̣" }, + ["Ḹ"]={ "Ḷ", "̄" }, + ["ḹ"]={ "ḷ", "̄" }, + ["Ḻ"]={ "L", "̱" }, + ["ḻ"]={ "l", "̱" }, + ["Ḽ"]={ "L", "̭" }, + ["ḽ"]={ "l", "̭" }, + ["Ḿ"]={ "M", "́" }, + ["ḿ"]={ "m", "́" }, + ["Ṁ"]={ "M", "̇" }, + ["ṁ"]={ "m", "̇" }, + ["Ṃ"]={ "M", "̣" }, + ["ṃ"]={ "m", "̣" }, + ["Ṅ"]={ "N", "̇" }, + ["ṅ"]={ "n", "̇" }, + ["Ṇ"]={ "N", "̣" }, + ["ṇ"]={ "n", "̣" }, + ["Ṉ"]={ "N", "̱" }, + ["ṉ"]={ "n", "̱" }, + ["Ṋ"]={ "N", "̭" }, + ["ṋ"]={ "n", "̭" }, + ["Ṍ"]={ "Õ", "́" }, + ["ṍ"]={ "õ", "́" }, + ["Ṏ"]={ "Õ", "̈" }, + ["ṏ"]={ "õ", "̈" }, + ["Ṑ"]={ "Ō", "̀" }, + ["ṑ"]={ "ō", "̀" }, + ["Ṓ"]={ "Ō", "́" }, + ["ṓ"]={ "ō", "́" }, + ["Ṕ"]={ "P", "́" }, + ["ṕ"]={ "p", "́" }, + ["Ṗ"]={ "P", "̇" }, + ["ṗ"]={ "p", "̇" }, + ["Ṙ"]={ "R", "̇" }, + ["ṙ"]={ "r", "̇" }, + ["Ṛ"]={ "R", "̣" }, + ["ṛ"]={ "r", "̣" }, + ["Ṝ"]={ "Ṛ", "̄" }, + ["ṝ"]={ "ṛ", "̄" }, + ["Ṟ"]={ "R", "̱" }, + ["ṟ"]={ "r", "̱" }, + ["Ṡ"]={ "S", "̇" }, + ["ṡ"]={ "s", "̇" }, + ["Ṣ"]={ "S", "̣" }, + ["ṣ"]={ "s", "̣" }, + ["Ṥ"]={ "Ś", "̇" }, + ["ṥ"]={ "ś", "̇" }, + ["Ṧ"]={ "Š", "̇" }, + ["ṧ"]={ "š", "̇" }, + ["Ṩ"]={ "Ṣ", "̇" }, + ["ṩ"]={ "ṣ", "̇" }, + ["Ṫ"]={ "T", "̇" }, + ["ṫ"]={ "t", "̇" }, + ["Ṭ"]={ "T", "̣" }, + ["ṭ"]={ "t", "̣" }, + ["Ṯ"]={ "T", "̱" }, + ["ṯ"]={ "t", "̱" }, + ["Ṱ"]={ "T", "̭" }, + ["ṱ"]={ "t", "̭" }, + ["Ṳ"]={ "U", "̤" }, + ["ṳ"]={ "u", "̤" }, + ["Ṵ"]={ "U", "̰" }, + ["ṵ"]={ "u", "̰" }, + ["Ṷ"]={ "U", "̭" }, + ["ṷ"]={ "u", "̭" }, + ["Ṹ"]={ "Ũ", "́" }, + ["ṹ"]={ "ũ", "́" }, + ["Ṻ"]={ "Ū", "̈" }, + ["ṻ"]={ "ū", "̈" }, + ["Ṽ"]={ "V", "̃" }, + ["ṽ"]={ "v", "̃" }, + ["Ṿ"]={ "V", "̣" }, + ["ṿ"]={ "v", "̣" }, + ["Ẁ"]={ "W", "̀" }, + ["ẁ"]={ "w", "̀" }, + ["Ẃ"]={ "W", "́" }, + ["ẃ"]={ "w", "́" }, + ["Ẅ"]={ "W", "̈" }, + ["ẅ"]={ "w", "̈" }, + ["Ẇ"]={ "W", "̇" }, + ["ẇ"]={ "w", "̇" }, + ["Ẉ"]={ "W", "̣" }, + ["ẉ"]={ "w", "̣" }, + ["Ẋ"]={ "X", "̇" }, + ["ẋ"]={ "x", "̇" }, + ["Ẍ"]={ "X", "̈" }, + ["ẍ"]={ "x", "̈" }, + ["Ẏ"]={ "Y", "̇" }, + ["ẏ"]={ "y", "̇" }, + ["Ẑ"]={ "Z", "̂" }, + ["ẑ"]={ "z", "̂" }, + ["Ẓ"]={ "Z", "̣" }, + ["ẓ"]={ "z", "̣" }, + ["Ẕ"]={ "Z", "̱" }, + ["ẕ"]={ "z", "̱" }, + ["ẖ"]={ "h", "̱" }, + ["ẗ"]={ "t", "̈" }, + ["ẘ"]={ "w", "̊" }, + ["ẙ"]={ "y", "̊" }, + ["ẛ"]={ "ſ", "̇" }, + ["Ạ"]={ "A", "̣" }, + ["ạ"]={ "a", "̣" }, + ["Ả"]={ "A", "̉" }, + ["ả"]={ "a", "̉" }, + ["Ấ"]={ "Â", "́" }, + ["ấ"]={ "â", "́" }, + ["Ầ"]={ "Â", "̀" }, + ["ầ"]={ "â", "̀" }, + ["Ẩ"]={ "Â", "̉" }, + ["ẩ"]={ "â", "̉" }, + ["Ẫ"]={ "Â", "̃" }, + ["ẫ"]={ "â", "̃" }, + ["Ậ"]={ "Ạ", "̂" }, + ["ậ"]={ "ạ", "̂" }, + ["Ắ"]={ "Ă", "́" }, + ["ắ"]={ "ă", "́" }, + ["Ằ"]={ "Ă", "̀" }, + ["ằ"]={ "ă", "̀" }, + ["Ẳ"]={ "Ă", "̉" }, + ["ẳ"]={ "ă", "̉" }, + ["Ẵ"]={ "Ă", "̃" }, + ["ẵ"]={ "ă", "̃" }, + ["Ặ"]={ "Ạ", "̆" }, + ["ặ"]={ "ạ", "̆" }, + ["Ẹ"]={ "E", "̣" }, + ["ẹ"]={ "e", "̣" }, + ["Ẻ"]={ "E", "̉" }, + ["ẻ"]={ "e", "̉" }, + ["Ẽ"]={ "E", "̃" }, + ["ẽ"]={ "e", "̃" }, + ["Ế"]={ "Ê", "́" }, + ["ế"]={ "ê", "́" }, + ["Ề"]={ "Ê", "̀" }, + ["ề"]={ "ê", "̀" }, + ["Ể"]={ "Ê", "̉" }, + ["ể"]={ "ê", "̉" }, + ["Ễ"]={ "Ê", "̃" }, + ["ễ"]={ "ê", "̃" }, + ["Ệ"]={ "Ẹ", "̂" }, + ["ệ"]={ "ẹ", "̂" }, + ["Ỉ"]={ "I", "̉" }, + ["ỉ"]={ "i", "̉" }, + ["Ị"]={ "I", "̣" }, + ["ị"]={ "i", "̣" }, + ["Ọ"]={ "O", "̣" }, + ["ọ"]={ "o", "̣" }, + ["Ỏ"]={ "O", "̉" }, + ["ỏ"]={ "o", "̉" }, + ["Ố"]={ "Ô", "́" }, + ["ố"]={ "ô", "́" }, + ["Ồ"]={ "Ô", "̀" }, + ["ồ"]={ "ô", "̀" }, + ["Ổ"]={ "Ô", "̉" }, + ["ổ"]={ "ô", "̉" }, + ["Ỗ"]={ "Ô", "̃" }, + ["ỗ"]={ "ô", "̃" }, + ["Ộ"]={ "Ọ", "̂" }, + ["ộ"]={ "ọ", "̂" }, + ["Ớ"]={ "Ơ", "́" }, + ["ớ"]={ "ơ", "́" }, + ["Ờ"]={ "Ơ", "̀" }, + ["ờ"]={ "ơ", "̀" }, + ["Ở"]={ "Ơ", "̉" }, + ["ở"]={ "ơ", "̉" }, + ["Ỡ"]={ "Ơ", "̃" }, + ["ỡ"]={ "ơ", "̃" }, + ["Ợ"]={ "Ơ", "̣" }, + ["ợ"]={ "ơ", "̣" }, + ["Ụ"]={ "U", "̣" }, + ["ụ"]={ "u", "̣" }, + ["Ủ"]={ "U", "̉" }, + ["ủ"]={ "u", "̉" }, + ["Ứ"]={ "Ư", "́" }, + ["ứ"]={ "ư", "́" }, + ["Ừ"]={ "Ư", "̀" }, + ["ừ"]={ "ư", "̀" }, + ["Ử"]={ "Ư", "̉" }, + ["ử"]={ "ư", "̉" }, + ["Ữ"]={ "Ư", "̃" }, + ["ữ"]={ "ư", "̃" }, + ["Ự"]={ "Ư", "̣" }, + ["ự"]={ "ư", "̣" }, + ["Ỳ"]={ "Y", "̀" }, + ["ỳ"]={ "y", "̀" }, + ["Ỵ"]={ "Y", "̣" }, + ["ỵ"]={ "y", "̣" }, + ["Ỷ"]={ "Y", "̉" }, + ["ỷ"]={ "y", "̉" }, + ["Ỹ"]={ "Y", "̃" }, + ["ỹ"]={ "y", "̃" }, + ["ἀ"]={ "α", "̓" }, + ["ἁ"]={ "α", "̔" }, + ["ἂ"]={ "ἀ", "̀" }, + ["ἃ"]={ "ἁ", "̀" }, + ["ἄ"]={ "ἀ", "́" }, + ["ἅ"]={ "ἁ", "́" }, + ["ἆ"]={ "ἀ", "͂" }, + ["ἇ"]={ "ἁ", "͂" }, + ["Ἀ"]={ "Α", "̓" }, + ["Ἁ"]={ "Α", "̔" }, + ["Ἂ"]={ "Ἀ", "̀" }, + ["Ἃ"]={ "Ἁ", "̀" }, + ["Ἄ"]={ "Ἀ", "́" }, + ["Ἅ"]={ "Ἁ", "́" }, + ["Ἆ"]={ "Ἀ", "͂" }, + ["Ἇ"]={ "Ἁ", "͂" }, + ["ἐ"]={ "ε", "̓" }, + ["ἑ"]={ "ε", "̔" }, + ["ἒ"]={ "ἐ", "̀" }, + ["ἓ"]={ "ἑ", "̀" }, + ["ἔ"]={ "ἐ", "́" }, + ["ἕ"]={ "ἑ", "́" }, + ["Ἐ"]={ "Ε", "̓" }, + ["Ἑ"]={ "Ε", "̔" }, + ["Ἒ"]={ "Ἐ", "̀" }, + ["Ἓ"]={ "Ἑ", "̀" }, + ["Ἔ"]={ "Ἐ", "́" }, + ["Ἕ"]={ "Ἑ", "́" }, + ["ἠ"]={ "η", "̓" }, + ["ἡ"]={ "η", "̔" }, + ["ἢ"]={ "ἠ", "̀" }, + ["ἣ"]={ "ἡ", "̀" }, + ["ἤ"]={ "ἠ", "́" }, + ["ἥ"]={ "ἡ", "́" }, + ["ἦ"]={ "ἠ", "͂" }, + ["ἧ"]={ "ἡ", "͂" }, + ["Ἠ"]={ "Η", "̓" }, + ["Ἡ"]={ "Η", "̔" }, + ["Ἢ"]={ "Ἠ", "̀" }, + ["Ἣ"]={ "Ἡ", "̀" }, + ["Ἤ"]={ "Ἠ", "́" }, + ["Ἥ"]={ "Ἡ", "́" }, + ["Ἦ"]={ "Ἠ", "͂" }, + ["Ἧ"]={ "Ἡ", "͂" }, + ["ἰ"]={ "ι", "̓" }, + ["ἱ"]={ "ι", "̔" }, + ["ἲ"]={ "ἰ", "̀" }, + ["ἳ"]={ "ἱ", "̀" }, + ["ἴ"]={ "ἰ", "́" }, + ["ἵ"]={ "ἱ", "́" }, + ["ἶ"]={ "ἰ", "͂" }, + ["ἷ"]={ "ἱ", "͂" }, + ["Ἰ"]={ "Ι", "̓" }, + ["Ἱ"]={ "Ι", "̔" }, + ["Ἲ"]={ "Ἰ", "̀" }, + ["Ἳ"]={ "Ἱ", "̀" }, + ["Ἴ"]={ "Ἰ", "́" }, + ["Ἵ"]={ "Ἱ", "́" }, + ["Ἶ"]={ "Ἰ", "͂" }, + ["Ἷ"]={ "Ἱ", "͂" }, + ["ὀ"]={ "ο", "̓" }, + ["ὁ"]={ "ο", "̔" }, + ["ὂ"]={ "ὀ", "̀" }, + ["ὃ"]={ "ὁ", "̀" }, + ["ὄ"]={ "ὀ", "́" }, + ["ὅ"]={ "ὁ", "́" }, + ["Ὀ"]={ "Ο", "̓" }, + ["Ὁ"]={ "Ο", "̔" }, + ["Ὂ"]={ "Ὀ", "̀" }, + ["Ὃ"]={ "Ὁ", "̀" }, + ["Ὄ"]={ "Ὀ", "́" }, + ["Ὅ"]={ "Ὁ", "́" }, + ["ὐ"]={ "υ", "̓" }, + ["ὑ"]={ "υ", "̔" }, + ["ὒ"]={ "ὐ", "̀" }, + ["ὓ"]={ "ὑ", "̀" }, + ["ὔ"]={ "ὐ", "́" }, + ["ὕ"]={ "ὑ", "́" }, + ["ὖ"]={ "ὐ", "͂" }, + ["ὗ"]={ "ὑ", "͂" }, + ["Ὑ"]={ "Υ", "̔" }, + ["Ὓ"]={ "Ὑ", "̀" }, + ["Ὕ"]={ "Ὑ", "́" }, + ["Ὗ"]={ "Ὑ", "͂" }, + ["ὠ"]={ "ω", "̓" }, + ["ὡ"]={ "ω", "̔" }, + ["ὢ"]={ "ὠ", "̀" }, + ["ὣ"]={ "ὡ", "̀" }, + ["ὤ"]={ "ὠ", "́" }, + ["ὥ"]={ "ὡ", "́" }, + ["ὦ"]={ "ὠ", "͂" }, + ["ὧ"]={ "ὡ", "͂" }, + ["Ὠ"]={ "Ω", "̓" }, + ["Ὡ"]={ "Ω", "̔" }, + ["Ὢ"]={ "Ὠ", "̀" }, + ["Ὣ"]={ "Ὡ", "̀" }, + ["Ὤ"]={ "Ὠ", "́" }, + ["Ὥ"]={ "Ὡ", "́" }, + ["Ὦ"]={ "Ὠ", "͂" }, + ["Ὧ"]={ "Ὡ", "͂" }, + ["ὰ"]={ "α", "̀" }, + ["ὲ"]={ "ε", "̀" }, + ["ὴ"]={ "η", "̀" }, + ["ὶ"]={ "ι", "̀" }, + ["ὸ"]={ "ο", "̀" }, + ["ὺ"]={ "υ", "̀" }, + ["ὼ"]={ "ω", "̀" }, + ["ᾀ"]={ "ἀ", "ͅ" }, + ["ᾁ"]={ "ἁ", "ͅ" }, + ["ᾂ"]={ "ἂ", "ͅ" }, + ["ᾃ"]={ "ἃ", "ͅ" }, + ["ᾄ"]={ "ἄ", "ͅ" }, + ["ᾅ"]={ "ἅ", "ͅ" }, + ["ᾆ"]={ "ἆ", "ͅ" }, + ["ᾇ"]={ "ἇ", "ͅ" }, + ["ᾈ"]={ "Ἀ", "ͅ" }, + ["ᾉ"]={ "Ἁ", "ͅ" }, + ["ᾊ"]={ "Ἂ", "ͅ" }, + ["ᾋ"]={ "Ἃ", "ͅ" }, + ["ᾌ"]={ "Ἄ", "ͅ" }, + ["ᾍ"]={ "Ἅ", "ͅ" }, + ["ᾎ"]={ "Ἆ", "ͅ" }, + ["ᾏ"]={ "Ἇ", "ͅ" }, + ["ᾐ"]={ "ἠ", "ͅ" }, + ["ᾑ"]={ "ἡ", "ͅ" }, + ["ᾒ"]={ "ἢ", "ͅ" }, + ["ᾓ"]={ "ἣ", "ͅ" }, + ["ᾔ"]={ "ἤ", "ͅ" }, + ["ᾕ"]={ "ἥ", "ͅ" }, + ["ᾖ"]={ "ἦ", "ͅ" }, + ["ᾗ"]={ "ἧ", "ͅ" }, + ["ᾘ"]={ "Ἠ", "ͅ" }, + ["ᾙ"]={ "Ἡ", "ͅ" }, + ["ᾚ"]={ "Ἢ", "ͅ" }, + ["ᾛ"]={ "Ἣ", "ͅ" }, + ["ᾜ"]={ "Ἤ", "ͅ" }, + ["ᾝ"]={ "Ἥ", "ͅ" }, + ["ᾞ"]={ "Ἦ", "ͅ" }, + ["ᾟ"]={ "Ἧ", "ͅ" }, + ["ᾠ"]={ "ὠ", "ͅ" }, + ["ᾡ"]={ "ὡ", "ͅ" }, + ["ᾢ"]={ "ὢ", "ͅ" }, + ["ᾣ"]={ "ὣ", "ͅ" }, + ["ᾤ"]={ "ὤ", "ͅ" }, + ["ᾥ"]={ "ὥ", "ͅ" }, + ["ᾦ"]={ "ὦ", "ͅ" }, + ["ᾧ"]={ "ὧ", "ͅ" }, + ["ᾨ"]={ "Ὠ", "ͅ" }, + ["ᾩ"]={ "Ὡ", "ͅ" }, + ["ᾪ"]={ "Ὢ", "ͅ" }, + ["ᾫ"]={ "Ὣ", "ͅ" }, + ["ᾬ"]={ "Ὤ", "ͅ" }, + ["ᾭ"]={ "Ὥ", "ͅ" }, + ["ᾮ"]={ "Ὦ", "ͅ" }, + ["ᾯ"]={ "Ὧ", "ͅ" }, + ["ᾰ"]={ "α", "̆" }, + ["ᾱ"]={ "α", "̄" }, + ["ᾲ"]={ "ὰ", "ͅ" }, + ["ᾳ"]={ "α", "ͅ" }, + ["ᾴ"]={ "ά", "ͅ" }, + ["ᾶ"]={ "α", "͂" }, + ["ᾷ"]={ "ᾶ", "ͅ" }, + ["Ᾰ"]={ "Α", "̆" }, + ["Ᾱ"]={ "Α", "̄" }, + ["Ὰ"]={ "Α", "̀" }, + ["ᾼ"]={ "Α", "ͅ" }, + ["῁"]={ "¨", "͂" }, + ["ῂ"]={ "ὴ", "ͅ" }, + ["ῃ"]={ "η", "ͅ" }, + ["ῄ"]={ "ή", "ͅ" }, + ["ῆ"]={ "η", "͂" }, + ["ῇ"]={ "ῆ", "ͅ" }, + ["Ὲ"]={ "Ε", "̀" }, + ["Ὴ"]={ "Η", "̀" }, + ["ῌ"]={ "Η", "ͅ" }, + ["῍"]={ "᾿", "̀" }, + ["῎"]={ "᾿", "́" }, + ["῏"]={ "᾿", "͂" }, + ["ῐ"]={ "ι", "̆" }, + ["ῑ"]={ "ι", "̄" }, + ["ῒ"]={ "ϊ", "̀" }, + ["ῖ"]={ "ι", "͂" }, + ["ῗ"]={ "ϊ", "͂" }, + ["Ῐ"]={ "Ι", "̆" }, + ["Ῑ"]={ "Ι", "̄" }, + ["Ὶ"]={ "Ι", "̀" }, + ["῝"]={ "῾", "̀" }, + ["῞"]={ "῾", "́" }, + ["῟"]={ "῾", "͂" }, + ["ῠ"]={ "υ", "̆" }, + ["ῡ"]={ "υ", "̄" }, + ["ῢ"]={ "ϋ", "̀" }, + ["ῤ"]={ "ρ", "̓" }, + ["ῥ"]={ "ρ", "̔" }, + ["ῦ"]={ "υ", "͂" }, + ["ῧ"]={ "ϋ", "͂" }, + ["Ῠ"]={ "Υ", "̆" }, + ["Ῡ"]={ "Υ", "̄" }, + ["Ὺ"]={ "Υ", "̀" }, + ["Ῥ"]={ "Ρ", "̔" }, + ["῭"]={ "¨", "̀" }, + ["ῲ"]={ "ὼ", "ͅ" }, + ["ῳ"]={ "ω", "ͅ" }, + ["ῴ"]={ "ώ", "ͅ" }, + ["ῶ"]={ "ω", "͂" }, + ["ῷ"]={ "ῶ", "ͅ" }, + ["Ὸ"]={ "Ο", "̀" }, + ["Ὼ"]={ "Ω", "̀" }, + ["ῼ"]={ "Ω", "ͅ" }, + ["↚"]={ "←", "̸" }, + ["↛"]={ "→", "̸" }, + ["↮"]={ "↔", "̸" }, + ["⇍"]={ "⇐", "̸" }, + ["⇎"]={ "⇔", "̸" }, + ["⇏"]={ "⇒", "̸" }, + ["∄"]={ "∃", "̸" }, + ["∉"]={ "∈", "̸" }, + ["∌"]={ "∋", "̸" }, + ["∤"]={ "∣", "̸" }, + ["∦"]={ "∥", "̸" }, + ["≁"]={ "∼", "̸" }, + ["≄"]={ "≃", "̸" }, + ["≇"]={ "≅", "̸" }, + ["≉"]={ "≈", "̸" }, + ["≠"]={ "=", "̸" }, + ["≢"]={ "≡", "̸" }, + ["≭"]={ "≍", "̸" }, + ["≮"]={ "<", "̸" }, + ["≯"]={ ">", "̸" }, + ["≰"]={ "≤", "̸" }, + ["≱"]={ "≥", "̸" }, + ["≴"]={ "≲", "̸" }, + ["≵"]={ "≳", "̸" }, + ["≸"]={ "≶", "̸" }, + ["≹"]={ "≷", "̸" }, + ["⊀"]={ "≺", "̸" }, + ["⊁"]={ "≻", "̸" }, + ["⊄"]={ "⊂", "̸" }, + ["⊅"]={ "⊃", "̸" }, + ["⊈"]={ "⊆", "̸" }, + ["⊉"]={ "⊇", "̸" }, + ["⊬"]={ "⊢", "̸" }, + ["⊭"]={ "⊨", "̸" }, + ["⊮"]={ "⊩", "̸" }, + ["⊯"]={ "⊫", "̸" }, + ["⋠"]={ "≼", "̸" }, + ["⋡"]={ "≽", "̸" }, + ["⋢"]={ "⊑", "̸" }, + ["⋣"]={ "⊒", "̸" }, + ["⋪"]={ "⊲", "̸" }, + ["⋫"]={ "⊳", "̸" }, + ["⋬"]={ "⊴", "̸" }, + ["⋭"]={ "⊵", "̸" }, + ["⫝̸"]={ "⫝", "̸" }, + ["が"]={ "か", "゙" }, + ["ぎ"]={ "き", "゙" }, + ["ぐ"]={ "く", "゙" }, + ["げ"]={ "け", "゙" }, + ["ご"]={ "こ", "゙" }, + ["ざ"]={ "さ", "゙" }, + ["じ"]={ "し", "゙" }, + ["ず"]={ "す", "゙" }, + ["ぜ"]={ "せ", "゙" }, + ["ぞ"]={ "そ", "゙" }, + ["だ"]={ "た", "゙" }, + ["ぢ"]={ "ち", "゙" }, + ["づ"]={ "つ", "゙" }, + ["で"]={ "て", "゙" }, + ["ど"]={ "と", "゙" }, + ["ば"]={ "は", "゙" }, + ["ぱ"]={ "は", "゚" }, + ["び"]={ "ひ", "゙" }, + ["ぴ"]={ "ひ", "゚" }, + ["ぶ"]={ "ふ", "゙" }, + ["ぷ"]={ "ふ", "゚" }, + ["べ"]={ "へ", "゙" }, + ["ぺ"]={ "へ", "゚" }, + ["ぼ"]={ "ほ", "゙" }, + ["ぽ"]={ "ほ", "゚" }, + ["ゔ"]={ "う", "゙" }, + ["ゞ"]={ "ゝ", "゙" }, + ["ガ"]={ "カ", "゙" }, + ["ギ"]={ "キ", "゙" }, + ["グ"]={ "ク", "゙" }, + ["ゲ"]={ "ケ", "゙" }, + ["ゴ"]={ "コ", "゙" }, + ["ザ"]={ "サ", "゙" }, + ["ジ"]={ "シ", "゙" }, + ["ズ"]={ "ス", "゙" }, + ["ゼ"]={ "セ", "゙" }, + ["ゾ"]={ "ソ", "゙" }, + ["ダ"]={ "タ", "゙" }, + ["ヂ"]={ "チ", "゙" }, + ["ヅ"]={ "ツ", "゙" }, + ["デ"]={ "テ", "゙" }, + ["ド"]={ "ト", "゙" }, + ["バ"]={ "ハ", "゙" }, + ["パ"]={ "ハ", "゚" }, + ["ビ"]={ "ヒ", "゙" }, + ["ピ"]={ "ヒ", "゚" }, + ["ブ"]={ "フ", "゙" }, + ["プ"]={ "フ", "゚" }, + ["ベ"]={ "ヘ", "゙" }, + ["ペ"]={ "ヘ", "゚" }, + ["ボ"]={ "ホ", "゙" }, + ["ポ"]={ "ホ", "゚" }, + ["ヴ"]={ "ウ", "゙" }, + ["ヷ"]={ "ワ", "゙" }, + ["ヸ"]={ "ヰ", "゙" }, + ["ヹ"]={ "ヱ", "゙" }, + ["ヺ"]={ "ヲ", "゙" }, + ["ヾ"]={ "ヽ", "゙" }, + ["יִ"]={ "י", "ִ" }, + ["ײַ"]={ "ײ", "ַ" }, + ["שׁ"]={ "ש", "ׁ" }, + ["שׂ"]={ "ש", "ׂ" }, + ["שּׁ"]={ "שּ", "ׁ" }, + ["שּׂ"]={ "שּ", "ׂ" }, + ["אַ"]={ "א", "ַ" }, + ["אָ"]={ "א", "ָ" }, + ["אּ"]={ "א", "ּ" }, + ["בּ"]={ "ב", "ּ" }, + ["גּ"]={ "ג", "ּ" }, + ["דּ"]={ "ד", "ּ" }, + ["הּ"]={ "ה", "ּ" }, + ["וּ"]={ "ו", "ּ" }, + ["זּ"]={ "ז", "ּ" }, + ["טּ"]={ "ט", "ּ" }, + ["יּ"]={ "י", "ּ" }, + ["ךּ"]={ "ך", "ּ" }, + ["כּ"]={ "כ", "ּ" }, + ["לּ"]={ "ל", "ּ" }, + ["מּ"]={ "מ", "ּ" }, + ["נּ"]={ "נ", "ּ" }, + ["סּ"]={ "ס", "ּ" }, + ["ףּ"]={ "ף", "ּ" }, + ["פּ"]={ "פ", "ּ" }, + ["צּ"]={ "צ", "ּ" }, + ["קּ"]={ "ק", "ּ" }, + ["רּ"]={ "ר", "ּ" }, + ["שּ"]={ "ש", "ּ" }, + ["תּ"]={ "ת", "ּ" }, + ["וֹ"]={ "ו", "ֹ" }, + ["בֿ"]={ "ב", "ֿ" }, + ["כֿ"]={ "כ", "ֿ" }, + ["פֿ"]={ "פ", "ֿ" }, + ["𑂚"]={ "𑂙", "𑂺" }, + ["𑂜"]={ "𑂛", "𑂺" }, + ["𑂫"]={ "𑂥", "𑂺" }, + ["𑄮"]={ "𑄱", "𑄧" }, + ["𑄯"]={ "𑄲", "𑄧" }, + ["𑍋"]={ "𑍇", "𑌾" }, + ["𑍌"]={ "𑍇", "𑍗" }, + ["𑒻"]={ "𑒹", "𑒺" }, + ["𑒼"]={ "𑒹", "𑒰" }, + ["𑒾"]={ "𑒹", "𑒽" }, + ["𑖺"]={ "𑖸", "𑖯" }, + ["𑖻"]={ "𑖹", "𑖯" }, + ["𝅗𝅥"]={ "𝅗", "𝅥" }, + ["𝅘𝅥"]={ "𝅘", "𝅥" }, + ["𝅘𝅥𝅮"]={ "𝅘𝅥", "𝅮" }, + ["𝅘𝅥𝅯"]={ "𝅘𝅥", "𝅯" }, + ["𝅘𝅥𝅰"]={ "𝅘𝅥", "𝅰" }, + ["𝅘𝅥𝅱"]={ "𝅘𝅥", "𝅱" }, + ["𝅘𝅥𝅲"]={ "𝅘𝅥", "𝅲" }, + ["𝆹𝅥"]={ "𝆹", "𝅥" }, + ["𝆺𝅥"]={ "𝆺", "𝅥" }, + ["𝆹𝅥𝅮"]={ "𝆹𝅥", "𝅮" }, + ["𝆺𝅥𝅮"]={ "𝆺𝅥", "𝅮" }, + ["𝆹𝅥𝅯"]={ "𝆹𝅥", "𝅯" }, + ["𝆺𝅥𝅯"]={ "𝆺𝅥", "𝅯" }, + }, + }, + }, + ["name"]="collapse", + ["prepend"]=true, + ["type"]="ligature", +}
\ No newline at end of file diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index b8d5ef8f0..dbd0a5227 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 05/19/16 13:43:44 +-- merge date : 05/14/17 19:09:26 do -- begin closure to overcome local limits and interference @@ -108,6 +108,16 @@ if flush then local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end end +FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load +if not FFISUPPORTED then + local okay;okay,ffi=pcall(require,"ffi") + FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load +end +if not FFISUPPORTED then + ffi=nil +elseif not ffi.number then + ffi.number=tonumber +end end -- closure @@ -203,6 +213,7 @@ patterns.nonwhitespace=nonwhitespace local stripper=spacer^0*C((spacer^0*nonspacer^1)^0) local fullstripper=whitespace^0*C((whitespace^0*nonwhitespace^1)^0) local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0)) +local nospacer=Cs((whitespace^1/""+nonwhitespace^1)^0) local b_collapser=Cs(whitespace^0/""*(nonwhitespace^1+whitespace^1/" ")^0) local e_collapser=Cs((whitespace^1*P(-1)/""+nonwhitespace^1+whitespace^1/" ")^0) local m_collapser=Cs((nonwhitespace^1+whitespace^1/" ")^0) @@ -212,6 +223,7 @@ local m_stripper=Cs((nonspacer^1+spacer^1/" ")^0) patterns.stripper=stripper patterns.fullstripper=fullstripper patterns.collapser=collapser +patterns.nospacer=nospacer patterns.b_collapser=b_collapser patterns.m_collapser=m_collapser patterns.e_collapser=e_collapser @@ -678,27 +690,7 @@ function lpeg.append(list,pp,delayed,checked) end local p_false=P(false) local p_true=P(true) -local function make(t) - local function making(t) - local p=p_false - local keys=sortedkeys(t) - for i=1,#keys do - local k=keys[i] - if k~="" then - local v=t[k] - if v==true then - p=p+P(k)*p_true - elseif v==false then - else - p=p+P(k)*making(v) - end - end - end - if t[""] then - p=p+p_true - end - return p - end +local function make(t,rest) local p=p_false local keys=sortedkeys(t) for i=1,#keys do @@ -709,10 +701,13 @@ local function make(t) p=p+P(k)*p_true elseif v==false then else - p=p+P(k)*making(v) + p=p+P(k)*make(v,v[""]) end end end + if rest then + p=p+p_true + end return p end local function collapse(t,x) @@ -962,22 +957,26 @@ end local stripper=patterns.stripper local fullstripper=patterns.fullstripper local collapser=patterns.collapser +local nospacer=patterns.nospacer local longtostring=patterns.longtostring function string.strip(str) - return lpegmatch(stripper,str) or "" + return str and lpegmatch(stripper,str) or "" end function string.fullstrip(str) - return lpegmatch(fullstripper,str) or "" + return str and lpegmatch(fullstripper,str) or "" end function string.collapsespaces(str) - return lpegmatch(collapser,str) or "" + return str and lpegmatch(collapser,str) or "" +end +function string.nospaces(str) + return str and lpegmatch(nospacer,str) or "" end function string.longtostring(str) - return lpegmatch(longtostring,str) or "" + return str and lpegmatch(longtostring,str) or "" end local pattern=P(" ")^0*P(-1) function string.is_empty(str) - if str=="" then + if not str or str=="" then return true else return lpegmatch(pattern,str) and true or false @@ -1022,6 +1021,21 @@ function string.tformat(fmt,...) end string.quote=string.quoted string.unquote=string.unquoted +if not string.bytetable then + local limit=5000 + function string.bytetable(str) + local n=#str + if n>limit then + local t={ byte(str,1,limit) } + for i=limit+1,n do + t[i]=byte(str,i) + end + return t + else + return { byte(str,1,n) } + end + end +end end -- closure @@ -1352,19 +1366,23 @@ function table.fromhash(t) end return hsh end -local noquotes,hexify,handle,compact,inline,functions +local noquotes,hexify,handle,compact,inline,functions,metacheck local reserved=table.tohash { 'and','break','do','else','elseif','end','false','for','function','if', 'in','local','nil','not','or','repeat','return','then','true','until','while', 'NaN','goto', } -local function simple_table(t) +local function is_simple_table(t,hexify) local nt=#t if nt>0 then local n=0 for _,v in next,t do n=n+1 + if type(v)=="table" then + return nil + end end + local haszero=rawget(t,0) if n==nt then local tt={} for i=1,nt do @@ -1374,10 +1392,10 @@ local function simple_table(t) if hexify then tt[i]=format("0x%X",v) else - tt[i]=tostring(v) + tt[i]=v end elseif tv=="string" then - tt[i]=format("%q",v) + tt[i]=format("%q",v) elseif tv=="boolean" then tt[i]=v and "true" or "false" else @@ -1385,10 +1403,32 @@ local function simple_table(t) end end return tt + elseif haszero and (n==nt+1) then + local tt={} + for i=0,nt do + local v=t[i] + local tv=type(v) + if tv=="number" then + if hexify then + tt[i+1]=format("0x%X",v) + else + tt[i+1]=v + end + elseif tv=="string" then + tt[i+1]=format("%q",v) + elseif tv=="boolean" then + tt[i+1]=v and "true" or "false" + else + return nil + end + end + tt[1]="[0] = "..tt[1] + return tt end end return nil end +table.is_simple_table=is_simple_table local propername=patterns.propername local function dummy() end local function do_serialize(root,name,depth,level,indexed) @@ -1422,7 +1462,7 @@ local function do_serialize(root,name,depth,level,indexed) if compact then last=#root for k=1,last do - if root[k]==nil then + if rawget(root,k)==nil then last=k-1 break end @@ -1450,7 +1490,7 @@ local function do_serialize(root,name,depth,level,indexed) if next(v)==nil then handle(format("%s {},",depth)) elseif inline then - local st=simple_table(v) + local st=is_simple_table(v,hexify) if st then handle(format("%s { %s },",depth,concat(st,", "))) else @@ -1487,6 +1527,7 @@ local function do_serialize(root,name,depth,level,indexed) else handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) end + elseif tk~="string" then elseif noquotes and not reserved[k] and lpegmatch(propername,k) then if hexify then handle(format("%s %s=0x%X,",depth,k,v)) @@ -1509,6 +1550,7 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tk=="boolean" then handle(format("%s [%s]=%q,",depth,k and "true" or "false",v)) + elseif tk~="string" then elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=%q,",depth,k,v)) else @@ -1524,13 +1566,14 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tk=="boolean" then handle(format("%s [%s]={},",depth,k and "true" or "false")) + elseif tk~="string" then elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s={},",depth,k)) else handle(format("%s [%q]={},",depth,k)) end elseif inline then - local st=simple_table(v) + local st=is_simple_table(v,hexify) if st then if tk=="number" then if hexify then @@ -1540,6 +1583,7 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tk=="boolean" then handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", "))) + elseif tk~="string" then elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s={ %s },",depth,k,concat(st,", "))) else @@ -1560,6 +1604,7 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tk=="boolean" then handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false")) + elseif tk~="string" then elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=%s,",depth,k,v and "true" or "false")) else @@ -1576,6 +1621,7 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tk=="boolean" then handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f)) + elseif tk~="string" then elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=load(%q),",depth,k,f)) else @@ -1591,6 +1637,7 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tk=="boolean" then handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v))) + elseif tk~="string" then elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=%q,",depth,k,tostring(v))) else @@ -1612,6 +1659,7 @@ local function serialize(_handle,root,name,specification) functions=specification.functions compact=specification.compact inline=specification.inline and compact + metacheck=specification.metacheck if functions==nil then functions=true end @@ -1621,6 +1669,9 @@ local function serialize(_handle,root,name,specification) if inline==nil then inline=compact end + if metacheck==nil then + metacheck=true + end else noquotes=false hexify=false @@ -1628,6 +1679,7 @@ local function serialize(_handle,root,name,specification) compact=true inline=true functions=true + metacheck=true end if tname=="string" then if name=="return" then @@ -1651,7 +1703,7 @@ local function serialize(_handle,root,name,specification) handle("t={") end if root then - if getmetatable(root) then + if metacheck and getmetatable(root) then local dummy=root._w_h_a_t_e_v_e_r_ root._w_h_a_t_e_v_e_r_=nil end @@ -1727,6 +1779,38 @@ local function flattened(t,f,depth) return f end table.flattened=flattened +local function collapsed(t,f,h) + if f==nil then + f={} + h={} + end + for k=1,#t do + local v=t[k] + if type(v)=="table" then + collapsed(v,f,h) + elseif not h[v] then + f[#f+1]=v + h[v]=true + end + end + return f +end +local function collapsedhash(t,h) + if h==nil then + h={} + end + for k=1,#t do + local v=t[k] + if type(v)=="table" then + collapsedhash(v,h) + else + h[v]=true + end + end + return h +end +table.collapsed=collapsed +table.collapsedhash=collapsedhash local function unnest(t,f) if not f then f={} @@ -1833,6 +1917,12 @@ function table.swapped(t,s) end return n end +function table.hashed(t) + for i=1,#t do + t[t[i]]=i + end + return t +end function table.mirrored(t) local n={} for k,v in next,t do @@ -2006,6 +2096,7 @@ if not modules then modules={} end modules ['l-io']={ license="see context related readme files" } local io=io +local open,flush,write,read=io.open,io.flush,io.write,io.read local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format local concat=table.concat local floor=math.floor @@ -2015,50 +2106,56 @@ if string.find(os.getenv("PATH"),";",1,true) then else io.fileseparator,io.pathseparator="/",":" end -local function readall(f) - return f:read("*all") -end +local large=2^24 +local medium=large/16 +local small=medium/8 local function readall(f) local size=f:seek("end") - if size==0 then - return "" - elseif size<1024*1024 then + if size>0 then f:seek("set",0) - return f:read('*all') + return f:read(size) else - local done=f:seek("set",0) - local step - if size<1024*1024 then - step=1024*1024 - elseif size>16*1024*1024 then - step=16*1024*1024 - else - step=floor(size/(1024*1024))*1024*1024/8 - end - local data={} - while true do - local r=f:read(step) - if not r then - return concat(data) - else - data[#data+1]=r - end - end + return "" end end io.readall=readall function io.loaddata(filename,textmode) - local f=io.open(filename,(textmode and 'r') or 'rb') + local f=open(filename,(textmode and 'r') or 'rb') if f then - local data=readall(f) + local size=f:seek("end") + local data=nil + if size>0 then + f:seek("set",0) + data=f:read(size) + end f:close() - if #data>0 then - return data + return data + end +end +function io.copydata(source,target,action) + local f=open(source,"rb") + if f then + local g=open(target,"wb") + if g then + local size=f:seek("end") + if size>0 then + f:seek("set",0) + local data=f:read(size) + if action then + data=action(data) + end + if data then + g:write(data) + end + end + g:close() end + f:close() + flush() end end function io.savedata(filename,data,joiner) - local f=io.open(filename,"wb") + local f=open(filename,"wb") if f then if type(data)=="table" then f:write(concat(data,joiner or "")) @@ -2068,40 +2165,70 @@ function io.savedata(filename,data,joiner) f:write(data or "") end f:close() - io.flush() + flush() return true else return false end end -function io.loadlines(filename,n) - local f=io.open(filename,'r') - if not f then - elseif n then - local lines={} - for i=1,n do - local line=f:read("*lines") - if line then - lines[#lines+1]=line - else - break +if fio and fio.readline then + local readline=fio.readline + function io.loadlines(filename,n) + local f=open(filename,'r') + if not f then + elseif n then + local lines={} + for i=1,n do + local line=readline(f) + if line then + lines[i]=line + else + break + end + end + f:close() + lines=concat(lines,"\n") + if #lines>0 then + return lines + end + else + local line=readline(f) + f:close() + if line and #line>0 then + return line end end - f:close() - lines=concat(lines,"\n") - if #lines>0 then - return lines - end - else - local line=f:read("*line") or "" - f:close() - if #line>0 then - return line + end +else + function io.loadlines(filename,n) + local f=open(filename,'r') + if not f then + elseif n then + local lines={} + for i=1,n do + local line=f:read("*lines") + if line then + lines[i]=line + else + break + end + end + f:close() + lines=concat(lines,"\n") + if #lines>0 then + return lines + end + else + local line=f:read("*line") or "" + f:close() + if #line>0 then + return line + end end end end function io.loadchunk(filename,n) - local f=io.open(filename,'rb') + local f=open(filename,'rb') if f then local data=f:read(n or 1024) f:close() @@ -2111,7 +2238,7 @@ function io.loadchunk(filename,n) end end function io.exists(filename) - local f=io.open(filename) + local f=open(filename) if f==nil then return false else @@ -2120,7 +2247,7 @@ function io.exists(filename) end end function io.size(filename) - local f=io.open(filename) + local f=open(filename) if f==nil then return 0 else @@ -2129,11 +2256,11 @@ function io.size(filename) return s end end -function io.noflines(f) +local function noflines(f) if type(f)=="string" then - local f=io.open(filename) + local f=open(filename) if f then - local n=f and io.noflines(f) or 0 + local n=f and noflines(f) or 0 f:close() return n else @@ -2148,6 +2275,7 @@ function io.noflines(f) return n end end +io.noflines=noflines local nextchar={ [ 4]=function(f) return f:read(1,1,1,1) @@ -2225,16 +2353,16 @@ function io.bytes(f,n) end function io.ask(question,default,options) while true do - io.write(question) + write(question) if options then - io.write(format(" [%s]",concat(options,"|"))) + write(format(" [%s]",concat(options,"|"))) end if default then - io.write(format(" [%s]",default)) + write(format(" [%s]",default)) end - io.write(format(" ")) - io.flush() - local answer=io.read() + write(format(" ")) + flush() + local answer=read() answer=gsub(answer,"^%s*(.*)%s*$","%1") if answer=="" and default then return default @@ -2256,7 +2384,7 @@ function io.ask(question,default,options) end end end -local function readnumber(f,n,m) +local function readnumber(f,n,m) if m then f:seek("set",n) n=m @@ -2265,31 +2393,31 @@ local function readnumber(f,n,m) return byte(f:read(1)) elseif n==2 then local a,b=byte(f:read(2),1,2) - return 256*a+b + return 0x100*a+b elseif n==3 then local a,b,c=byte(f:read(3),1,3) - return 256*256*a+256*b+c + return 0x10000*a+0x100*b+c elseif n==4 then local a,b,c,d=byte(f:read(4),1,4) - return 256*256*256*a+256*256*b+256*c+d + return 0x1000000*a+0x10000*b+0x100*c+d elseif n==8 then local a,b=readnumber(f,4),readnumber(f,4) - return 256*a+b + return 0x100*a+b elseif n==12 then local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4) - return 256*256*a+256*b+c + return 0x10000*a+0x100*b+c elseif n==-2 then local b,a=byte(f:read(2),1,2) - return 256*a+b + return 0x100*a+b elseif n==-3 then local c,b,a=byte(f:read(3),1,3) - return 256*256*a+256*b+c + return 0x10000*a+0x100*b+c elseif n==-4 then local d,c,b,a=byte(f:read(4),1,4) - return 256*256*256*a+256*256*b+256*c+d + return 0x1000000*a+0x10000*b+0x100*c+d elseif n==-8 then local h,g,f,e,d,c,b,a=byte(f:read(8),1,8) - return 256*256*256*256*256*256*256*a+256*256*256*256*256*256*b+256*256*256*256*256*c+256*256*256*256*d+256*256*256*e+256*256*f+256*g+h + return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h else return 0 end @@ -2643,13 +2771,15 @@ function file.robustname(str,strict) end end end -file.readdata=io.loaddata -file.savedata=io.savedata +local loaddata=io.loaddata +local savedata=io.savedata +file.readdata=loaddata +file.savedata=savedata function file.copy(oldname,newname) if oldname and newname then - local data=io.loaddata(oldname) + local data=loaddata(oldname) if data and data~="" then - file.savedata(newname,data) + savedata(newname,data) end end end @@ -2785,6 +2915,637 @@ end -- closure do -- begin closure to overcome local limits and interference +if not modules then modules={} end modules ['l-unicode']={ + version=1.001, + comment="companion to luat-lib.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +utf=utf or (unicode and unicode.utf8) or {} +utf.characters=utf.characters or string.utfcharacters +utf.values=utf.values or string.utfvalues +local type=type +local char,byte,format,sub,gmatch=string.char,string.byte,string.format,string.sub,string.gmatch +local concat=table.concat +local P,C,R,Cs,Ct,Cmt,Cc,Carg,Cp=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Ct,lpeg.Cmt,lpeg.Cc,lpeg.Carg,lpeg.Cp +local lpegmatch=lpeg.match +local patterns=lpeg.patterns +local tabletopattern=lpeg.utfchartabletopattern +local bytepairs=string.bytepairs +local finder=lpeg.finder +local replacer=lpeg.replacer +local utfvalues=utf.values +local utfgmatch=utf.gmatch +local p_utftype=patterns.utftype +local p_utfstricttype=patterns.utfstricttype +local p_utfoffset=patterns.utfoffset +local p_utf8char=patterns.utf8character +local p_utf8byte=patterns.utf8byte +local p_utfbom=patterns.utfbom +local p_newline=patterns.newline +local p_whitespace=patterns.whitespace +if not unicode then + unicode={ utf=utf } +end +if not utf.char then + local floor,char=math.floor,string.char + function utf.char(n) + if n<0x80 then + return char(n) + elseif n<0x800 then + return char( + 0xC0+floor(n/0x40), + 0x80+(n%0x40) + ) + elseif n<0x10000 then + return char( + 0xE0+floor(n/0x1000), + 0x80+(floor(n/0x40)%0x40), + 0x80+(n%0x40) + ) + elseif n<0x200000 then + return char( + 0xF0+floor(n/0x40000), + 0x80+(floor(n/0x1000)%0x40), + 0x80+(floor(n/0x40)%0x40), + 0x80+(n%0x40) + ) + else + return "" + end + end +end +if not utf.byte then + local utf8byte=patterns.utf8byte + function utf.byte(c) + return lpegmatch(utf8byte,c) + end +end +local utfchar,utfbyte=utf.char,utf.byte +function utf.filetype(data) + return data and lpegmatch(p_utftype,data) or "unknown" +end +local toentities=Cs ( + ( + patterns.utf8one+( + patterns.utf8two+patterns.utf8three+patterns.utf8four + )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end + )^0 +) +patterns.toentities=toentities +function utf.toentities(str) + return lpegmatch(toentities,str) +end +local one=P(1) +local two=C(1)*C(1) +local four=C(R(utfchar(0xD8),utfchar(0xFF)))*C(1)*C(1)*C(1) +local pattern=P("\254\255")*Cs(( + four/function(a,b,c,d) + local ab=0xFF*byte(a)+byte(b) + local cd=0xFF*byte(c)+byte(d) + return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000) + end+two/function(a,b) + return utfchar(byte(a)*256+byte(b)) + end+one + )^1 )+P("\255\254")*Cs(( + four/function(b,a,d,c) + local ab=0xFF*byte(a)+byte(b) + local cd=0xFF*byte(c)+byte(d) + return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000) + end+two/function(b,a) + return utfchar(byte(a)*256+byte(b)) + end+one + )^1 ) +function string.toutf(s) + return lpegmatch(pattern,s) or s +end +local validatedutf=Cs ( + ( + patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�" + )^0 +) +patterns.validatedutf=validatedutf +function utf.is_valid(str) + return type(str)=="string" and lpegmatch(validatedutf,str) or false +end +if not utf.len then + local n,f=0,1 + local utfcharcounter=patterns.utfbom^-1*Cmt ( + Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1, + function(_,t,d) + n=n+(t-f)/d + f=t + return true + end + )^0 + function utf.len(str) + n,f=0,1 + lpegmatch(utfcharcounter,str or "") + return n + end +end +utf.length=utf.len +if not utf.sub then + local utflength=utf.length + local b,e,n,first,last=0,0,0,0,0 + local function slide_zero(s,p) + n=n+1 + if n>=last then + e=p-1 + else + return p + end + end + local function slide_one(s,p) + n=n+1 + if n==first then + b=p + end + if n>=last then + e=p-1 + else + return p + end + end + local function slide_two(s,p) + n=n+1 + if n==first then + b=p + else + return true + end + end + local pattern_zero=Cmt(p_utf8char,slide_zero)^0 + local pattern_one=Cmt(p_utf8char,slide_one )^0 + local pattern_two=Cmt(p_utf8char,slide_two )^0 + local pattern_first=C(patterns.utf8character) + function utf.sub(str,start,stop) + if not start then + return str + end + if start==0 then + start=1 + end + if not stop then + if start<0 then + local l=utflength(str) + start=l+start + else + start=start-1 + end + b,n,first=0,0,start + lpegmatch(pattern_two,str) + if n>=first then + return sub(str,b) + else + return "" + end + end + if start<0 or stop<0 then + local l=utf.length(str) + if start<0 then + start=l+start + if start<=0 then + start=1 + else + start=start+1 + end + end + if stop<0 then + stop=l+stop + if stop==0 then + stop=1 + else + stop=stop+1 + end + end + end + if start==1 and stop==1 then + return lpegmatch(pattern_first,str) or "" + elseif start>stop then + return "" + elseif start>1 then + b,e,n,first,last=0,0,0,start-1,stop + lpegmatch(pattern_one,str) + if n>=first and e==0 then + e=#str + end + return sub(str,b,e) + else + b,e,n,last=1,0,0,stop + lpegmatch(pattern_zero,str) + if e==0 then + e=#str + end + return sub(str,b,e) + end + end +end +function utf.remapper(mapping,option,action) + local variant=type(mapping) + if variant=="table" then + action=action or mapping + if option=="dynamic" then + local pattern=false + table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end) + return function(str) + if not str or str=="" then + return "" + else + if not pattern then + pattern=Cs((tabletopattern(mapping)/action+p_utf8char)^0) + end + return lpegmatch(pattern,str) + end + end + elseif option=="pattern" then + return Cs((tabletopattern(mapping)/action+p_utf8char)^0) + else + local pattern=Cs((tabletopattern(mapping)/action+p_utf8char)^0) + return function(str) + if not str or str=="" then + return "" + else + return lpegmatch(pattern,str) + end + end,pattern + end + elseif variant=="function" then + if option=="pattern" then + return Cs((p_utf8char/mapping+p_utf8char)^0) + else + local pattern=Cs((p_utf8char/mapping+p_utf8char)^0) + return function(str) + if not str or str=="" then + return "" + else + return lpegmatch(pattern,str) + end + end,pattern + end + else + return function(str) + return str or "" + end + end +end +function utf.replacer(t) + local r=replacer(t,false,false,true) + return function(str) + return lpegmatch(r,str) + end +end +function utf.subtituter(t) + local f=finder (t) + local r=replacer(t,false,false,true) + return function(str) + local i=lpegmatch(f,str) + if not i then + return str + elseif i>#str then + return str + else + return lpegmatch(r,str) + end + end +end +local utflinesplitter=p_utfbom^-1*lpeg.tsplitat(p_newline) +local utfcharsplitter_ows=p_utfbom^-1*Ct(C(p_utf8char)^0) +local utfcharsplitter_iws=p_utfbom^-1*Ct((p_whitespace^1+C(p_utf8char))^0) +local utfcharsplitter_raw=Ct(C(p_utf8char)^0) +patterns.utflinesplitter=utflinesplitter +function utf.splitlines(str) + return lpegmatch(utflinesplitter,str or "") +end +function utf.split(str,ignorewhitespace) + if ignorewhitespace then + return lpegmatch(utfcharsplitter_iws,str or "") + else + return lpegmatch(utfcharsplitter_ows,str or "") + end +end +function utf.totable(str) + return lpegmatch(utfcharsplitter_raw,str) +end +function utf.magic(f) + local str=f:read(4) or "" + local off=lpegmatch(p_utfoffset,str) + if off<4 then + f:seek('set',off) + end + return lpegmatch(p_utftype,str) +end +local utf16_to_utf8_be,utf16_to_utf8_le +local utf32_to_utf8_be,utf32_to_utf8_le +local utf_16_be_getbom=patterns.utfbom_16_be^-1 +local utf_16_le_getbom=patterns.utfbom_16_le^-1 +local utf_32_be_getbom=patterns.utfbom_32_be^-1 +local utf_32_le_getbom=patterns.utfbom_32_le^-1 +local utf_16_be_linesplitter=utf_16_be_getbom*lpeg.tsplitat(patterns.utf_16_be_nl) +local utf_16_le_linesplitter=utf_16_le_getbom*lpeg.tsplitat(patterns.utf_16_le_nl) +local utf_32_be_linesplitter=utf_32_be_getbom*lpeg.tsplitat(patterns.utf_32_be_nl) +local utf_32_le_linesplitter=utf_32_le_getbom*lpeg.tsplitat(patterns.utf_32_le_nl) +local more=0 +local p_utf16_to_utf8_be=C(1)*C(1)/function(left,right) + local now=256*byte(left)+byte(right) + if more>0 then + now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 + more=0 + return utfchar(now) + elseif now>=0xD800 and now<=0xDBFF then + more=now + return "" + else + return utfchar(now) + end +end +local p_utf16_to_utf8_le=C(1)*C(1)/function(right,left) + local now=256*byte(left)+byte(right) + if more>0 then + now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 + more=0 + return utfchar(now) + elseif now>=0xD800 and now<=0xDBFF then + more=now + return "" + else + return utfchar(now) + end +end +local p_utf32_to_utf8_be=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d) + return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d)) +end +local p_utf32_to_utf8_le=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d) + return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a)) +end +p_utf16_to_utf8_be=P(true)/function() more=0 end*utf_16_be_getbom*Cs(p_utf16_to_utf8_be^0) +p_utf16_to_utf8_le=P(true)/function() more=0 end*utf_16_le_getbom*Cs(p_utf16_to_utf8_le^0) +p_utf32_to_utf8_be=P(true)/function() more=0 end*utf_32_be_getbom*Cs(p_utf32_to_utf8_be^0) +p_utf32_to_utf8_le=P(true)/function() more=0 end*utf_32_le_getbom*Cs(p_utf32_to_utf8_le^0) +patterns.utf16_to_utf8_be=p_utf16_to_utf8_be +patterns.utf16_to_utf8_le=p_utf16_to_utf8_le +patterns.utf32_to_utf8_be=p_utf32_to_utf8_be +patterns.utf32_to_utf8_le=p_utf32_to_utf8_le +utf16_to_utf8_be=function(s) + if s and s~="" then + return lpegmatch(p_utf16_to_utf8_be,s) + else + return s + end +end +local utf16_to_utf8_be_t=function(t) + if not t then + return nil + elseif type(t)=="string" then + t=lpegmatch(utf_16_be_linesplitter,t) + end + for i=1,#t do + local s=t[i] + if s~="" then + t[i]=lpegmatch(p_utf16_to_utf8_be,s) + end + end + return t +end +utf16_to_utf8_le=function(s) + if s and s~="" then + return lpegmatch(p_utf16_to_utf8_le,s) + else + return s + end +end +local utf16_to_utf8_le_t=function(t) + if not t then + return nil + elseif type(t)=="string" then + t=lpegmatch(utf_16_le_linesplitter,t) + end + for i=1,#t do + local s=t[i] + if s~="" then + t[i]=lpegmatch(p_utf16_to_utf8_le,s) + end + end + return t +end +utf32_to_utf8_be=function(s) + if s and s~="" then + return lpegmatch(p_utf32_to_utf8_be,s) + else + return s + end +end +local utf32_to_utf8_be_t=function(t) + if not t then + return nil + elseif type(t)=="string" then + t=lpegmatch(utf_32_be_linesplitter,t) + end + for i=1,#t do + local s=t[i] + if s~="" then + t[i]=lpegmatch(p_utf32_to_utf8_be,s) + end + end + return t +end +utf32_to_utf8_le=function(s) + if s and s~="" then + return lpegmatch(p_utf32_to_utf8_le,s) + else + return s + end +end +local utf32_to_utf8_le_t=function(t) + if not t then + return nil + elseif type(t)=="string" then + t=lpegmatch(utf_32_le_linesplitter,t) + end + for i=1,#t do + local s=t[i] + if s~="" then + t[i]=lpegmatch(p_utf32_to_utf8_le,s) + end + end + return t +end +utf.utf16_to_utf8_le_t=utf16_to_utf8_le_t +utf.utf16_to_utf8_be_t=utf16_to_utf8_be_t +utf.utf32_to_utf8_le_t=utf32_to_utf8_le_t +utf.utf32_to_utf8_be_t=utf32_to_utf8_be_t +utf.utf16_to_utf8_le=utf16_to_utf8_le +utf.utf16_to_utf8_be=utf16_to_utf8_be +utf.utf32_to_utf8_le=utf32_to_utf8_le +utf.utf32_to_utf8_be=utf32_to_utf8_be +function utf.utf8_to_utf8_t(t) + return type(t)=="string" and lpegmatch(utflinesplitter,t) or t +end +function utf.utf16_to_utf8_t(t,endian) + return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t +end +function utf.utf32_to_utf8_t(t,endian) + return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t +end +local function little(b) + if b<0x10000 then + return char(b%256,b/256) + else + b=b-0x10000 + local b1,b2=b/1024+0xD800,b%1024+0xDC00 + return char(b1%256,b1/256,b2%256,b2/256) + end +end +local function big(b) + if b<0x10000 then + return char(b/256,b%256) + else + b=b-0x10000 + local b1,b2=b/1024+0xD800,b%1024+0xDC00 + return char(b1/256,b1%256,b2/256,b2%256) + end +end +local l_remap=Cs((p_utf8byte/little+P(1)/"")^0) +local b_remap=Cs((p_utf8byte/big+P(1)/"")^0) +local function utf8_to_utf16_be(str,nobom) + if nobom then + return lpegmatch(b_remap,str) + else + return char(254,255)..lpegmatch(b_remap,str) + end +end +local function utf8_to_utf16_le(str,nobom) + if nobom then + return lpegmatch(l_remap,str) + else + return char(255,254)..lpegmatch(l_remap,str) + end +end +utf.utf8_to_utf16_be=utf8_to_utf16_be +utf.utf8_to_utf16_le=utf8_to_utf16_le +function utf.utf8_to_utf16(str,littleendian,nobom) + if littleendian then + return utf8_to_utf16_le(str,nobom) + else + return utf8_to_utf16_be(str,nobom) + end +end +local pattern=Cs ( + (p_utf8byte/function(unicode ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0 +) +function utf.tocodes(str,separator) + return lpegmatch(pattern,str,1,separator or " ") +end +function utf.ustring(s) + return format("U+%05X",type(s)=="number" and s or utfbyte(s)) +end +function utf.xstring(s) + return format("0x%05X",type(s)=="number" and s or utfbyte(s)) +end +function utf.toeight(str) + if not str or str=="" then + return nil + end + local utftype=lpegmatch(p_utfstricttype,str) + if utftype=="utf-8" then + return sub(str,4) + elseif utftype=="utf-16-be" then + return utf16_to_utf8_be(str) + elseif utftype=="utf-16-le" then + return utf16_to_utf8_le(str) + else + return str + end +end +local p_nany=p_utf8char/"" +if utfgmatch then + function utf.count(str,what) + if type(what)=="string" then + local n=0 + for _ in utfgmatch(str,what) do + n=n+1 + end + return n + else + return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str) + end + end +else + local cache={} + function utf.count(str,what) + if type(what)=="string" then + local p=cache[what] + if not p then + p=Cs((P(what)/" "+p_nany)^0) + cache[p]=p + end + return #lpegmatch(p,str) + else + return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str) + end + end +end +if not utf.characters then + function utf.characters(str) + return gmatch(str,".[\128-\191]*") + end + string.utfcharacters=utf.characters +end +if not utf.values then + local find=string.find + local dummy=function() + end + function utf.values(str) + local n=#str + if n==0 then + return dummy + elseif n==1 then + return function() return utfbyte(str) end + else + local p=1 + return function() + local b,e=find(str,".[\128-\191]*",p) + if b then + p=e+1 + return utfbyte(sub(str,b,e)) + end + end + end + end + string.utfvalues=utf.values +end +function utf.chrlen(u) + return + (u<0x80 and 1) or + (u<0xE0 and 2) or + (u<0xF0 and 3) or + (u<0xF8 and 4) or + (u<0xFC and 5) or + (u<0xFE and 6) or 0 +end +local extract=bit32.extract +local char=string.char +function unicode.toutf32string(n) + if n<=0xFF then + return + char(n).."\000\000\000" + elseif n<=0xFFFF then + return + char(extract(n,0,8))..char(extract(n,8,8)).."\000\000" + elseif n<=0xFFFFFF then + return + char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000" + else + return + char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8)) + end +end + +end -- closure + +do -- begin closure to overcome local limits and interference + if not modules then modules={} end modules ['util-str']={ version=1.001, comment="companion to luat-lib.mkiv", @@ -2795,7 +3556,7 @@ if not modules then modules={} end modules ['util-str']={ utilities=utilities or {} utilities.strings=utilities.strings or {} local strings=utilities.strings -local format,gsub,rep,sub=string.format,string.gsub,string.rep,string.sub +local format,gsub,rep,sub,find=string.format,string.gsub,string.rep,string.sub,string.find local load,dump=load,string.dump local tonumber,type,tostring=tonumber,type,tostring local unpack,concat=table.unpack,table.concat @@ -2978,6 +3739,25 @@ function number.signed(i) return "-",-i end end +local digit=patterns.digit +local period=patterns.period +local three=digit*digit*digit +local splitter=Cs ( + (((1-(three^1*period))^1+C(three))*(Carg(1)*three)^1+C((1-period)^1))*(P(1)/""*Carg(2))*C(2) +) +patterns.formattednumber=splitter +function number.formatted(n,sep1,sep2) + local s=type(s)=="string" and n or format("%0.2f",n) + if sep1==true then + return lpegmatch(splitter,s,1,".",",") + elseif sep1=="." then + return lpegmatch(splitter,s,1,sep1,sep2 or ",") + elseif sep1=="," then + return lpegmatch(splitter,s,1,sep1,sep2 or ".") + else + return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".") + end +end local zero=P("0")^1/"" local plus=P("+")/"" local minus=P("-") @@ -3003,6 +3783,27 @@ function number.sparseexponent(f,n) end return tostring(n) end +local hf={} +local hs={} +setmetatable(hf,{ __index=function(t,k) + local v="%."..k.."f" + t[k]=v + return v +end } ) +setmetatable(hs,{ __index=function(t,k) + local v="%"..k.."s" + t[k]=v + return v +end } ) +function number.formattedfloat(n,b,a) + local s=format(hf[a],n) + local l=(b or 0)+(a or 0)+1 + if #s<l then + return format(hs[l],s) + else + return s + end +end local template=[[ %s %s @@ -3030,6 +3831,7 @@ local autodouble=string.autodouble local sequenced=table.sequenced local formattednumber=number.formatted local sparseexponent=number.sparseexponent +local formattedfloat=number.formattedfloat ]] else environment={ @@ -3053,6 +3855,7 @@ else sequenced=table.sequenced, formattednumber=number.formatted, sparseexponent=number.sparseexponent, + formattedfloat=number.formattedfloat } end local arguments={ "a1" } @@ -3063,6 +3866,7 @@ setmetatable(arguments,{ __index=function(t,k) end }) local prefix_any=C((S("+- .")+R("09"))^0) +local prefix_sub=(C((S("+-")+R("09"))^0)+Cc(0))*P(".")*(C((S("+-")+R("09"))^0)+Cc(0)) local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0) local format_s=function(f) n=n+1 @@ -3113,6 +3917,10 @@ local format_F=function(f) return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n) end end +local format_k=function(b,a) + n=n+1 + return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0) +end local format_g=function(f) n=n+1 return format("format('%%%sg',a%s)",f,n) @@ -3261,25 +4069,6 @@ end local format_W=function(f) return format("nspaces[%s]",tonumber(f) or 0) end -local digit=patterns.digit -local period=patterns.period -local three=digit*digit*digit -local splitter=Cs ( - (((1-(three^1*period))^1+C(three))*(Carg(1)*three)^1+C((1-period)^1))*(P(1)/""*Carg(2))*C(2) -) -patterns.formattednumber=splitter -function number.formatted(n,sep1,sep2) - local s=type(s)=="string" and n or format("%0.2f",n) - if sep1==true then - return lpegmatch(splitter,s,1,".",",") - elseif sep1=="." then - return lpegmatch(splitter,s,1,sep1,sep2 or ",") - elseif sep1=="," then - return lpegmatch(splitter,s,1,sep1,sep2 or ".") - else - return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".") - end -end local format_m=function(f) n=n+1 if not f or f=="" then @@ -3304,9 +4093,16 @@ end local format_extension=function(extensions,f,name) local extension=extensions[name] or "tostring(%s)" local f=tonumber(f) or 1 + local w=find(extension,"%.%.%.") if f==0 then + if w then + extension=gsub(extension,"%.%.%.","") + end return extension elseif f==1 then + if w then + extension=gsub(extension,"%.%.%.","%%s") + end n=n+1 local a="a"..n return format(extension,a,a) @@ -3314,10 +4110,13 @@ local format_extension=function(extensions,f,name) local a="a"..(n+f+1) return format(extension,a,a) else + if w then + extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s") + end local t={} for i=1,f do n=n+1 - t[#t+1]="a"..n + t[i]="a"..n end return format(extension,unpack(t)) end @@ -3330,7 +4129,8 @@ local builder=Cs { "start", +V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o") +V("c")+V("C")+V("S") +V("Q") -+V("N") ++V("N") ++V("k") +V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w") +V("W") +V("a") @@ -3357,6 +4157,7 @@ local builder=Cs { "start", ["S"]=(prefix_any*P("S"))/format_S, ["Q"]=(prefix_any*P("Q"))/format_S, ["N"]=(prefix_any*P("N"))/format_N, + ["k"]=(prefix_sub*P("k"))/format_k, ["c"]=(prefix_any*P("c"))/format_c, ["C"]=(prefix_any*P("C"))/format_C, ["r"]=(prefix_any*P("r"))/format_r, @@ -3482,7 +4283,9 @@ if not modules then modules={} end modules ['util-fil']={ license="see context related readme files" } local byte=string.byte -local extract=bit32.extract +local char=string.char +local extract=bit32 and bit32.extract +local floor=math.floor utilities=utilities or {} local files={} utilities.files=files @@ -3501,6 +4304,7 @@ end function files.size(f) return f:seek("end") end +files.getsize=files.size function files.setposition(f,n) if zerobased[f] then f:seek("set",n) @@ -3538,6 +4342,10 @@ end function files.readbytes(f,n) return byte(f:read(n),1,n) end +function files.readbytetable(f,n) + local s=f:read(n or 1) + return { byte(s,1,#s) } +end function files.readchar(f) return f:read(1) end @@ -3547,7 +4355,7 @@ end function files.readinteger1(f) local n=byte(f:read(1)) if n>=0x80 then - return n-0xFF-1 + return n-0x100 else return n end @@ -3555,55 +4363,107 @@ end files.readcardinal1=files.readbyte files.readcardinal=files.readcardinal1 files.readinteger=files.readinteger1 +files.readsignedbyte=files.readinteger1 function files.readcardinal2(f) local a,b=byte(f:read(2),1,2) return 0x100*a+b end +function files.readcardinal2le(f) + local b,a=byte(f:read(2),1,2) + return 0x100*a+b +end function files.readinteger2(f) local a,b=byte(f:read(2),1,2) - local n=0x100*a+b - if n>=0x8000 then - return n-0xFFFF-1 + if a>=0x80 then + return 0x100*a+b-0x10000 else - return n + return 0x100*a+b + end +end +function files.readinteger2le(f) + local b,a=byte(f:read(2),1,2) + if a>=0x80 then + return 0x100*a+b-0x10000 + else + return 0x100*a+b end end function files.readcardinal3(f) local a,b,c=byte(f:read(3),1,3) return 0x10000*a+0x100*b+c end +function files.readcardinal3le(f) + local c,b,a=byte(f:read(3),1,3) + return 0x10000*a+0x100*b+c +end +function files.readinteger3(f) + local a,b,c=byte(f:read(3),1,3) + if a>=0x80 then + return 0x10000*a+0x100*b+c-0x1000000 + else + return 0x10000*a+0x100*b+c + end +end +function files.readinteger3le(f) + local c,b,a=byte(f:read(3),1,3) + if a>=0x80 then + return 0x10000*a+0x100*b+c-0x1000000 + else + return 0x10000*a+0x100*b+c + end +end function files.readcardinal4(f) local a,b,c,d=byte(f:read(4),1,4) return 0x1000000*a+0x10000*b+0x100*c+d end +function files.readcardinal4le(f) + local d,c,b,a=byte(f:read(4),1,4) + return 0x1000000*a+0x10000*b+0x100*c+d +end function files.readinteger4(f) local a,b,c,d=byte(f:read(4),1,4) - local n=0x1000000*a+0x10000*b+0x100*c+d - if n>=0x8000000 then - return n-0xFFFFFFFF-1 + if a>=0x80 then + return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000 else - return n + return 0x1000000*a+0x10000*b+0x100*c+d end end -function files.readfixed4(f) - local a,b,c,d=byte(f:read(4),1,4) - local n=0x100*a+b - if n>=0x8000 then - return n-0xFFFF-1+(0x100*c+d)/0xFFFF +function files.readinteger4le(f) + local d,c,b,a=byte(f:read(4),1,4) + if a>=0x80 then + return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000 else - return n+(0x100*c+d)/0xFFFF + return 0x1000000*a+0x10000*b+0x100*c+d end end -function files.read2dot14(f) +function files.readfixed2(f) local a,b=byte(f:read(2),1,2) - local n=0x100*a+b - local m=extract(n,0,30) - if n>0x7FFF then - n=extract(n,30,2) - return m/0x4000-4 + if a>=0x80 then + return (a-0x100)+b/0x100 + else + return (a )+b/0x100 + end +end +function files.readfixed4(f) + local a,b,c,d=byte(f:read(4),1,4) + if a>=0x80 then + return (0x100*a+b-0x10000)+(0x100*c+d)/0x10000 else - n=extract(n,30,2) - return n+m/0x4000 + return (0x100*a+b )+(0x100*c+d)/0x10000 + end +end +if extract then + local extract=bit32.extract + local band=bit32.band + function files.read2dot14(f) + local a,b=byte(f:read(2),1,2) + if a>=0x80 then + local n=-(0x100*a+b) + return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0)) + else + local n=0x100*a+b + return (extract(n,14,2)+(band(n,0x3FFF)/16384.0)) + end end end function files.skipshort(f,n) @@ -3612,6 +4472,55 @@ end function files.skiplong(f,n) f:read(4*(n or 1)) end +function files.writecardinal2(f,n) + local a=char(n%256) + n=floor(n/256) + local b=char(n%256) + f:write(b,a) +end +function files.writecardinal4(f,n) + local a=char(n%256) + n=floor(n/256) + local b=char(n%256) + n=floor(n/256) + local c=char(n%256) + n=floor(n/256) + local d=char(n%256) + f:write(d,c,b,a) +end +function files.writestring(f,s) + f:write(char(byte(s,1,#s))) +end +function files.writebyte(f,b) + f:write(char(b)) +end +if fio and fio.readcardinal1 then + files.readcardinal1=fio.readcardinal1 + files.readcardinal2=fio.readcardinal2 + files.readcardinal3=fio.readcardinal3 + files.readcardinal4=fio.readcardinal4 + files.readinteger1=fio.readinteger1 + files.readinteger2=fio.readinteger2 + files.readinteger3=fio.readinteger3 + files.readinteger4=fio.readinteger4 + files.read2dot14=fio.read2dot14 + files.setposition=fio.setposition + files.getposition=fio.getposition + files.readbyte=files.readcardinal1 + files.readsignedbyte=files.readinteger1 + files.readcardinal=files.readcardinal1 + files.readinteger=files.readinteger1 + local skipposition=fio.skipposition + files.skipposition=skipposition + files.readbytes=fio.readbytes + files.readbytetable=fio.readbytetable + function files.skipshort(f,n) + skipposition(f,2*(n or 1)) + end + function files.skiplong(f,n) + skipposition(f,4*(n or 1)) + end +end end -- closure @@ -3697,6 +4606,7 @@ local remapper={ cidmap="cid maps", pfb="type1 fonts", afm="afm", + enc="enc files", } function resolvers.findfile(name,fileformat) name=string.gsub(name,"\\","/") @@ -3810,44 +4720,42 @@ function caches.is_writable(path,name) local fullname=makefullname(path,name) return fullname and file.is_writable(fullname) end -function caches.loaddata(paths,name) - for i=1,#paths do - local data=false - local luaname,lucname=makefullname(paths[i],name) - if lucname and not lfs.isfile(lucname) and type(caches.compile)=="function" then - texio.write(string.format("(compiling luc: %s)",lucname)) - data=loadfile(luaname) - if data then - data=data() - end - if data then - caches.compile(data,luaname,lucname) - return data - end - end - if lucname and lfs.isfile(lucname) then +function caches.loaddata(readables,name,writable) + for i=1,#readables do + local path=readables[i] + local loader=false + local luaname,lucname=makefullname(path,name) + if lfs.isfile(lucname) then texio.write(string.format("(load luc: %s)",lucname)) - data=loadfile(lucname) - if data then - data=data() + loader=loadfile(lucname) + end + if not loader and lfs.isfile(luaname) then + local luacrap,lucname=makefullname(writable,name) + texio.write(string.format("(compiling luc: %s)",lucname)) + if lfs.isfile(lucname) then + loader=loadfile(lucname) end - if data then - return data + caches.compile(data,luaname,lucname) + if lfs.isfile(lucname) then + texio.write(string.format("(load luc: %s)",lucname)) + loader=loadfile(lucname) else texio.write(string.format("(loading failed: %s)",lucname)) end - end - if luaname and lfs.isfile(luaname) then - texio.write(string.format("(load lua: %s)",luaname)) - data=loadfile(luaname) - if data then - data=data() - end - if data then - return data + if not loader then + texio.write(string.format("(load lua: %s)",luaname)) + loader=loadfile(luaname) + else + texio.write(string.format("(loading failed: %s)",luaname)) end end + if loader then + loader=loader() + collectgarbage("step") + return loader + end end + return false end function caches.savedata(path,name,data) local luaname,lucname=makefullname(path,name) @@ -3974,7 +4882,7 @@ function containers.read(container,name) local storage=container.storage local stored=storage[name] if not stored and container.enabled and caches and containers.usecache then - stored=caches.loaddata(container.readables,name) + stored=caches.loaddata(container.readables,name,container.writable) if stored and stored.cache_version==container.version then if trace_cache or trace_containers then report_containers("action %a, category %a, name %a","load",container.subcategory,name) @@ -4073,7 +4981,7 @@ end nodes.nodecodes=nodecodes nodes.glyphcodes=glyphcodes nodes.disccodes=disccodes -local free_node=node.free +local flush_node=node.flush_node local remove_node=node.remove local new_node=node.new local traverse_id=node.traverse_id @@ -4093,7 +5001,7 @@ function nodes.remove(head,current,free_too) head,current=remove_node(head,current) if t then if free_too then - free_node(t) + flush_node(t) t=nil else t.next,t.prev=nil,nil @@ -4117,12 +5025,14 @@ nodes.getattr=getfield nodes.setattr=setfield nodes.tostring=node.tostring or tostring nodes.copy=node.copy +nodes.copy_node=node.copy nodes.copy_list=node.copy_list nodes.delete=node.delete nodes.dimensions=node.dimensions nodes.end_of_math=node.end_of_math nodes.flush_list=node.flush_list nodes.flush_node=node.flush_node +nodes.flush=node.flush_node nodes.free=node.free nodes.insert_after=node.insert_after nodes.insert_before=node.insert_before @@ -4136,7 +5046,6 @@ nodes.vpack=node.vpack nodes.first_glyph=node.first_glyph nodes.has_glyph=node.has_glyph or node.first_glyph nodes.current_attr=node.current_attr -nodes.do_ligature_n=node.do_ligature_n nodes.has_field=node.has_field nodes.last_node=node.last_node nodes.usedlist=node.usedlist @@ -4173,16 +5082,37 @@ nuts.setattr=setfield nuts.getfont=direct.getfont nuts.setfont=direct.setfont nuts.getsubtype=direct.getsubtype -nuts.setsubtype=direct.setsubtype or function(n,s) setfield(n,"subtype",s) end +nuts.setsubtype=direct.setsubtype nuts.getchar=direct.getchar nuts.setchar=direct.setchar nuts.getdisc=direct.getdisc nuts.setdisc=direct.setdisc nuts.setlink=direct.setlink nuts.getlist=direct.getlist -nuts.setlist=direct.setlist or function(n,l) setfield(n,"list",l) end -nuts.getleader=direct.getleader -nuts.setleader=direct.setleader or function(n,l) setfield(n,"leader",l) end +nuts.setlist=direct.setlist +nuts.getoffsets=direct.getoffsets or + function(n) + return getfield(n,"xoffset"),getfield(n,"yoffset") + end +nuts.setoffsets=direct.setoffsets or + function(n,x,y) + if x then setfield(n,"xoffset",x) end + if y then setfield(n,"xoffset",y) end + end +nuts.getleader=direct.getleader or function(n) return getfield(n,"leader") end +nuts.setleader=direct.setleader or function(n,l) setfield(n,"leader",l) end +nuts.getcomponents=direct.getcomponents or function(n) return getfield(n,"components") end +nuts.setcomponents=direct.setcomponents or function(n,c) setfield(n,"components",c) end +nuts.getkern=direct.getkern or function(n) return getfield(n,"kern") end +nuts.setkern=direct.setkern or function(n,k) setfield(n,"kern",k) end +nuts.getdir=direct.getkern or function(n) return getfield(n,"dir") end +nuts.setdir=direct.setkern or function(n,d) setfield(n,"dir",d) end +nuts.getwidth=direct.getwidth or function(n) return getfield(n,"width") end +nuts.setwidth=direct.setwidth or function(n,w) return setfield(n,"width",w) end +nuts.getheight=direct.getheight or function(n) return getfield(n,"height") end +nuts.setheight=direct.setheight or function(n,h) return setfield(n,"height",h) end +nuts.getdepth=direct.getdepth or function(n) return getfield(n,"depth") end +nuts.setdepth=direct.setdepth or function(n,d) return setfield(n,"depth",d) end if not direct.is_glyph then local getchar=direct.getchar local getid=direct.getid @@ -4223,9 +5153,12 @@ nuts.insert_before=direct.insert_before nuts.insert_after=direct.insert_after nuts.delete=direct.delete nuts.copy=direct.copy +nuts.copy_node=direct.copy nuts.copy_list=direct.copy_list nuts.tail=direct.tail nuts.flush_list=direct.flush_list +nuts.flush_node=direct.flush_node +nuts.flush=direct.flush nuts.free=direct.free nuts.remove=direct.remove nuts.is_node=direct.is_node @@ -4267,6 +5200,116 @@ nuts.setprop=function(n,k,v) end nodes.setprop=nodes.setproperty nodes.getprop=nodes.getproperty +local setprev=nuts.setprev +local setnext=nuts.setnext +local getnext=nuts.getnext +local setlink=nuts.setlink +local getfield=nuts.getfield +local setfield=nuts.setfield +local getcomponents=nuts.getcomponents +local setcomponents=nuts.setcomponents +local find_tail=nuts.tail +local flush_list=nuts.flush_list +local flush_node=nuts.flush_node +local traverse_id=nuts.traverse_id +local copy_node=nuts.copy_node +local glyph_code=nodes.nodecodes.glyph +function nuts.set_components(target,start,stop) + local head=getcomponents(target) + if head then + flush_list(head) + head=nil + end + if start then + setprev(start) + else + return nil + end + if stop then + setnext(stop) + end + local tail=nil + while start do + local c=getcomponents(start) + local n=getnext(start) + if c then + if head then + setlink(tail,c) + else + head=c + end + tail=find_tail(c) + setcomponents(start) + flush_node(start) + else + if head then + setlink(tail,start) + else + head=start + end + tail=start + end + start=n + end + setcomponents(target,head) + return head +end +nuts.get_components=nuts.getcomponents +function nuts.take_components(target) + local c=getcomponents(target) + setcomponents(target) + return c +end +function nuts.count_components(n,marks) + local components=getcomponents(n) + if components then + if marks then + local i=0 + for g in traverse_id(glyph_code,components) do + if not marks[getchar(g)] then + i=i+1 + end + end + return i + else + return count(glyph_code,components) + end + else + return 0 + end +end +function nuts.copy_no_components(g,copyinjection) + local components=getcomponents(g) + if components then + setcomponents(g) + local n=copy_node(g) + if copyinjection then + copyinjection(n,g) + end + setcomponents(g,components) + return n + else + local n=copy_node(g) + if copyinjection then + copyinjection(n,g) + end + return n + end +end +function nuts.copy_only_glyphs(current) + local head=nil + local previous=nil + for n in traverse_id(glyph_code,current) do + n=copy_node(n) + if head then + setlink(previous,n) + else + head=n + end + previous=n + end + return head +end end -- closure @@ -5034,7 +6077,6 @@ if not modules then modules={} end modules ['font-ini']={ license="see context related readme files" } local allocate=utilities.storage.allocate -local report_defining=logs.reporter("fonts","defining") fonts=fonts or {} local fonts=fonts fonts.hashes={ identifiers=allocate() } @@ -5060,10 +6102,11 @@ if not modules then modules={} end modules ['font-con']={ license="see context related readme files" } local next,tostring,rawget=next,tostring,rawget -local format,match,lower,gsub=string.format,string.match,string.lower,string.gsub -local utfbyte=utf.byte -local sort,insert,concat,sortedkeys,serialize,fastcopy=table.sort,table.insert,table.concat,table.sortedkeys,table.serialize,table.fastcopy +local format,match,lower,gsub,find=string.format,string.match,string.lower,string.gsub,string.find +local sort,insert,concat=table.sort,table.insert,table.concat +local sortedkeys,sortedhash,serialize,fastcopy=table.sortedkeys,table.sortedhash,table.serialize,table.fastcopy local derivetable=table.derive +local ioflush=io.flush local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end) local report_defining=logs.reporter("fonts","defining") @@ -5081,89 +6124,6 @@ constructors.version=1.01 constructors.cache=containers.define("fonts","constructors",constructors.version,false) constructors.privateoffset=0xF0000 constructors.cacheintex=true -constructors.keys={ - properties={ - encodingbytes="number", - embedding="number", - cidinfo={}, - format="string", - fontname="string", - fullname="string", - filename="filename", - psname="string", - name="string", - virtualized="boolean", - hasitalics="boolean", - autoitalicamount="basepoints", - nostackmath="boolean", - noglyphnames="boolean", - mode="string", - hasmath="boolean", - mathitalics="boolean", - textitalics="boolean", - finalized="boolean", - }, - parameters={ - mathsize="number", - scriptpercentage="float", - scriptscriptpercentage="float", - units="cardinal", - designsize="scaledpoints", - expansion={ - stretch="integerscale", - shrink="integerscale", - step="integerscale", - auto="boolean", - }, - protrusion={ - auto="boolean", - }, - slantfactor="float", - extendfactor="float", - factor="float", - hfactor="float", - vfactor="float", - size="scaledpoints", - units="scaledpoints", - scaledpoints="scaledpoints", - slantperpoint="scaledpoints", - spacing={ - width="scaledpoints", - stretch="scaledpoints", - shrink="scaledpoints", - extra="scaledpoints", - }, - xheight="scaledpoints", - quad="scaledpoints", - ascender="scaledpoints", - descender="scaledpoints", - synonyms={ - space="spacing.width", - spacestretch="spacing.stretch", - spaceshrink="spacing.shrink", - extraspace="spacing.extra", - x_height="xheight", - space_stretch="spacing.stretch", - space_shrink="spacing.shrink", - extra_space="spacing.extra", - em="quad", - ex="xheight", - slant="slantperpoint", - }, - }, - description={ - width="basepoints", - height="basepoints", - depth="basepoints", - boundingbox={}, - }, - character={ - width="scaledpoints", - height="scaledpoints", - depth="scaledpoints", - italic="scaledpoints", - }, -} local designsizes=allocate() constructors.designsizes=designsizes local loadedfonts=allocate() @@ -5209,7 +6169,9 @@ end local unscaled={ ScriptPercentScaleDown=true, ScriptScriptPercentScaleDown=true, - RadicalDegreeBottomRaisePercent=true + RadicalDegreeBottomRaisePercent=true, + NoLimitSupFactor=true, + NoLimitSubFactor=true, } function constructors.assignmathparameters(target,original) local mathparameters=original.mathparameters @@ -5288,6 +6250,36 @@ function constructors.enhanceparameters(parameters) extra=extra, } end +local function mathkerns(v,vdelta) + local k={} + for i=1,#v do + local entry=v[i] + local height=entry.height + local kern=entry.kern + k[i]={ + height=height and vdelta*height or 0, + kern=kern and vdelta*kern or 0, + } + end + return k +end +local psfake=0 +local function fixedpsname(psname,fallback) + local usedname=psname + if psname and psname~="" then + if find(psname," ") then + usedname=gsub(psname,"[%s]+","-") + else + end + elseif not fallback or fallback=="" then + psfake=psfake+1 + psname="fakename-"..psfake + else + psname=fallback + usedname=gsub(psname,"[^a-zA-Z0-9]+","-") + end + return usedname,psname~=usedname +end function constructors.scale(tfmdata,specification) local target={} if tonumber(specification) then @@ -5361,14 +6353,12 @@ function constructors.scale(tfmdata,specification) target.cidinfo=properties.cidinfo target.format=properties.format target.cache=constructors.cacheintex and "yes" or "renew" - local fontname=properties.fontname or tfmdata.fontname - local fullname=properties.fullname or tfmdata.fullname - local filename=properties.filename or tfmdata.filename - local psname=properties.psname or tfmdata.psname + local fontname=properties.fontname or tfmdata.fontname + local fullname=properties.fullname or tfmdata.fullname + local filename=properties.filename or tfmdata.filename + local psname=properties.psname or tfmdata.psname local name=properties.name or tfmdata.name - if not psname or psname=="" then - psname=fontname or (fullname and fonts.names.cleanname(fullname)) - end + local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename)) target.fontname=fontname target.fullname=fullname target.filename=filename @@ -5418,10 +6408,14 @@ function constructors.scale(tfmdata,specification) local haskerns=properties.haskerns or properties.mode=="base" local hasligatures=properties.hasligatures or properties.mode=="base" local realdimensions=properties.realdimensions + local writingmode=properties.writingmode or "horizontal" + local identity=properties.identity or "horizontal" if changed and not next(changed) then changed=false end target.type=isvirtual and "virtual" or "real" + target.writingmode=writingmode=="vertical" and "vertical" or "horizontal" + target.identity=identity=="vertical" and "vertical" or "horizontal" target.postprocessors=tfmdata.postprocessors local targetslant=(parameters.slant or parameters[1] or 0)*factors.pt local targetspace=(parameters.space or parameters[2] or 0)*hdelta @@ -5481,8 +6475,9 @@ function constructors.scale(tfmdata,specification) end end if trace_defining then - report_defining("defining tfm, name %a, fullname %a, filename %a, hscale %a, vscale %a, math %a, italics %a", - name,fullname,filename,hdelta,vdelta,hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled") + report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a", + name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta, + hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled") end constructors.beforecopyingcharacters(target,tfmdata) local sharedkerns={} @@ -5626,22 +6621,15 @@ function constructors.scale(tfmdata,specification) chr.top_accent=vdelta*va end if stackmath then - local mk=character.mathkerns + local mk=character.mathkerns if mk then - local kerns={} - local v=mk.top_right if v then local k={} for i=1,#v do local vi=v[i] - k[i]={ height=vdelta*vi.height,kern=vdelta*vi.kern } - end kerns.top_right=k end - local v=mk.top_left if v then local k={} for i=1,#v do local vi=v[i] - k[i]={ height=vdelta*vi.height,kern=vdelta*vi.kern } - end kerns.top_left=k end - local v=mk.bottom_left if v then local k={} for i=1,#v do local vi=v[i] - k[i]={ height=vdelta*vi.height,kern=vdelta*vi.kern } - end kerns.bottom_left=k end - local v=mk.bottom_right if v then local k={} for i=1,#v do local vi=v[i] - k[i]={ height=vdelta*vi.height,kern=vdelta*vi.kern } - end kerns.bottom_right=k end - chr.mathkern=kerns + local tr,tl,br,bl=mk.topright,mk.topleft,mk.bottomright,mk.bottomleft + chr.mathkern={ + top_right=tr and mathkerns(tr,vdelta) or nil, + top_left=tl and mathkerns(tl,vdelta) or nil, + bottom_right=br and mathkerns(br,vdelta) or nil, + bottom_left=bl and mathkerns(bl,vdelta) or nil, + } end end if hasitalics then @@ -5813,6 +6801,8 @@ function constructors.finalize(tfmdata) cidinfo=tfmdata.cidinfo or nil, format=tfmdata.format or "type1", direction=tfmdata.direction or 0, + writingmode=tfmdata.writingmode or "horizontal", + identity=tfmdata.identity or "horizontal", } end if not tfmdata.resources then @@ -5859,20 +6849,20 @@ constructors.hashmethods=hashmethods function constructors.hashfeatures(specification) local features=specification.features if features then - local t,tn={},0 - for category,list in next,features do + local t,n={},0 + for category,list in sortedhash(features) do if next(list) then local hasher=hashmethods[category] if hasher then local hash=hasher(list) if hash then - tn=tn+1 - t[tn]=category..":"..hash + n=n+1 + t[n]=category..":"..hash end end end end - if tn>0 then + if n>0 then return concat(t," & ") end end @@ -5886,15 +6876,11 @@ hashmethods.normal=function(list) elseif k=="number" or k=="features" then else n=n+1 - s[n]=k + s[n]=k..'='..tostring(v) end end if n>0 then sort(s) - for i=1,n do - local k=s[i] - s[i]=k..'='..tostring(list[k]) - end return concat(s,"+") end end @@ -5954,119 +6940,231 @@ setmetatableindex(formats,function(t,k) end return rawget(t,file.suffix(l)) end) -local locations={} -local function setindeed(mode,target,group,name,action,position) - local t=target[mode] - if not t then - report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode) - os.exit() - elseif position then - insert(t,position,{ name=name,action=action }) - else - for i=1,#t do - local ti=t[i] - if ti.name==name then - ti.action=action - return +do + local function setindeed(mode,source,target,group,name,position) + local action=source[mode] + if not action then + return + end + local t=target[mode] + if not t then + report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode) + os.exit() + elseif position then + insert(t,position,{ name=name,action=action }) + else + for i=1,#t do + local ti=t[i] + if ti.name==name then + ti.action=action + return + end end + insert(t,{ name=name,action=action }) end - insert(t,{ name=name,action=action }) end -end -local function set(group,name,target,source) - target=target[group] - if not target then - report_defining("fatal target error in setting feature %a, group %a",name,group) - os.exit() - end - local source=source[group] - if not source then - report_defining("fatal source error in setting feature %a, group %a",name,group) - os.exit() - end - local node=source.node - local base=source.base - local position=source.position - if node then - setindeed("node",target,group,name,node,position) - end - if base then - setindeed("base",target,group,name,base,position) - end -end -local function register(where,specification) - local name=specification.name - if name and name~="" then - local default=specification.default - local description=specification.description - local initializers=specification.initializers - local processors=specification.processors - local manipulators=specification.manipulators - local modechecker=specification.modechecker - if default then - where.defaults[name]=default - end - if description and description~="" then - where.descriptions[name]=description - end - if initializers then - set('initializers',name,where,specification) + local function set(group,name,target,source) + target=target[group] + if not target then + report_defining("fatal target error in setting feature %a, group %a",name,group) + os.exit() end - if processors then - set('processors',name,where,specification) - end - if manipulators then - set('manipulators',name,where,specification) + local source=source[group] + if not source then + report_defining("fatal source error in setting feature %a, group %a",name,group) + os.exit() end - if modechecker then - where.modechecker=modechecker + local position=source.position + setindeed("node",source,target,group,name,position) + setindeed("base",source,target,group,name,position) + setindeed("plug",source,target,group,name,position) + end + local function register(where,specification) + local name=specification.name + if name and name~="" then + local default=specification.default + local description=specification.description + local initializers=specification.initializers + local processors=specification.processors + local manipulators=specification.manipulators + local modechecker=specification.modechecker + if default then + where.defaults[name]=default + end + if description and description~="" then + where.descriptions[name]=description + end + if initializers then + set('initializers',name,where,specification) + end + if processors then + set('processors',name,where,specification) + end + if manipulators then + set('manipulators',name,where,specification) + end + if modechecker then + where.modechecker=modechecker + end end end -end -constructors.registerfeature=register -function constructors.getfeatureaction(what,where,mode,name) - what=handlers[what].features - if what then - where=what[where] - if where then - mode=where[mode] - if mode then - for i=1,#mode do - local m=mode[i] - if m.name==name then - return m.action + constructors.registerfeature=register + function constructors.getfeatureaction(what,where,mode,name) + what=handlers[what].features + if what then + where=what[where] + if where then + mode=where[mode] + if mode then + for i=1,#mode do + local m=mode[i] + if m.name==name then + return m.action + end end end end end end -end -function constructors.newhandler(what) - local handler=handlers[what] - if not handler then - handler={} - handlers[what]=handler + local newfeatures={} + constructors.newfeatures=newfeatures + constructors.features=newfeatures + local function setnewfeatures(what) + local handler=handlers[what] + local features=handler.features + if not features then + local tables=handler.tables + local statistics=handler.statistics + features=allocate { + defaults={}, + descriptions=tables and tables.features or {}, + used=statistics and statistics.usedfeatures or {}, + initializers={ base={},node={},plug={} }, + processors={ base={},node={},plug={} }, + manipulators={ base={},node={},plug={} }, + } + features.register=function(specification) return register(features,specification) end + handler.features=features + end + return features end - return handler + setmetatable(newfeatures,{ + __call=function(t,k) local v=t[k] return v end, + __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end, + }) end -function constructors.newfeatures(what) - local handler=handlers[what] - local features=handler.features - if not features then - local tables=handler.tables - local statistics=handler.statistics - features=allocate { - defaults={}, - descriptions=tables and tables.features or {}, - used=statistics and statistics.usedfeatures or {}, - initializers={ base={},node={} }, - processors={ base={},node={} }, - manipulators={ base={},node={} }, - } - features.register=function(specification) return register(features,specification) end - handler.features=features +do + local newhandler={} + constructors.handlers=newhandler + constructors.newhandler=newhandler + local function setnewhandler(what) + local handler=handlers[what] + if not handler then + handler={} + handlers[what]=handler + end + return handler + end + setmetatable(newhandler,{ + __call=function(t,k) local v=t[k] return v end, + __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end, + }) +end +do + local newenhancer={} + constructors.enhancers=newenhancer + constructors.newenhancer=newenhancer + local function setnewenhancer(format) + local handler=handlers[format] + local enhancers=handler.enhancers + if not enhancers then + local actions=allocate() + local before=allocate() + local after=allocate() + local order=allocate() + local patches={ before=before,after=after } + local trace=false + local report=logs.reporter("fonts",format.." enhancing") + trackers.register(format..".loading",function(v) trace=v end) + local function enhance(name,data,filename,raw) + local enhancer=actions[name] + if enhancer then + if trace then + report("apply enhancement %a to file %a",name,filename) + ioflush() + end + enhancer(data,filename,raw) + else + end + end + local function apply(data,filename,raw) + local basename=file.basename(lower(filename)) + if trace then + report("%s enhancing file %a","start",filename) + end + ioflush() + for e=1,#order do + local enhancer=order[e] + local b=before[enhancer] + if b then + for pattern,action in next,b do + if find(basename,pattern) then + action(data,filename,raw) + end + end + end + enhance(enhancer,data,filename,raw) + local a=after[enhancer] + if a then + for pattern,action in next,a do + if find(basename,pattern) then + action(data,filename,raw) + end + end + end + ioflush() + end + if trace then + report("%s enhancing file %a","stop",filename) + end + ioflush() + end + local function register(what,action) + if action then + if actions[what] then + else + order[#order+1]=what + end + actions[what]=action + else + report("bad enhancer %a",what) + end + end + local function patch(what,where,pattern,action) + local pw=patches[what] + if pw then + local ww=pw[where] + if ww then + ww[pattern]=action + else + pw[where]={ [pattern]=action} + end + end + end + enhancers={ + register=register, + apply=apply, + patch=patch, + patches={ register=patch }, + } + handler.enhancers=enhancers + end + return enhancers end - return features + setmetatable(newenhancer,{ + __call=function(t,k) local v=t[k] return v end, + __index=function(t,k) local v=setnewenhancer(k) t[k]=v return v end, + }) end function constructors.checkedfeatures(what,features) local defaults=handlers[what].features.defaults @@ -6087,7 +7185,6 @@ function constructors.initializefeatures(what,tfmdata,features,trace,report) local properties=tfmdata.properties or {} local whathandler=handlers[what] local whatfeatures=whathandler.features - local whatinitializers=whatfeatures.initializers local whatmodechecker=whatfeatures.modechecker local mode=properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base" properties.mode=mode @@ -6222,19 +7319,61 @@ if context then os.exit() end local fonts=fonts -fonts.encodings={} -fonts.encodings.agl={} -fonts.encodings.known={} -setmetatable(fonts.encodings.agl,{ __index=function(t,k) +local encodings={} +fonts.encodings=encodings +encodings.agl={} +encodings.known={} +setmetatable(encodings.agl,{ __index=function(t,k) if k=="unicodes" then texio.write(" <loading (extended) adobe glyph list>") local unicodes=dofile(resolvers.findfile("font-age.lua")) - fonts.encodings.agl={ unicodes=unicodes } + encodings.agl={ unicodes=unicodes } return unicodes else return nil end end }) +encodings.cache=containers.define("fonts","enc",encodings.version,true) +function encodings.load(filename) + local name=file.removesuffix(filename) + local data=containers.read(encodings.cache,name) + if data then + return data + end + local vector,tag,hash,unicodes={},"",{},{} + local foundname=resolvers.findfile(filename,'enc') + if foundname and foundname~="" then + local ok,encoding,size=resolvers.loadbinfile(foundname) + if ok and encoding then + encoding=string.gsub(encoding,"%%(.-)\n","") + local unicoding=encodings.agl.unicodes + local tag,vec=string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def") + local i=0 + for ch in string.gmatch(vec,"/([%a%d%.]+)") do + if ch~=".notdef" then + vector[i]=ch + if not hash[ch] then + hash[ch]=i + else + end + local u=unicoding[ch] + if u then + unicodes[u]=i + end + end + i=i+1 + end + end + end + local data={ + name=name, + tag=tag, + vector=vector, + hash=hash, + unicodes=unicodes + } + return containers.write(encodings.cache,name,data) +end end -- closure @@ -6403,13 +7542,13 @@ if not modules then modules={} end modules ['font-map']={ local tonumber,next,type=tonumber,next,type local match,format,find,concat,gsub,lower=string.match,string.format,string.find,table.concat,string.gsub,string.lower local P,R,S,C,Ct,Cc,lpegmatch=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.match -local utfbyte=utf.byte local floor=math.floor local formatters=string.formatters +local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end) -local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_unimapping=v end) -local report_fonts=logs.reporter("fonts","loading") -local force_ligatures=false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end) +local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end) +local report_fonts=logs.reporter("fonts","loading") +local force_ligatures=true directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end) local fonts=fonts or {} local mappings=fonts.mappings or {} fonts.mappings=mappings @@ -6438,7 +7577,7 @@ local function makenameparser(str) end local f_single=formatters["%04X"] local f_double=formatters["%04X%04X"] -local function tounicode16(unicode,name) +local function tounicode16(unicode) if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then return f_single(unicode) else @@ -6446,7 +7585,7 @@ local function tounicode16(unicode,name) return f_double(floor(unicode/1024)+0xD800,unicode%1024+0xDC00) end end -local function tounicode16sequence(unicodes,name) +local function tounicode16sequence(unicodes) local t={} for l=1,#unicodes do local u=unicodes[l] @@ -6497,36 +7636,44 @@ mappings.fromunicode16=fromunicode16 local ligseparator=P("_") local varseparator=P(".") local namesplitter=Ct(C((1-ligseparator-varseparator)^1)*(ligseparator*C((1-ligseparator-varseparator)^1))^0) -local overloads=allocate { - IJ={ name="I_J",unicode={ 0x49,0x4A },mess=0x0132 }, - ij={ name="i_j",unicode={ 0x69,0x6A },mess=0x0133 }, - ff={ name="f_f",unicode={ 0x66,0x66 },mess=0xFB00 }, - fi={ name="f_i",unicode={ 0x66,0x69 },mess=0xFB01 }, - fl={ name="f_l",unicode={ 0x66,0x6C },mess=0xFB02 }, - ffi={ name="f_f_i",unicode={ 0x66,0x66,0x69 },mess=0xFB03 }, - ffl={ name="f_f_l",unicode={ 0x66,0x66,0x6C },mess=0xFB04 }, - fj={ name="f_j",unicode={ 0x66,0x6A } }, - fk={ name="f_k",unicode={ 0x66,0x6B } }, -} -for k,v in next,overloads do - local name=v.name - local mess=v.mess - if name then - overloads[name]=v - end - if mess then - overloads[mess]=v +do + local overloads=allocate { + IJ={ name="I_J",unicode={ 0x49,0x4A },mess=0x0132 }, + ij={ name="i_j",unicode={ 0x69,0x6A },mess=0x0133 }, + ff={ name="f_f",unicode={ 0x66,0x66 },mess=0xFB00 }, + fi={ name="f_i",unicode={ 0x66,0x69 },mess=0xFB01 }, + fl={ name="f_l",unicode={ 0x66,0x6C },mess=0xFB02 }, + ffi={ name="f_f_i",unicode={ 0x66,0x66,0x69 },mess=0xFB03 }, + ffl={ name="f_f_l",unicode={ 0x66,0x66,0x6C },mess=0xFB04 }, + fj={ name="f_j",unicode={ 0x66,0x6A } }, + fk={ name="f_k",unicode={ 0x66,0x6B } }, + } + local o={} + for k,v in next,overloads do + local name=v.name + local mess=v.mess + if name then + o[name]=v + end + if mess then + o[mess]=v + end + o[k]=v end + mappings.overloads=o end -mappings.overloads=overloads function mappings.addtounicode(data,filename,checklookups) local resources=data.resources local unicodes=resources.unicodes if not unicodes then + if trace_mapping then + report_fonts("no unicode list, quitting tounicode for %a",filename) + end return end local properties=data.properties local descriptions=data.descriptions + local overloads=mappings.overloads unicodes['space']=unicodes['space'] or 32 unicodes['hyphen']=unicodes['hyphen'] or 45 unicodes['zwj']=unicodes['zwj'] or 0x200D @@ -6549,10 +7696,13 @@ function mappings.addtounicode(data,filename,checklookups) end local ns=0 local nl=0 - for du,glyph in next,descriptions do + local dlist=sortedkeys(descriptions) + for i=1,#dlist do + local du=dlist[i] + local glyph=descriptions[du] local name=glyph.name if name then - local overload=overloads[name] + local overload=overloads[name] or overloads[du] if overload then glyph.unicode=overload.unicode else @@ -6671,37 +7821,52 @@ function mappings.addtounicode(data,filename,checklookups) end end end + else + local overload=overloads[du] + if overload then + glyph.unicode=overload.unicode + end end end if type(checklookups)=="function" then checklookups(data,missing,nofmissing) end - local collected=false local unicoded=0 - for unicode,glyph in next,descriptions do - if glyph.class=="ligature" and (force_ligatures or not glyph.unicode) then - if not collected then - collected=fonts.handlers.otf.readers.getcomponents(data) - if not collected then - break - end + local collected=fonts.handlers.otf.readers.getcomponents(data) + local function resolve(glyph,u) + local n=#u + for i=1,n do + if u[i]>private then + n=0 + break end - local u=collected[unicode] + end + if n>0 then + if n>1 then + glyph.unicode=u + else + glyph.unicode=u[1] + end + unicoded=unicoded+1 + end + end + if not collected then + elseif force_ligatures then + for i=1,#dlist do + local du=dlist[i] + local u=collected[du] if u then - local n=#u - for i=1,n do - if u[i]>private then - n=0 - break - end - end - if n>0 then - if n>1 then - glyph.unicode=u - else - glyph.unicode=u[1] - end - unicoded=unicoded+1 + resolve(descriptions[du],u) + end + end + else + for i=1,#dlist do + local du=dlist[i] + local glyph=descriptions[du] + if glyph.class=="ligature" and not glyph.unicode then + local u=collected[du] + if u then + resolve(glyph,u) end end end @@ -6710,9 +7875,11 @@ function mappings.addtounicode(data,filename,checklookups) report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded) end if trace_mapping then - for unic,glyph in table.sortedhash(descriptions) do - local name=glyph.name - local index=glyph.index + for i=1,#dlist do + local du=dlist[i] + local glyph=descriptions[du] + local name=glyph.name or "-" + local index=glyph.index or 0 local unicode=glyph.unicode if unicode then if type(unicode)=="table" then @@ -6720,12 +7887,12 @@ function mappings.addtounicode(data,filename,checklookups) for i=1,#unicode do unicodes[i]=formatters("%U",unicode[i]) end - report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,unic,unicodes) + report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes) else - report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,unic,unicode) + report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode) end else - report_fonts("internal slot %U, name %a, unicode %U",index,name,unic) + report_fonts("internal slot %U, name %a, unicode %U",index,name,du) end end end @@ -6815,165 +7982,6 @@ end -- closure do -- begin closure to overcome local limits and interference -if not modules then modules={} end modules ['font-tfm']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next=next -local match=string.match -local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) -local trace_features=false trackers.register("tfm.features",function(v) trace_features=v end) -local report_defining=logs.reporter("fonts","defining") -local report_tfm=logs.reporter("fonts","tfm loading") -local findbinfile=resolvers.findbinfile -local fonts=fonts -local handlers=fonts.handlers -local readers=fonts.readers -local constructors=fonts.constructors -local encodings=fonts.encodings -local tfm=constructors.newhandler("tfm") -tfm.version=1.000 -tfm.maxnestingdepth=5 -tfm.maxnestingsize=65536*1024 -local tfmfeatures=constructors.newfeatures("tfm") -local registertfmfeature=tfmfeatures.register -constructors.resolvevirtualtoo=false -fonts.formats.tfm="type1" -fonts.formats.ofm="type1" -function tfm.setfeatures(tfmdata,features) - local okay=constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm) - if okay then - return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm) - else - return {} - end -end -local depth={} -local function read_from_tfm(specification) - local filename=specification.filename - local size=specification.size - depth[filename]=(depth[filename] or 0)+1 - if trace_defining then - report_defining("loading tfm file %a at size %s",filename,size) - end - local tfmdata=font.read_tfm(filename,size) - if tfmdata then - local features=specification.features and specification.features.normal or {} - local resources=tfmdata.resources or {} - local properties=tfmdata.properties or {} - local parameters=tfmdata.parameters or {} - local shared=tfmdata.shared or {} - properties.name=tfmdata.name - properties.fontname=tfmdata.fontname - properties.psname=tfmdata.psname - properties.filename=specification.filename - properties.format=fonts.formats.tfm - parameters.size=size - tfmdata.properties=properties - tfmdata.resources=resources - tfmdata.parameters=parameters - tfmdata.shared=shared - shared.rawdata={} - shared.features=features - shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil - parameters.slant=parameters.slant or parameters[1] or 0 - parameters.space=parameters.space or parameters[2] or 0 - parameters.space_stretch=parameters.space_stretch or parameters[3] or 0 - parameters.space_shrink=parameters.space_shrink or parameters[4] or 0 - parameters.x_height=parameters.x_height or parameters[5] or 0 - parameters.quad=parameters.quad or parameters[6] or 0 - parameters.extra_space=parameters.extra_space or parameters[7] or 0 - constructors.enhanceparameters(parameters) - if constructors.resolvevirtualtoo then - fonts.loggers.register(tfmdata,file.suffix(filename),specification) - local vfname=findbinfile(specification.name,'ovf') - if vfname and vfname~="" then - local vfdata=font.read_vf(vfname,size) - if vfdata then - local chars=tfmdata.characters - for k,v in next,vfdata.characters do - chars[k].commands=v.commands - end - properties.virtualized=true - tfmdata.fonts=vfdata.fonts - tfmdata.type="virtual" - local fontlist=vfdata.fonts - local name=file.nameonly(filename) - for i=1,#fontlist do - local n=fontlist[i].name - local s=fontlist[i].size - local d=depth[filename] - s=constructors.scaled(s,vfdata.designsize) - if d>tfm.maxnestingdepth then - report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth) - fontlist[i]={ id=0 } - elseif (d>1) and (s>tfm.maxnestingsize) then - report_defining("virtual font %a exceeds size %s",n,s) - fontlist[i]={ id=0 } - else - local t,id=fonts.constructors.readanddefine(n,s) - fontlist[i]={ id=id } - end - end - end - end - end - local allfeatures=tfmdata.shared.features or specification.features.normal - constructors.applymanipulators("tfm",tfmdata,allfeatures.normal,trace_features,report_tfm) - if not features.encoding then - local encoding,filename=match(properties.filename,"^(.-)%-(.*)$") - if filename and encoding and encodings.known and encodings.known[encoding] then - features.encoding=encoding - end - end - properties.haskerns=true - properties.hasligatures=true - resources.unicodes={} - resources.lookuptags={} - depth[filename]=depth[filename]-1 - return tfmdata - else - depth[filename]=depth[filename]-1 - end -end -local function check_tfm(specification,fullname) - local foundname=findbinfile(fullname,'tfm') or "" - if foundname=="" then - foundname=findbinfile(fullname,'ofm') or "" - end - if foundname=="" then - foundname=fonts.names.getfilename(fullname,"tfm") or "" - end - if foundname~="" then - specification.filename=foundname - specification.format="ofm" - return read_from_tfm(specification) - elseif trace_defining then - report_defining("loading tfm with name %a fails",specification.name) - end -end -readers.check_tfm=check_tfm -function readers.tfm(specification) - local fullname=specification.filename or "" - if fullname=="" then - local forced=specification.forced or "" - if forced~="" then - fullname=specification.name.."."..forced - else - fullname=specification.name - end - end - return check_tfm(specification,fullname) -end -readers.ofm=readers.tfm - -end -- closure - -do -- begin closure to overcome local limits and interference - if not modules then modules={} end modules ['font-oti']={ version=1.001, comment="companion to font-ini.mkiv", @@ -6984,8 +7992,8 @@ if not modules then modules={} end modules ['font-oti']={ local lower=string.lower local fonts=fonts local constructors=fonts.constructors -local otf=constructors.newhandler("otf") -local otffeatures=constructors.newfeatures("otf") +local otf=constructors.handlers.otf +local otffeatures=constructors.features.otf local registerotffeature=otffeatures.register local otftables=otf.tables or {} otf.tables=otftables @@ -7000,6 +8008,7 @@ local function setmode(tfmdata,value) tfmdata.properties.mode=lower(value) end end +otf.modeinitializer=setmode local function setlanguage(tfmdata,value) if value then local cleanvalue=lower(value) @@ -7034,6 +8043,7 @@ registerotffeature { initializers={ base=setmode, node=setmode, + plug=setmode, } } registerotffeature { @@ -7042,6 +8052,7 @@ registerotffeature { initializers={ base=setlanguage, node=setlanguage, + plug=setlanguage, } } registerotffeature { @@ -7050,6 +8061,7 @@ registerotffeature { initializers={ base=setscript, node=setscript, + plug=setscript, } } otftables.featuretypes=allocate { @@ -7122,21 +8134,20 @@ if not modules then modules={} end modules ['font-otr']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local next,type,unpack=next,type,unpack -local byte,lower,char,strip,gsub=string.byte,string.lower,string.char,string.strip,string.gsub -local bittest=bit32.btest -local concat,remove,unpack,fastcopy=table.concat,table.remov,table.unpack,table.fastcopy -local floor,abs,sqrt,round=math.floor,math.abs,math.sqrt,math.round +local next,type=next,type +local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub +local floor,round=math.floor,math.round local P,R,S,C,Cs,Cc,Ct,Carg,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg,lpeg.Cmt local lpegmatch=lpeg.match local setmetatableindex=table.setmetatableindex local formatters=string.formatters local sortedkeys=table.sortedkeys local sortedhash=table.sortedhash -local stripstring=string.strip +local stripstring=string.nospaces local utf16_to_utf8_be=utf.utf16_to_utf8_be local report=logs.reporter("otf reader") local trace_cmap=false +local trace_cmap_detail=false fonts=fonts or {} local handlers=fonts.handlers or {} fonts.handlers=handlers @@ -7145,10 +8156,11 @@ handlers.otf=otf local readers=otf.readers or {} otf.readers=readers local streamreader=utilities.files +local streamwriter=utilities.files readers.streamreader=streamreader +readers.streamwriter=streamwriter local openfile=streamreader.open local closefile=streamreader.close -local skipbytes=streamreader.skip local setposition=streamreader.setposition local skipshort=streamreader.skipshort local readbytes=streamreader.readbytes @@ -7156,32 +8168,24 @@ local readstring=streamreader.readstring local readbyte=streamreader.readcardinal1 local readushort=streamreader.readcardinal2 local readuint=streamreader.readcardinal3 -local readulong=streamreader.readcardinal4 -local readchar=streamreader.readinteger1 +local readulong=streamreader.readcardinal4 local readshort=streamreader.readinteger2 local readlong=streamreader.readinteger4 local readfixed=streamreader.readfixed4 +local read2dot14=streamreader.read2dot14 local readfword=readshort local readufword=readushort local readoffset=readushort -local read2dot14=streamreader.read2dot14 function streamreader.readtag(f) - return lower(strip(readstring(f,4))) + return lower(stripstring(readstring(f,4))) end local function readlongdatetime(f) local a,b,c,d,e,f,g,h=readbytes(f,8) return 0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h end local tableversion=0.004 -local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 readers.tableversion=tableversion -local reportedskipped={} -local function reportskippedtable(tag) - if not reportedskipped[tag] then - report("loading of table %a skipped (reported once only)",tag) - reportedskipped[tag]=true - end -end +local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 local reservednames={ [0]="copyright", "family", "subfamily", @@ -7207,6 +8211,7 @@ local reservednames={ [0]="copyright", "wwssubfamily", "lightbackgroundpalette", "darkbackgroundpalette", + "variationspostscriptnameprefix", } local platforms={ [0]="unicode", "macintosh", @@ -7372,6 +8377,37 @@ local panosewidths={ [ 8]="verycondensed", [ 9]="monospaced", } +local helpers={} +readers.helpers=helpers +local function gotodatatable(f,fontdata,tag,criterium) + if criterium and f then + local datatable=fontdata.tables[tag] + if datatable then + local tableoffset=datatable.offset + setposition(f,tableoffset) + return tableoffset + end + end +end +local function reportskippedtable(f,fontdata,tag,criterium) + if criterium and f then + local datatable=fontdata.tables[tag] + if datatable then + report("loading of table %a skipped",tag) + end + end +end +local function setvariabledata(fontdata,tag,data) + local variabledata=fontdata.variabledata + if variabledata then + variabledata[tag]=data + else + fontdata.variabledata={ [tag]=data } + end +end +helpers.gotodatatable=gotodatatable +helpers.setvariabledata=setvariabledata +helpers.reportskippedtable=reportskippedtable local platformnames={ postscriptname=true, fullname=true, @@ -7382,13 +8418,12 @@ local platformnames={ compatiblefullname=true, } function readers.name(f,fontdata,specification) - local datatable=fontdata.tables.name - if datatable then - setposition(f,datatable.offset) + local tableoffset=gotodatatable(f,fontdata,"name",true) + if tableoffset then local format=readushort(f) local nofnames=readushort(f) local offset=readushort(f) - local start=datatable.offset+offset + local start=tableoffset+offset local namelists={ unicode={}, windows={}, @@ -7407,19 +8442,17 @@ function readers.name(f,fontdata,specification) local encoding=encodings[encoding] local language=languages[language] if encoding and language then - local name=reservednames[readushort(f)] - if name then - namelist[#namelist+1]={ - platform=platform, - encoding=encoding, - language=language, - name=name, - length=readushort(f), - offset=start+readushort(f), - } - else - skipshort(f,2) - end + local index=readushort(f) + local name=reservednames[index] + namelist[#namelist+1]={ + platform=platform, + encoding=encoding, + language=language, + name=name, + index=index, + length=readushort(f), + offset=start+readushort(f), + } else skipshort(f,3) end @@ -7435,12 +8468,14 @@ function readers.name(f,fontdata,specification) end local names={} local done={} + local extras={} local function filter(platform,e,l) local namelist=namelists[platform] for i=1,#namelist do local name=namelist[i] local nametag=name.name - if not done[nametag] then + local index=name.index + if not done[nametag or i] then local encoding=name.encoding local language=name.language if (not e or encoding==e) and (not l or language==l) then @@ -7453,13 +8488,16 @@ function readers.name(f,fontdata,specification) if decoder then content=decoder(content) end - names[nametag]={ - content=content, - platform=platform, - encoding=encoding, - language=language, - } - done[nametag]=true + if nametag then + names[nametag]={ + content=content, + platform=platform, + encoding=encoding, + language=language, + } + end + extras[index]=content + done[nametag or i]=true end end end @@ -7470,6 +8508,7 @@ function readers.name(f,fontdata,specification) filter("macintosh") filter("unicode") fontdata.names=names + fontdata.extras=extras if specification.platformnames then local collected={} for platform,namelist in next,namelists do @@ -7517,9 +8556,8 @@ local function getname(fontdata,key) end end readers["os/2"]=function(f,fontdata) - local datatable=fontdata.tables["os/2"] - if datatable then - setposition(f,datatable.offset) + local tableoffset=gotodatatable(f,fontdata,"os/2",true) + if tableoffset then local version=readushort(f) local windowsmetrics={ version=version, @@ -7569,9 +8607,8 @@ readers["os/2"]=function(f,fontdata) end end readers.head=function(f,fontdata) - local datatable=fontdata.tables.head - if datatable then - setposition(f,datatable.offset) + local tableoffset=gotodatatable(f,fontdata,"head",true) + if tableoffset then local fontheader={ version=readfixed(f), revision=readfixed(f), @@ -7598,108 +8635,155 @@ readers.head=function(f,fontdata) fontdata.nofglyphs=0 end readers.hhea=function(f,fontdata,specification) - if specification.details then - local datatable=fontdata.tables.hhea - if datatable then - setposition(f,datatable.offset) - fontdata.horizontalheader={ - version=readfixed(f), - ascender=readfword(f), - descender=readfword(f), - linegap=readfword(f), - maxadvancewidth=readufword(f), - minleftsidebearing=readfword(f), - minrightsidebearing=readfword(f), - maxextent=readfword(f), - caretsloperise=readshort(f), - caretsloperun=readshort(f), - caretoffset=readshort(f), - reserved_1=readshort(f), - reserved_2=readshort(f), - reserved_3=readshort(f), - reserved_4=readshort(f), - metricdataformat=readshort(f), - nofhmetrics=readushort(f), + local tableoffset=gotodatatable(f,fontdata,"hhea",specification.details) + if tableoffset then + fontdata.horizontalheader={ + version=readfixed(f), + ascender=readfword(f), + descender=readfword(f), + linegap=readfword(f), + maxadvancewidth=readufword(f), + minleftsidebearing=readfword(f), + minrightsidebearing=readfword(f), + maxextent=readfword(f), + caretsloperise=readshort(f), + caretsloperun=readshort(f), + caretoffset=readshort(f), + reserved_1=readshort(f), + reserved_2=readshort(f), + reserved_3=readshort(f), + reserved_4=readshort(f), + metricdataformat=readshort(f), + nofmetrics=readushort(f), + } + else + fontdata.horizontalheader={ + nofmetrics=0, + } + end +end +readers.vhea=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"vhea",specification.details) + if tableoffset then + fontdata.verticalheader={ + version=readfixed(f), + ascender=readfword(f), + descender=readfword(f), + linegap=readfword(f), + maxadvanceheight=readufword(f), + mintopsidebearing=readfword(f), + minbottomsidebearing=readfword(f), + maxextent=readfword(f), + caretsloperise=readshort(f), + caretsloperun=readshort(f), + caretoffset=readshort(f), + reserved_1=readshort(f), + reserved_2=readshort(f), + reserved_3=readshort(f), + reserved_4=readshort(f), + metricdataformat=readshort(f), + nofmetrics=readushort(f), + } + else + fontdata.verticalheader={ + nofmetrics=0, + } + end +end +readers.maxp=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"maxp",specification.details) + if tableoffset then + local version=readfixed(f) + local nofglyphs=readushort(f) + fontdata.nofglyphs=nofglyphs + if version==0.5 then + fontdata.maximumprofile={ + version=version, + nofglyphs=nofglyphs, + } + elseif version==1.0 then + fontdata.maximumprofile={ + version=version, + nofglyphs=nofglyphs, + points=readushort(f), + contours=readushort(f), + compositepoints=readushort(f), + compositecontours=readushort(f), + zones=readushort(f), + twilightpoints=readushort(f), + storage=readushort(f), + functiondefs=readushort(f), + instructiondefs=readushort(f), + stackelements=readushort(f), + sizeofinstructions=readushort(f), + componentelements=readushort(f), + componentdepth=readushort(f), } else - fontdata.horizontalheader={ - nofhmetrics=0, + fontdata.maximumprofile={ + version=version, + nofglyphs=0, } end end end -readers.maxp=function(f,fontdata,specification) - if specification.details then - local datatable=fontdata.tables.maxp - if datatable then - setposition(f,datatable.offset) - local version=readfixed(f) - local nofglyphs=readushort(f) - fontdata.nofglyphs=nofglyphs - if version==0.5 then - fontdata.maximumprofile={ - version=version, - nofglyphs=nofglyphs, - } - return - elseif version==1.0 then - fontdata.maximumprofile={ - version=version, - nofglyphs=nofglyphs, - points=readushort(f), - contours=readushort(f), - compositepoints=readushort(f), - compositecontours=readushort(f), - zones=readushort(f), - twilightpoints=readushort(f), - storage=readushort(f), - functiondefs=readushort(f), - instructiondefs=readushort(f), - stackelements=readushort(f), - sizeofinstructions=readushort(f), - componentelements=readushort(f), - componentdepth=readushort(f), - } - return +readers.hmtx=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"hmtx",specification.glyphs) + if tableoffset then + local horizontalheader=fontdata.horizontalheader + local nofmetrics=horizontalheader.nofmetrics + local glyphs=fontdata.glyphs + local nofglyphs=fontdata.nofglyphs + local width=0 + local leftsidebearing=0 + for i=0,nofmetrics-1 do + local glyph=glyphs[i] + width=readshort(f) + leftsidebearing=readshort(f) + if width~=0 then + glyph.width=width + end + end + for i=nofmetrics,nofglyphs-1 do + local glyph=glyphs[i] + if width~=0 then + glyph.width=width end end - fontdata.maximumprofile={ - version=version, - nofglyphs=0, - } end end -readers.hmtx=function(f,fontdata,specification) - if specification.glyphs then - local datatable=fontdata.tables.hmtx - if datatable then - setposition(f,datatable.offset) - local nofmetrics=fontdata.horizontalheader.nofhmetrics - local glyphs=fontdata.glyphs - local nofglyphs=fontdata.nofglyphs - local width=0 - local leftsidebearing=0 - for i=0,nofmetrics-1 do - local glyph=glyphs[i] - width=readshort(f) - leftsidebearing=readshort(f) - if width~=0 then - glyph.width=width - end +readers.vmtx=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"vmtx",specification.glyphs) + if tableoffset then + local verticalheader=fontdata.verticalheader + local nofmetrics=verticalheader.nofmetrics + local glyphs=fontdata.glyphs + local nofglyphs=fontdata.nofglyphs + local vheight=0 + local vdefault=verticalheader.ascender+verticalheader.descender + local topsidebearing=0 + for i=0,nofmetrics-1 do + local glyph=glyphs[i] + vheight=readshort(f) + topsidebearing=readshort(f) + if vheight~=0 and vheight~=vdefault then + glyph.vheight=vheight end - for i=nofmetrics,nofglyphs-1 do - local glyph=glyphs[i] - if width~=0 then - glyph.width=width - end + end + for i=nofmetrics,nofglyphs-1 do + local glyph=glyphs[i] + if vheight~=0 and vheight~=vdefault then + glyph.vheight=vheight end end end end +readers.vorg=function(f,fontdata,specification) + reportskippedtable(f,fontdata,"vorg",specification.glyphs) +end readers.post=function(f,fontdata,specification) - local datatable=fontdata.tables.post - if datatable then - setposition(f,datatable.offset) + local tableoffset=gotodatatable(f,fontdata,"post",true) + if tableoffset then local version=readfixed(f) fontdata.postscript={ version=version, @@ -7756,9 +8840,7 @@ readers.post=function(f,fontdata,specification) end end readers.cff=function(f,fontdata,specification) - if specification.glyphs then - reportskippedtable("cff") - end + reportskippedtable(f,fontdata,"cff",specification.glyphs) end local formatreaders={} local duplicatestoo=true @@ -7770,11 +8852,13 @@ local sequence={ { 0,0,6 }, { 3,0,6 }, { 0,5,14 }, +{ 0,4,12 }, { 3,10,13 }, } local supported={} for i=1,#sequence do - local sp,se,sf=unpack(sequence[i]) + local si=sequence[i] + local sp,se,sf=si[1],si[2],si[3] local p=supported[sp] if not p then p={} @@ -7828,7 +8912,7 @@ formatreaders[4]=function(f,fontdata,offset) elseif startchar==0xFFFF and offset==0 then elseif offset==0xFFFF then elseif offset==0 then - if trace_cmap then + if trace_cmap_detail then report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar+delta)%65536) end for unicode=startchar,endchar do @@ -7860,7 +8944,7 @@ formatreaders[4]=function(f,fontdata,offset) end else local shift=(segment-nofsegments+offset/2)-startchar - if trace_cmap then + if trace_cmap_detail then report("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar+delta)%65536) end for unicode=startchar,endchar do @@ -7908,7 +8992,7 @@ formatreaders[6]=function(f,fontdata,offset) local count=readushort(f) local stop=start+count-1 local nofdone=0 - if trace_cmap then + if trace_cmap_detail then report("format 6 from %C to %C",2,start,stop) end for unicode=start,stop do @@ -7941,7 +9025,7 @@ formatreaders[12]=function(f,fontdata,offset) local first=readulong(f) local last=readulong(f) local index=readulong(f) - if trace_cmap then + if trace_cmap_detail then report("format 12 from %C to %C starts at index %i",first,last,index) end for unicode=first,last do @@ -7980,7 +9064,7 @@ formatreaders[13]=function(f,fontdata,offset) local last=readulong(f) local index=readulong(f) if first<privateoffset then - if trace_cmap then + if trace_cmap_detail then report("format 13 from %C to %C get index %i",first,last,index) end local glyph=glyphs[index] @@ -8070,75 +9154,81 @@ local function checkcmap(f,fontdata,records,platform,encoding,format) local p=platforms[platform] local e=encodings[p] local n=reader(f,fontdata,data) or 0 - report("cmap checked: platform %i (%s), encoding %i (%s), format %i, new unicodes %i",platform,p,encoding,e and e[encoding] or "?",format,n) + if trace_cmap then + report("cmap checked: platform %i (%s), encoding %i (%s), format %i, new unicodes %i",platform,p,encoding,e and e[encoding] or "?",format,n) + end return n end function readers.cmap(f,fontdata,specification) - if specification.glyphs then - local datatable=fontdata.tables.cmap - if datatable then - local tableoffset=datatable.offset - setposition(f,tableoffset) - local version=readushort(f) - local noftables=readushort(f) - local records={} - local unicodecid=false - local variantcid=false - local variants={} - local duplicates=fontdata.duplicates or {} - fontdata.duplicates=duplicates - for i=1,noftables do - local platform=readushort(f) - local encoding=readushort(f) - local offset=readulong(f) - local record=records[platform] - if not record then - records[platform]={ - [encoding]={ - offsets={ offset }, - formats={}, - } + local tableoffset=gotodatatable(f,fontdata,"cmap",specification.glyphs) + if tableoffset then + local version=readushort(f) + local noftables=readushort(f) + local records={} + local unicodecid=false + local variantcid=false + local variants={} + local duplicates=fontdata.duplicates or {} + fontdata.duplicates=duplicates + for i=1,noftables do + local platform=readushort(f) + local encoding=readushort(f) + local offset=readulong(f) + local record=records[platform] + if not record then + records[platform]={ + [encoding]={ + offsets={ offset }, + formats={}, + } + } + else + local subtables=record[encoding] + if not subtables then + record[encoding]={ + offsets={ offset }, + formats={}, } else - local subtables=record[encoding] - if not subtables then - record[encoding]={ - offsets={ offset }, - formats={}, - } - else - local offsets=subtables.offsets - offsets[#offsets+1]=offset - end + local offsets=subtables.offsets + offsets[#offsets+1]=offset end end + end + if trace_cmap then report("found cmaps:") - for platform,record in sortedhash(records) do - local p=platforms[platform] - local e=encodings[p] - local sp=supported[platform] - local ps=p or "?" + end + for platform,record in sortedhash(records) do + local p=platforms[platform] + local e=encodings[p] + local sp=supported[platform] + local ps=p or "?" + if trace_cmap then if sp then report(" platform %i: %s",platform,ps) else report(" platform %i: %s (unsupported)",platform,ps) end - for encoding,subtables in sortedhash(record) do - local se=sp and sp[encoding] - local es=e and e[encoding] or "?" + end + for encoding,subtables in sortedhash(record) do + local se=sp and sp[encoding] + local es=e and e[encoding] or "?" + if trace_cmap then if se then report(" encoding %i: %s",encoding,es) else report(" encoding %i: %s (unsupported)",encoding,es) end - local offsets=subtables.offsets - local formats=subtables.formats - for i=1,#offsets do - local offset=tableoffset+offsets[i] - setposition(f,offset) - formats[readushort(f)]=offset - end - record[encoding]=formats + end + local offsets=subtables.offsets + local formats=subtables.formats + for i=1,#offsets do + local offset=tableoffset+offsets[i] + setposition(f,offset) + formats[readushort(f)]=offset + end + record[encoding]=formats + if trace_cmap then local list=sortedkeys(formats) for i=1,#list do if not (se and se[list[i]]) then @@ -8148,203 +9238,110 @@ function readers.cmap(f,fontdata,specification) report(" formats: % t",list) end end - local ok=false - for i=1,#sequence do - local sp,se,sf=unpack(sequence[i]) - if checkcmap(f,fontdata,records,sp,se,sf)>0 then - ok=true - end - end - if not ok then - report("no useable unicode cmap found") + end + local ok=false + for i=1,#sequence do + local si=sequence[i] + local sp,se,sf=si[1],si[2],si[3] + if checkcmap(f,fontdata,records,sp,se,sf)>0 then + ok=true end - fontdata.cidmaps={ - version=version, - noftables=noftables, - records=records, - } - else - fontdata.cidmaps={} end + if not ok then + report("no useable unicode cmap found") + end + fontdata.cidmaps={ + version=version, + noftables=noftables, + records=records, + } + else + fontdata.cidmaps={} end end function readers.loca(f,fontdata,specification) - if specification.glyphs then - reportskippedtable("loca") - end + reportskippedtable(f,fontdata,"loca",specification.glyphs) end function readers.glyf(f,fontdata,specification) - if specification.glyphs then - reportskippedtable("glyf") - end + reportskippedtable(f,fontdata,"glyf",specification.glyphs) +end +function readers.colr(f,fontdata,specification) + reportskippedtable(f,fontdata,"colr",specification.glyphs) +end +function readers.cpal(f,fontdata,specification) + reportskippedtable(f,fontdata,"cpal",specification.glyphs) +end +function readers.svg(f,fontdata,specification) + reportskippedtable(f,fontdata,"svg",specification.glyphs) +end +function readers.sbix(f,fontdata,specification) + reportskippedtable(f,fontdata,"sbix",specification.glyphs) +end +function readers.cbdt(f,fontdata,specification) + reportskippedtable(f,fontdata,"cbdt",specification.glyphs) +end +function readers.cblc(f,fontdata,specification) + reportskippedtable(f,fontdata,"cblc",specification.glyphs) +end +function readers.ebdt(f,fontdata,specification) + reportskippedtable(f,fontdata,"ebdt",specification.glyphs) +end +function readers.ebsc(f,fontdata,specification) + reportskippedtable(f,fontdata,"ebsc",specification.glyphs) +end +function readers.eblc(f,fontdata,specification) + reportskippedtable(f,fontdata,"eblc",specification.glyphs) end function readers.kern(f,fontdata,specification) - if specification.kerns then - local datatable=fontdata.tables.kern - if datatable then - setposition(f,datatable.offset) + local tableoffset=gotodatatable(f,fontdata,"kern",specification.kerns) + if tableoffset then + local version=readushort(f) + local noftables=readushort(f) + for i=1,noftables do local version=readushort(f) - local noftables=readushort(f) - for i=1,noftables do - local version=readushort(f) - local length=readushort(f) - local coverage=readushort(f) - local format=bit32.rshift(coverage,8) - if format==0 then - local nofpairs=readushort(f) - local searchrange=readushort(f) - local entryselector=readushort(f) - local rangeshift=readushort(f) - local kerns={} - local glyphs=fontdata.glyphs - for i=1,nofpairs do - local left=readushort(f) - local right=readushort(f) - local kern=readfword(f) - local glyph=glyphs[left] - local kerns=glyph.kerns - if kerns then - kerns[right]=kern - else - glyph.kerns={ [right]=kern } - end + local length=readushort(f) + local coverage=readushort(f) + local format=bit32.rshift(coverage,8) + if format==0 then + local nofpairs=readushort(f) + local searchrange=readushort(f) + local entryselector=readushort(f) + local rangeshift=readushort(f) + local kerns={} + local glyphs=fontdata.glyphs + for i=1,nofpairs do + local left=readushort(f) + local right=readushort(f) + local kern=readfword(f) + local glyph=glyphs[left] + local kerns=glyph.kerns + if kerns then + kerns[right]=kern + else + glyph.kerns={ [right]=kern } end - elseif format==2 then - report("todo: kern classes") - else - report("todo: kerns") end + elseif format==2 then + report("todo: kern classes") + else + report("todo: kerns") end end end end function readers.gdef(f,fontdata,specification) - if specification.details then - reportskippedtable("gdef") - end + reportskippedtable(f,fontdata,"gdef",specification.details) end function readers.gsub(f,fontdata,specification) - if specification.details then - reportskippedtable("gsub") - end + reportskippedtable(f,fontdata,"gsub",specification.details) end function readers.gpos(f,fontdata,specification) - if specification.details then - reportskippedtable("gpos") - end + reportskippedtable(f,fontdata,"gpos",specification.details) end function readers.math(f,fontdata,specification) - if specification.glyphs then - reportskippedtable("math") - end -end -local function packoutlines(data,makesequence) - local subfonts=data.subfonts - if subfonts then - for i=1,#subfonts do - packoutlines(subfonts[i],makesequence) - end - return - end - local common=data.segments - if common then - return - end - local glyphs=data.glyphs - if not glyphs then - return - end - if makesequence then - for index=1,#glyphs do - local glyph=glyphs[index] - local segments=glyph.segments - if segments then - local sequence={} - local nofsequence=0 - for i=1,#segments do - local segment=segments[i] - local nofsegment=#segment - nofsequence=nofsequence+1 - sequence[nofsequence]=segment[nofsegment] - for i=1,nofsegment-1 do - nofsequence=nofsequence+1 - sequence[nofsequence]=segment[i] - end - end - glyph.sequence=sequence - glyph.segments=nil - end - end - else - local hash={} - local common={} - local reverse={} - local last=0 - for index=1,#glyphs do - local segments=glyphs[index].segments - if segments then - for i=1,#segments do - local h=concat(segments[i]," ") - hash[h]=(hash[h] or 0)+1 - end - end - end - for index=1,#glyphs do - local segments=glyphs[index].segments - if segments then - for i=1,#segments do - local segment=segments[i] - local h=concat(segment," ") - if hash[h]>1 then - local idx=reverse[h] - if not idx then - last=last+1 - reverse[h]=last - common[last]=segment - idx=last - end - segments[i]=idx - end - end - end - end - if last>0 then - data.segments=common - end - end -end -local function unpackoutlines(data) - local subfonts=data.subfonts - if subfonts then - for i=1,#subfonts do - unpackoutlines(subfonts[i]) - end - return - end - local common=data.segments - if not common then - return - end - local glyphs=data.glyphs - if not glyphs then - return - end - for index=1,#glyphs do - local segments=glyphs[index].segments - if segments then - for i=1,#segments do - local c=common[segments[i]] - if c then - segments[i]=c - end - end - end - end - data.segments=nil + reportskippedtable(f,fontdata,"math",specification.details) end -otf.packoutlines=packoutlines -otf.unpackoutlines=unpackoutlines -local function getinfo(maindata,sub,platformnames,rawfamilynames) +local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,instancenames) local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata local names=fontdata.names local info=nil @@ -8354,8 +9351,8 @@ local function getinfo(maindata,sub,platformnames,rawfamilynames) local fontheader=fontdata.fontheader or {} local cffinfo=fontdata.cffinfo or {} local filename=fontdata.filename - local weight=getname(fontdata,"weight") or cffinfo.weight or metrics.weight - local width=getname(fontdata,"width") or cffinfo.width or metrics.width + local weight=getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight) + local width=getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width ) local fontname=getname(fontdata,"postscriptname") local fullname=getname(fontdata,"fullname") local family=getname(fontdata,"family") @@ -8368,6 +9365,25 @@ local function getinfo(maindata,sub,platformnames,rawfamilynames) if not familyname then familyname=family end if not subfamilyname then subfamilyname=subfamily end end + if platformnames then + platformnames=fontdata.platformnames + end + if instancenames then + local variabledata=fontdata.variabledata + if variabledata then + local instances=variabledata and variabledata.instances + if instances then + instancenames={} + for i=1,#instances do + instancenames[i]=lower(stripstring(instances[i].subfamily)) + end + else + instancenames=nil + end + else + instancenames=nil + end + end info={ subfontindex=fontdata.subfontindex or sub or 0, version=getname(fontdata,"version"), @@ -8395,8 +9411,30 @@ local function getinfo(maindata,sub,platformnames,rawfamilynames) capheight=metrics.capheight, ascender=metrics.typoascender, descender=metrics.typodescender, - platformnames=platformnames and fontdata.platformnames or nil, + platformnames=platformnames or nil, + instancenames=instancenames or nil, } + if metricstoo then + local keys={ + "version", + "ascender","descender","linegap", + "maxadvancewidth","maxadvanceheight","maxextent", + "minbottomsidebearing","mintopsidebearing", + } + local h=fontdata.horizontalheader or {} + local v=fontdata.verticalheader or {} + if h then + local th={} + local tv={} + for i=1,#keys do + local key=keys[i] + th[key]=h[key] or 0 + tv[key]=v[key] or 0 + end + info.horizontalmetrics=th + info.verticalmetrics=tv + end + end elseif n then info={ filename=fontdata.filename, @@ -8428,6 +9466,7 @@ local function loadtables(f,specification,offset) entryselector=readushort(f), rangeshift=readushort(f), tables=tables, + foundtables=false, } for i=1,fontdata.noftables do local tag=lower(stripstring(readstring(f,4))) @@ -8443,7 +9482,8 @@ local function loadtables(f,specification,offset) length=length, } end - if tables.cff then + fontdata.foundtables=sortedkeys(tables) + if tables.cff or tables.cff2 then fontdata.format="opentype" else fontdata.format="truetype" @@ -8461,12 +9501,25 @@ local function prepareglyps(fontdata) fontdata.glyphs=glyphs fontdata.mapping={} end +local function readtable(tag,f,fontdata,specification,...) + local reader=readers[tag] + if reader then + reader(f,fontdata,specification,...) + end +end +local variablefonts_supported=(context and true) or (logs and logs.application and true) or false local function readdata(f,offset,specification) local fontdata=loadtables(f,specification,offset) if specification.glyphs then prepareglyps(fontdata) end - readers["name"](f,fontdata,specification) + if not variablefonts_supported then + specification.instance=nil + specification.variable=nil + specification.factors=nil + end + fontdata.temporary={} + readtable("name",f,fontdata,specification) local askedname=specification.askedname if askedname then local fullname=getname(fontdata,"fullname") or "" @@ -8476,21 +9529,98 @@ local function readdata(f,offset,specification) return end end - readers["os/2"](f,fontdata,specification) - readers["head"](f,fontdata,specification) - readers["maxp"](f,fontdata,specification) - readers["hhea"](f,fontdata,specification) - readers["hmtx"](f,fontdata,specification) - readers["post"](f,fontdata,specification) - readers["cff" ](f,fontdata,specification) - readers["cmap"](f,fontdata,specification) - readers["loca"](f,fontdata,specification) - readers["glyf"](f,fontdata,specification) - readers["kern"](f,fontdata,specification) - readers["gdef"](f,fontdata,specification) - readers["gsub"](f,fontdata,specification) - readers["gpos"](f,fontdata,specification) - readers["math"](f,fontdata,specification) + readtable("stat",f,fontdata,specification) + readtable("avar",f,fontdata,specification) + readtable("fvar",f,fontdata,specification) + if variablefonts_supported then + local variabledata=fontdata.variabledata + if variabledata then + local instances=variabledata.instances + local axis=variabledata.axis + if axis and (not instances or #instances==0) then + instances={} + variabledata.instances=instances + local function add(n,subfamily,value) + local values={} + for i=1,#axis do + local a=axis[i] + values[i]={ + axis=a.tag, + value=i==n and value or a.default, + } + end + instances[#instances+1]={ + subfamily=subfamily, + values=values, + } + end + for i=1,#axis do + local a=axis[i] + local tag=a.tag + add(i,"default"..tag,a.default) + add(i,"minimum"..tag,a.minimum) + add(i,"maximum"..tag,a.maximum) + end + end + end + if not specification.factors then + local instance=specification.instance + if type(instance)=="string" then + local factors=helpers.getfactors(fontdata,instance) + if factors then + specification.factors=factors + fontdata.factors=factors + fontdata.instance=instance + report("user instance: %s, factors: % t",instance,factors) + else + report("user instance: %s, bad factors",instance) + end + end + end + if not fontdata.factors then + if fontdata.variabledata then + local factors=helpers.getfactors(fontdata,true) + if factors then + specification.factors=factors + fontdata.factors=factors + report("factors: % t",factors) + else + report("bad factors") + end + else + end + end + end + readtable("os/2",f,fontdata,specification) + readtable("head",f,fontdata,specification) + readtable("maxp",f,fontdata,specification) + readtable("hhea",f,fontdata,specification) + readtable("vhea",f,fontdata,specification) + readtable("hmtx",f,fontdata,specification) + readtable("vmtx",f,fontdata,specification) + readtable("vorg",f,fontdata,specification) + readtable("post",f,fontdata,specification) + readtable("mvar",f,fontdata,specification) + readtable("hvar",f,fontdata,specification) + readtable("vvar",f,fontdata,specification) + readtable("gdef",f,fontdata,specification) + readtable("cff",f,fontdata,specification) + readtable("cff2",f,fontdata,specification) + readtable("cmap",f,fontdata,specification) + readtable("loca",f,fontdata,specification) + readtable("glyf",f,fontdata,specification) + readtable("colr",f,fontdata,specification) + readtable("cpal",f,fontdata,specification) + readtable("svg",f,fontdata,specification) + readtable("sbix",f,fontdata,specification) + readtable("cbdt",f,fontdata,specification) + readtable("cblc",f,fontdata,specification) + readtable("ebdt",f,fontdata,specification) + readtable("eblc",f,fontdata,specification) + readtable("kern",f,fontdata,specification) + readtable("gsub",f,fontdata,specification) + readtable("gpos",f,fontdata,specification) + readtable("math",f,fontdata,specification) fontdata.locations=nil fontdata.tables=nil fontdata.cidmaps=nil @@ -8567,7 +9697,7 @@ local function loadfontdata(specification) return fontdata or {} end end -local function loadfont(specification,n) +local function loadfont(specification,n,instance) if type(specification)=="string" then specification={ filename=specification, @@ -8576,10 +9706,12 @@ local function loadfont(specification,n) glyphs=true, shapes=true, kerns=true, + variable=true, globalkerns=true, lookups=true, subfont=n or true, tounicode=false, + instance=instance } end if specification.shapes or specification.lookups or specification.kerns then @@ -8594,6 +9726,10 @@ local function loadfont(specification,n) if specification.platformnames then specification.platformnames=true end + if specification.instance or instance then + specification.variable=true + specification.instance=specification.instance or instance + end local function message(str) report("fatal error in file %a: %s\n%s",specification.filename,str,debug.traceback()) end @@ -8602,12 +9738,22 @@ local function loadfont(specification,n) return result end end -function readers.loadshapes(filename,n) +function readers.loadshapes(filename,n,instance,streams) local fontdata=loadfont { filename=filename, shapes=true, + streams=streams, + variable=true, subfont=n, + instance=instance, } + if fontdata then + for k,v in next,fontdata.glyphs do + v.class=nil + v.index=nil + v.math=nil + end + end return fontdata and { filename=filename, format=fontdata.format, @@ -8620,13 +9766,15 @@ function readers.loadshapes(filename,n) units=0, } end -function readers.loadfont(filename,n) +function readers.loadfont(filename,n,instance) local fontdata=loadfont { filename=filename, glyphs=true, shapes=false, lookups=true, + variable=true, subfont=n, + instance=instance, } if fontdata then return { @@ -8638,9 +9786,13 @@ function readers.loadfont(filename,n) descriptions=fontdata.descriptions, format=fontdata.format, goodies={}, - metadata=getinfo(fontdata,n), + metadata=getinfo(fontdata,n,false,false,true,true), properties={ hasitalics=fontdata.hasitalics or false, + maxcolorclass=fontdata.maxcolorclass, + hascolor=fontdata.hascolor or false, + instance=fontdata.instance, + factors=fontdata.factors, }, resources={ filename=filename, @@ -8656,6 +9808,11 @@ function readers.loadfont(filename,n) version=getname(fontdata,"version"), cidinfo=fontdata.cidinfo, mathconstants=fontdata.mathconstants, + colorpalettes=fontdata.colorpalettes, + svgshapes=fontdata.svgshapes, + sbixshapes=fontdata.sbixshapes, + variabledata=fontdata.variabledata, + foundtables=fontdata.foundtables, }, } end @@ -8664,6 +9821,7 @@ function readers.getinfo(filename,specification) local subfont=nil local platformnames=false local rawfamilynames=false + local instancenames=true if type(specification)=="table" then subfont=tonumber(specification.subfont) platformnames=specification.platformnames @@ -8675,19 +9833,20 @@ function readers.getinfo(filename,specification) filename=filename, details=true, platformnames=platformnames, + instancenames=true, } if fontdata then local subfonts=fontdata.subfonts if not subfonts then - return getinfo(fontdata,nil,platformnames,rawfamilynames) + return getinfo(fontdata,nil,platformnames,rawfamilynames,false,instancenames) elseif not subfont then local info={} for i=1,#subfonts do - info[i]=getinfo(fontdata,i,platformnames,rawfamilynames) + info[i]=getinfo(fontdata,i,platformnames,rawfamilynames,false,instancenames) end return info elseif subfont>=1 and subfont<=#subfonts then - return getinfo(fontdata,subfont,platformnames,rawfamilynames) + return getinfo(fontdata,subfont,platformnames,rawfamilynames,false,instancenames) else return { filename=filename, @@ -8733,56 +9892,6 @@ function readers.extend(fontdata) end end end -if fonts.hashes then - local identifiers=fonts.hashes.identifiers - local loadshapes=readers.loadshapes - readers.version=0.006 - readers.cache=containers.define("fonts","shapes",readers.version,true) - local function load(filename,sub) - local base=file.basename(filename) - local name=file.removesuffix(base) - local kind=file.suffix(filename) - local attr=lfs.attributes(filename) - local size=attr and attr.size or 0 - local time=attr and attr.modification or 0 - local sub=tonumber(sub) - if size>0 and (kind=="otf" or kind=="ttf" or kind=="tcc") then - local hash=containers.cleanname(base) - if sub then - hash=hash.."-"..sub - end - data=containers.read(readers.cache,hash) - if not data or data.time~=time or data.size~=size then - data=loadshapes(filename,sub) - if data then - data.size=size - data.format=data.format or (kind=="otf" and "opentype") or "truetype" - data.time=time - packoutlines(data) - containers.write(readers.cache,hash,data) - data=containers.read(readers.cache,hash) - end - end - unpackoutlines(data) - else - data={ - filename=filename, - size=0, - time=time, - format="unknown", - units=1000, - glyphs={} - } - end - return data - end - fonts.hashes.shapes=table.setmetatableindex(function(t,k) - local d=identifiers[k] - local v=load(d.properties.filename,d.subindex) - t[k]=v - return v - end) -end end -- closure @@ -8796,14 +9905,15 @@ if not modules then modules={} end modules ['font-cff']={ license="see context related readme files" } local next,type,tonumber=next,type,tonumber -local byte=string.byte +local byte,char,gmatch=string.byte,string.char,string.gmatch local concat,remove=table.concat,table.remove -local floor,abs,round,ceil=math.floor,math.abs,math.round,math.ceil +local floor,abs,round,ceil,min,max=math.floor,math.abs,math.round,math.ceil,math.min,math.max local P,C,R,S,C,Cs,Ct=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Ct local lpegmatch=lpeg.match +local formatters=string.formatters +local bytetable=string.bytetable local readers=fonts.handlers.otf.readers local streamreader=readers.streamreader -local readbytes=streamreader.readbytes local readstring=streamreader.readstring local readbyte=streamreader.readcardinal1 local readushort=streamreader.readcardinal2 @@ -8811,6 +9921,7 @@ local readuint=streamreader.readcardinal3 local readulong=streamreader.readcardinal4 local setposition=streamreader.setposition local getposition=streamreader.getposition +local readbytetable=streamreader.readbytetable local setmetatableindex=table.setmetatableindex local trace_charstrings=false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings=v end) local report=logs.reporter("otf reader","cff") @@ -8819,6 +9930,8 @@ local parsecharstring local parsecharstrings local resetcharstrings local parseprivates +local startparsing +local stopparsing local defaultstrings={ [0]= ".notdef","space","exclam","quotedbl","numbersign","dollar","percent", "ampersand","quoteright","parenleft","parenright","asterisk","plus", @@ -8894,18 +10007,24 @@ local cffreaders={ } local function readheader(f) local offset=getposition(f) + local major=readbyte(f) local header={ offset=offset, - major=readbyte(f), + major=major, minor=readbyte(f), size=readbyte(f), - osize=readbyte(f), } + if major==1 then + header.dsize=readbyte(f) + elseif major==2 then + header.dsize=readushort(f) + else + end setposition(f,offset+header.size) return header end -local function readlengths(f) - local count=readushort(f) +local function readlengths(f,longcount) + local count=longcount and readulong(f) or readushort(f) if count==0 then return {} end @@ -8919,7 +10038,12 @@ local function readlengths(f) local previous=read(f) for i=1,count do local offset=read(f) - lengths[i]=offset-previous + local length=offset-previous + if length<0 then + report("bad offset: %i",length) + length=0 + end + lengths[i]=length previous=offset end return lengths @@ -8984,7 +10108,7 @@ do end+P("\16")/function() result.encoding=stack[top] top=0 - end+P("\17")/function() + end+P("\17")/function() result.charstrings=stack[top] top=0 end+P("\18")/function() @@ -8995,10 +10119,20 @@ do top=0 end+P("\19")/function() result.subroutines=stack[top] + top=0 end+P("\20")/function() result.defaultwidthx=stack[top] + top=0 end+P("\21")/function() result.nominalwidthx=stack[top] + top=0 + end ++P("\24")/function() + result.vstore=stack[top] + top=0 + end+P("\25")/function() + result.maxstack=stack[top] + top=0 end local p_double=P("\12")*( P("\00")/function() @@ -9022,7 +10156,7 @@ do end+P("\06")/function() result.charstringtype=stack[top] top=0 - end+P("\07")/function() + end+P("\07")/function() result.fontmatrix={ unpack(stack,1,6) } top=0 end+P("\08")/function() @@ -9060,10 +10194,10 @@ do end+P("\35")/function() result.cid.uidbase=stack[top] top=0 - end+P("\36")/function() + end+P("\36")/function() result.cid.fdarray=stack[top] top=0 - end+P("\37")/function() + end+P("\37")/function() result.cid.fdselect=stack[top] top=0 end+P("\38")/function() @@ -9128,12 +10262,12 @@ do local p_dictionary=( p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported )^1 - parsedictionaries=function(data,dictionaries) + parsedictionaries=function(data,dictionaries,what) stack={} strings=data.strings for i=1,#dictionaries do top=0 - result={ + result=what=="cff" and { monospaced=false, italicangle=0, underlineposition=-100, @@ -9151,6 +10285,12 @@ do fonttype=0, count=8720, } + } or { + charstringtype=2, + charset=0, + vstore=0, + cid={ + }, } lpegmatch(p_dictionary,dictionaries[i]) dictionaries[i]=result @@ -9192,6 +10332,9 @@ do local stems=0 local globalbias=0 local localbias=0 + local nominalwidth=0 + local defaultwidth=0 + local charset=false local globals=false local locals=false local depth=1 @@ -9201,6 +10344,13 @@ do local ymax=0 local checked=false local keepcurve=false + local version=2 + local regions=false + local nofregions=0 + local region=false + local factors=false + local axis=false + local vsindex=0 local function showstate(where) report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top) end @@ -9211,14 +10361,14 @@ do report("%w%-10s : %s",depth*2,where,tostring(value)) end end - local function moveto(x,y) + local function xymoveto() if keepcurve then r=r+1 result[r]={ x,y,"m" } end if checked then - if x<xmin then xmin=x elseif x>xmax then xmax=x end - if y<ymin then ymin=y elseif y>ymax then ymax=y end + if x>xmax then xmax=x elseif x<xmin then xmin=x end + if y>ymax then ymax=y elseif y<ymin then ymin=y end else xmin=x ymin=y @@ -9227,14 +10377,55 @@ do checked=true end end - local function lineto(x,y) + local function xmoveto() + if keepcurve then + r=r+1 + result[r]={ x,y,"m" } + end + if not checked then + xmin=x + ymin=y + xmax=x + ymax=y + checked=true + elseif x>xmax then + xmax=x + elseif x<xmin then + xmin=x + end + end + local function ymoveto() + if keepcurve then + r=r+1 + result[r]={ x,y,"m" } + end + if not checked then + xmin=x + ymin=y + xmax=x + ymax=y + checked=true + elseif y>ymax then + ymax=y + elseif y<ymin then + ymin=y + end + end + local function moveto() + if trace_charstrings then + showstate("moveto") + end + top=0 + xymoveto() + end + local function xylineto() if keepcurve then r=r+1 result[r]={ x,y,"l" } end if checked then - if x<xmin then xmin=x elseif x>xmax then xmax=x end - if y<ymin then ymin=y elseif y>ymax then ymax=y end + if x>xmax then xmax=x elseif x<xmin then xmin=x end + if y>ymax then ymax=y elseif y<ymin then ymin=y end else xmin=x ymin=y @@ -9243,14 +10434,51 @@ do checked=true end end - local function curveto(x1,y1,x2,y2,x3,y3) + local function xlineto() + if keepcurve then + r=r+1 + result[r]={ x,y,"l" } + end + if not checked then + xmin=x + ymin=y + xmax=x + ymax=y + checked=true + elseif x>xmax then + xmax=x + elseif x<xmin then + xmin=x + end + end + local function ylineto() + if keepcurve then + r=r+1 + result[r]={ x,y,"l" } + end + if not checked then + xmin=x + ymin=y + xmax=x + ymax=y + checked=true + elseif y>ymax then + ymax=y + elseif y<ymin then + ymin=y + end + end + local function xycurveto(x1,y1,x2,y2,x3,y3) + if trace_charstrings then + showstate("curveto") + end if keepcurve then r=r+1 result[r]={ x1,y1,x2,y2,x3,y3,"c" } end if checked then - if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end - if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end + if x1>xmax then xmax=x1 elseif x1<xmin then xmin=x1 end + if y1>ymax then ymax=y1 elseif y1<ymin then ymin=y1 end else xmin=x1 ymin=y1 @@ -9258,21 +10486,21 @@ do ymax=y1 checked=true end - if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end - if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end - if x3<xmin then xmin=x3 elseif x3>xmax then xmax=x3 end - if y3<ymin then ymin=y3 elseif y3>ymax then ymax=y3 end + if x2>xmax then xmax=x2 elseif x2<xmin then xmin=x2 end + if y2>ymax then ymax=y2 elseif y2<ymin then ymin=y2 end + if x3>xmax then xmax=x3 elseif x3<xmin then xmin=x3 end + if y3>ymax then ymax=y3 elseif y3<ymin then ymin=y3 end end local function rmoveto() - if top>2 then - if not width then + if not width then + if top>2 then width=stack[1] if trace_charstrings then - showvalue("width",width) + showvalue("backtrack width",width) end + else + width=true end - elseif not width then - width=true end if trace_charstrings then showstate("rmoveto") @@ -9280,43 +10508,43 @@ do x=x+stack[top-1] y=y+stack[top] top=0 - moveto(x,y) + xymoveto() end local function hmoveto() - if top>1 then - if not width then + if not width then + if top>1 then width=stack[1] if trace_charstrings then - showvalue("width",width) + showvalue("backtrack width",width) end + else + width=true end - elseif not width then - width=true end if trace_charstrings then showstate("hmoveto") end x=x+stack[top] top=0 - moveto(x,y) + xmoveto() end local function vmoveto() - if top>1 then - if not width then + if not width then + if top>1 then width=stack[1] if trace_charstrings then - showvalue("width",width) + showvalue("backtrack width",width) end + else + width=true end - elseif not width then - width=true end if trace_charstrings then showstate("vmoveto") end y=y+stack[top] top=0 - moveto(x,y) + ymoveto() end local function rlineto() if trace_charstrings then @@ -9325,20 +10553,7 @@ do for i=1,top,2 do x=x+stack[i] y=y+stack[i+1] - lineto(x,y) - end - top=0 - end - local function xlineto(swap) - for i=1,top do - if swap then - x=x+stack[i] - swap=false - else - y=y+stack[i] - swap=true - end - lineto(x,y) + xylineto() end top=0 end @@ -9346,13 +10561,47 @@ do if trace_charstrings then showstate("hlineto") end - xlineto(true) + if top==1 then + x=x+stack[1] + xlineto() + else + local swap=true + for i=1,top do + if swap then + x=x+stack[i] + xlineto() + swap=false + else + y=y+stack[i] + ylineto() + swap=true + end + end + end + top=0 end local function vlineto() if trace_charstrings then showstate("vlineto") end - xlineto(false) + if top==1 then + y=y+stack[1] + ylineto() + else + local swap=false + for i=1,top do + if swap then + x=x+stack[i] + xlineto() + swap=false + else + y=y+stack[i] + ylineto() + swap=true + end + end + end + top=0 end local function rrcurveto() if trace_charstrings then @@ -9363,9 +10612,9 @@ do local ay=y+stack[i+1] local bx=ax+stack[i+2] local by=ay+stack[i+3] - x=bx+stack[i+4] - y=by+stack[i+5] - curveto(ax,ay,bx,by,x,y) + x=bx+stack[i+4] + y=by+stack[i+5] + xycurveto(ax,ay,bx,by,x,y) end top=0 end @@ -9375,17 +10624,17 @@ do end local s=1 if top%2~=0 then - y=y+stack[1] + y=y+stack[1] s=2 end for i=s,top,4 do - local ax=x+stack[i] + local ax=x+stack[i] local ay=y local bx=ax+stack[i+1] local by=ay+stack[i+2] - x=bx+stack[i+3] + x=bx+stack[i+3] y=by - curveto(ax,ay,bx,by,x,y) + xycurveto(ax,ay,bx,by,x,y) end top=0 end @@ -9396,17 +10645,17 @@ do local s=1 local d=0 if top%2~=0 then - d=stack[1] + d=stack[1] s=2 end for i=s,top,4 do local ax=x+d - local ay=y+stack[i] + local ay=y+stack[i] local bx=ax+stack[i+1] local by=ay+stack[i+2] x=bx - y=by+stack[i+3] - curveto(ax,ay,bx,by,x,y) + y=by+stack[i+3] + xycurveto(ax,ay,bx,by,x,y) d=0 end top=0 @@ -9416,7 +10665,6 @@ do if last then top=top-1 end - local sw=swap for i=1,top,4 do local ax,ay,bx,by if swap then @@ -9444,7 +10692,7 @@ do end swap=true end - curveto(ax,ay,bx,by,x,y) + xycurveto(ax,ay,bx,by,x,y) end top=0 end @@ -9471,11 +10719,11 @@ do local by=ay+stack[i+3] x=bx+stack[i+4] y=by+stack[i+5] - curveto(ax,ay,bx,by,x,y) + xycurveto(ax,ay,bx,by,x,y) end x=x+stack[top-1] y=y+stack[top] - lineto(x,y) + xylineto() top=0 end local function rlinecurve() @@ -9486,7 +10734,7 @@ do for i=1,top-6,2 do x=x+stack[i] y=y+stack[i+1] - lineto(x,y) + xylineto() end end local ax=x+stack[top-5] @@ -9495,7 +10743,7 @@ do local by=ay+stack[top-2] x=bx+stack[top-1] y=by+stack[top] - curveto(ax,ay,bx,by,x,y) + xycurveto(ax,ay,bx,by,x,y) top=0 end local function flex() @@ -9508,33 +10756,33 @@ do local by=ay+stack[4] local cx=bx+stack[5] local cy=by+stack[6] - curveto(ax,ay,bx,by,cx,cy) + xycurveto(ax,ay,bx,by,cx,cy) local dx=cx+stack[7] local dy=cy+stack[8] local ex=dx+stack[9] local ey=dy+stack[10] x=ex+stack[11] y=ey+stack[12] - curveto(dx,dy,ex,ey,x,y) + xycurveto(dx,dy,ex,ey,x,y) top=0 end local function hflex() if trace_charstrings then showstate("hflex") end - local ax=x+stack[1] + local ax=x+stack[1] local ay=y local bx=ax+stack[2] local by=ay+stack[3] local cx=bx+stack[4] local cy=by - curveto(ax,ay,bx,by,cx,cy) + xycurveto(ax,ay,bx,by,cx,cy) local dx=cx+stack[5] local dy=by local ex=dx+stack[6] local ey=y x=ex+stack[7] - curveto(dx,dy,ex,ey,x,y) + xycurveto(dx,dy,ex,ey,x,y) top=0 end local function hflex1() @@ -9547,13 +10795,13 @@ do local by=ay+stack[4] local cx=bx+stack[5] local cy=by - curveto(ax,ay,bx,by,cx,cy) + xycurveto(ax,ay,bx,by,cx,cy) local dx=cx+stack[6] local dy=by local ex=dx+stack[7] local ey=dy+stack[8] x=ex+stack[9] - curveto(dx,dy,ex,ey,x,y) + xycurveto(dx,dy,ex,ey,x,y) top=0 end local function flex1() @@ -9566,7 +10814,7 @@ do local by=ay+stack[4] local cx=bx+stack[5] local cy=by+stack[6] - curveto(ax,ay,bx,by,cx,cy) + xycurveto(ax,ay,bx,by,cx,cy) local dx=cx+stack[7] local dy=cy+stack[8] local ex=dx+stack[9] @@ -9576,7 +10824,7 @@ do else y=ey+stack[11] end - curveto(dx,dy,ex,ey,x,y) + xycurveto(dx,dy,ex,ey,x,y) top=0 end local function getstem() @@ -9623,12 +10871,180 @@ do return floor((stems+7)/8) end end - local function unsupported() + local function unsupported(t) + if trace_charstrings then + showstate("unsupported "..t) + end + top=0 + end + local function unsupportedsub(t) if trace_charstrings then - showstate("unsupported") + showstate("unsupported sub "..t) + end + top=0 + end + local function getstem3() + if trace_charstrings then + showstate("stem3") + end + top=0 + end + local function divide() + if version==1 then + local d=stack[top] + top=top-1 + stack[top]=stack[top]/d + end + end + local function closepath() + if version==1 then + if trace_charstrings then + showstate("closepath") + end + end + top=0 + end + local function hsbw() + if version==1 then + if trace_charstrings then + showstate("dotsection") + end + width=stack[top] end top=0 end + local function seac() + if version==1 then + if trace_charstrings then + showstate("seac") + end + end + top=0 + end + local function sbw() + if version==1 then + if trace_charstrings then + showstate("sbw") + end + width=stack[top-1] + end + top=0 + end + local function callothersubr() + if version==1 then + if trace_charstrings then + showstate("callothersubr (unsupported)") + end + end + top=0 + end + local function pop() + if version==1 then + if trace_charstrings then + showstate("pop (unsupported)") + end + top=top+1 + stack[top]=0 + else + top=0 + end + end + local function setcurrentpoint() + if version==1 then + if trace_charstrings then + showstate("pop (unsupported)") + end + x=x+stack[top-1] + y=y+stack[top] + end + top=0 + end + local reginit=false + local function updateregions(n) + if regions then + local current=regions[n] or regions[1] + nofregions=#current + if axis and n~=reginit then + factors={} + for i=1,nofregions do + local region=current[i] + local s=1 + for j=1,#axis do + local f=axis[j] + local r=region[j] + local start=r.start + local peak=r.peak + local stop=r.stop + if start>peak or peak>stop then + elseif start<0 and stop>0 and peak~=0 then + elseif peak==0 then + elseif f<start or f>stop then + s=0 + break + elseif f<peak then + s=s*(f-start)/(peak-start) + elseif f>peak then + s=s*(stop-f)/(stop-peak) + else + end + end + factors[i]=s + end + end + end + reginit=n + end + local function setvsindex() + local vsindex=stack[top] + if trace_charstrings then + showstate(formatters["vsindex %i"](vsindex)) + end + updateregions(vsindex) + top=top-1 + end + local function blend() + local n=stack[top] + top=top-1 + if axis then + if trace_charstrings then + local t=top-nofregions*n + local m=t-n + for i=1,n do + local k=m+i + local d=m+n+(i-1)*nofregions + local old=stack[k] + local new=old + for r=1,nofregions do + new=new+stack[d+r]*factors[r] + end + stack[k]=new + showstate(formatters["blend %i of %i: %s -> %s"](i,n,old,new)) + end + top=t + elseif n==1 then + top=top-nofregions + local v=stack[top] + for r=1,nofregions do + v=v+stack[top+r]*factors[r] + end + stack[top]=v + else + top=top-nofregions*n + local d=top + local k=top-n + for i=1,n do + k=k+1 + local v=stack[k] + for r=1,nofregions do + v=v+stack[d+r]*factors[r] + end + stack[k]=v + d=d+nofregions + end + end + else + end + end local actions={ [0]=unsupported, getstem, unsupported, @@ -9642,10 +11058,10 @@ do unsupported, unsupported, unsupported, + hsbw, unsupported, - unsupported, - unsupported, - unsupported, + setvsindex, + blend, unsupported, getstem, getmask, @@ -9663,75 +11079,158 @@ do hvcurveto, } local subactions={ + [000]=dotsection, + [001]=getstem3, + [002]=getstem3, + [006]=seac, + [007]=sbw, + [012]=divide, + [016]=callothersubr, + [017]=pop, + [033]=setcurrentpoint, [034]=hflex, [035]=flex, [036]=hflex1, [037]=flex1, } - local p_bytes=Ct((P(1)/byte)^0) - local function call(scope,list,bias,process) - local index=stack[top]+bias - top=top-1 - if trace_charstrings then - showvalue(scope,index,true) + local c_endchar=char(14) + local passon do + local rshift=bit32.rshift + local band=bit32.band + local round=math.round + local encode=table.setmetatableindex(function(t,i) + for i=-2048,-1130 do + t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF)) + end + for i=-1131,-108 do + local v=0xFB00-i-108 + t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF)) + end + for i=-107,107 do + t[i]=char(i+139) + end + for i=108,1131 do + local v=0xF700+i-108 + t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF)) + end + for i=1132,2048 do + t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF)) + end + return t[i] + end) + local function setvsindex() + local vsindex=stack[top] + updateregions(vsindex) + top=top-1 end - local str=list[index] - if str then - if type(str)=="string" then - str=lpegmatch(p_bytes,str) - list[index]=str + local function blend() + local n=stack[top] + top=top-1 + if not axis then + elseif n==1 then + top=top-nofregions + local v=stack[top] + for r=1,nofregions do + v=v+stack[top+r]*factors[r] + end + stack[top]=round(v) + else + top=top-nofregions*n + local d=top + local k=top-n + for i=1,n do + k=k+1 + local v=stack[k] + for r=1,nofregions do + v=v+stack[d+r]*factors[r] + end + stack[k]=round(v) + d=d+nofregions + end end - depth=depth+1 - process(str) - depth=depth-1 + end + passon=function(operation) + if operation==15 then + setvsindex() + elseif operation==16 then + blend() + else + for i=1,top do + r=r+1 + result[r]=encode[stack[i]] + end + r=r+1 + result[r]=char(operation) + top=0 + end + end + end + local process + local function call(scope,list,bias) + depth=depth+1 + if top==0 then + showstate(formatters["unknown %s call"](scope)) + top=0 else - report("unknown %s %i",scope,index) + local index=stack[top]+bias + top=top-1 + if trace_charstrings then + showvalue(scope,index,true) + end + local tab=list[index] + if tab then + process(tab) + else + showstate(formatters["unknown %s call %i"](scope,index)) + top=0 + end end + depth=depth-1 end - local function process(tab) + local justpass=false + process=function(tab) local i=1 local n=#tab while i<=n do local t=tab[i] - if t>=32 and t<=246 then - top=top+1 - stack[top]=t-139 - i=i+1 - elseif t>=247 and t<=250 then + if t>=32 then top=top+1 - stack[top]=(t-247)*256+tab[i+1]+108 - i=i+2 - elseif t>=251 and t<=254 then - top=top+1 - stack[top]=-(t-251)*256-tab[i+1]-108 - i=i+2 + if t<=246 then + stack[top]=t-139 + i=i+1 + elseif t<=250 then + stack[top]=t*256-63124+tab[i+1] + i=i+2 + elseif t<=254 then + stack[top]=-t*256+64148-tab[i+1] + i=i+2 + else + local n=0x100*tab[i+1]+tab[i+2] + if n>=0x8000 then + stack[top]=n-0x10000+(0x100*tab[i+3]+tab[i+4])/0xFFFF + else + stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF + end + i=i+5 + end elseif t==28 then top=top+1 local n=0x100*tab[i+1]+tab[i+2] if n>=0x8000 then - stack[top]=n-0xFFFF-1 + stack[top]=n-0x10000 else stack[top]=n end i=i+3 - elseif t==255 then - local n=0x100*tab[i+1]+tab[i+2] - top=top+1 - if n>=0x8000 then - stack[top]=n-0xFFFF-1+(0x100*tab[i+3]+tab[i+4])/0xFFFF - else - stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF - end - i=i+5 - elseif t==11 then + elseif t==11 then if trace_charstrings then showstate("return") end return elseif t==10 then - call("local",locals,localbias,process) + call("local",locals,localbias) i=i+1 - elseif t==14 then + elseif t==14 then if width then elseif top>0 then width=stack[1] @@ -9746,14 +11245,14 @@ do end return elseif t==29 then - call("global",globals,globalbias,process) + call("global",globals,globalbias) i=i+1 elseif t==12 then i=i+1 local t=tab[i] local a=subactions[t] if a then - a() + a(t) else if trace_charstrings then showvalue("<subaction>",t) @@ -9761,112 +11260,49 @@ do top=0 end i=i+1 + elseif justpass then + passon(t) + i=i+1 else local a=actions[t] if a then - local s=a() + local s=a(t) if s then - i=i+s + i=i+s+1 + else + i=i+1 end else if trace_charstrings then showvalue("<action>",t) end top=0 + i=i+1 end - i=i+1 end end end - parsecharstrings=function(data,glyphs,doshapes) - local dictionary=data.dictionaries[1] - local charstrings=dictionary.charstrings - local charset=dictionary.charset - keepcurve=doshapes - stack={} - glyphs=glyphs or {} - strings=data.strings - locals=dictionary.subroutines - globals=data.routines - globalbias=#globals - localbias=#locals - globalbias=((globalbias<1240 and 107) or (globalbias<33900 and 1131) or 32768)+1 - localbias=((localbias<1240 and 107) or (localbias<33900 and 1131) or 32768)+1 - local nominalwidth=dictionary.private.data.nominalwidthx or 0 - local defaultwidth=dictionary.private.data.defaultwidthx or 0 - for i=1,#charstrings do - local str=charstrings[i] - local tab=lpegmatch(p_bytes,str) - local index=i-1 - x=0 - y=0 - width=false - r=0 - top=0 - stems=0 - result={} - xmin=0 - xmax=0 - ymin=0 - ymax=0 - checked=false - if trace_charstrings then - report("glyph: %i",index) - report("data: % t",tab) - end - process(tab) - local boundingbox={ round(xmin),round(ymin),round(xmax),round(ymax) } - if width==true or width==false then - width=defaultwidth - else - width=nominalwidth+width - end - local glyph=glyphs[index] - if not glyph then - glyphs[index]={ - segments=doshapes~=false and result or nil, - boundingbox=boundingbox, - width=width, - name=charset[index], - } - else - glyph.segments=doshapes~=false and result or nil - glyph.boundingbox=boundingbox - if not glyph.width then - glyph.width=width - end - if charset and not glyph.name then - glyph.name=charset[index] - end - end - if trace_charstrings then - report("width: %s",tostring(width)) - report("boundingbox: % t",boundingbox) - end - charstrings[i]=nil + local function setbias(globals,locals) + if version==1 then + return + false, + false + else + local g,l=#globals,#locals + return + ((g<1240 and 107) or (g<33900 and 1131) or 32768)+1, + ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1 end - return glyphs end - parsecharstring=function(data,dictionary,charstring,glyphs,index,doshapes) - local private=dictionary.private - keepcurve=doshapes - strings=data.strings - locals=dictionary.subroutines or {} - globals=data.routines or {} - globalbias=#globals - localbias=#locals - globalbias=((globalbias<1240 and 107) or (globalbias<33900 and 1131) or 32768)+1 - localbias=((localbias<1240 and 107) or (localbias<33900 and 1131) or 32768)+1 - local nominalwidth=private and private.data.nominalwidthx or 0 - local defaultwidth=private and private.data.defaultwidthx or 0 - local tab=lpegmatch(p_bytes,charstring) + local function processshape(tab,index) + tab=bytetable(tab) x=0 y=0 width=false r=0 top=0 stems=0 - result={} + result={} xmin=0 xmax=0 ymin=0 @@ -9874,26 +11310,35 @@ do checked=false if trace_charstrings then report("glyph: %i",index) - report("data: % t",tab) + report("data : % t",tab) + end + if regions then + updateregions(vsindex) end process(tab) - local boundingbox={ xmin,ymin,xmax,ymax } + local boundingbox={ + round(xmin), + round(ymin), + round(xmax), + round(ymax), + } if width==true or width==false then width=defaultwidth else width=nominalwidth+width end -index=index-1 local glyph=glyphs[index] - if not glyph then - glyphs[index]={ - segments=doshapes~=false and result or nil, - boundingbox=boundingbox, - width=width, - name=charset[index], - } - else - glyph.segments=doshapes~=false and result or nil + if justpass then + r=r+1 + result[r]=c_endchar + local stream=concat(result) + if glyph then + glyph.stream=stream + else + glyphs[index]={ stream=stream } + end + elseif glyph then + glyph.segments=keepcurve~=false and result or nil glyph.boundingbox=boundingbox if not glyph.width then glyph.width=width @@ -9901,23 +11346,93 @@ index=index-1 if charset and not glyph.name then glyph.name=charset[index] end + elseif keepcurve then + glyphs[index]={ + segments=result, + boundingbox=boundingbox, + width=width, + name=charset and charset[index] or nil, + } + else + glyphs[index]={ + boundingbox=boundingbox, + width=width, + name=charset and charset[index] or nil, + } end if trace_charstrings then - report("width: %s",tostring(width)) + report("width : %s",tostring(width)) report("boundingbox: % t",boundingbox) end - return charstring end - resetcharstrings=function() + startparsing=function(fontdata,data,streams) + reginit=false + axis=false + regions=data.regions + justpass=streams==true + if regions then + regions={ regions } + axis=data.factors or false + end + end + stopparsing=function(fontdata,data) + stack={} + glyphs=false result={} top=0 - stack={} + locals=false + globals=false + strings=false + end + local function setwidths(private) + if not private then + return 0,0 + end + local privatedata=private.data + if not privatedata then + return 0,0 + end + return privatedata.nominalwidthx or 0,privatedata.defaultwidthx or 0 + end + parsecharstrings=function(fontdata,data,glphs,doshapes,tversion,streams) + local dictionary=data.dictionaries[1] + local charstrings=dictionary.charstrings + keepcurve=doshapes + version=tversion + strings=data.strings + globals=data.routines or {} + locals=dictionary.subroutines or {} + charset=dictionary.charset + vsindex=dictionary.vsindex or 0 + glyphs=glphs or {} + globalbias,localbias=setbias(globals,locals) + nominalwidth,defaultwidth=setwidths(dictionary.private) + startparsing(fontdata,data,streams) + for index=1,#charstrings do + processshape(charstrings[index],index-1) + charstrings[index]=nil + end + stopparsing(fontdata,data) + return glyphs + end + parsecharstring=function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion) + keepcurve=doshapes + version=tversion + strings=data.strings + globals=data.routines or {} + locals=dictionary.subroutines or {} + charset=false + vsindex=dictionary.vsindex or 0 + glyphs=glphs or {} + globalbias,localbias=setbias(globals,locals) + nominalwidth,defaultwidth=setwidths(dictionary.private) + processshape(tab,index-1) end end local function readglobals(f,data) local routines=readlengths(f) for i=1,#routines do - routines[i]=readstring(f,routines[i]) + routines[i]=readbytetable(f,routines[i]) end data.routines=routines end @@ -9929,7 +11444,7 @@ local function readcharsets(f,data,dictionary) local strings=data.strings local nofglyphs=data.nofglyphs local charsetoffset=dictionary.charset - if charsetoffset~=0 then + if charsetoffset and charsetoffset~=0 then setposition(f,header.offset+charsetoffset) local format=readbyte(f) local charset={ [0]=".notdef" } @@ -9955,6 +11470,9 @@ local function readcharsets(f,data,dictionary) else report("cff parser: unsupported charset format %a",format) end + else + dictionary.nocharset=true + dictionary.charset=nil end end local function readprivates(f,data) @@ -9975,7 +11493,7 @@ local function readlocals(f,data,dictionary) setposition(f,header.offset+private.offset+subroutineoffset) local subroutines=readlengths(f) for i=1,#subroutines do - subroutines[i]=readstring(f,subroutines[i]) + subroutines[i]=readbytetable(f,subroutines[i]) end dictionary.subroutines=subroutines private.data.subroutines=nil @@ -9986,15 +11504,16 @@ local function readlocals(f,data,dictionary) dictionary.subroutines={} end end -local function readcharstrings(f,data) +local function readcharstrings(f,data,what) local header=data.header local dictionaries=data.dictionaries local dictionary=dictionaries[1] - local type=dictionary.charstringtype + local stringtype=dictionary.charstringtype local offset=dictionary.charstrings - if type==2 then + if type(offset)~="number" then + elseif stringtype==2 then setposition(f,header.offset+offset) - local charstrings=readlengths(f) + local charstrings=readlengths(f,what=="cff2") local nofglyphs=#charstrings for i=1,nofglyphs do charstrings[i]=readstring(f,charstrings[i]) @@ -10002,7 +11521,7 @@ local function readcharstrings(f,data) data.nofglyphs=nofglyphs dictionary.charstrings=charstrings else - report("unsupported charstr type %i",type) + report("unsupported charstr type %i",stringtype) data.nofglyphs=0 dictionary.charstrings={} end @@ -10020,28 +11539,36 @@ local function readcidprivates(f,data) end parseprivates(data,dictionaries) end -local function readnoselect(f,data,glyphs,doshapes) +readers.parsecharstrings=parsecharstrings +local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams) local dictionaries=data.dictionaries local dictionary=dictionaries[1] readglobals(f,data) - readcharstrings(f,data) - readencodings(f,data) - readcharsets(f,data,dictionary) + readcharstrings(f,data,version) + if version=="cff2" then + dictionary.charset=nil + else + readencodings(f,data) + readcharsets(f,data,dictionary) + end readprivates(f,data) parseprivates(data,data.dictionaries) readlocals(f,data,dictionary) - parsecharstrings(data,glyphs,doshapes) - resetcharstrings() + startparsing(fontdata,data,streams) + parsecharstrings(fontdata,data,glyphs,doshapes,version,streams) + stopparsing(fontdata,data) end -local function readfdselect(f,data,glyphs,doshapes) +local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams) local header=data.header local dictionaries=data.dictionaries local dictionary=dictionaries[1] local cid=dictionary.cid local cidselect=cid and cid.fdselect readglobals(f,data) - readcharstrings(f,data) - readencodings(f,data) + readcharstrings(f,data,version) + if version~="cff2" then + readencodings(f,data) + end local charstrings=dictionary.charstrings local fdindex={} local nofglyphs=data.nofglyphs @@ -10090,68 +11617,133 @@ local function readfdselect(f,data,glyphs,doshapes) for i=1,#dictionaries do readlocals(f,data,dictionaries[i]) end + startparsing(fontdata,data,streams) for i=1,#charstrings do - parsecharstring(data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes) + parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version) + charstrings[i]=nil end - resetcharstrings() + stopparsing(fontdata,data) end end +local gotodatatable=readers.helpers.gotodatatable +local function cleanup(data,dictionaries) +end function readers.cff(f,fontdata,specification) - if specification.details then - local datatable=fontdata.tables.cff - if datatable then - local offset=datatable.offset - local glyphs=fontdata.glyphs - if not f then - report("invalid filehandle") - return - end - if offset then - setposition(f,offset) - end - local header=readheader(f) - if header.major>1 then - report("version mismatch") - return - end - local names=readfontnames(f) - local dictionaries=readtopdictionaries(f) - local strings=readstrings(f) - local data={ - header=header, - names=names, - dictionaries=dictionaries, - strings=strings, - nofglyphs=fontdata.nofglyphs, - } - parsedictionaries(data,data.dictionaries) - local d=dictionaries[1] - local c=d.cid - fontdata.cffinfo={ - familynamename=d.familyname, - fullname=d.fullname, - boundingbox=d.boundingbox, - weight=d.weight, - italicangle=d.italicangle, - underlineposition=d.underlineposition, - underlinethickness=d.underlinethickness, - monospaced=d.monospaced, - } - fontdata.cidinfo=c and { - registry=c.registry, - ordering=c.ordering, - supplement=c.supplement, - } - if not specification.glyphs then + local tableoffset=gotodatatable(f,fontdata,"cff",specification.details) + if tableoffset then + local header=readheader(f) + if header.major~=1 then + report("only version %s is supported for table %a",1,"cff") + return + end + local glyphs=fontdata.glyphs + local names=readfontnames(f) + local dictionaries=readtopdictionaries(f) + local strings=readstrings(f) + local data={ + header=header, + names=names, + dictionaries=dictionaries, + strings=strings, + nofglyphs=fontdata.nofglyphs, + } + parsedictionaries(data,dictionaries,"cff") + local dic=dictionaries[1] + local cid=dic.cid + fontdata.cffinfo={ + familynamename=dic.familyname, + fullname=dic.fullname, + boundingbox=dic.boundingbox, + weight=dic.weight, + italicangle=dic.italicangle, + underlineposition=dic.underlineposition, + underlinethickness=dic.underlinethickness, + monospaced=dic.monospaced, + } + fontdata.cidinfo=cid and { + registry=cid.registry, + ordering=cid.ordering, + supplement=cid.supplement, + } + if specification.glyphs then + local all=specification.shapes or false + if cid and cid.fdselect then + readfdselect(f,fontdata,data,glyphs,all,"cff") else - local cid=d.cid - if cid and cid.fdselect then - readfdselect(f,data,glyphs,specification.shapes or false) - else - readnoselect(f,data,glyphs,specification.shapes or false) - end + readnoselect(f,fontdata,data,glyphs,all,"cff") end end + cleanup(data,dictionaries) + end +end +function readers.cff2(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"cff2",specification.glyphs) + if tableoffset then + local header=readheader(f) + if header.major~=2 then + report("only version %s is supported for table %a",2,"cff2") + return + end + local glyphs=fontdata.glyphs + local dictionaries={ readstring(f,header.dsize) } + local data={ + header=header, + dictionaries=dictionaries, + nofglyphs=fontdata.nofglyphs, + } + parsedictionaries(data,dictionaries,"cff2") + local offset=dictionaries[1].vstore + if offset>0 then + local storeoffset=dictionaries[1].vstore+data.header.offset+2 + local regions,deltas=readers.helpers.readvariationdata(f,storeoffset,factors) + data.regions=regions + data.deltas=deltas + else + data.regions={} + data.deltas={} + end + data.factors=specification.factors + local cid=data.dictionaries[1].cid + local all=specification.shapes or false + if cid and cid.fdselect then + readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) + else + readnoselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) + end + cleanup(data,dictionaries) + end +end +function readers.cffcheck(filename) + local f=io.open(filename,"rb") + if f then + local fontdata={ + glyphs={}, + } + local header=readheader(f) + if header.major~=1 then + report("only version %s is supported for table %a",1,"cff") + return + end + local names=readfontnames(f) + local dictionaries=readtopdictionaries(f) + local strings=readstrings(f) + local glyphs={} + local data={ + header=header, + names=names, + dictionaries=dictionaries, + strings=strings, + glyphs=glyphs, + nofglyphs=4, + } + parsedictionaries(data,dictionaries,"cff") + local cid=data.dictionaries[1].cid + if cid and cid.fdselect then + readfdselect(f,fontdata,data,glyphs,false) + else + readnoselect(f,fontdata,data,glyphs,false) + end + return data end end @@ -10167,9 +11759,12 @@ if not modules then modules={} end modules ['font-ttf']={ license="see context related readme files" } local next,type,unpack=next,type,unpack -local bittest=bit32.btest -local sqrt=math.sqrt +local bittest,band,rshift=bit32.btest,bit32.band,bit32.rshift +local sqrt,round=math.sqrt,math.round +local char=string.char +local concat=table.concat local report=logs.reporter("otf reader","ttf") +local trace_deltas=false local readers=fonts.handlers.otf.readers local streamreader=readers.streamreader local setposition=streamreader.setposition @@ -10181,22 +11776,30 @@ local readulong=streamreader.readcardinal4 local readchar=streamreader.readinteger1 local readshort=streamreader.readinteger2 local read2dot14=streamreader.read2dot14 +local readinteger=streamreader.readinteger1 +local helpers=readers.helpers +local gotodatatable=helpers.gotodatatable local function mergecomposites(glyphs,shapes) local function merge(index,shape,components) local contours={} + local points={} local nofcontours=0 + local nofpoints=0 + local offset=0 + local deltas=shape.deltas for i=1,#components do local component=components[i] local subindex=component.index local subshape=shapes[subindex] local subcontours=subshape.contours + local subpoints=subshape.points if not subcontours then local subcomponents=subshape.components if subcomponents then - subcontours=merge(subindex,subshape,subcomponents) + subcontours,subpoints=merge(subindex,subshape,subcomponents) end end - if subcontours then + if subpoints then local matrix=component.matrix local xscale=matrix[1] local xrotate=matrix[2] @@ -10204,35 +11807,38 @@ local function mergecomposites(glyphs,shapes) local yscale=matrix[4] local xoffset=matrix[5] local yoffset=matrix[6] + for i=1,#subpoints do + local p=subpoints[i] + local x=p[1] + local y=p[2] + nofpoints=nofpoints+1 + points[nofpoints]={ + xscale*x+xrotate*y+xoffset, + yscale*y+yrotate*x+yoffset, + p[3] + } + end for i=1,#subcontours do - local points=subcontours[i] - local result={} - for i=1,#points do - local p=points[i] - local x=p[1] - local y=p[2] - result[i]={ - xscale*x+xrotate*y+xoffset, - yscale*y+yrotate*x+yoffset, - p[3] - } - end nofcontours=nofcontours+1 - contours[nofcontours]=result + contours[nofcontours]=offset+subcontours[i] end + offset=offset+#subpoints else report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex) end end + shape.points=points shape.contours=contours shape.components=nil - return contours + return contours,points end for index=1,#glyphs do local shape=shapes[index] - local components=shape.components - if components then - merge(index,shape,components) + if shape then + local components=shape.components + if components then + merge(index,shape,components) + end end end end @@ -10242,123 +11848,510 @@ local function readnothing(f,nofcontours) } end local function curveto(m_x,m_y,l_x,l_y,r_x,r_y) - return { + return l_x+2/3*(m_x-l_x),l_y+2/3*(m_y-l_y), r_x+2/3*(m_x-r_x),r_y+2/3*(m_y-r_y), - r_x,r_y,"c" - } + r_x,r_y,"c" +end +local function applyaxis(glyph,shape,deltas,dowidth) + local points=shape.points + if points then + local nofpoints=#points + local h=nofpoints+2 + local l=nofpoints+1 + local dw=0 + local dl=0 + for i=1,#deltas do + local deltaset=deltas[i] + local xvalues=deltaset.xvalues + local yvalues=deltaset.yvalues + local dpoints=deltaset.points + local factor=deltaset.factor + if dpoints then + local nofdpoints=#dpoints + for i=1,nofdpoints do + local d=dpoints[i] + local p=points[d] + if p then + if xvalues then + local x=xvalues[i] + if x and x~=0 then + p[1]=p[1]+factor*x + end + end + if yvalues then + local y=yvalues[i] + if y and y~=0 then + p[2]=p[2]+factor*y + end + end + elseif dowidth then + if d==h then + local x=xvalues[i] + if x then + dw=dw+factor*x + end + elseif d==l then + local x=xvalues[i] + if x then + dl=dl+factor*x + end + end + end + end + else + for i=1,nofpoints do + local p=points[i] + if xvalues then + local x=xvalues[i] + if x and x~=0 then + p[1]=p[1]+factor*x + end + end + if yvalues then + local y=yvalues[i] + if y and y~=0 then + p[2]=p[2]+factor*y + end + end + end + if dowidth then + local x=xvalues[h] + if x then + dw=dw+factor*x + end + local x=xvalues[l] + if x then + dl=dl+factor*x + end + end + end + end + if dowidth then + local width=glyph.width or 0 + glyph.width=width+dw-dl + end + else + report("no points for glyph %a",glyph.name) + end end -local function contours2outlines(glyphs,shapes) - local quadratic=true +local quadratic=false +local function contours2outlines_normal(glyphs,shapes) for index=1,#glyphs do - local glyph=glyphs[index] local shape=shapes[index] - local contours=shape.contours - if contours then - local nofcontours=#contours - local segments={} - local nofsegments=0 - glyph.segments=segments - if nofcontours>0 then - for i=1,nofcontours do - local contour=contours[i] - local nofcontour=#contour - if nofcontour>0 then - local first_pt=contour[1] - local first_on=first_pt[3] - if nofcontour==1 then - first_pt[3]="m" - nofsegments=nofsegments+1 - segments[nofsegments]=first_pt - else + if shape then + local glyph=glyphs[index] + local contours=shape.contours + local points=shape.points + if contours then + local nofcontours=#contours + local segments={} + local nofsegments=0 + glyph.segments=segments + if nofcontours>0 then + local px,py=0,0 + local first=1 + for i=1,nofcontours do + local last=contours[i] + if last>=first then + local first_pt=points[first] local first_on=first_pt[3] - local last_pt=contour[nofcontour] - local last_on=last_pt[3] - local start=1 - local control_pt=false - if first_on then - start=2 - else - if last_on then - first_pt=last_pt + if first==last then + first_pt[3]="m" + nofsegments=nofsegments+1 + segments[nofsegments]=first_pt + else + local first_on=first_pt[3] + local last_pt=points[last] + local last_on=last_pt[3] + local start=1 + local control_pt=false + if first_on then + start=2 else - first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false } + if last_on then + first_pt=last_pt + else + first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false } + end + control_pt=first_pt end - control_pt=first_pt - end - nofsegments=nofsegments+1 - segments[nofsegments]={ first_pt[1],first_pt[2],"m" } - local previous_pt=first_pt - for i=start,nofcontour do - local current_pt=contour[i] - local current_on=current_pt[3] - local previous_on=previous_pt[3] - if previous_on then - if current_on then + local x,y=first_pt[1],first_pt[2] + if not done then + xmin,ymin,xmax,ymax=x,y,x,y + done=true + end + nofsegments=nofsegments+1 + segments[nofsegments]={ x,y,"m" } + if not quadratic then + px,py=x,y + end + local previous_pt=first_pt + for i=first,last do + local current_pt=points[i] + local current_on=current_pt[3] + local previous_on=previous_pt[3] + if previous_on then + if current_on then + local x,y=current_pt[1],current_pt[2] + nofsegments=nofsegments+1 + segments[nofsegments]={ x,y,"l" } + if not quadratic then + px,py=x,y + end + else + control_pt=current_pt + end + elseif current_on then + local x1,y1=control_pt[1],control_pt[2] + local x2,y2=current_pt[1],current_pt[2] nofsegments=nofsegments+1 - segments[nofsegments]={ current_pt[1],current_pt[2],"l" } + if quadratic then + segments[nofsegments]={ x1,y1,x2,y2,"q" } + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + control_pt=false else + local x2,y2=(previous_pt[1]+current_pt[1])/2,(previous_pt[2]+current_pt[2])/2 + local x1,y1=control_pt[1],control_pt[2] + nofsegments=nofsegments+1 + if quadratic then + segments[nofsegments]={ x1,y1,x2,y2,"q" } + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end control_pt=current_pt end - elseif current_on then - local ps=segments[nofsegments] + previous_pt=current_pt + end + if first_pt==last_pt then + else nofsegments=nofsegments+1 - if quadratic then - segments[nofsegments]={ control_pt[1],control_pt[2],current_pt[1],current_pt[2],"q" } + local x2,y2=first_pt[1],first_pt[2] + if not control_pt then + segments[nofsegments]={ x2,y2,"l" } + elseif quadratic then + local x1,y1=control_pt[1],control_pt[2] + segments[nofsegments]={ x1,y1,x2,y2,"q" } + else + local x1,y1=control_pt[1],control_pt[2] + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + end + end + end + first=last+1 + end + end + end + end + end +end +local function contours2outlines_shaped(glyphs,shapes,keepcurve) + for index=1,#glyphs do + local shape=shapes[index] + if shape then + local glyph=glyphs[index] + local contours=shape.contours + local points=shape.points + if contours then + local nofcontours=#contours + local segments=keepcurve and {} or nil + local nofsegments=0 + if keepcurve then + glyph.segments=segments + end + if nofcontours>0 then + local xmin,ymin,xmax,ymax,done=0,0,0,0,false + local px,py=0,0 + local first=1 + for i=1,nofcontours do + local last=contours[i] + if last>=first then + local first_pt=points[first] + local first_on=first_pt[3] + if first==last then + if keepcurve then + first_pt[3]="m" + nofsegments=nofsegments+1 + segments[nofsegments]=first_pt + end + else + local first_on=first_pt[3] + local last_pt=points[last] + local last_on=last_pt[3] + local start=1 + local control_pt=false + if first_on then + start=2 + else + if last_on then + first_pt=last_pt else - local p=segments[nofsegments-1] local n=#p - segments[nofsegments]=curveto(control_pt[1],control_pt[2],p[n-2],p[n-1],current_pt[1],current_pt[2]) + first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false } end - control_pt=false + control_pt=first_pt + end + local x,y=first_pt[1],first_pt[2] + if not done then + xmin,ymin,xmax,ymax=x,y,x,y + done=true else + if x<xmin then xmin=x elseif x>xmax then xmax=x end + if y<ymin then ymin=y elseif y>ymax then ymax=y end + end + if keepcurve then nofsegments=nofsegments+1 - local halfway_x=(previous_pt[1]+current_pt[1])/2 - local halfway_y=(previous_pt[2]+current_pt[2])/2 + segments[nofsegments]={ x,y,"m" } + end + if not quadratic then + px,py=x,y + end + local previous_pt=first_pt + for i=first,last do + local current_pt=points[i] + local current_on=current_pt[3] + local previous_on=previous_pt[3] + if previous_on then + if current_on then + local x,y=current_pt[1],current_pt[2] + if x<xmin then xmin=x elseif x>xmax then xmax=x end + if y<ymin then ymin=y elseif y>ymax then ymax=y end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x,y,"l" } + end + if not quadratic then + px,py=x,y + end + else + control_pt=current_pt + end + elseif current_on then + local x1,y1=control_pt[1],control_pt[2] + local x2,y2=current_pt[1],current_pt[2] + if quadratic then + if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end + if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,"q" } + end + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end + if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end + if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end + if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end + if px<xmin then xmin=px elseif px>xmax then xmax=px end + if py<ymin then ymin=py elseif py>ymax then ymax=py end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + end + control_pt=false + else + local x2,y2=(previous_pt[1]+current_pt[1])/2,(previous_pt[2]+current_pt[2])/2 + local x1,y1=control_pt[1],control_pt[2] + if quadratic then + if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end + if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,"q" } + end + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end + if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end + if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end + if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end + if px<xmin then xmin=px elseif px>xmax then xmax=px end + if py<ymin then ymin=py elseif py>ymax then ymax=py end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + end + control_pt=current_pt + end + previous_pt=current_pt + end + if first_pt==last_pt then + elseif not control_pt then + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ first_pt[1],first_pt[2],"l" } + end + else + local x1,y1=control_pt[1],control_pt[2] + local x2,y2=first_pt[1],first_pt[2] + if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end + if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end if quadratic then - segments[nofsegments]={ control_pt[1],control_pt[2],halfway_x,halfway_y,"q" } + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,"q" } + end else - local p=segments[nofsegments-1] local n=#p - segments[nofsegments]=curveto(control_pt[1],control_pt[2],p[n-2],p[n-1],halfway_x,halfway_y) + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end + if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end + if px<xmin then xmin=px elseif px>xmax then xmax=px end + if py<ymin then ymin=py elseif py>ymax then ymax=py end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end end - control_pt=current_pt end - previous_pt=current_pt end - if first_pt==last_pt then + end + first=last+1 + end + glyph.boundingbox={ round(xmin),round(ymin),round(xmax),round(ymax) } + end + end + end + end +end +local c_zero=char(0) +local s_zero=char(0,0) +local function toushort(n) + return char(band(rshift(n,8),0xFF),band(n,0xFF)) +end +local function toshort(n) + if n<0 then + n=n+0x10000 + end + return char(band(rshift(n,8),0xFF),band(n,0xFF)) +end +local function repackpoints(glyphs,shapes) + local noboundingbox={ 0,0,0,0 } + local result={} + for index=1,#glyphs do + local shape=shapes[index] + if shape then + local r=0 + local glyph=glyphs[index] + if false then + else + local contours=shape.contours + local nofcontours=contours and #contours or 0 + local boundingbox=glyph.boundingbox or noboundingbox + r=r+1 result[r]=toshort(nofcontours) + r=r+1 result[r]=toshort(boundingbox[1]) + r=r+1 result[r]=toshort(boundingbox[2]) + r=r+1 result[r]=toshort(boundingbox[3]) + r=r+1 result[r]=toshort(boundingbox[4]) + if nofcontours>0 then + for i=1,nofcontours do + r=r+1 result[r]=toshort(contours[i]-1) + end + r=r+1 result[r]=s_zero + local points=shape.points + local currentx=0 + local currenty=0 + local xpoints={} + local ypoints={} + local x=0 + local y=0 + local lastflag=nil + local nofflags=0 + for i=1,#points do + local pt=points[i] + local px=pt[1] + local py=pt[2] + local fl=pt[3] and 0x01 or 0x00 + if px==currentx then + fl=fl+0x10 + else + local dx=round(px-currentx) + if dx<-255 or dx>255 then + x=x+1 xpoints[x]=toshort(dx) + elseif dx<0 then + fl=fl+0x02 + x=x+1 xpoints[x]=char(-dx) + elseif dx>0 then + fl=fl+0x12 + x=x+1 xpoints[x]=char(dx) else - nofsegments=nofsegments+1 - if not control_pt then - segments[nofsegments]={ first_pt[1],first_pt[2],"l" } - elseif quadratic then - segments[nofsegments]={ control_pt[1],control_pt[2],first_pt[1],first_pt[2],"q" } - else - local p=last_pt local n=#p - segments[nofsegments]=curveto(control_pt[1],control_pt[2],p[n-2],p[n-1],first_pt[1],first_pt[2]) - end + fl=fl+0x02 + x=x+1 xpoints[x]=c_zero end end + if py==currenty then + fl=fl+0x20 + else + local dy=round(py-currenty) + if dy<-255 or dy>255 then + y=y+1 ypoints[y]=toshort(dy) + elseif dy<0 then + fl=fl+0x04 + y=y+1 ypoints[y]=char(-dy) + elseif dy>0 then + fl=fl+0x24 + y=y+1 ypoints[y]=char(dy) + else + fl=fl+0x04 + y=y+1 ypoints[y]=c_zero + end + end + currentx=px + currenty=py + if lastflag==fl then + nofflags=nofflags+1 + else + if nofflags==1 then + r=r+1 result[r]=char(lastflag) + elseif nofflags==2 then + r=r+1 result[r]=char(lastflag,lastflag) + elseif nofflags>2 then + lastflag=lastflag+0x08 + r=r+1 result[r]=char(lastflag,nofflags-1) + end + nofflags=1 + lastflag=fl + end + end + if nofflags==1 then + r=r+1 result[r]=char(lastflag) + elseif nofflags==2 then + r=r+1 result[r]=char(lastflag,lastflag) + elseif nofflags>2 then + lastflag=lastflag+0x08 + r=r+1 result[r]=char(lastflag,nofflags-1) end + r=r+1 result[r]=concat(xpoints) + r=r+1 result[r]=concat(ypoints) end end + glyph.stream=concat(result,"",1,r) + else end end end -local function readglyph(f,nofcontours) +local function readglyph(f,nofcontours) local points={} - local endpoints={} + local contours={} local instructions={} local flags={} for i=1,nofcontours do - endpoints[i]=readshort(f)+1 + contours[i]=readshort(f)+1 end - local nofpoints=endpoints[nofcontours] + local nofpoints=contours[nofcontours] local nofinstructions=readushort(f) skipbytes(f,nofinstructions) local i=1 while i<=nofpoints do local flag=readbyte(f) flags[i]=flag - if bittest(flag,0x0008) then + if bittest(flag,0x08) then for j=1,readbyte(f) do i=i+1 flags[i]=flag @@ -10369,8 +12362,8 @@ local function readglyph(f,nofcontours) local x=0 for i=1,nofpoints do local flag=flags[i] - local short=bittest(flag,0x0002) - local same=bittest(flag,0x0010) + local short=bittest(flag,0x02) + local same=bittest(flag,0x10) if short then if same then x=x+readbyte(f) @@ -10381,13 +12374,13 @@ local function readglyph(f,nofcontours) else x=x+readshort(f) end - points[i]={ x,y,bittest(flag,0x0001) } + points[i]={ x,0,bittest(flag,0x01) } end local y=0 for i=1,nofpoints do local flag=flags[i] - local short=bittest(flag,0x0004) - local same=bittest(flag,0x0020) + local short=bittest(flag,0x04) + local same=bittest(flag,0x20) if short then if same then y=y+readbyte(f) @@ -10400,15 +12393,11 @@ local function readglyph(f,nofcontours) end points[i][2]=y end - local first=1 - for i=1,#endpoints do - local last=endpoints[i] - endpoints[i]={ unpack(points,first,last) } - first=last+1 - end return { type="glyph", - contours=endpoints, + points=points, + contours=contours, + nofpoints=nofpoints, } end local function readcomposite(f) @@ -10499,15 +12488,13 @@ function readers.loca(f,fontdata,specification) local locations={} setposition(f,datatable.offset) if format==1 then - local nofglyphs=datatable.length/4-1 - -1 + local nofglyphs=datatable.length/4-2 for i=0,nofglyphs do locations[i]=offset+readulong(f) end fontdata.nofglyphs=nofglyphs else - local nofglyphs=datatable.length/2-1 - -1 + local nofglyphs=datatable.length/2-2 for i=0,nofglyphs do locations[i]=offset+readushort(f)*2 end @@ -10518,53 +12505,317 @@ function readers.loca(f,fontdata,specification) end end function readers.glyf(f,fontdata,specification) - if specification.glyphs then - local datatable=fontdata.tables.glyf - if datatable then - local locations=fontdata.locations - if locations then - local glyphs=fontdata.glyphs - local nofglyphs=fontdata.nofglyphs - local filesize=fontdata.filesize - local nothing={ 0,0,0,0 } - local shapes={} - local loadshapes=specification.shapes - for index=0,nofglyphs do - local location=locations[index] - if location>=filesize then - report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1) - fontdata.nofglyphs=index-1 - fontdata.badfont=true - break - elseif location>0 then - setposition(f,location) - local nofcontours=readshort(f) - glyphs[index].boundingbox={ - readshort(f), - readshort(f), - readshort(f), - readshort(f), - } - if not loadshapes then - elseif nofcontours==0 then - shapes[index]=readnothing(f,nofcontours) - elseif nofcontours>0 then - shapes[index]=readglyph(f,nofcontours) + local tableoffset=gotodatatable(f,fontdata,"glyf",specification.glyphs) + if tableoffset then + local locations=fontdata.locations + if locations then + local glyphs=fontdata.glyphs + local nofglyphs=fontdata.nofglyphs + local filesize=fontdata.filesize + local nothing={ 0,0,0,0 } + local shapes={} + local loadshapes=specification.shapes or specification.instance + for index=0,nofglyphs do + local location=locations[index] + if location>=filesize then + report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1) + fontdata.nofglyphs=index-1 + fontdata.badfont=true + break + elseif location>0 then + setposition(f,location) + local nofcontours=readshort(f) + glyphs[index].boundingbox={ + readshort(f), + readshort(f), + readshort(f), + readshort(f), + } + if not loadshapes then + elseif nofcontours==0 then + shapes[index]=readnothing(f,nofcontours) + elseif nofcontours>0 then + shapes[index]=readglyph(f,nofcontours) + else + shapes[index]=readcomposite(f,nofcontours) + end + else + if loadshapes then + shapes[index]={} + end + glyphs[index].boundingbox=nothing + end + end + if loadshapes then + if readers.gvar then + readers.gvar(f,fontdata,specification,glyphs,shapes) + end + mergecomposites(glyphs,shapes) + if specification.instance then + if specification.streams then + repackpoints(glyphs,shapes) + else + contours2outlines_shaped(glyphs,shapes,specification.shapes) + end + elseif specification.shapes then + contours2outlines_normal(glyphs,shapes) + end + end + end + end +end +local function readtuplerecord(f,nofaxis) + local record={} + for i=1,nofaxis do + record[i]=read2dot14(f) + end + return record +end +local function readpoints(f) + local count=readbyte(f) + if count==0 then + return nil,0 + else + if count<128 then + elseif bittest(count,0x80) then + count=band(count,0x7F)*256+readbyte(f) + else + end + local points={} + local p=0 + local n=1 + while p<count do + local control=readbyte(f) + local runreader=bittest(control,0x80) and readushort or readbyte + local runlength=band(control,0x7F) + for i=1,runlength+1 do + n=n+runreader(f) + p=p+1 + points[p]=n + end + end + return points,p + end +end +local function readdeltas(f,nofpoints) + local deltas={} + local p=0 + local z=0 + while nofpoints>0 do + local control=readbyte(f) +if not control then + break +end + local allzero=bittest(control,0x80) + local runlength=band(control,0x3F)+1 + if allzero then + z=z+runlength + else + local runreader=bittest(control,0x40) and readshort or readinteger + if z>0 then + for i=1,z do + p=p+1 + deltas[p]=0 + end + z=0 + end + for i=1,runlength do + p=p+1 + deltas[p]=runreader(f) + end + end + nofpoints=nofpoints-runlength + end + if p>0 then + return deltas + else + end +end +local function readdeltas(f,nofpoints) + local deltas={} + local p=0 + while nofpoints>0 do + local control=readbyte(f) + if control then + local allzero=bittest(control,0x80) + local runlength=band(control,0x3F)+1 + if allzero then + for i=1,runlength do + p=p+1 + deltas[p]=0 + end + else + local runreader=bittest(control,0x40) and readshort or readinteger + for i=1,runlength do + p=p+1 + deltas[p]=runreader(f) + end + end + nofpoints=nofpoints-runlength + else + break + end + end + if p>0 then + return deltas + else + end +end +function readers.gvar(f,fontdata,specification,glyphdata,shapedata) + local instance=specification.instance + if not instance then + return + end + local factors=specification.factors + if not factors then + return + end + local tableoffset=gotodatatable(f,fontdata,"gvar",specification.variable or specification.shapes) + if tableoffset then + local version=readulong(f) + local nofaxis=readushort(f) + local noftuples=readushort(f) + local tupleoffset=tableoffset+readulong(f) + local nofglyphs=readushort(f) + local flags=readushort(f) + local dataoffset=tableoffset+readulong(f) + local data={} + local tuples={} + local glyphdata=fontdata.glyphs + local dowidth=not fontdata.variabledata.hvarwidths + if bittest(flags,0x0001) then + for i=1,nofglyphs+1 do + data[i]=dataoffset+readulong(f) + end + else + for i=1,nofglyphs+1 do + data[i]=dataoffset+2*readushort(f) + end + end + if noftuples>0 then + setposition(f,tupleoffset) + for i=1,noftuples do + tuples[i]=readtuplerecord(f,nofaxis) + end + end + local nextoffset=false + local startoffset=data[1] + for i=1,nofglyphs do + nextoffset=data[i+1] + local glyph=glyphdata[i-1] + local name=trace_deltas and glyph.name + if startoffset==nextoffset then + if name then + report("no deltas for glyph %a",name) + end + else + local shape=shapedata[i-1] + if not shape then + if name then + report("no shape for glyph %a",name) + end + else + lastoffset=startoffset + setposition(f,startoffset) + local flags=readushort(f) + local count=band(flags,0x0FFF) + local offset=startoffset+readushort(f) + local deltas={} + local allpoints=(shape.nofpoints or 0) + local shared=false + local nofshared=0 + if bittest(flags,0x8000) then + local current=getposition(f) + setposition(f,offset) + shared,nofshared=readpoints(f) + offset=getposition(f) + setposition(f,current) + end + for j=1,count do + local size=readushort(f) + local flags=readushort(f) + local index=band(flags,0x0FFF) + local haspeak=bittest(flags,0x8000) + local intermediate=bittest(flags,0x4000) + local private=bittest(flags,0x2000) + local peak=nil + local start=nil + local stop=nil + local xvalues=nil + local yvalues=nil + local points=shared + local nofpoints=nofshared + if haspeak then + peak=readtuplerecord(f,nofaxis) else - shapes[index]=readcomposite(f,nofcontours) + if index+1>#tuples then + report("error, bad tuple index",index) + end + peak=tuples[index+1] end - else - if loadshapes then - shapes[index]={} + if intermediate then + start=readtuplerecord(f,nofaxis) + stop=readtuplerecord(f,nofaxis) + end + if size>0 then + local current=getposition(f) + setposition(f,offset) + if private then + points,nofpoints=readpoints(f) + end + if nofpoints==0 then + nofpoints=allpoints+4 + end + if nofpoints>0 then + xvalues=readdeltas(f,nofpoints) + yvalues=readdeltas(f,nofpoints) + end + offset=offset+size + setposition(f,current) + end + if not xvalues and not yvalues then + points=nil + end + local s=1 + for i=1,nofaxis do + local f=factors[i] + local peak=peak and peak [i] or 0 + local start=start and start[i] or (peak<0 and peak or 0) + local stop=stop and stop [i] or (peak>0 and peak or 0) + if start>peak or peak>stop then + elseif start<0 and stop>0 and peak~=0 then + elseif peak==0 then + elseif f<start or f>stop then + s=0 + break + elseif f<peak then + s=s*(f-start)/(peak-start) + elseif f>peak then + s=s*(stop-f)/(stop-peak) + else + end + end + if s==0 then + if name then + report("no deltas applied for glyph %a",name) + end + else + deltas[#deltas+1]={ + factor=s, + points=points, + xvalues=xvalues, + yvalues=yvalues, + } end - glyphs[index].boundingbox=nothing end - end - if loadshapes then - mergecomposites(glyphs,shapes) - contours2outlines(glyphs,shapes) + if shape.type=="glyph" then + applyaxis(glyph,shape,deltas,dowidth) + else + shape.deltas=deltas + end end end + startoffset=nextoffset end end end @@ -10582,13 +12833,23 @@ if not modules then modules={} end modules ['font-dsp']={ } local next,type=next,type local bittest=bit32.btest +local band=bit32.band +local extract=bit32.extract +local bor=bit32.bor +local lshift=bit32.lshift local rshift=bit32.rshift -local concat=table.concat +local gsub=string.gsub local lower=string.lower local sub=string.sub local strip=string.strip local tohash=table.tohash +local concat=table.concat +local copy=table.copy local reversed=table.reversed +local sort=table.sort +local insert=table.insert +local round=math.round +local lpegmatch=lpeg.match local setmetatableindex=table.setmetatableindex local formatters=string.formatters local sortedkeys=table.sortedkeys @@ -10597,16 +12858,28 @@ local report=logs.reporter("otf reader") local readers=fonts.handlers.otf.readers local streamreader=readers.streamreader local setposition=streamreader.setposition -local skipbytes=streamreader.skip -local skipshort=streamreader.skipshort +local getposition=streamreader.getposition local readushort=streamreader.readcardinal2 local readulong=streamreader.readcardinal4 +local readinteger=streamreader.readinteger1 local readshort=streamreader.readinteger2 -local readfword=readshort local readstring=streamreader.readstring local readtag=streamreader.readtag +local readbytes=streamreader.readbytes +local readfixed=streamreader.readfixed4 +local read2dot14=streamreader.read2dot14 +local skipshort=streamreader.skipshort +local skipbytes=streamreader.skip +local readfword=readshort +local readbytetable=streamreader.readbytetable +local readbyte=streamreader.readbyte local gsubhandlers={} local gposhandlers={} +readers.gsubhandlers=gsubhandlers +readers.gposhandlers=gposhandlers +local helpers=readers.helpers +local gotodatatable=helpers.gotodatatable +local setvariabledata=helpers.setvariabledata local lookupidoffset=-1 local classes={ "base", @@ -10640,6 +12913,51 @@ local chaindirections={ chainedcontext=1, reversechainedcontextsingle=-1, } +local function setmetrics(data,where,tag,d) + local w=data[where] + if w then + local v=w[tag] + if v then + w[tag]=v+d + end + end +end +local variabletags={ + hasc=function(data,d) setmetrics(data,"windowsmetrics","typoascender",d) end, + hdsc=function(data,d) setmetrics(data,"windowsmetrics","typodescender",d) end, + hlgp=function(data,d) setmetrics(data,"windowsmetrics","typolinegap",d) end, + hcla=function(data,d) setmetrics(data,"windowsmetrics","winascent",d) end, + hcld=function(data,d) setmetrics(data,"windowsmetrics","windescent",d) end, + vasc=function(data,d) setmetrics(data,"vhea not done","ascent",d) end, + vdsc=function(data,d) setmetrics(data,"vhea not done","descent",d) end, + vlgp=function(data,d) setmetrics(data,"vhea not done","linegap",d) end, + xhgt=function(data,d) setmetrics(data,"windowsmetrics","xheight",d) end, + cpht=function(data,d) setmetrics(data,"windowsmetrics","capheight",d) end, + sbxs=function(data,d) setmetrics(data,"windowsmetrics","subscriptxsize",d) end, + sbys=function(data,d) setmetrics(data,"windowsmetrics","subscriptysize",d) end, + sbxo=function(data,d) setmetrics(data,"windowsmetrics","subscriptxoffset",d) end, + sbyo=function(data,d) setmetrics(data,"windowsmetrics","subscriptyoffset",d) end, + spxs=function(data,d) setmetrics(data,"windowsmetrics","superscriptxsize",d) end, + spys=function(data,d) setmetrics(data,"windowsmetrics","superscriptysize",d) end, + spxo=function(data,d) setmetrics(data,"windowsmetrics","superscriptxoffset",d) end, + spyo=function(data,d) setmetrics(data,"windowsmetrics","superscriptyoffset",d) end, + strs=function(data,d) setmetrics(data,"windowsmetrics","strikeoutsize",d) end, + stro=function(data,d) setmetrics(data,"windowsmetrics","strikeoutpos",d) end, + unds=function(data,d) setmetrics(data,"postscript","underlineposition",d) end, + undo=function(data,d) setmetrics(data,"postscript","underlinethickness",d) end, +} +local read_cardinal={ + streamreader.readcardinal1, + streamreader.readcardinal2, + streamreader.readcardinal3, + streamreader.readcardinal4, +} +local read_integer={ + streamreader.readinteger1, + streamreader.readinteger2, + streamreader.readinteger3, + streamreader.readinteger4, +} local lookupnames={ gsub={ single="gsub_single", @@ -10671,6 +12989,213 @@ local lookupflags=setmetatableindex(function(t,k) t[k]=v return v end) +local pattern=lpeg.Cf ( + lpeg.Ct("")*lpeg.Cg ( + lpeg.C((lpeg.R("az","09")+lpeg.P(" "))^1)*lpeg.S(" :=")*(lpeg.patterns.number/tonumber)*lpeg.S(" ,")^0 + )^1,rawset +) +local hash=table.setmetatableindex(function(t,k) + local v=lpegmatch(pattern,k) + local t={} + for k,v in sortedhash(v) do + t[#t+1]=k.."="..v + end + v=concat(t,",") + t[k]=v + return v +end) +helpers.normalizedaxishash=hash +local cleanname=fonts.names and fonts.names.cleanname or function(name) + return name and (gsub(lower(name),"[^%a%d]","")) or nil +end +helpers.cleanname=cleanname +function helpers.normalizedaxis(str) + return hash[str] or str +end +local function axistofactors(str) + return lpegmatch(pattern,str) +end +local function getaxisscale(segments,minimum,default,maximum,user) + if not minimum or not default or not maximum then + return false + end + if user<minimum then + user=minimum + elseif user>maximum then + user=maximum + end + if user<default then + default=- (default-user)/(default-minimum) + elseif user>default then + default=(user-default)/(maximum-default) + else + default=0 + end + if not segments then + return default + end + local e + for i=1,#segments do + local s=segments[i] + if type(s)~="number" then + report("using default axis scale") + return default + elseif s[1]>=default then + if s[2]==default then + return default + else + e=i + break + end + end + end + if e then + local b=segments[e-1] + local e=segments[e] + return b[2]+(e[2]-b[2])*(default-b[1])/(e[1]-b[1]) + else + return false + end +end +local function getfactors(data,instancespec) + if instancespec==true then + elseif type(instancespec)~="string" or instancespec=="" then + return + end + local variabledata=data.variabledata + if not variabledata then + return + end + local instances=variabledata.instances + local axis=variabledata.axis + local segments=variabledata.segments + if instances and axis then + local values + if instancespec==true then + values={} + for i=1,#axis do + values[i]={ + value=axis[i].default, + } + end + else + for i=1,#instances do + local instance=instances[i] + if cleanname(instance.subfamily)==instancespec then + values=instance.values + break + end + end + end + if values then + local factors={} + for i=1,#axis do + local a=axis[i] + factors[i]=getaxisscale(segments,a.minimum,a.default,a.maximum,values[i].value) + end + return factors + end + local values=axistofactors(hash[instancespec] or instancespec) + if values then + local factors={} + for i=1,#axis do + local a=axis[i] + local d=a.default + factors[i]=getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d) + end + return factors + end + end +end +local function getscales(regions,factors) + local scales={} + for i=1,#regions do + local region=regions[i] + local s=1 + for j=1,#region do + local axis=region[j] + local f=factors[j] + local start=axis.start + local peak=axis.peak + local stop=axis.stop + if start>peak or peak>stop then + elseif start<0 and stop>0 and peak~=0 then + elseif peak==0 then + elseif f<start or f>stop then + s=0 + break + elseif f<peak then + s=s*(f-start)/(peak-start) + elseif f>peak then + s=s*(stop-f)/(stop-peak) + else + end + end + scales[i]=s + end + return scales +end +helpers.getaxisscale=getaxisscale +helpers.getfactors=getfactors +helpers.getscales=getscales +helpers.axistofactors=axistofactors +local function readvariationdata(f,storeoffset,factors) + local position=getposition(f) + setposition(f,storeoffset) + local format=readushort(f) + local regionoffset=storeoffset+readulong(f) + local nofdeltadata=readushort(f) + local deltadata={} + for i=1,nofdeltadata do + deltadata[i]=readulong(f) + end + setposition(f,regionoffset) + local nofaxis=readushort(f) + local nofregions=readushort(f) + local regions={} + for i=1,nofregions do + local t={} + for i=1,nofaxis do + t[i]={ + start=read2dot14(f), + peak=read2dot14(f), + stop=read2dot14(f), + } + end + regions[i]=t + end + if factors then + for i=1,nofdeltadata do + setposition(f,storeoffset+deltadata[i]) + local nofdeltasets=readushort(f) + local nofshorts=readushort(f) + local nofregions=readushort(f) + local usedregions={} + local deltas={} + for i=1,nofregions do + usedregions[i]=regions[readushort(f)+1] + end + for i=1,nofdeltasets do + local t={} + for i=1,nofshorts do + t[i]=readshort(f) + end + for i=nofshorts+1,nofregions do + t[i]=readinteger(f) + end + deltas[i]=t + end + deltadata[i]={ + regions=usedregions, + deltas=deltas, + scales=factors and getscales(usedregions,factors) or nil, + } + end + end + setposition(f,position) + return regions,deltadata +end +helpers.readvariationdata=readvariationdata local function readcoverage(f,offset,simple) setposition(f,offset) local coverageformat=readushort(f) @@ -10710,10 +13235,15 @@ local function readcoverage(f,offset,simple) end return coverage end -local function readclassdef(f,offset) +local function readclassdef(f,offset,preset) setposition(f,offset) local classdefformat=readushort(f) local classdef={} + if type(preset)=="number" then + for k=0,preset-1 do + classdef[k]=1 + end + end if classdefformat==1 then local index=readushort(f) local nofclassdef=readushort(f) @@ -10735,6 +13265,13 @@ local function readclassdef(f,offset) else report("unknown classdef format %a ",classdefformat) end + if type(preset)=="table" then + for k in next,preset do + if not classdef[k] then + classdef[k]=1 + end + end + end return classdef end local function classtocoverage(defs) @@ -10751,34 +13288,150 @@ local function classtocoverage(defs) return list end end -local function readposition(f,format) +local skips={ [0]=0, + 1, + 1, + 2, + 1, + 2, + 2, + 3, + 2, + 2, + 3, + 2, + 3, + 3, + 4, +} +local function readvariation(f,offset) + local p=getposition(f) + setposition(f,offset) + local outer=readushort(f) + local inner=readushort(f) + local format=readushort(f) + setposition(f,p) + if format==0x8000 then + return outer,inner + end +end +local function readposition(f,format,mainoffset,getdelta) if format==0 then - return nil + return end - local x=bittest(format,0x0001) and readshort(f) or 0 - local y=bittest(format,0x0002) and readshort(f) or 0 - local h=bittest(format,0x0004) and readshort(f) or 0 - local v=bittest(format,0x0008) and readshort(f) or 0 - if x==0 and y==0 and h==0 and v==0 then - return nil + if format==0x04 then + local h=readshort(f) + if h==0 then + return + else + return { 0,0,h,0 } + end + end + if format==0x05 then + local x=readshort(f) + local h=readshort(f) + if x==0 and h==0 then + return + else + return { x,0,h,0 } + end + end + if format==0x44 then + local h=readshort(f) + if getdelta then + local d=readshort(f) + if d>0 then + local outer,inner=readvariation(f,mainoffset+d) + if outer then + h=h+getdelta(outer,inner) + end + end + else + skipshort(f,1) + end + if h==0 then + return + else + return { 0,0,h,0 } + end + end + local x=bittest(format,0x01) and readshort(f) or 0 + local y=bittest(format,0x02) and readshort(f) or 0 + local h=bittest(format,0x04) and readshort(f) or 0 + local v=bittest(format,0x08) and readshort(f) or 0 + if format>=0x10 then + local X=bittest(format,0x10) and skipshort(f) or 0 + local Y=bittest(format,0x20) and skipshort(f) or 0 + local H=bittest(format,0x40) and skipshort(f) or 0 + local V=bittest(format,0x80) and skipshort(f) or 0 + local s=skips[extract(format,4,4)] + if s>0 then + skipshort(f,s) + end + if getdelta then + if X>0 then + local outer,inner=readvariation(f,mainoffset+X) + if outer then + x=x+getdelta(outer,inner) + end + end + if Y>0 then + local outer,inner=readvariation(f,mainoffset+Y) + if outer then + y=y+getdelta(outer,inner) + end + end + if H>0 then + local outer,inner=readvariation(f,mainoffset+H) + if outer then + h=h+getdelta(outer,inner) + end + end + if V>0 then + local outer,inner=readvariation(f,mainoffset+V) + if outer then + v=v+getdelta(outer,inner) + end + end + end + return { x,y,h,v } + elseif x==0 and y==0 and h==0 and v==0 then + return else return { x,y,h,v } end end -local function readanchor(f,offset) +local function readanchor(f,offset,getdelta) if not offset or offset==0 then return nil end setposition(f,offset) - local format=readshort(f) - if format==0 then - report("invalid anchor format %i @ position %i",format,offset) - return false - elseif format>3 then - report("unsupported anchor format %i @ position %i",format,offset) - return false + local format=readshort(f) + local x=readshort(f) + local y=readshort(f) + if format==3 then + if getdelta then + local X=readshort(f) + local Y=readshort(f) + if X>0 then + local outer,inner=readvariation(f,offset+X) + if outer then + x=x+getdelta(outer,inner) + end + end + if Y>0 then + local outer,inner=readvariation(f,offset+Y) + if outer then + y=y+getdelta(outer,inner) + end + end + else + skipshort(f,2) + end + return { x,y } + else + return { x,y } end - return { readshort(f),readshort(f) } end local function readfirst(f,offset) if offset then @@ -10834,6 +13487,31 @@ local function covered(subset,all) end return used end +local function readlookuparray(f,noflookups,nofcurrent) + local lookups={} + if noflookups>0 then + local length=0 + for i=1,noflookups do + local index=readushort(f)+1 + if index>length then + length=index + end + local lookup=readushort(f)+1 + local list=lookups[index] + if list then + list[#list+1]=lookup + else + lookups[index]={ lookup } + end + end + for index=1,length do + if not lookups[index] then + lookups[index]=false + end + end + end + return lookups +end local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) local tableoffset=lookupoffset+offset setposition(f,tableoffset) @@ -10858,10 +13536,7 @@ local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,n for i=2,nofcurrent do current[i]={ readushort(f) } end - local lookups={} - for i=1,noflookups do - lookups[readushort(f)+1]=readushort(f)+1 - end + local lookups=readlookuparray(f,noflookups,nofcurrent) rules[#rules+1]={ current=current, lookups=lookups @@ -10883,7 +13558,7 @@ local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,n local rules={} if subclasssets then coverage=readcoverage(f,tableoffset+coverage) - currentclassdef=readclassdef(f,tableoffset+currentclassdef) + currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage) local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs) for class=1,#subclasssets do local offset=subclasssets[class] @@ -10902,10 +13577,7 @@ local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,n for i=2,nofcurrent do current[i]=currentclasses[readushort(f)+1] end - local lookups={} - for i=1,noflookups do - lookups[readushort(f)+1]=readushort(f)+1 - end + local lookups=readlookuparray(f,noflookups,nofcurrent) rules[#rules+1]={ current=current, lookups=lookups @@ -10929,10 +13601,7 @@ local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,n elseif subtype==3 then local current=readarray(f) local noflookups=readushort(f) - local lookups={} - for i=1,noflookups do - lookups[readushort(f)+1]=readushort(f)+1 - end + local lookups=readlookuparray(f,noflookups,#current) current=readcoveragearray(f,tableoffset,current,true) return { format="coverage", @@ -10987,10 +13656,7 @@ local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nof end end local noflookups=readushort(f) - local lookups={} - for i=1,noflookups do - lookups[readushort(f)+1]=readushort(f)+1 - end + local lookups=readlookuparray(f,noflookups,nofcurrent) rules[#rules+1]={ before=before, current=current, @@ -11016,9 +13682,9 @@ local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nof local rules={} if subclasssets then local coverage=readcoverage(f,tableoffset+coverage) - local beforeclassdef=readclassdef(f,tableoffset+beforeclassdef) - local currentclassdef=readclassdef(f,tableoffset+currentclassdef) - local afterclassdef=readclassdef(f,tableoffset+afterclassdef) + local beforeclassdef=readclassdef(f,tableoffset+beforeclassdef,nofglyphs) + local currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage) + local afterclassdef=readclassdef(f,tableoffset+afterclassdef,nofglyphs) local beforeclasses=classtocoverage(beforeclassdef,fontdata.glyphs) local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs) local afterclasses=classtocoverage(afterclassdef,fontdata.glyphs) @@ -11055,10 +13721,7 @@ local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nof end end local noflookups=readushort(f) - local lookups={} - for i=1,noflookups do - lookups[readushort(f)+1]=readushort(f)+1 - end + local lookups=readlookuparray(f,noflookups,nofcurrent) rules[#rules+1]={ before=before, current=current, @@ -11086,10 +13749,7 @@ local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nof local current=readarray(f) local after=readarray(f) local noflookups=readushort(f) - local lookups={} - for i=1,noflookups do - lookups[readushort(f)+1]=readushort(f)+1 - end + local lookups=readlookuparray(f,noflookups,#current) before=readcoveragearray(f,tableoffset,before,true) current=readcoveragearray(f,tableoffset,current,true) after=readcoveragearray(f,tableoffset,after,true) @@ -11297,20 +13957,21 @@ function gsubhandlers.reversechainedcontextsingle(f,fontdata,lookupid,lookupoffs report("unsupported subtype %a in %a substitution",subtype,"reversechainedcontextsingle") end end -local function readpairsets(f,tableoffset,sets,format1,format2) +local function readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) local done={} for i=1,#sets do local offset=sets[i] local reused=done[offset] if not reused then - setposition(f,tableoffset+offset) + offset=tableoffset+offset + setposition(f,offset) local n=readushort(f) reused={} for i=1,n do reused[i]={ readushort(f), - readposition(f,format1), - readposition(f,format2) + readposition(f,format1,offset,getdelta), + readposition(f,format2,offset,getdelta), } end done[offset]=reused @@ -11319,14 +13980,14 @@ local function readpairsets(f,tableoffset,sets,format1,format2) end return sets end -local function readpairclasssets(f,nofclasses1,nofclasses2,format1,format2) +local function readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,mainoffset,getdelta) local classlist1={} for i=1,nofclasses1 do local classlist2={} classlist1[i]=classlist2 for j=1,nofclasses2 do - local one=readposition(f,format1) - local two=readposition(f,format2) + local one=readposition(f,format1,mainoffset,getdelta) + local two=readposition(f,format2,mainoffset,getdelta) if one or two then classlist2[j]={ one,two } else @@ -11340,25 +14001,26 @@ function gposhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofg local tableoffset=lookupoffset+offset setposition(f,tableoffset) local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta if subtype==1 then local coverage=readushort(f) local format=readushort(f) - local value=readposition(f,format) + local value=readposition(f,format,tableoffset,getdelta) local coverage=readcoverage(f,tableoffset+coverage) for index,newindex in next,coverage do coverage[index]=value end return { format="pair", - coverage=coverage + coverage=coverage, } elseif subtype==2 then local coverage=readushort(f) local format=readushort(f) - local values={} local nofvalues=readushort(f) + local values={} for i=1,nofvalues do - values[i]=readposition(f,format) + values[i]=readposition(f,format,tableoffset,getdelta) end local coverage=readcoverage(f,tableoffset+coverage) for index,newindex in next,coverage do @@ -11366,7 +14028,7 @@ function gposhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofg end return { format="pair", - coverage=coverage + coverage=coverage, } else report("unsupported subtype %a in %a positioning",subtype,"single") @@ -11376,12 +14038,13 @@ function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofgly local tableoffset=lookupoffset+offset setposition(f,tableoffset) local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta if subtype==1 then local coverage=readushort(f) local format1=readushort(f) local format2=readushort(f) local sets=readarray(f) - sets=readpairsets(f,tableoffset,sets,format1,format2) + sets=readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) coverage=readcoverage(f,tableoffset+coverage) for index,newindex in next,coverage do local set=sets[newindex+1] @@ -11403,7 +14066,7 @@ function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofgly end return { format="pair", - coverage=coverage + coverage=coverage, } elseif subtype==2 then local coverage=readushort(f) @@ -11413,10 +14076,10 @@ function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofgly local classdef2=readushort(f) local nofclasses1=readushort(f) local nofclasses2=readushort(f) - local classlist=readpairclasssets(f,nofclasses1,nofclasses2,format1,format2) + local classlist=readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,tableoffset,getdelta) coverage=readcoverage(f,tableoffset+coverage) - classdef1=readclassdef(f,tableoffset+classdef1) - classdef2=readclassdef(f,tableoffset+classdef2) + classdef1=readclassdef(f,tableoffset+classdef1,coverage) + classdef2=readclassdef(f,tableoffset+classdef2,nofglyphs) local usedcoverage={} for g1,c1 in next,classdef1 do if coverage[g1] then @@ -11440,7 +14103,7 @@ function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofgly end return { format="pair", - coverage=usedcoverage + coverage=usedcoverage, } elseif subtype==3 then report("yet unsupported subtype %a in %a positioning",subtype,"pair") @@ -11452,6 +14115,7 @@ function gposhandlers.cursive(f,fontdata,lookupid,lookupoffset,offset,glyphs,nof local tableoffset=lookupoffset+offset setposition(f,tableoffset) local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta if subtype==1 then local coverage=tableoffset+readushort(f) local nofrecords=readushort(f) @@ -11469,15 +14133,15 @@ function gposhandlers.cursive(f,fontdata,lookupid,lookupoffset,offset,glyphs,nof local r=records[i] records[i]={ 1, - readanchor(f,r.entry) or nil, - readanchor(f,r.exit ) or nil, + readanchor(f,r.entry,getdelta) or nil, + readanchor(f,r.exit,getdelta) or nil, } end for index,newindex in next,coverage do coverage[index]=records[newindex+1] end return { - coverage=coverage + coverage=coverage, } else report("unsupported subtype %a in %a positioning",subtype,"cursive") @@ -11487,6 +14151,7 @@ local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyp local tableoffset=lookupoffset+offset setposition(f,tableoffset) local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta if subtype==1 then local markcoverage=tableoffset+readushort(f) local basecoverage=tableoffset+readushort(f) @@ -11513,7 +14178,7 @@ local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyp for i=1,nofmarkclasses do local mc=markclasses[i] if mc then - mc[2]=readanchor(f,mc[2]) + mc[2]=readanchor(f,mc[2],getdelta) end end setposition(f,baseoffset) @@ -11561,7 +14226,7 @@ local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyp local classes=components[c] if classes then for i=1,nofclasses do - local anchor=readanchor(f,classes[i]) + local anchor=readanchor(f,classes[i],getdelta) local bclass=baseclasses[i] local bentry=bclass[b] if bentry then @@ -11603,7 +14268,7 @@ local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyp local r=baserecords[i] local b=basecoverage[i] for j=1,nofclasses do - baseclasses[j][b]=readanchor(f,r[j]) + baseclasses[j][b]=readanchor(f,r[j],getdelta) end end for index,newindex in next,markcoverage do @@ -11639,15 +14304,39 @@ function gposhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,n end do local plugins={} - function plugins.size(f,fontdata,tableoffset,parameters) - if not fontdata.designsize then - setposition(f,tableoffset+parameters) - local designsize=readushort(f) - if designsize>0 then + function plugins.size(f,fontdata,tableoffset,feature) + if fontdata.designsize then + else + local function check(offset) + setposition(f,offset) + local designsize=readushort(f) + if designsize>0 then + local fontstyleid=readushort(f) + local guimenuid=readushort(f) + local minsize=readushort(f) + local maxsize=readushort(f) + if minsize==0 and maxsize==0 and fontstyleid==0 and guimenuid==0 then + minsize=designsize + maxsize=designsize + end + if designsize>=minsize and designsize<=maxsize then + return minsize,maxsize,designsize + end + end + end + local minsize,maxsize,designsize=check(tableoffset+feature.offset+feature.parameters) + if not designsize then + minsize,maxsize,designsize=check(tableoffset+feature.parameters) + if designsize then + report("bad size feature in %a, falling back to wrong offset",fontdata.filename or "?") + else + report("bad size feature in %a,",fontdata.filename or "?") + end + end + if designsize then + fontdata.minsize=minsize + fontdata.maxsize=maxsize fontdata.designsize=designsize - skipshort(f,2) - fontdata.minsize=readushort(f) - fontdata.maxsize=readushort(f) end end end @@ -11784,7 +14473,7 @@ do feature.parameters=parameters local plugin=plugins[feature.tag] if plugin then - plugin(f,fontdata,offset,parameters) + plugin(f,fontdata,featureoffset,feature) end end end @@ -11798,8 +14487,8 @@ do lookups[i]=readushort(f) end for lookupid=1,noflookups do - local index=lookups[lookupid] - setposition(f,lookupoffset+index) + local offset=lookups[lookupid] + setposition(f,lookupoffset+offset) local subtables={} local typebits=readushort(f) local flagbits=readushort(f) @@ -11807,8 +14496,7 @@ do local lookupflags=lookupflags[flagbits] local nofsubtables=readushort(f) for j=1,nofsubtables do - local offset=readushort(f) - subtables[j]=offset+index + subtables[j]=offset+readushort(f) end local markclass=bittest(flagbits,0x0010) if markclass then @@ -11830,20 +14518,8 @@ do end return lookups end - local function readscriptoffsets(f,fontdata,tableoffset) - if not tableoffset then - return - end - setposition(f,tableoffset) - local version=readulong(f) - if version~=0x00010000 then - report("table version %a of %a is not supported (yet), maybe font %s is bad",version,what,fontdata.filename) - return - end - return tableoffset+readushort(f),tableoffset+readushort(f),tableoffset+readushort(f) - end local f_lookupname=formatters["%s_%s_%s"] - local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what) + local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) local sequences=fontdata.sequences or {} local sublookuplist=fontdata.sublookups or {} fontdata.sequences=sequences @@ -11961,6 +14637,13 @@ do end end local reported={} + local function report_issue(i,what,sequence,kind) + local name=sequence.name + if not reported[name] then + report("rule %i in %s lookup %a has %s lookups",i,what,name,kind) + reported[name]=true + end + end for i=lastsequence+1,nofsequences do local sequence=sequences[i] local steps=sequence.steps @@ -11972,41 +14655,65 @@ do local rule=rules[i] local rlookups=rule.lookups if not rlookups then - local name=sequence.name - if not reported[name] then - report("rule %i in %s lookup %a has %s lookups",i,what,name,"no") - reported[name]=true - end + report_issue(i,what,sequence,"no") elseif not next(rlookups) then - local name=sequence.name - if not reported[name] then - report("rule %i in %s lookup %a has %s lookups",i,what,name,"empty") - reported[name]=true - end + report_issue(i,what,sequence,"empty") rule.lookups=nil else - for index,lookupid in sortedhash(rlookups) do - local h=sublookuphash[lookupid] - if not h then - nofsublookups=nofsublookups+1 - local d=lookups[lookupid].done - h={ - index=nofsublookups, - name=f_lookupname(lookupprefix,"d",lookupid+lookupidoffset), - derived=true, - steps=d.steps, - nofsteps=d.nofsteps, - type=d.lookuptype, - markclass=d.markclass or nil, - flags=d.flags, - } - sublookuplist[nofsublookups]=h - sublookuphash[lookupid]=nofsublookups - sublookupcheck[lookupid]=1 + local length=#rlookups + for index=1,length do + local lookuplist=rlookups[index] + if lookuplist then + local length=#lookuplist + local found={} + local noffound=0 + for index=1,length do + local lookupid=lookuplist[index] + if lookupid then + local h=sublookuphash[lookupid] + if not h then + local lookup=lookups[lookupid] + if lookup then + local d=lookup.done + if d then + nofsublookups=nofsublookups+1 + h={ + index=nofsublookups, + name=f_lookupname(lookupprefix,"d",lookupid+lookupidoffset), + derived=true, + steps=d.steps, + nofsteps=d.nofsteps, + type=d.lookuptype or "gsub_single", + markclass=d.markclass or nil, + flags=d.flags, + } + sublookuplist[nofsublookups]=copy(h) + sublookuphash[lookupid]=nofsublookups + sublookupcheck[lookupid]=1 + h=nofsublookups + else + report_issue(i,what,sequence,"missing") + rule.lookups=nil + break + end + else + report_issue(i,what,sequence,"bad") + rule.lookups=nil + break + end + else + sublookupcheck[lookupid]=sublookupcheck[lookupid]+1 + end + if h then + noffound=noffound+1 + found[noffound]=h + end + end + end + rlookups[index]=noffound>0 and found or false else - sublookupcheck[lookupid]=sublookupcheck[lookupid]+1 + rlookups[index]=false end - rlookups[index]=h end end end @@ -12022,33 +14729,110 @@ do end end end - local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo) - local datatable=fontdata.tables[what] - if not datatable then - return - end - local tableoffset=datatable.offset - if not tableoffset then - return + local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) + setposition(f,variationsoffset) + local version=readulong(f) + local nofrecords=readulong(f) + local records={} + for i=1,nofrecords do + records[i]={ + conditions=readulong(f), + substitutions=readulong(f), + } end - local scriptoffset,featureoffset,lookupoffset=readscriptoffsets(f,fontdata,tableoffset) - if not scriptoffset then - return + for i=1,nofrecords do + local record=records[i] + local offset=record.conditions + if offset==0 then + record.condition=nil + record.matchtype="always" + else + setposition(f,variationsoffset+offset) + local nofconditions=readushort(f) + local conditions={} + for i=1,nofconditions do + conditions[i]=variationsoffset+offset+readulong(f) + end + record.conditions=conditions + record.matchtype="condition" + end end - local scripts=readscriplan(f,fontdata,scriptoffset) - local features=readfeatures(f,fontdata,featureoffset) - local scriptlangs,featurehash,featureorder=reorderfeatures(fontdata,scripts,features) - if fontdata.features then - fontdata.features[what]=scriptlangs - else - fontdata.features={ [what]=scriptlangs } + for i=1,nofrecords do + local record=records[i] + if record.matchtype=="condition" then + local conditions=record.conditions + for i=1,#conditions do + setposition(f,conditions[i]) + conditions[i]={ + format=readushort(f), + axis=readushort(f), + minvalue=read2dot14(f), + maxvalue=read2dot14(f), + } + end + end end - if not lookupstoo then - return + for i=1,nofrecords do + local record=records[i] + local offset=record.substitutions + if offset==0 then + record.substitutions={} + else + setposition(f,variationsoffset+offset) + local version=readulong(f) + local nofsubstitutions=readushort(f) + local substitutions={} + for i=1,nofsubstitutions do + substitutions[readushort(f)]=readulong(f) + end + for index,alternates in sortedhash(substitutions) do + if index==0 then + record.substitutions=false + else + local tableoffset=variationsoffset+offset+alternates + setposition(f,tableoffset) + local parameters=readulong(f) + local noflookups=readushort(f) + local lookups={} + for i=1,noflookups do + lookups[i]=readushort(f) + end + record.substitutions=lookups + end + end + end end - local lookups=readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) - if lookups then - resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what) + setvariabledata(fontdata,"features",records) + end + local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo) + local tableoffset=gotodatatable(f,fontdata,what,true) + if tableoffset then + local version=readulong(f) + local scriptoffset=tableoffset+readushort(f) + local featureoffset=tableoffset+readushort(f) + local lookupoffset=tableoffset+readushort(f) + local variationsoffset=version>0x00010000 and (tableoffset+readulong(f)) or 0 + if not scriptoffset then + return + end + local scripts=readscriplan(f,fontdata,scriptoffset) + local features=readfeatures(f,fontdata,featureoffset) + local scriptlangs,featurehash,featureorder=reorderfeatures(fontdata,scripts,features) + if fontdata.features then + fontdata.features[what]=scriptlangs + else + fontdata.features={ [what]=scriptlangs } + end + if not lookupstoo then + return + end + local lookups=readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) + if lookups then + resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) + end + if variationsoffset>0 then + loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) + end end end local function checkkerns(f,fontdata,specification) @@ -12067,57 +14851,61 @@ do report("ignoring global kern table using gpos kern feature") return end - report("adding global kern table as gpos feature %a",name) setposition(f,datatable.offset) local version=readushort(f) local noftables=readushort(f) - local kerns=setmetatableindex("table") - for i=1,noftables do - local version=readushort(f) - local length=readushort(f) - local coverage=readushort(f) - local format=bit32.rshift(coverage,8) - if format==0 then - local nofpairs=readushort(f) - local searchrange=readushort(f) - local entryselector=readushort(f) - local rangeshift=readushort(f) - for i=1,nofpairs do - kerns[readushort(f)][readushort(f)]=readfword(f) + if noftables>1 then + report("adding global kern table as gpos feature %a",name) + local kerns=setmetatableindex("table") + for i=1,noftables do + local version=readushort(f) + local length=readushort(f) + local coverage=readushort(f) + local format=bit32.rshift(coverage,8) + if format==0 then + local nofpairs=readushort(f) + local searchrange=readushort(f) + local entryselector=readushort(f) + local rangeshift=readushort(f) + for i=1,nofpairs do + kerns[readushort(f)][readushort(f)]=readfword(f) + end + elseif format==2 then + else end - elseif format==2 then + end + local feature={ dflt={ dflt=true } } + if not features then + fontdata.features={ gpos={ [name]=feature } } + elseif not gposfeatures then + fontdata.features.gpos={ [name]=feature } else + gposfeatures[name]=feature end - end - local feature={ dflt={ dflt=true } } - if not features then - fontdata.features={ gpos={ [name]=feature } } - elseif not gposfeatures then - fontdata.features.gpos={ [name]=feature } + local sequences=fontdata.sequences + if not sequences then + sequences={} + fontdata.sequences=sequences + end + local nofsequences=#sequences+1 + sequences[nofsequences]={ + index=nofsequences, + name=name, + steps={ + { + coverage=kerns, + format="kern", + }, + }, + nofsteps=1, + type="gpos_pair", + flags={ false,false,false,false }, + order={ name }, + features={ [name]=feature }, + } else - gposfeatures[name]=feature + report("ignoring empty kern table of feature %a",name) end - local sequences=fontdata.sequences - if not sequences then - sequences={} - fontdata.sequences=sequences - end - local nofsequences=#sequences+1 - sequences[nofsequences]={ - index=nofsequences, - name=name, - steps={ - { - coverage=kerns, - format="kern", - }, - }, - nofsteps=1, - type="gpos_pair", - flags={ false,false,false,false }, - order={ name }, - features={ [name]=feature }, - } end function readers.gsub(f,fontdata,specification) if specification.details then @@ -12134,86 +14922,114 @@ do end end function readers.gdef(f,fontdata,specification) - if specification.glyphs then - local datatable=fontdata.tables.gdef - if datatable then - local tableoffset=datatable.offset - setposition(f,tableoffset) - local version=readulong(f) - local classoffset=tableoffset+readushort(f) - local attachmentoffset=tableoffset+readushort(f) - local ligaturecarets=tableoffset+readushort(f) - local markclassoffset=tableoffset+readushort(f) - local marksetsoffset=version==0x00010002 and (tableoffset+readushort(f)) - local glyphs=fontdata.glyphs - local marks={} - local markclasses=setmetatableindex("table") - local marksets=setmetatableindex("table") - fontdata.marks=marks - fontdata.markclasses=markclasses - fontdata.marksets=marksets - setposition(f,classoffset) - local classformat=readushort(f) - if classformat==1 then + if not specification.glyphs then + return + end + local datatable=fontdata.tables.gdef + if datatable then + local tableoffset=datatable.offset + setposition(f,tableoffset) + local version=readulong(f) + local classoffset=tableoffset+readushort(f) + local attachmentoffset=tableoffset+readushort(f) + local ligaturecarets=tableoffset+readushort(f) + local markclassoffset=tableoffset+readushort(f) + local marksetsoffset=version>=0x00010002 and (tableoffset+readushort(f)) + local varsetsoffset=version>=0x00010003 and (tableoffset+readulong(f)) + local glyphs=fontdata.glyphs + local marks={} + local markclasses=setmetatableindex("table") + local marksets=setmetatableindex("table") + fontdata.marks=marks + fontdata.markclasses=markclasses + fontdata.marksets=marksets + setposition(f,classoffset) + local classformat=readushort(f) + if classformat==1 then + local firstindex=readushort(f) + local lastindex=firstindex+readushort(f)-1 + for index=firstindex,lastindex do + local class=classes[readushort(f)] + if class=="mark" then + marks[index]=true + end + glyphs[index].class=class + end + elseif classformat==2 then + local nofranges=readushort(f) + for i=1,nofranges do local firstindex=readushort(f) - local lastindex=firstindex+readushort(f)-1 - for index=firstindex,lastindex do - local class=classes[readushort(f)] - if class=="mark" then - marks[index]=true - end - glyphs[index].class=class - end - elseif classformat==2 then - local nofranges=readushort(f) - for i=1,nofranges do - local firstindex=readushort(f) - local lastindex=readushort(f) - local class=classes[readushort(f)] - if class then - for index=firstindex,lastindex do - glyphs[index].class=class - if class=="mark" then - marks[index]=true - end + local lastindex=readushort(f) + local class=classes[readushort(f)] + if class then + for index=firstindex,lastindex do + glyphs[index].class=class + if class=="mark" then + marks[index]=true end end end end - setposition(f,markclassoffset) - local classformat=readushort(f) - if classformat==1 then + end + setposition(f,markclassoffset) + local classformat=readushort(f) + if classformat==1 then + local firstindex=readushort(f) + local lastindex=firstindex+readushort(f)-1 + for index=firstindex,lastindex do + markclasses[readushort(f)][index]=true + end + elseif classformat==2 then + local nofranges=readushort(f) + for i=1,nofranges do local firstindex=readushort(f) - local lastindex=firstindex+readushort(f)-1 + local lastindex=readushort(f) + local class=markclasses[readushort(f)] for index=firstindex,lastindex do - markclasses[readushort(f)][index]=true - end - elseif classformat==2 then - local nofranges=readushort(f) - for i=1,nofranges do - local firstindex=readushort(f) - local lastindex=readushort(f) - local class=markclasses[readushort(f)] - for index=firstindex,lastindex do - class[index]=true - end + class[index]=true end end - if marksetsoffset then - setposition(f,marksetsoffset) - local format=readushort(f) - if format==1 then - local nofsets=readushort(f) - local sets={} - for i=1,nofsets do - sets[i]=readulong(f) - end - for i=1,nofsets do - local offset=sets[i] - if offset~=0 then - marksets[i]=readcoverage(f,marksetsoffset+offset) + end + if marksetsoffset and marksetsoffset>tableoffset then + setposition(f,marksetsoffset) + local format=readushort(f) + if format==1 then + local nofsets=readushort(f) + local sets={} + for i=1,nofsets do + sets[i]=readulong(f) + end + for i=1,nofsets do + local offset=sets[i] + if offset~=0 then + marksets[i]=readcoverage(f,marksetsoffset+offset) + end + end + end + end + local factors=specification.factors + if (specification.variable or factors) and varsetsoffset and varsetsoffset>tableoffset then + local regions,deltas=readvariationdata(f,varsetsoffset,factors) + if factors then + fontdata.temporary.getdelta=function(outer,inner) + local delta=deltas[outer+1] + if delta then + local d=delta.deltas[inner+1] + if d then + local scales=delta.scales + local dd=0 + for i=1,#scales do + local di=d[i] + if di then + dd=dd+scales[i]*di + else + break + end + end + return round(dd) end end + return 0 end end end @@ -12343,7 +15159,13 @@ local function readmathglyphinfo(f,fontdata,offset) local function get(offset) setposition(f,kernoffset+offset) local n=readushort(f) - if n>0 then + if n==0 then + local k=readmathvalue(f) + if k==0 then + else + return { { kern=k } } + end + else local l={} for i=1,n do l[i]={ height=readmathvalue(f) } @@ -12379,10 +15201,10 @@ local function readmathglyphinfo(f,fontdata,offset) if next(kernset) then local glyph=glyphs[coverage[i]] local math=glyph.math - if not math then - glyph.math={ kerns=kernset } - else + if math then math.kerns=kernset + else + glyph.math={ kerns=kernset } end end end @@ -12479,29 +15301,501 @@ local function readmathvariants(f,fontdata,offset) get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic") end function readers.math(f,fontdata,specification) - if specification.glyphs then - local datatable=fontdata.tables.math - if datatable then - local tableoffset=datatable.offset - setposition(f,tableoffset) - local version=readulong(f) - if version~=0x00010000 then - report("table version %a of %a is not supported (yet), maybe font %s is bad",version,what,fontdata.filename) - return + local tableoffset=gotodatatable(f,fontdata,"math",specification.glyphs) + if tableoffset then + local version=readulong(f) + local constants=readushort(f) + local glyphinfo=readushort(f) + local variants=readushort(f) + if constants==0 then + report("the math table of %a has no constants",fontdata.filename) + else + readmathconstants(f,fontdata,tableoffset+constants) + end + if glyphinfo~=0 then + readmathglyphinfo(f,fontdata,tableoffset+glyphinfo) + end + if variants~=0 then + readmathvariants(f,fontdata,tableoffset+variants) + end + end +end +function readers.colr(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"colr",specification.glyphs) + if tableoffset then + local version=readushort(f) + if version~=0 then + report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"colr",fontdata.filename) + return + end + if not fontdata.tables.cpal then + report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal") + fontdata.colorpalettes={} + end + local glyphs=fontdata.glyphs + local nofglyphs=readushort(f) + local baseoffset=readulong(f) + local layeroffset=readulong(f) + local noflayers=readushort(f) + local layerrecords={} + local maxclass=0 + setposition(f,tableoffset+layeroffset) + for i=1,noflayers do + local slot=readushort(f) + local class=readushort(f) + if class<0xFFFF then + class=class+1 + if class>maxclass then + maxclass=class + end + end + layerrecords[i]={ + slot=slot, + class=class, + } + end + fontdata.maxcolorclass=maxclass + setposition(f,tableoffset+baseoffset) + for i=0,nofglyphs-1 do + local glyphindex=readushort(f) + local firstlayer=readushort(f) + local noflayers=readushort(f) + local t={} + for i=1,noflayers do + t[i]=layerrecords[firstlayer+i] end - local constants=readushort(f) - local glyphinfo=readushort(f) - local variants=readushort(f) - if constants==0 then - report("the math table of %a has no constants",fontdata.filename) - else - readmathconstants(f,fontdata,tableoffset+constants) + glyphs[glyphindex].colors=t + end + end + fontdata.hascolor=true +end +function readers.cpal(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"cpal",specification.glyphs) + if tableoffset then + local version=readushort(f) + local nofpaletteentries=readushort(f) + local nofpalettes=readushort(f) + local nofcolorrecords=readushort(f) + local firstcoloroffset=readulong(f) + local colorrecords={} + local palettes={} + for i=1,nofpalettes do + palettes[i]=readushort(f) + end + if version==1 then + local palettettypesoffset=readulong(f) + local palettelabelsoffset=readulong(f) + local paletteentryoffset=readulong(f) + end + setposition(f,tableoffset+firstcoloroffset) + for i=1,nofcolorrecords do + local b,g,r,a=readbytes(f,4) + colorrecords[i]={ + r,g,b,a~=255 and a or nil, + } + end + for i=1,nofpalettes do + local p={} + local o=palettes[i] + for j=1,nofpaletteentries do + p[j]=colorrecords[o+j] + end + palettes[i]=p + end + fontdata.colorpalettes=palettes + end +end +function readers.svg(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"svg",specification.glyphs) + if tableoffset then + local version=readushort(f) + local glyphs=fontdata.glyphs + local indexoffset=tableoffset+readulong(f) + local reserved=readulong(f) + setposition(f,indexoffset) + local nofentries=readushort(f) + local entries={} + for i=1,nofentries do + entries[i]={ + first=readushort(f), + last=readushort(f), + offset=indexoffset+readulong(f), + length=readulong(f), + } + end + for i=1,nofentries do + local entry=entries[i] + setposition(f,entry.offset) + entries[i]={ + first=entry.first, + last=entry.last, + data=readstring(f,entry.length) + } + end + fontdata.svgshapes=entries + end + fontdata.hascolor=true +end +function readers.sbix(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"sbix",specification.glyphs) + if tableoffset then + local version=readushort(f) + local flags=readushort(f) + local nofstrikes=readulong(f) + local strikes={} + local nofglyphs=fontdata.nofglyphs + for i=1,nofstrikes do + strikes[i]=readulong(f) + end + local shapes={} + local done=0 + for i=1,nofstrikes do + local strikeoffset=strikes[i]+tableoffset + setposition(f,strikeoffset) + strikes[i]={ + ppem=readushort(f), + ppi=readushort(f), + offset=strikeoffset + } end - if glyphinfo~=0 then - readmathglyphinfo(f,fontdata,tableoffset+glyphinfo) + sort(strikes,function(a,b) + if b.ppem==a.ppem then + return b.ppi<a.ppi + else + return b.ppem<a.ppem + end + end) + local glyphs={} + for i=1,nofstrikes do + local strike=strikes[i] + local strikeppem=strike.ppem + local strikeppi=strike.ppi + local strikeoffset=strike.offset + setposition(f,strikeoffset) + for i=0,nofglyphs do + glyphs[i]=readulong(f) + end + local glyphoffset=glyphs[0] + for i=0,nofglyphs-1 do + local nextoffset=glyphs[i+1] + if not shapes[i] then + local datasize=nextoffset-glyphoffset + if datasize>0 then + setposition(f,strikeoffset+glyphoffset) + shapes[i]={ + x=readshort(f), + y=readshort(f), + tag=readtag(f), + data=readstring(f,datasize-8), + ppem=strikeppem, + ppi=strikeppi, + } + done=done+1 + if done==nofglyphs then + break + end + end + end + glyphoffset=nextoffset + end end - if variants~=0 then - readmathvariants(f,fontdata,tableoffset+variants) + fontdata.sbixshapes=shapes + end +end +function readers.stat(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"stat",true) + if tableoffset then + local extras=fontdata.extras + local version=readulong(f) + local axissize=readushort(f) + local nofaxis=readushort(f) + local axisoffset=readulong(f) + local nofvalues=readushort(f) + local valuesoffset=readulong(f) + local fallbackname=extras[readushort(f)] + local axis={} + local values={} + setposition(f,tableoffset+axisoffset) + for i=1,nofaxis do + axis[i]={ + tag=readtag(f), + name=lower(extras[readushort(f)]), + ordering=readushort(f), + variants={} + } + end + setposition(f,tableoffset+valuesoffset) + for i=1,nofvalues do + values[i]=readushort(f) + end + for i=1,nofvalues do + setposition(f,tableoffset+valuesoffset+values[i]) + local format=readushort(f) + local index=readushort(f)+1 + local flags=readushort(f) + local name=lower(extras[readushort(f)]) + local value=readfixed(f) + local variant + if format==1 then + variant={ + flags=flags, + name=name, + value=value, + } + elseif format==2 then + variant={ + flags=flags, + name=name, + value=value, + minimum=readfixed(f), + maximum=readfixed(f), + } + elseif format==3 then + variant={ + flags=flags, + name=name, + value=value, + link=readfixed(f), + } + end + insert(axis[index].variants,variant) + end + sort(axis,function(a,b) + return a.ordering<b.ordering + end) + for i=1,#axis do + local a=axis[i] + sort(a.variants,function(a,b) + return a.name<b.name + end) + a.ordering=nil + end + setvariabledata(fontdata,"designaxis",axis) + setvariabledata(fontdata,"fallbackname",fallbackname) + end +end +function readers.avar(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"avar",true) + if tableoffset then + local function collect() + local nofvalues=readushort(f) + local values={} + local lastfrom=false + local lastto=false + for i=1,nofvalues do + local f,t=read2dot14(f),read2dot14(f) + if lastfrom and f<=lastfrom then + elseif lastto and t>=lastto then + else + values[#values+1]={ f,t } + lastfrom,lastto=f,t + end + end + nofvalues=#values + if nofvalues>2 then + local some=values[1] + if some[1]==-1 and some[2]==-1 then + some=values[nofvalues] + if some[1]==1 and some[2]==1 then + for i=2,nofvalues-1 do + some=values[i] + if some[1]==0 and some[2]==0 then + return values + end + end + end + end + end + return false + end + local majorversion=readushort(f) + local minorversion=readushort(f) + local reserved=readushort(f) + local nofaxis=readushort(f) + local segments={} + for i=1,nofaxis do + segments[i]=collect() + end + setvariabledata(fontdata,"segments",segments) + end +end +function readers.fvar(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"fvar",true) + if tableoffset then + local version=readulong(f) + local offsettoaxis=tableoffset+readushort(f) + local reserved=skipshort(f) + local nofaxis=readushort(f) + local sizeofaxis=readushort(f) + local nofinstances=readushort(f) + local sizeofinstances=readushort(f) + local extras=fontdata.extras + local axis={} + local instances={} + setposition(f,offsettoaxis) + for i=1,nofaxis do + axis[i]={ + tag=readtag(f), + minimum=readfixed(f), + default=readfixed(f), + maximum=readfixed(f), + flags=readushort(f), + name=lower(extras[readushort(f)] or "bad name"), + } + local n=sizeofaxis-20 + if n>0 then + skipbytes(f,n) + elseif n<0 then + end + end + local nofbytes=2+2+2+nofaxis*4 + local readpsname=nofbytes<=sizeofinstances + local skippable=sizeofinstances-nofbytes + for i=1,nofinstances do + local subfamid=readushort(f) + local flags=readushort(f) + local values={} + for i=1,nofaxis do + values[i]={ + axis=axis[i].tag, + value=readfixed(f), + } + end + local psnameid=readpsname and readushort(f) or 0xFFFF + if subfamid==2 or subfamid==17 then + elseif subfamid==0xFFFF then + subfamid=nil + elseif subfamid<=256 or subfamid>=32768 then + subfamid=nil + end + if psnameid==6 then + elseif psnameid==0xFFFF then + psnameid=nil + elseif psnameid<=256 or psnameid>=32768 then + psnameid=nil + end + instances[i]={ + subfamily=extras[subfamid], + psname=psnameid and extras[psnameid] or nil, + values=values, + } + if skippable>0 then + skipbytes(f,skippable) + end + end + setvariabledata(fontdata,"axis",axis) + setvariabledata(fontdata,"instances",instances) + end +end +function readers.hvar(f,fontdata,specification) + local factors=specification.factors + if not factors then + return + end + local tableoffset=gotodatatable(f,fontdata,"hvar",specification.variable) + if not tableoffset then + return + end + local version=readulong(f) + local variationoffset=tableoffset+readulong(f) + local advanceoffset=tableoffset+readulong(f) + local lsboffset=tableoffset+readulong(f) + local rsboffset=tableoffset+readulong(f) + local regions={} + local variations={} + local innerindex={} + local outerindex={} + if variationoffset>0 then + regions,deltas=readvariationdata(f,variationoffset,factors) + end + if not regions then + return + end + if advanceoffset>0 then + setposition(f,advanceoffset) + local format=readushort(f) + local mapcount=readushort(f) + local entrysize=rshift(band(format,0x0030),4)+1 + local nofinnerbits=band(format,0x000F)+1 + local innermask=lshift(1,nofinnerbits)-1 + local readcardinal=read_cardinal[entrysize] + for i=0,mapcount-1 do + local mapdata=readcardinal(f) + outerindex[i]=rshift(mapdata,nofinnerbits) + innerindex[i]=band(mapdata,innermask) + end + setvariabledata(fontdata,"hvarwidths",true) + local glyphs=fontdata.glyphs + for i=0,fontdata.nofglyphs-1 do + local glyph=glyphs[i] + local width=glyph.width + if width then + local outer=outerindex[i] or 0 + local inner=innerindex[i] or i + if outer and inner then + local delta=deltas[outer+1] + if delta then + local d=delta.deltas[inner+1] + if d then + local scales=delta.scales + local deltaw=0 + for i=1,#scales do + local di=d[i] + if di then + deltaw=deltaw+scales[i]*di + else + break + end + end + glyph.width=width+round(deltaw) + end + end + end + end + end + end +end +function readers.vvar(f,fontdata,specification) + if not specification.variable then + return + end +end +function readers.mvar(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"mvar",specification.variable) + if tableoffset then + local version=readulong(f) + local reserved=skipshort(f,1) + local recordsize=readushort(f) + local nofrecords=readushort(f) + local offsettostore=tableoffset+readushort(f) + local dimensions={} + local factors=specification.factors + if factors then + local regions,deltas=readvariationdata(f,offsettostore,factors) + for i=1,nofrecords do + local tag=readtag(f) + local var=variabletags[tag] + if var then + local outer=readushort(f) + local inner=readushort(f) + local delta=deltas[outer+1] + if delta then + local d=delta.deltas[inner+1] + if d then + local scales=delta.scales + local dd=0 + for i=1,#scales do + dd=dd+scales[i]*d[i] + end + var(fontdata,round(dd)) + end + end + else + skipshort(f,2) + end + if recordsize>8 then + skipbytes(recordsize-8) + end end end end @@ -12535,7 +15829,11 @@ local f_unicode=formatters["U%05X"] local f_index=formatters["I%05X"] local f_character_y=formatters["%C"] local f_character_n=formatters["[ %C ]"] -local doduplicates=true +local check_duplicates=true +local check_soft_hyphen=false +directives.register("otf.checksofthyphen",function(v) + check_soft_hyphen=v +end) local function replaced(list,index,replacement) if type(list)=="number" then return replacement @@ -12603,7 +15901,7 @@ local function unifyresources(fontdata,indices) end end local done={} - local duplicates=doduplicates and resources.duplicates + local duplicates=check_duplicates and resources.duplicates if duplicates and not next(duplicates) then duplicates=false end @@ -12840,10 +16138,31 @@ local function unifyresources(fontdata,indices) unifythem(resources.sublookups) end local function copyduplicates(fontdata) - if doduplicates then + if check_duplicates then local descriptions=fontdata.descriptions local resources=fontdata.resources local duplicates=resources.duplicates + if check_soft_hyphen then + local ds=descriptions[0xAD] + if not ds or ds.width==0 then + if ds then + descriptions[0xAD]=nil + report("patching soft hyphen") + else + report("adding soft hyphen") + end + if not duplicates then + duplicates={} + resources.duplicates=duplicates + end + local dh=duplicates[0x2D] + if dh then + dh[#dh+1]={ [0xAD]=true } + else + duplicates[0x2D]={ [0xAD]=true } + end + end + end if duplicates then for u,d in next,duplicates do local du=descriptions[u] @@ -13163,6 +16482,18 @@ local function unifyglyphs(fontdata,usenames) end end end + local colorpalettes=resources.colorpalettes + if colorpalettes then + for index=1,#glyphs do + local colors=glyphs[index].colors + if colors then + for i=1,#colors do + local c=colors[i] + c.slot=indices[c.slot] + end + end + end + end fontdata.private=private fontdata.glyphs=nil fontdata.names=names @@ -13272,6 +16603,7 @@ function readers.getcomponents(fontdata) end end end +readers.unifymissing=unifymissing function readers.rehash(fontdata,hashmethod) if not (fontdata and fontdata.glyphs) then return @@ -13285,7 +16617,7 @@ function readers.rehash(fontdata,hashmethod) copyduplicates(fontdata) unifymissing(fontdata) else - fontdata.hashmethod="unicode" + fontdata.hashmethod="unicodes" local indices=unifyglyphs(fontdata) unifyresources(fontdata,indices) copyduplicates(fontdata) @@ -13300,10 +16632,10 @@ function readers.checkhash(fontdata) elseif hashmethod=="names" and fontdata.names then unifyresources(fontdata,fontdata.names) copyduplicates(fontdata) - fontdata.hashmethod="unicode" + fontdata.hashmethod="unicodes" fontdata.names=nil else - readers.rehash(fontdata,"unicode") + readers.rehash(fontdata,"unicodes") end end function readers.addunicodetable(fontdata) @@ -13563,6 +16895,8 @@ function readers.pack(data) local sequences=resources.sequences local sublookups=resources.sublookups local features=resources.features + local palettes=resources.colorpalettes + local variable=resources.variabledata local chardata=characters and characters.data local descriptions=data.descriptions or data.glyphs if not descriptions then @@ -13674,7 +17008,7 @@ function readers.pack(data) local r=rule.before if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end local r=rule.after if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end local r=rule.current if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end - local r=rule.replacements if r then rule.replacements=pack_flat (r) end + local r=rule.replacements if r then rule.replacements=pack_flat (r) end end end end @@ -13705,6 +17039,54 @@ function readers.pack(data) end end end + if palettes then + for i=1,#palettes do + local p=palettes[i] + for j=1,#p do + p[j]=pack_indexed(p[j]) + end + end + end + if variable then + local instances=variable.instances + if instances then + for i=1,#instances do + local v=instances[i].values + for j=1,#v do + v[j]=pack_normal(v[j]) + end + end + end + local function packdeltas(main) + if main then + local deltas=main.deltas + if deltas then + for i=1,#deltas do + local di=deltas[i] + local d=di.deltas + local r=di.regions + for j=1,#d do + d[j]=pack_indexed(d[j]) + end + di.regions=pack_indexed(di.regions) + end + end + local regions=main.regions + if regions then + for i=1,#regions do + local r=regions[i] + for j=1,#r do + r[j]=pack_normal(r[j]) + end + end + end + end + end + packdeltas(variable.global) + packdeltas(variable.horizontal) + packdeltas(variable.vertical) + packdeltas(variable.metrics) + end if not success(1,pass) then return end @@ -13768,7 +17150,19 @@ function readers.pack(data) if sublookups then packthem(sublookups) end - if not success(2,pass) then + if variable then + local function unpackdeltas(main) + if main then + local regions=main.regions + if regions then + main.regions=pack_normal(regions) + end + end + end + unpackdeltas(variable.global) + unpackdeltas(variable.horizontal) + unpackdeltas(variable.vertical) + unpackdeltas(variable.metrics) end end for pass=1,2 do @@ -13825,6 +17219,8 @@ function readers.unpack(data) local sequences=resources.sequences local sublookups=resources.sublookups local features=resources.features + local palettes=resources.colorpalettes + local variable=resources.variabledata local unpacked={} setmetatable(unpacked,unpacked_mt) for unicode,description in next,descriptions do @@ -14011,7 +17407,7 @@ function readers.unpack(data) end local replacements=rule.replacements if replacements then - local tv=tables[replace] + local tv=tables[replacements] if tv then rule.replacements=tv end @@ -14063,6 +17459,74 @@ function readers.unpack(data) end end end + if palettes then + for i=1,#palettes do + local p=palettes[i] + for j=1,#p do + local tv=tables[p[j]] + if tv then + p[j]=tv + end + end + end + end + if variable then + local instances=variable.instances + if instances then + for i=1,#instances do + local v=instances[i].values + for j=1,#v do + local tv=tables[v[j]] + if tv then + v[j]=tv + end + end + end + end + local function unpackdeltas(main) + if main then + local deltas=main.deltas + if deltas then + for i=1,#deltas do + local di=deltas[i] + local d=di.deltas + local r=di.regions + for j=1,#d do + local tv=tables[d[j]] + if tv then + d[j]=tv + end + end + local tv=di.regions + if tv then + di.regions=tv + end + end + end + local regions=main.regions + if regions then + local tv=tables[regions] + if tv then + main.regions=tv + regions=tv + end + for i=1,#regions do + local r=regions[i] + for j=1,#r do + local tv=tables[r[j]] + if tv then + r[j]=tv + end + end + end + end + end + end + unpackdeltas(variable.global) + unpackdeltas(variable.horizontal) + unpackdeltas(variable.vertical) + unpackdeltas(variable.metrics) + end data.tables=nil end end @@ -14444,14 +17908,19 @@ function readers.expand(data) local lookups=rule.lookups or false local subtype=nil if lookups then - for k,v in next,lookups do - local lookup=sublookups[v] - if lookup then - lookups[k]=lookup - if not subtype then - subtype=lookup.type + for i=1,#lookups do + local lookups=lookups[i] + if lookups then + for k,v in next,lookups do + local lookup=sublookups[v] + if lookup then + lookups[k]=lookup + if not subtype then + subtype=lookup.type + end + else + end end - else end end end @@ -14496,10 +17965,9 @@ if not modules then modules={} end modules ['font-otl']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files", } -local gmatch,find,match,lower,strip=string.gmatch,string.find,string.match,string.lower,string.strip +local lower=string.lower local type,next,tonumber,tostring,unpack=type,next,tonumber,tostring,unpack local abs=math.abs -local ioflush=io.flush local derivetable=table.derive local formatters=string.formatters local setmetatableindex=table.setmetatableindex @@ -14516,19 +17984,22 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_de local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf -otf.version=3.020 +otf.version=3.029 otf.cache=containers.define("fonts","otl",otf.version,true) +otf.svgcache=containers.define("fonts","svg",otf.version,true) +otf.sbixcache=containers.define("fonts","sbix",otf.version,true) +otf.pdfcache=containers.define("fonts","pdf",otf.version,true) +otf.svgenabled=false +otf.sbixenabled=false local otfreaders=otf.readers local hashes=fonts.hashes local definers=fonts.definers local readers=fonts.readers local constructors=fonts.constructors -local otffeatures=constructors.newfeatures("otf") +local otffeatures=constructors.features.otf local registerotffeature=otffeatures.register -local enhancers=allocate() -otf.enhancers=enhancers -local patches={} -enhancers.patches=patches +local otfenhancers=constructors.enhancers.otf +local registerotfenhancer=otfenhancers.register local forceload=false local cleanup=0 local syncspace=true @@ -14544,86 +18015,13 @@ registerdirective("fonts.otf.loader.cleanup",function(v) cleanup=tonumber(v) or registerdirective("fonts.otf.loader.force",function(v) forceload=v end) registerdirective("fonts.otf.loader.syncspace",function(v) syncspace=v end) registerdirective("fonts.otf.loader.forcenotdef",function(v) forcenotdef=v end) -local ordered_enhancers={ - "check extra features", -} -local actions=allocate() -local before=allocate() -local after=allocate() -patches.before=before -patches.after=after -local function enhance(name,data,filename,raw) - local enhancer=actions[name] - if enhancer then - if trace_loading then - report_otf("apply enhancement %a to file %a",name,filename) - ioflush() - end - enhancer(data,filename,raw) - else - end -end -function enhancers.apply(data,filename,raw) - local basename=file.basename(lower(filename)) - if trace_loading then - report_otf("%s enhancing file %a","start",filename) - end - ioflush() - for e=1,#ordered_enhancers do - local enhancer=ordered_enhancers[e] - local b=before[enhancer] - if b then - for pattern,action in next,b do - if find(basename,pattern) then - action(data,filename,raw) - end - end - end - enhance(enhancer,data,filename,raw) - local a=after[enhancer] - if a then - for pattern,action in next,a do - if find(basename,pattern) then - action(data,filename,raw) - end - end - end - ioflush() - end - if trace_loading then - report_otf("%s enhancing file %a","stop",filename) - end - ioflush() -end -function patches.register(what,where,pattern,action) - local pw=patches[what] - if pw then - local ww=pw[where] - if ww then - ww[pattern]=action - else - pw[where]={ [pattern]=action} - end - end -end -function patches.report(fmt,...) - if trace_loading then - report_otf("patching: %s",formatters[fmt](...)) - end -end -function enhancers.register(what,action) - actions[what]=action -end -function otf.load(filename,sub,featurefile) - local featurefile=nil +registerotfenhancer("check extra features",function() end) +function otf.load(filename,sub,instance) local base=file.basename(file.removesuffix(filename)) - local name=file.removesuffix(base) + local name=file.removesuffix(base) local attr=lfs.attributes(filename) local size=attr and attr.size or 0 local time=attr and attr.modification or 0 - if featurefile then - name=name.."@"..file.removesuffix(file.basename(featurefile)) - end if sub=="" then sub=false end @@ -14631,27 +18029,10 @@ function otf.load(filename,sub,featurefile) if sub then hash=hash.."-"..sub end - hash=containers.cleanname(hash) - local featurefiles - if featurefile then - featurefiles={} - for s in gmatch(featurefile,"[^,]+") do - local name=resolvers.findfile(file.addsuffix(s,'fea'),'fea') or "" - if name=="" then - report_otf("loading error, no featurefile %a",s) - else - local attr=lfs.attributes(name) - featurefiles[#featurefiles+1]={ - name=name, - size=attr and attr.size or 0, - time=attr and attr.modification or 0, - } - end - end - if #featurefiles==0 then - featurefiles=nil - end + if instance then + hash=hash.."-"..instance end + hash=containers.cleanname(hash) local data=containers.read(otf.cache,hash) local reload=not data or data.size~=size or data.time~=time or data.tableversion~=otfreaders.tableversion if forceload then @@ -14661,8 +18042,39 @@ function otf.load(filename,sub,featurefile) if reload then report_otf("loading %a, hash %a",filename,hash) starttiming(otfreaders) - data=otfreaders.loadfont(filename,sub or 1) + data=otfreaders.loadfont(filename,sub or 1,instance) if data then + local resources=data.resources + local svgshapes=resources.svgshapes + local sbixshapes=resources.sbixshapes + if svgshapes then + resources.svgshapes=nil + if otf.svgenabled then + local timestamp=os.date() + containers.write(otf.svgcache,hash,{ + svgshapes=svgshapes, + timestamp=timestamp, + }) + data.properties.svg={ + hash=hash, + timestamp=timestamp, + } + end + end + if sbixshapes then + resources.sbixshapes=nil + if otf.sbixenabled then + local timestamp=os.date() + containers.write(otf.sbixcache,hash,{ + sbixshapes=sbixshapes, + timestamp=timestamp, + }) + data.properties.sbix={ + hash=hash, + timestamp=timestamp, + } + end + end otfreaders.compact(data) otfreaders.rehash(data,"unicodes") otfreaders.addunicodetable(data) @@ -14675,7 +18087,7 @@ function otf.load(filename,sub,featurefile) collectgarbage("collect") end stoptiming(otfreaders) - if elapsedtime then + if elapsedtime then report_otf("loading, optimizing, packing and caching time %s",elapsedtime(otfreaders)) end if cleanup>3 then @@ -14697,11 +18109,22 @@ function otf.load(filename,sub,featurefile) otfreaders.unpack(data) otfreaders.expand(data) otfreaders.addunicodetable(data) - enhancers.apply(data,filename,data) + otfenhancers.apply(data,filename,data) if applyruntimefixes then applyruntimefixes(filename,data) end data.metadata.math=data.resources.mathconstants + local classes=data.resources.classes + if not classes then + local descriptions=data.descriptions + classes=setmetatableindex(function(t,k) + local d=descriptions[k] + local v=(d and d.class or "base") or false + t[k]=v + return v + end) + data.resources.classes=classes + end end return data end @@ -14716,7 +18139,6 @@ end local function copytotfm(data,cache_id) if data then local metadata=data.metadata - local resources=data.resources local properties=derivetable(data.properties) local descriptions=derivetable(data.descriptions) local goodies=derivetable(data.goodies) @@ -14838,13 +18260,13 @@ local function copytotfm(data,cache_id) spaceunits,spacer=charwidth,"charwidth" end end - spaceunits=tonumber(spaceunits) or 500 + spaceunits=tonumber(spaceunits) or units/2 parameters.slant=0 - parameters.space=spaceunits + parameters.space=spaceunits parameters.space_stretch=1*units/2 - parameters.space_shrink=1*units/3 - parameters.x_height=2*units/5 - parameters.quad=units + parameters.space_shrink=1*units/3 + parameters.x_height=2*units/5 + parameters.quad=units if spaceunits<2*units/5 then end if italicangle and italicangle~=0 then @@ -14897,16 +18319,45 @@ local function copytotfm(data,cache_id) } end end +local converters={ + woff={ + cachename="webfonts", + action=otf.readers.woff2otf, + } +} +local function checkconversion(specification) + local filename=specification.filename + local converter=converters[lower(file.suffix(filename))] + if converter then + local base=file.basename(filename) + local name=file.removesuffix(base) + local attr=lfs.attributes(filename) + local size=attr and attr.size or 0 + local time=attr and attr.modification or 0 + if size>0 then + local cleanname=containers.cleanname(name) + local cachename=caches.setfirstwritablefile(cleanname,converter.cachename) + if not io.exists(cachename) or (time~=lfs.attributes(cachename).modification) then + report_otf("caching font %a in %a",filename,cachename) + converter.action(filename,cachename) + lfs.touch(cachename,time,time) + end + specification.filename=cachename + end + end +end local function otftotfm(specification) local cache_id=specification.hash local tfmdata=containers.read(constructors.cache,cache_id) if not tfmdata then + checkconversion(specification) local name=specification.name local sub=specification.sub local subindex=specification.subindex local filename=specification.filename local features=specification.features.normal - local rawdata=otf.load(filename,sub,features and features.featurefile) + local instance=specification.instance or (features and features.axis) + local rawdata=otf.load(filename,sub,instance) if rawdata and next(rawdata) then local descriptions=rawdata.descriptions rawdata.lookuphash={} @@ -15030,7 +18481,6 @@ local function getgsub(tfmdata,k,kind,value) local properties=tfmdata.properties local validlookups,lookuplist=otf.collectlookups(rawdata,kind,properties.script,properties.language) if validlookups then - local choice=tonumber(value) or 1 for i=1,#lookuplist do local lookup=lookuplist[i] local steps=lookup.steps @@ -15051,7 +18501,7 @@ local function getgsub(tfmdata,k,kind,value) end otf.getgsub=getgsub function otf.getsubstitution(tfmdata,k,kind,value) - local found,kind=getgsub(tfmdata,k,kind) + local found,kind=getgsub(tfmdata,k,kind,value) if not found then elseif kind=="gsub_single" then return found @@ -15108,9 +18558,13 @@ local function opentypereader(specification,suffix) end end readers.opentype=opentypereader -function readers.otf (specification) return opentypereader(specification,"otf") end -function readers.ttf (specification) return opentypereader(specification,"ttf") end -function readers.ttc (specification) return opentypereader(specification,"ttf") end +function readers.otf(specification) return opentypereader(specification,"otf") end +function readers.ttf(specification) return opentypereader(specification,"ttf") end +function readers.ttc(specification) return opentypereader(specification,"ttf") end +function readers.woff(specification) + checkconversion(specification) + opentypereader(specification,"") +end function otf.scriptandlanguage(tfmdata,attr) local properties=tfmdata.properties return properties.script or "dflt",properties.language or "dflt" @@ -15170,8 +18624,6 @@ local concat,unpack=table.concat,table.unpack local insert,remove=table.insert,table.remove local format,gmatch,gsub,find,match,lower,strip=string.format,string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip local type,next,tonumber,tostring,rawget=type,next,tonumber,tostring,rawget -local lpegmatch=lpeg.match -local utfchar=utf.char local trace_baseinit=false trackers.register("otf.baseinit",function(v) trace_baseinit=v end) local trace_singles=false trackers.register("otf.singles",function(v) trace_singles=v end) local trace_multiples=false trackers.register("otf.multiples",function(v) trace_multiples=v end) @@ -15256,7 +18708,7 @@ local function registerbasehash(tfmdata) basehash[hash]=base end properties.basehash=base - properties.fullname=properties.fullname.."-"..base + properties.fullname=(properties.fullname or properties.name).."-"..base applied={} end local function registerbasefeature(feature,value) @@ -15324,6 +18776,10 @@ local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplis local trace_singles=trace_baseinit and trace_singles local trace_alternatives=trace_baseinit and trace_alternatives local trace_ligatures=trace_baseinit and trace_ligatures + if not changed then + changed={} + tfmdata.changed=changed + end for i=1,#lookuplist do local sequence=lookuplist[i] local steps=sequence.steps @@ -15331,12 +18787,10 @@ local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplis if kind=="gsub_single" then for i=1,#steps do for unicode,data in next,steps[i].coverage do - if not changed[unicode] then if trace_singles then report_substitution(feature,sequence,descriptions,unicode,data) end changed[unicode]=data - end end end elseif kind=="gsub_alternate" then @@ -15477,7 +18931,8 @@ local function featuresinitializer(tfmdata,value) local properties=tfmdata.properties local script=properties.script local language=properties.language - local rawfeatures=rawdata.resources.features + local rawresources=rawdata.resources + local rawfeatures=rawresources and rawresources.features local basesubstitutions=rawfeatures and rawfeatures.gsub local basepositionings=rawfeatures and rawfeatures.gpos if basesubstitutions or basepositionings then @@ -15542,15 +18997,13 @@ if not modules then modules={} end modules ['font-otj']={ license="see context related readme files", } if not nodes.properties then return end -local next,rawget=next,rawget -local utfchar=utf.char +local next,rawget,tonumber=next,rawget,tonumber local fastcopy=table.fastcopy local registertracker=trackers.register local trace_injections=false registertracker("fonts.injections",function(v) trace_injections=v end) local trace_marks=false registertracker("fonts.injections.marks",function(v) trace_marks=v end) local trace_cursive=false registertracker("fonts.injections.cursive",function(v) trace_cursive=v end) -local trace_spaces=false registertracker("otf.spaces",function(v) trace_spaces=v end) -local use_advance=false directives.register("fonts.injections.advance",function(v) use_advance=v end) +local trace_spaces=false registertracker("fonts.injections.spaces",function(v) trace_spaces=v end) local report_injections=logs.reporter("fonts","injections") local report_spaces=logs.reporter("fonts","spaces") local attributes,nodes,node=attributes,nodes,node @@ -15578,17 +19031,22 @@ local getnext=nuts.getnext local getprev=nuts.getprev local getid=nuts.getid local getfont=nuts.getfont -local getsubtype=nuts.getsubtype local getchar=nuts.getchar +local getoffsets=nuts.getoffsets local getboth=nuts.getboth -local ischar=nuts.is_char local getdisc=nuts.getdisc local setdisc=nuts.setdisc +local setoffsets=nuts.setoffsets +local ischar=nuts.is_char +local getkern=nuts.getkern +local setkern=nuts.setkern +local setlink=nuts.setlink +local setwidth=nuts.setwidth +local getwidth=nuts.getwidth local traverse_id=nuts.traverse_id local traverse_char=nuts.traverse_char local insert_node_before=nuts.insert_before local insert_node_after=nuts.insert_after -local find_tail=nuts.tail local properties=nodes.properties.data function injections.installnewkern(nk) newkern=nk or newkern @@ -15626,7 +19084,7 @@ function injections.copy(target,source) if tp then tp.injections=si else - propertydata[target]={ + properties[target]={ injections=si, } end @@ -15816,7 +19274,7 @@ function injections.setkern(current,factor,rlmode,x,injection) return 0,0 end end -function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) +function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark) local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2]) nofregisteredmarks=nofregisteredmarks+1 if rlmode>=0 then @@ -15834,6 +19292,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) i.markbase=nofregisteredmarks i.markbasenode=base i.markmark=mkmk + i.checkmark=checkmark end else p.injections={ @@ -15843,6 +19302,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) markbase=nofregisteredmarks, markbasenode=base, markmark=mkmk, + checkmark=checkmark, } end else @@ -15854,6 +19314,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) markbase=nofregisteredmarks, markbasenode=base, markmark=mkmk, + checkmark=checkmark, }, } end @@ -15952,11 +19413,12 @@ local function show_result(head) while current do local id=getid(current) if id==glyph_code then - report_injections("char: %C, width %p, xoffset %p, yoffset %p", - getchar(current),getfield(current,"width"),getfield(current,"xoffset"),getfield(current,"yoffset")) + local w=getwidth(current) + local x,y=getoffsets(current) + report_injections("char: %C, width %p, xoffset %p, yoffset %p",getchar(current),w,x,y) skipping=false elseif id==kern_code then - report_injections("kern: %p",getfield(current,"kern")) + report_injections("kern: %p",getkern(current)) skipping=false elseif not skipping then report_injections() @@ -15982,70 +19444,58 @@ local function inject_kerns_only(head,where) local posttail=nil local replacetail=nil while current do - local id=getid(current) local next=getnext(current) - if id==glyph_code then - if getsubtype(current)<256 then - local p=rawget(properties,current) - if p then - local i=p.injections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - if use_advance then - setfield(current,"xoffset",leftkern) - setfield(current,"xadvance",leftkern) - else - insert_node_before(head,current,newkern(leftkern)) + local char,id=ischar(current) + if char then + local p=rawget(properties,current) + if p then + local i=p.injections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + head=insert_node_before(head,current,newkern(leftkern)) + end + end + if prevdisc then + local done=false + if post then + local i=p.postinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(posttail,newkern(leftkern)) + done=true end end end - if prevdisc then - local done=false - if post then - local i=p.postinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - if use_advance then - setfield(post,"xadvance",leftkern) - else - insert_node_after(post,posttail,newkern(leftkern)) - done=true - end - end + if replace then + local i=p.replaceinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(replacetail,newkern(leftkern)) + done=true end end - if replace then - local i=p.replaceinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - if use_advance then - setfield(replace,"xadvance",leftkern) - else - insert_node_after(replace,replacetail,newkern(leftkern)) - done=true - end - end - end - else - local i=p.emptyinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setfield(prev,"replace",newkern(leftkern)) - end + else + local i=p.emptyinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setfield(prev,"replace",newkern(leftkern)) end end - if done then - setdisc(prevdisc,pre,post,replace) - end + end + if done then + setdisc(prevdisc,pre,post,replace) end end end prevdisc=nil prevglyph=current + elseif char==false then + prevdisc=nil + prevglyph=current elseif id==disc_code then pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) local done=false @@ -16057,13 +19507,8 @@ local function inject_kerns_only(head,where) if i then local leftkern=i.leftkern if leftkern and leftkern~=0 then - if use_advance then - setfield(pre,"xoffset",leftkern) - setfield(pre,"xadvance",leftkern) - else - pre=insert_node_before(pre,n,newkern(leftkern)) - done=true - end + pre=insert_node_before(pre,n,newkern(leftkern)) + done=true end end end @@ -16077,13 +19522,8 @@ local function inject_kerns_only(head,where) if i then local leftkern=i.leftkern if leftkern and leftkern~=0 then - if use_advance then - setfield(post,"xoffset",leftkern) - setfield(post,"xadvance",leftkern) - else - post=insert_node_before(post,n,newkern(leftkern)) - done=true - end + post=insert_node_before(post,n,newkern(leftkern)) + done=true end end end @@ -16097,13 +19537,8 @@ local function inject_kerns_only(head,where) if i then local leftkern=i.leftkern if leftkern and leftkern~=0 then - if use_advance then - setfield(replace,"xoffset",leftkern) - setfield(replace,"xadvance",leftkern) - else - replace=insert_node_before(replace,n,newkern(leftkern)) - done=true - end + replace=insert_node_before(replace,n,newkern(leftkern)) + done=true end end end @@ -16145,78 +19580,79 @@ local function inject_pairs_only(head,where) local posttail=nil local replacetail=nil while current do - local id=getid(current) local next=getnext(current) - if id==glyph_code then - if getsubtype(current)<256 then - local p=rawget(properties,current) - if p then - local i=p.injections + local char,id=ischar(current) + if char then + local p=rawget(properties,current) + if p then + local i=p.injections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(current,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + head=insert_node_before(head,current,newkern(leftkern)) + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(head,current,newkern(rightkern)) + end + else + local i=p.emptyinjections if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setfield(current,"yoffset",yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - insert_node_before(head,current,newkern(leftkern)) - end local rightkern=i.rightkern if rightkern and rightkern~=0 then - insert_node_after(head,current,newkern(rightkern)) - end - else - local i=p.emptyinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - if next and getid(next)==disc_code then - if replace then - else - setfield(next,"replace",newkern(rightkern)) - end + if next and getid(next)==disc_code then + if replace then + else + setfield(next,"replace",newkern(rightkern)) end end end end - if prevdisc then - local done=false - if post then - local i=p.postinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - insert_node_after(post,posttail,newkern(leftkern)) - done=true - end + end + if prevdisc then + local done=false + if post then + local i=p.postinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(posttail,newkern(leftkern)) + done=true end end - if replace then - local i=p.replaceinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - insert_node_after(replace,replacetail,newkern(leftkern)) - done=true - end - end - else - local i=p.emptyinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setfield(prev,"replace",newkern(leftkern)) - end + end + if replace then + local i=p.replaceinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(replacetail,newkern(leftkern)) + done=true end end - if done then - setdisc(prevdisc,pre,post,replace) + else + local i=p.emptyinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setfield(prev,"replace",newkern(leftkern)) + end end end + if done then + setdisc(prevdisc,pre,post,replace) + end end end prevdisc=nil prevglyph=current + elseif char==false then + prevdisc=nil + prevglyph=current elseif id==disc_code then pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) local done=false @@ -16228,7 +19664,7 @@ local function inject_pairs_only(head,where) if i then local yoffset=i.yoffset if yoffset and yoffset~=0 then - setfield(n,"yoffset",yoffset) + setoffsets(n,false,yoffset) end local leftkern=i.leftkern if leftkern and leftkern~=0 then @@ -16252,7 +19688,7 @@ local function inject_pairs_only(head,where) if i then local yoffset=i.yoffset if yoffset and yoffset~=0 then - setfield(n,"yoffset",yoffset) + setoffsets(n,false,yoffset) end local leftkern=i.leftkern if leftkern and leftkern~=0 then @@ -16276,7 +19712,7 @@ local function inject_pairs_only(head,where) if i then local yoffset=i.yoffset if yoffset and yoffset~=0 then - setfield(n,"yoffset",yoffset) + setoffsets(n,false,yoffset) end local leftkern=i.leftkern if leftkern and leftkern~=0 then @@ -16340,11 +19776,8 @@ local function inject_pairs_only(head,where) return tonode(head),true end local function showoffset(n,flag) - local o=getfield(n,"xoffset") - if o==0 then - o=getfield(n,"yoffset") - end - if o~=0 then + local x,y=getoffsets(n) + if x~=0 or y~=0 then setcolor(n,flag and "darkred" or "darkgreen") else resetcolor(n) @@ -16378,7 +19811,8 @@ local function inject_everything(head,where) local marks={} local nofmarks=0 local function processmark(p,n,pn) - local px=getfield(p,"xoffset") + local px,py=getoffsets(p) + local nx,ny=getoffsets(n) local ox=0 local rightkern=nil local pp=rawget(properties,p) @@ -16400,167 +19834,174 @@ local function inject_everything(head,where) ox=px-pn.markx end else - ox=px-pn.markx + ox=px-pn.markx-rightkern end end else ox=px-pn.markx - local wn=getfield(n,"width") - if wn~=0 then - pn.leftkern=-wn/2 - pn.rightkern=-wn/2 + if pn.checkmark then + local wn=getwidth(n) + if wn and wn~=0 then + wn=wn/2 + if trace_injections then + report_injections("correcting non zero width mark %C",getchar(n)) + end + insert_node_before(n,n,newkern(-wn)) + insert_node_after(n,n,newkern(-wn)) + end end end - local oy=getfield(n,"yoffset")+getfield(p,"yoffset")+pn.marky - setfield(n,"xoffset",ox) - setfield(n,"yoffset",oy) + local oy=ny+py+pn.marky + setoffsets(n,ox,oy) if trace_marks then showoffset(n,true) end end while current do - local id=getid(current) local next=getnext(current) - if id==glyph_code then - if getsubtype(current)<256 then - local p=rawget(properties,current) - if p then - local i=p.injections - if i then - local pm=i.markbasenode - if pm then - nofmarks=nofmarks+1 - marks[nofmarks]=current - else - if hascursives then - local cursivex=i.cursivex - if cursivex then - if cursiveanchor then - if cursivex~=0 then - i.leftkern=(i.leftkern or 0)+cursivex - end - if maxc==0 then - minc=1 - maxc=1 - glyphs[1]=cursiveanchor - else - maxc=maxc+1 - glyphs[maxc]=cursiveanchor - end - properties[cursiveanchor].cursivedy=i.cursivey - last=current + local char,id=ischar(current) + if char then + local p=rawget(properties,current) + if p then + local i=p.injections + if i then + local pm=i.markbasenode + if pm then + nofmarks=nofmarks+1 + marks[nofmarks]=current + else + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(current,false,yoffset) + end + if hascursives then + local cursivex=i.cursivex + if cursivex then + if cursiveanchor then + if cursivex~=0 then + i.leftkern=(i.leftkern or 0)+cursivex + end + if maxc==0 then + minc=1 + maxc=1 + glyphs[1]=cursiveanchor else - maxc=0 + maxc=maxc+1 + glyphs[maxc]=cursiveanchor end - elseif maxc>0 then - local ny=getfield(current,"yoffset") + properties[cursiveanchor].cursivedy=i.cursivey + last=current + else + maxc=0 + end + elseif maxc>0 then + local nx,ny=getoffsets(current) + for i=maxc,minc,-1 do + local ti=glyphs[i] + ny=ny+properties[ti].cursivedy + setoffsets(ti,false,ny) + if trace_cursive then + showoffset(ti) + end + end + maxc=0 + cursiveanchor=nil + end + if i.cursiveanchor then + cursiveanchor=current + else + if maxc>0 then + local nx,ny=getoffsets(current) for i=maxc,minc,-1 do local ti=glyphs[i] ny=ny+properties[ti].cursivedy - setfield(ti,"yoffset",ny) + setoffsets(ti,false,ny) if trace_cursive then showoffset(ti) end end maxc=0 - cursiveanchor=nil - end - if i.cursiveanchor then - cursiveanchor=current - else - if maxc>0 then - local ny=getfield(current,"yoffset") - for i=maxc,minc,-1 do - local ti=glyphs[i] - ny=ny+properties[ti].cursivedy - setfield(ti,"yoffset",ny) - if trace_cursive then - showoffset(ti) - end - end - maxc=0 - end - cursiveanchor=nil end - end - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setfield(current,"yoffset",yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - insert_node_before(head,current,newkern(leftkern)) - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(head,current,newkern(rightkern)) + cursiveanchor=nil end end - else - local i=p.emptyinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - if next and getid(next)==disc_code then - if replace then - else - setfield(next,"replace",newkern(rightkern)) - end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + head=insert_node_before(head,current,newkern(leftkern)) + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(head,current,newkern(rightkern)) + end + end + else + local i=p.emptyinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + if next and getid(next)==disc_code then + if replace then + else + setfield(next,"replace",newkern(rightkern)) end end end end - if prevdisc then - if p then - local done=false - if post then - local i=p.postinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - insert_node_after(post,posttail,newkern(leftkern)) - done=true - end + end + if prevdisc then + if p then + local done=false + if post then + local i=p.postinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(posttail,newkern(leftkern)) + done=true end end - if replace then - local i=p.replaceinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - insert_node_after(replace,replacetail,newkern(leftkern)) - done=true - end - end - else - local i=p.emptyinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setfield(prev,"replace",newkern(leftkern)) - end + end + if replace then + local i=p.replaceinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(replacetail,newkern(leftkern)) + done=true end end - if done then - setdisc(prevdisc,pre,post,replace) + else + local i=p.emptyinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setfield(prev,"replace",newkern(leftkern)) + end end end - end - else - if hascursives and maxc>0 then - local ny=getfield(current,"yoffset") - for i=maxc,minc,-1 do - local ti=glyphs[i] - ny=ny+properties[ti].cursivedy - setfield(ti,"yoffset",getfield(ti,"yoffset")+ny) + if done then + setdisc(prevdisc,pre,post,replace) end - maxc=0 - cursiveanchor=nil end end + else + if hascursives and maxc>0 then + local nx,ny=getoffsets(current) + for i=maxc,minc,-1 do + local ti=glyphs[i] + ny=ny+properties[ti].cursivedy + local xi,yi=getoffsets(ti) + setoffsets(ti,xi,yi+ny) + end + maxc=0 + cursiveanchor=nil + end end prevdisc=nil prevglyph=current + elseif char==false then + prevdisc=nil + prevglyph=current elseif id==disc_code then pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) local done=false @@ -16572,7 +20013,7 @@ local function inject_everything(head,where) if i then local yoffset=i.yoffset if yoffset and yoffset~=0 then - setfield(n,"yoffset",yoffset) + setoffsets(n,false,yoffset) end local leftkern=i.leftkern if leftkern and leftkern~=0 then @@ -16587,7 +20028,7 @@ local function inject_everything(head,where) if hasmarks then local pm=i.markbasenode if pm then - processmark(pm,current,i) + processmark(pm,n,i) end end end @@ -16602,7 +20043,7 @@ local function inject_everything(head,where) if i then local yoffset=i.yoffset if yoffset and yoffset~=0 then - setfield(n,"yoffset",yoffset) + setoffsets(n,false,yoffset) end local leftkern=i.leftkern if leftkern and leftkern~=0 then @@ -16617,7 +20058,7 @@ local function inject_everything(head,where) if hasmarks then local pm=i.markbasenode if pm then - processmark(pm,current,i) + processmark(pm,n,i) end end end @@ -16632,7 +20073,7 @@ local function inject_everything(head,where) if i then local yoffset=i.yoffset if yoffset and yoffset~=0 then - setfield(n,"yoffset",yoffset) + setoffsets(n,false,yoffset) end local leftkern=i.leftkern if leftkern and leftkern~=0 then @@ -16647,7 +20088,7 @@ local function inject_everything(head,where) if hasmarks then local pm=i.markbasenode if pm then - processmark(pm,current,i) + processmark(pm,n,i) end end end @@ -16695,11 +20136,11 @@ local function inject_everything(head,where) current=next end if hascursives and maxc>0 then - local ny=getfield(last,"yoffset") + local nx,ny=getoffsets(last) for i=maxc,minc,-1 do local ti=glyphs[i] ny=ny+properties[ti].cursivedy - setfield(ti,"yoffset",ny) + setoffsets(ti,false,ny) if trace_cursive then showoffset(ti) end @@ -16733,6 +20174,37 @@ function nodes.injections.setspacekerns(font,sequence) triggers={ [font]=sequence } end end +local getthreshold +if context then + local threshold=1 + local parameters=fonts.hashes.parameters + directives.register("otf.threshold",function(v) threshold=tonumber(v) or 1 end) + getthreshold=function(font) + local p=parameters[font] + local f=p.factor + local s=p.spacing + local t=threshold*(s and s.width or p.space or 0)-2 + return t>0 and t or 0,f + end +else + injections.threshold=0 + getthreshold=function(font) + local p=fontdata[font].parameters + local f=p.factor + local s=p.spacing + local t=injections.threshold*(s and s.width or p.space or 0)-2 + return t>0 and t or 0,f + end +end +injections.getthreshold=getthreshold +function injections.isspace(n,threshold,id) + if (id or getid(n))==glue_code then + local w=getwidth(n) + if threshold and w>threshold then + return 32 + end + end +end local function injectspaces(head) if not triggers then return head,false @@ -16748,10 +20220,9 @@ local function injectspaces(head) local function updatefont(font,trig) leftkerns=trig.left rightkerns=trig.right - local par=fontdata[font].parameters - factor=par.factor - threshold=par.spacing.width-1 lastfont=font + threshold, + factor=getthreshold(font) end for n in traverse_id(glue_code,tonut(head)) do local prev,next=getboth(n) @@ -16770,7 +20241,7 @@ local function injectspaces(head) end end if prevchar then - local font=getfont(next) + local font=getfont(prev) local trig=triggers[font] if trig then if lastfont~=font then @@ -16782,32 +20253,32 @@ local function injectspaces(head) end end if leftkern then - local old=getfield(n,"width") - if old>=threshold then + local old=getwidth(n) + if old>threshold then if rightkern then local new=old+(leftkern+rightkern)*factor if trace_spaces then report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar) end - setfield(n,"width",new) + setwidth(n,new) leftkern=false else local new=old+leftkern*factor if trace_spaces then report_spaces("%C [%p -> %p]",prevchar,old,new) end - setfield(n,"width",new) + setwidth(n,new) end end leftkern=false elseif rightkern then - local old=getfield(n,"width") - if old>=threshold then + local old=getwidth(n) + if old>threshold then local new=old+rightkern*factor if trace_spaces then report_spaces("[%p -> %p] %C",nextchar,old,new) end - setfield(n,"width",new) + setwidth(n,new) end rightkern=false end @@ -16820,10 +20291,19 @@ function injections.handler(head,where) head=injectspaces(head) end if nofregisteredmarks>0 or nofregisteredcursives>0 then + if trace_injections then + report_injections("injection variant %a","everything") + end return inject_everything(head,where) elseif nofregisteredpairs>0 then + if trace_injections then + report_injections("injection variant %a","pairs") + end return inject_pairs_only(head,where) elseif nofregisteredkerns>0 then + if trace_injections then + report_injections("injection variant %a","kerns") + end return inject_kerns_only(head,where) else return head,false @@ -16854,7 +20334,6 @@ analyzers.methods=methods local a_state=attributes.private('state') local nuts=nodes.nuts local tonut=nuts.tonut -local getfield=nuts.getfield local getnext=nuts.getnext local getprev=nuts.getprev local getprev=nuts.getprev @@ -16865,7 +20344,6 @@ local getsubtype=nuts.getsubtype local getchar=nuts.getchar local ischar=nuts.is_char local traverse_id=nuts.traverse_id -local traverse_node_list=nuts.traverse local end_of_math=nuts.end_of_math local nodecodes=nodes.nodecodes local disc_code=nodecodes.disc @@ -16873,7 +20351,7 @@ local math_code=nodecodes.math local fontdata=fonts.hashes.identifiers local categories=characters and characters.categories or {} local chardata=characters and characters.data -local otffeatures=fonts.constructors.newfeatures("otf") +local otffeatures=fonts.constructors.features.otf local registerotffeature=otffeatures.register local s_init=1 local s_rphf=7 local s_medi=2 local s_half=8 @@ -17038,33 +20516,40 @@ local mappers={ } local classifiers=characters.classifiers if not classifiers then - local first_arabic,last_arabic=characters.blockrange("arabic") - local first_syriac,last_syriac=characters.blockrange("syriac") - local first_mandiac,last_mandiac=characters.blockrange("mandiac") - local first_nko,last_nko=characters.blockrange("nko") + local f_arabic,l_arabic=characters.blockrange("arabic") + local f_syriac,l_syriac=characters.blockrange("syriac") + local f_mandiac,l_mandiac=characters.blockrange("mandiac") + local f_nko,l_nko=characters.blockrange("nko") + local f_ext_a,l_ext_a=characters.blockrange("arabicextendeda") classifiers=table.setmetatableindex(function(t,k) - local c=chardata[k] - local v=false - if c then - local arabic=c.arabic - if arabic then - v=mappers[arabic] - if not v then - log.report("analyze","error in mapping arabic %C",k) - v=false - end - elseif k>=first_arabic and k<=last_arabic or k>=first_syriac and k<=last_syriac or - k>=first_mandiac and k<=last_mandiac or k>=first_nko and k<=last_nko then - if categories[k]=="mn" then - v=s_mark - else - v=s_rest + if type(k)=="number" then + local c=chardata[k] + local v=false + if c then + local arabic=c.arabic + if arabic then + v=mappers[arabic] + if not v then + log.report("analyze","error in mapping arabic %C",k) + v=false + end + elseif (k>=f_arabic and k<=l_arabic) or + (k>=f_syriac and k<=l_syriac) or + (k>=f_mandiac and k<=l_mandiac) or + (k>=f_nko and k<=l_nko) or + (k>=f_ext_a and k<=l_ext_a) then + if categories[k]=="mn" then + v=s_mark + else + v=s_rest + end end end + t[k]=v + return v end - t[k]=v - return v end) + characters.classifiers=classifiers end function methods.arab(head,font,attr) local first,last=nil,nil @@ -17221,12 +20706,14 @@ local type,next,tonumber=type,next,tonumber local random=math.random local formatters=string.formatters local insert=table.insert -local logs,trackers,nodes,attributes=logs,trackers,nodes,attributes local registertracker=trackers.register -local registerdirective=directives.register +local logs=logs +local trackers=trackers +local nodes=nodes +local attributes=attributes local fonts=fonts local otf=fonts.handlers.otf -local trace_lookups=false registertracker("otf.lookups",function(v) trace_lookups=v end) +local tracers=nodes.tracers local trace_singles=false registertracker("otf.singles",function(v) trace_singles=v end) local trace_multiples=false registertracker("otf.multiples",function(v) trace_multiples=v end) local trace_alternatives=false registertracker("otf.alternatives",function(v) trace_alternatives=v end) @@ -17238,31 +20725,26 @@ local trace_cursive=false registertracker("otf.cursive",function(v) trace_cursiv local trace_preparing=false registertracker("otf.preparing",function(v) trace_preparing=v end) local trace_bugs=false registertracker("otf.bugs",function(v) trace_bugs=v end) local trace_details=false registertracker("otf.details",function(v) trace_details=v end) -local trace_applied=false registertracker("otf.applied",function(v) trace_applied=v end) local trace_steps=false registertracker("otf.steps",function(v) trace_steps=v end) local trace_skips=false registertracker("otf.skips",function(v) trace_skips=v end) local trace_directions=false registertracker("otf.directions",function(v) trace_directions=v end) +local trace_plugins=false registertracker("otf.plugins",function(v) trace_plugins=v end) local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kernruns=v end) local trace_discruns=false registertracker("otf.discruns",function(v) trace_discruns=v end) local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end) local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end) -local quit_on_no_replacement=true -local zwnjruns=true local optimizekerns=true -registerdirective("otf.zwnjruns",function(v) zwnjruns=v end) -registerdirective("otf.chain.quitonnoreplacement",function(value) quit_on_no_replacement=value end) local report_direct=logs.reporter("fonts","otf direct") local report_subchain=logs.reporter("fonts","otf subchain") local report_chain=logs.reporter("fonts","otf chain") local report_process=logs.reporter("fonts","otf process") local report_warning=logs.reporter("fonts","otf warning") local report_run=logs.reporter("fonts","otf run") -local report_check=logs.reporter("fonts","otf check") registertracker("otf.replacements","otf.singles,otf.multiples,otf.alternatives,otf.ligatures") registertracker("otf.positions","otf.marks,otf.kerns,otf.cursive") registertracker("otf.actions","otf.replacements,otf.positions") registertracker("otf.injections","nodes.injections") -registertracker("*otf.sample","otf.steps,otf.actions,otf.analyzing") +registertracker("otf.sample","otf.steps,otf.actions,otf.analyzing") local nuts=nodes.nuts local tonode=nuts.tonode local tonut=nuts.tonut @@ -17287,24 +20769,26 @@ local setchar=nuts.setchar local getdisc=nuts.getdisc local setdisc=nuts.setdisc local setlink=nuts.setlink +local getcomponents=nuts.getcomponents +local setcomponents=nuts.setcomponents +local getdir=nuts.getdir +local getwidth=nuts.getwidth local ischar=nuts.is_char -local insert_node_before=nuts.insert_before local insert_node_after=nuts.insert_after -local delete_node=nuts.delete -local remove_node=nuts.remove local copy_node=nuts.copy local copy_node_list=nuts.copy_list local find_node_tail=nuts.tail local flush_node_list=nuts.flush_list -local free_node=nuts.free +local flush_node=nuts.flush_node local end_of_math=nuts.end_of_math local traverse_nodes=nuts.traverse local traverse_id=nuts.traverse_id +local set_components=nuts.set_components +local take_components=nuts.take_components +local count_components=nuts.count_components +local copy_no_components=nuts.copy_no_components +local copy_only_glyphs=nuts.copy_only_glyphs local setmetatableindex=table.setmetatableindex -local zwnj=0x200C -local zwj=0x200D -local wildcard="*" -local default="dflt" local nodecodes=nodes.nodecodes local glyphcodes=nodes.glyphcodes local disccodes=nodes.disccodes @@ -17316,8 +20800,8 @@ local dir_code=nodecodes.dir local localpar_code=nodecodes.localpar local discretionary_code=disccodes.discretionary local ligature_code=glyphcodes.ligature -local privateattribute=attributes.private -local a_state=privateattribute('state') +local a_state=attributes.private('state') +local a_noligature=attributes.private("noligature") local injections=nodes.injections local setmark=injections.setmark local setcursive=injections.setcursive @@ -17327,20 +20811,22 @@ local resetinjection=injections.reset local copyinjection=injections.copy local setligaindex=injections.setligaindex local getligaindex=injections.getligaindex -local cursonce=true -local fonthashes=fonts.hashes -local fontdata=fonthashes.identifiers -local otffeatures=fonts.constructors.newfeatures("otf") +local fontdata=fonts.hashes.identifiers +local fontfeatures=fonts.hashes.features +local otffeatures=fonts.constructors.features.otf local registerotffeature=otffeatures.register local onetimemessage=fonts.loggers.onetimemessage or function() end +local getrandom=utilities and utilities.randomizer and utilities.randomizer.get otf.defaultnodealternate="none" local tfmdata=false local characters=false local descriptions=false local marks=false +local classes=false local currentfont=false local factor=0 local threshold=0 +local checkmarks=false local sweepnode=nil local sweepprev=nil local sweepnext=nil @@ -17349,17 +20835,17 @@ local notmatchpre={} local notmatchpost={} local notmatchreplace={} local handlers={} -local function isspace(n) - if getid(n)==glue_code then - local w=getfield(n,"width") - if w>=threshold then - return 32 - end - end +local isspace=injections.isspace +local getthreshold=injections.getthreshold +local checkstep=(tracers and tracers.steppers.check) or function() end +local registerstep=(tracers and tracers.steppers.register) or function() end +local registermessage=(tracers and tracers.steppers.message) or function() end +local function checkdisccontent(d) + local pre,post,replace=getdisc(d) + if pre then for n in traverse_id(glue_code,pre) do print("pre",nodes.idstostring(pre)) break end end + if post then for n in traverse_id(glue_code,post) do print("pos",nodes.idstostring(post)) break end end + if replace then for n in traverse_id(glue_code,replace) do print("rep",nodes.idstostring(replace)) break end end end -local checkstep=(nodes and nodes.tracers and nodes.tracers.steppers.check) or function() end -local registerstep=(nodes and nodes.tracers and nodes.tracers.steppers.register) or function() end -local registermessage=(nodes and nodes.tracers and nodes.tracers.steppers.message) or function() end local function logprocess(...) if trace_steps then registermessage(...) @@ -17417,26 +20903,19 @@ local function mref(rlmode) return "l2r" end end -local function copy_glyph(g) - local components=getfield(g,"components") - if components then - setfield(g,"components",nil) - local n=copy_node(g) - copyinjection(n,g) - setfield(g,"components",components) - return n - else - local n=copy_node(g) - copyinjection(n,g) - return n - end -end local function flattendisk(head,disc) - local _,_,replace,_,_,replacetail=getdisc(disc,true) - setfield(disc,"replace",nil) - free_node(disc) - if head==disc then - local next=getnext(disc) + local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) + local prev,next=getboth(disc) + local ishead=head==disc + setdisc(disc) + flush_node(disc) + if pre then + flush_node_list(pre) + end + if post then + flush_node_list(post) + end + if ishead then if replace then if next then setlink(replacetail,next) @@ -17448,7 +20927,6 @@ local function flattendisk(head,disc) return end else - local prev,next=getboth(disc) if replace then if next then setlink(replacetail,next) @@ -17468,54 +20946,54 @@ local function appenddisc(disc,list) if post then setlink(posttail,posthead) else - post=phead + post=posthead end if replace then setlink(replacetail,replacehead) else - replace=rhead + replace=replacehead end setdisc(disc,pre,post,replace) end +local take_components=getcomponents +local set_components=setcomponents +local function count_components(start,marks) + if getid(start)~=glyph_code then + return 0 + elseif getsubtype(start)==ligature_code then + local i=0 + local components=getcomponents(start) + while components do + i=i+count_components(components,marks) + components=getnext(components) + end + return i + elseif not marks[getchar(start)] then + return 1 + else + return 0 + end +end local function markstoligature(head,start,stop,char) if start==stop and getchar(start)==char then return head,start else local prev=getprev(start) local next=getnext(stop) - setprev(start,nil) - setnext(stop,nil) - local base=copy_glyph(start) + setprev(start) + setnext(stop) + local base=copy_no_components(start,copyinjection) if head==start then head=base end resetinjection(base) setchar(base,char) setsubtype(base,ligature_code) - setfield(base,"components",start) - setlink(prev,base) - setlink(base,next) + set_components(base,start) + setlink(prev,base,next) return head,base end end -local function getcomponentindex(start) - if getid(start)~=glyph_code then - return 0 - elseif getsubtype(start)==ligature_code then - local i=0 - local components=getfield(start,"components") - while components do - i=i+getcomponentindex(components) - components=getnext(components) - end - return i - elseif not marks[getchar(start)] then - return 1 - else - return 0 - end -end -local a_noligature=attributes.private("noligature") local function toligature(head,start,stop,char,dataset,sequence,markflag,discfound) if getattr(start,a_noligature)==1 then return head,start @@ -17525,29 +21003,20 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou setchar(start,char) return head,start end - local components=getfield(start,"components") - if components then - end local prev=getprev(start) local next=getnext(stop) local comp=start - setprev(start,nil) - setnext(stop,nil) - local base=copy_glyph(start) + setprev(start) + setnext(stop) + local base=copy_no_components(start,copyinjection) if start==head then head=base end resetinjection(base) setchar(base,char) setsubtype(base,ligature_code) - setfield(base,"components",comp) - if prev then - setnext(prev,base) - end - if next then - setprev(next,base) - end - setboth(base,prev,next) + set_components(base,comp) + setlink(prev,base,next) if not discfound then local deletemarks=markflag~="mark" local components=start @@ -17559,7 +21028,7 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou local char=getchar(start) if not marks[char] then baseindex=baseindex+componentindex - componentindex=getcomponentindex(start) + componentindex=count_components(start,marks) elseif not deletemarks then setligaindex(start,baseindex+getligaindex(start,componentindex)) if trace_marks then @@ -17594,47 +21063,35 @@ local function toligature(head,start,stop,char,dataset,sequence,markflag,discfou local discprev,discnext=getboth(discfound) if discprev and discnext then local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true) - if not replace then + if not replace then local prev=getprev(base) -local current=comp -local previous=nil -local copied=nil -while current do - if getid(current)==glyph_code then - local n=copy_node(current) - if copied then - setlink(previous,n) - else - copied=n - end - previous=n - end - current=getnext(current) -end - setprev(discnext,nil) - setnext(discprev,nil) + local comp=take_components(base) + local copied=copy_only_glyphs(comp) if pre then setlink(discprev,pre) + else + setnext(discprev) end pre=comp if post then setlink(posttail,discnext) - setprev(post,nil) + setprev(post) else post=discnext + setprev(discnext) end - setlink(prev,discfound) - setlink(discfound,next) - setboth(base,nil,nil) - setfield(base,"components",copied) - setdisc(discfound,pre,post,base,discretionary_code) - base=prev + setlink(prev,discfound,next) + setboth(base) + set_components(base,copied) + replace=base + setdisc(discfound,pre,post,replace) + base=prev end end end return head,base end -local function multiple_glyphs(head,start,multiple,ignoremarks) +local function multiple_glyphs(head,start,multiple,ignoremarks,what) local nofmultiples=#multiple if nofmultiples>0 then resetinjection(start) @@ -17648,6 +21105,17 @@ local function multiple_glyphs(head,start,multiple,ignoremarks) insert_node_after(head,start,n) start=n end + if what==true then + elseif what>1 then + local m=multiple[nofmultiples] + for i=2,what do + local n=copy_node(start) + resetinjection(n) + setchar(n,m) + insert_node_after(head,start,n) + start=n + end + end end return head,start,true else @@ -17659,8 +21127,10 @@ local function multiple_glyphs(head,start,multiple,ignoremarks) end local function get_alternative_glyph(start,alternatives,value) local n=#alternatives - if value=="random" then - local r=random(1,n) + if n==1 then + return alternatives[1],trace_alternatives and "1 (only one present)" + elseif value=="random" then + local r=getrandom and getrandom("glyph",1,n) or random(1,n) return alternatives[r],trace_alternatives and formatters["value %a, taking %a"](value,r) elseif value=="first" then return alternatives[1],trace_alternatives and formatters["value %a, taking %a"](value,1) @@ -17718,7 +21188,7 @@ function handlers.gsub_multiple(head,start,dataset,sequence,multiple) if trace_multiples then logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple)) end - return multiple_glyphs(head,start,multiple,sequence.flags[1]) + return multiple_glyphs(head,start,multiple,sequence.flags[1],dataset[1]) end function handlers.gsub_ligature(head,start,dataset,sequence,ligature) local current=getnext(start) @@ -17851,7 +21321,6 @@ function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,step,i,inje return head,start,false else local prev=start - local done=false while snext do local nextchar=ischar(snext,currentfont) if nextchar then @@ -17869,8 +21338,7 @@ function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,step,i,inje if trace_kerns then logprocess("%s: shifting single %s by %p",pref(dataset,sequence),gref(nextchar),k) end - done=true - break + return head,start,true end end if a and #a>0 then @@ -17887,15 +21355,13 @@ function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,step,i,inje logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") end end - done=true - break + return head,start,true elseif krn~=0 then local k=setkern(snext,factor,rlmode,krn,injection) if trace_kerns then logprocess("%s: inserting kern %p between %s and %s as %s",pref(dataset,sequence),k,gref(getchar(prev)),gref(nextchar),injection or "injections") end - done=true - break + return head,start,true else break end @@ -17903,7 +21369,7 @@ function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,step,i,inje break end end - return head,start,done + return head,start,false end end function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode) @@ -17939,7 +21405,7 @@ function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode) local ba=markanchors[1][basechar] if ba then local ma=markanchors[2] - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", pref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -17994,7 +21460,7 @@ function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlm local index=getligaindex(start) ba=ba[index] if ba then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) if trace_marks then logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", pref(dataset,sequence),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy) @@ -18041,7 +21507,7 @@ function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode) local ba=markanchors[1][basechar] if ba then local ma=markanchors[2] - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true) + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", pref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -18056,7 +21522,6 @@ function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode) return head,start,false end function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,step,i) - local done=false local startchar=getchar(start) if marks[startchar] then if trace_cursive then @@ -18064,7 +21529,7 @@ function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,st end else local nxt=getnext(start) - while not done and nxt do + while nxt do local nextchar=ischar(nxt,currentfont) if not nextchar then break @@ -18081,7 +21546,7 @@ function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,st if trace_cursive then logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,anchor,bound,mref(rlmode)) end - done=true + return head,start,true end end end @@ -18089,7 +21554,7 @@ function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,st end end end - return head,start,done + return head,start,false end local chainprocs={} local function logprocess(...) @@ -18121,6 +21586,9 @@ local function reversesub(head,start,stop,dataset,sequence,replacements,rlmode) end end chainprocs.reversesub=reversesub +local function reportzerosteps(dataset,sequence) + logwarning("%s: no steps",cref(dataset,sequence)) +end local function reportmoresteps(dataset,sequence) logwarning("%s: more than 1 step",cref(dataset,sequence)) end @@ -18130,29 +21598,34 @@ function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,c if nofsteps>1 then reportmoresteps(dataset,sequence) end - local current=start - while current do - local currentchar=ischar(current) - if currentchar then - local replacement=steps[1].coverage[currentchar] - if not replacement or replacement=="" then - if trace_bugs then - logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar)) + if nofsteps==0 then + reportzerosteps(dataset,sequence) + else + local current=start + local mapping=steps[1].coverage + while current do + local currentchar=ischar(current) + if currentchar then + local replacement=mapping[currentchar] + if not replacement or replacement=="" then + if trace_bugs then + logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar)) + end + else + if trace_singles then + logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement)) + end + resetinjection(current) + setchar(current,replacement) end + return head,start,true + elseif currentchar==false then + break + elseif current==stop then + break else - if trace_singles then - logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement)) - end - resetinjection(current) - setchar(current,replacement) + current=getnext(current) end - return head,start,true - elseif currentchar==false then - break - elseif current==stop then - break - else - current=getnext(current) end end return head,start,false @@ -18163,17 +21636,21 @@ function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup if nofsteps>1 then reportmoresteps(dataset,sequence) end - local startchar=getchar(start) - local replacement=steps[1].coverage[startchar] - if not replacement or replacement=="" then - if trace_bugs then - logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar)) - end + if nofsteps==0 then + reportzerosteps(dataset,sequence) else - if trace_multiples then - logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement)) + local startchar=getchar(start) + local replacement=steps[1].coverage[startchar] + if not replacement or replacement=="" then + if trace_bugs then + logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar)) + end + else + if trace_multiples then + logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement)) + end + return multiple_glyphs(head,start,replacement,sequence.flags[1],dataset[1]) end - return multiple_glyphs(head,start,replacement,currentlookup.flags[1]) end return head,start,false end @@ -18183,35 +21660,40 @@ function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlooku if nofsteps>1 then reportmoresteps(dataset,sequence) end - local kind=dataset[4] - local what=dataset[1] - local value=what==true and tfmdata.shared.features[kind] or what - local current=start - while current do - local currentchar=ischar(current) - if currentchar then - local alternatives=steps[1].coverage[currentchar] - if alternatives then - local choice,comment=get_alternative_glyph(current,alternatives,value) - if choice then - if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(char),choice,gref(choice),comment) - end - resetinjection(start) - setchar(start,choice) - else - if trace_alternatives then - logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(char),comment) + if nofsteps==0 then + reportzerosteps(dataset,sequence) + else + local kind=dataset[4] + local what=dataset[1] + local value=what==true and tfmdata.shared.features[kind] or what + local current=start + local mapping=steps[1].coverage + while current do + local currentchar=ischar(current) + if currentchar then + local alternatives=mapping[currentchar] + if alternatives then + local choice,comment=get_alternative_glyph(current,alternatives,value) + if choice then + if trace_alternatives then + logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(char),choice,gref(choice),comment) + end + resetinjection(start) + setchar(start,choice) + else + if trace_alternatives then + logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(char),comment) + end end end + return head,start,true + elseif currentchar==false then + break + elseif current==stop then + break + else + current=getnext(current) end - return head,start,true - elseif currentchar==false then - break - elseif current==stop then - break - else - current=getnext(current) end end return head,start,false @@ -18222,70 +21704,74 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup if nofsteps>1 then reportmoresteps(dataset,sequence) end - local startchar=getchar(start) - local ligatures=steps[1].coverage[startchar] - if not ligatures then - if trace_bugs then - logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar)) - end + if nofsteps==0 then + reportzerosteps(dataset,sequence) else - local current=getnext(start) - local discfound=false - local last=stop - local nofreplacements=1 - local skipmark=currentlookup.flags[1] - while current do - local id=getid(current) - if id==disc_code then - if not discfound then - discfound=current - end - if current==stop then - break - else - current=getnext(current) - end - else - local schar=getchar(current) - if skipmark and marks[schar] then + local startchar=getchar(start) + local ligatures=steps[1].coverage[startchar] + if not ligatures then + if trace_bugs then + logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar)) + end + else + local current=getnext(start) + local discfound=false + local last=stop + local nofreplacements=1 + local skipmark=currentlookup.flags[1] + while current do + local id=getid(current) + if id==disc_code then + if not discfound then + discfound=current + end + if current==stop then + break + else current=getnext(current) + end else - local lg=ligatures[schar] - if lg then - ligatures=lg - last=current - nofreplacements=nofreplacements+1 - if current==stop then - break - else + local schar=getchar(current) + if skipmark and marks[schar] then current=getnext(current) - end else - break + local lg=ligatures[schar] + if lg then + ligatures=lg + last=current + nofreplacements=nofreplacements+1 + if current==stop then + break + else + current=getnext(current) + end + else + break + end end end end - end - local ligature=ligatures.ligature - if ligature then - if chainindex then - stop=last - end - if trace_ligatures then + local ligature=ligatures.ligature + if ligature then + if chainindex then + stop=last + end + if trace_ligatures then + if start==stop then + logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature)) + else + logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature)) + end + end + head,start=toligature(head,start,stop,ligature,dataset,sequence,skipmark,discfound) + return head,start,true,nofreplacements,discfound + elseif trace_bugs then if start==stop then - logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature)) + logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar)) else - logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature)) + logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop))) end end - head,start=toligature(head,start,stop,ligature,dataset,sequence,skipmark,discfound) - return head,start,true,nofreplacements,discfound - elseif trace_bugs then - if start==stop then - logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar)) - else - logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop))) - end end end return head,start,false,0,false @@ -18296,19 +21782,23 @@ function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,r if nofsteps>1 then reportmoresteps(dataset,sequence) end - local startchar=getchar(start) - local step=steps[1] - local kerns=step.coverage[startchar] - if not kerns then - elseif step.format=="pair" then - local dx,dy,w,h=setpair(start,factor,rlmode,sequence.flags[4],kerns) - if trace_kerns then - logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),dx,dy,w,h) - end - else - local k=setkern(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %p",cref(dataset,sequence),gref(startchar),k) + if nofsteps==0 then + reportzerosteps(dataset,sequence) + else + local startchar=getchar(start) + local step=steps[1] + local kerns=step.coverage[startchar] + if not kerns then + elseif step.format=="pair" then + local dx,dy,w,h=setpair(start,factor,rlmode,sequence.flags[4],kerns) + if trace_kerns then + logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),dx,dy,w,h) + end + else + local k=setkern(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %p",cref(dataset,sequence),gref(startchar),k) + end end end return head,start,false @@ -18319,65 +21809,64 @@ function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlm if nofsteps>1 then reportmoresteps(dataset,sequence) end - local snext=getnext(start) - if snext then - local startchar=getchar(start) - local step=steps[1] - local kerns=step.coverage[startchar] - if kerns then - local prev=start - local done=false - while snext do - local nextchar=ischar(snext,currentfont) - if not nextchar then - break - end - local krn=kerns[nextchar] - if not krn and marks[nextchar] then - prev=snext - snext=getnext(snext) - elseif not krn then - break - elseif step.format=="pair" then - local a,b=krn[1],krn[2] - if optimizekerns then - if not b and a[1]==0 and a[2]==0 and a[4]==0 then - local k=setkern(snext,factor,rlmode,a[3],"injections") + if nofsteps==0 then + reportzerosteps(dataset,sequence) + else + local snext=getnext(start) + if snext then + local startchar=getchar(start) + local step=steps[1] + local kerns=step.coverage[startchar] + if kerns then + local prev=start + while snext do + local nextchar=ischar(snext,currentfont) + if not nextchar then + break + end + local krn=kerns[nextchar] + if not krn and marks[nextchar] then + prev=snext + snext=getnext(snext) + elseif not krn then + break + elseif step.format=="pair" then + local a,b=krn[1],krn[2] + if optimizekerns then + if not b and a[1]==0 and a[2]==0 and a[4]==0 then + local k=setkern(snext,factor,rlmode,a[3],"injections") + if trace_kerns then + logprocess("%s: shifting single %s by %p",cref(dataset,sequence),gref(startchar),k) + end + return head,start,true + end + end + if a and #a>0 then + local startchar=getchar(start) + local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,"injections") if trace_kerns then - logprocess("%s: shifting single %s by %p",cref(dataset,sequence),gref(startchar),k) + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) end - done=true - break end - end - if a and #a>0 then - local startchar=getchar(start) - local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,"injections") - if trace_kerns then - logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + if b and #b>0 then + local startchar=getchar(start) + local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,"injections") + if trace_kerns then + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end end - end - if b and #b>0 then - local startchar=getchar(start) - local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,"injections") + return head,start,true + elseif krn~=0 then + local k=setkern(snext,factor,rlmode,krn) if trace_kerns then - logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + logprocess("%s: inserting kern %s between %s and %s",cref(dataset,sequence),k,gref(getchar(prev)),gref(nextchar)) end + return head,start,true + else + break end - done=true - break - elseif krn~=0 then - local k=setkern(snext,factor,rlmode,krn) - if trace_kerns then - logprocess("%s: inserting kern %s between %s and %s",cref(dataset,sequence),k,gref(getchar(prev)),gref(nextchar)) - end - done=true - break - else - break end end - return head,start,done end end return head,start,false @@ -18388,60 +21877,64 @@ function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlooku if nofsteps>1 then reportmoresteps(dataset,sequence) end - local markchar=getchar(start) - if marks[markchar] then - local markanchors=steps[1].coverage[markchar] - if markanchors then - local base=getprev(start) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base=getprev(base) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break + if nofsteps==0 then + reportzerosteps(dataset,sequence) + else + local markchar=getchar(start) + if marks[markchar] then + local markanchors=steps[1].coverage[markchar] + if markanchors then + local base=getprev(start) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base=getprev(base) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) + end + return head,start,false end else if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) end return head,start,false end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) - end - return head,start,false end end - end - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - if ma then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) - if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", - cref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + if ma then + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", + cref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) + end + return head,start,true end - return head,start,true end + elseif trace_bugs then + logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1) end elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1) + logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2) end elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2) + logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) end elseif trace_bugs then - logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) end - elseif trace_bugs then - logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) end return head,start,false end @@ -18451,64 +21944,68 @@ function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentl if nofsteps>1 then reportmoresteps(dataset,sequence) end - local markchar=getchar(start) - if marks[markchar] then - local markanchors=steps[1].coverage[markchar] - if markanchors then - local base=getprev(start) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base=getprev(base) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break + if nofsteps==0 then + reportzerosteps(dataset,sequence) + else + local markchar=getchar(start) + if marks[markchar] then + local markanchors=steps[1].coverage[markchar] + if markanchors then + local base=getprev(start) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base=getprev(base) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1) + end + return head,start,false end else if trace_bugs then - logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1) + logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2) end return head,start,false end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2) - end - return head,start,false end end - end - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - if ma then - local index=getligaindex(start) - ba=ba[index] - if ba then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar]) - if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", - cref(dataset,sequence),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy) + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + if ma then + local index=getligaindex(start) + ba=ba[index] + if ba then + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", + cref(dataset,sequence),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy) + end + return head,start,true end - return head,start,true end end + elseif trace_bugs then + logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1) end elseif trace_bugs then - logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1) + logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2) end elseif trace_bugs then - logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2) + logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar)) end elseif trace_bugs then - logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar)) end - elseif trace_bugs then - logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar)) end return head,start,false end @@ -18518,48 +22015,52 @@ function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlooku if nofsteps>1 then reportmoresteps(dataset,sequence) end - local markchar=getchar(start) - if marks[markchar] then - local markanchors=steps[1].coverage[markchar] - if markanchors then - local base=getprev(start) - local slc=getligaindex(start) - if slc then - while base do - local blc=getligaindex(base) - if blc and blc~=slc then - base=getprev(base) - else - break + if nofsteps==0 then + reportzerosteps(dataset,sequence) + else + local markchar=getchar(start) + if marks[markchar] then + local markanchors=steps[1].coverage[markchar] + if markanchors then + local base=getprev(start) + local slc=getligaindex(start) + if slc then + while base do + local blc=getligaindex(base) + if blc and blc~=slc then + base=getprev(base) + else + break + end end end - end - if base then - local basechar=ischar(base,currentfont) - if basechar then - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - if ma then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true) - if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", - cref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) + if base then + local basechar=ischar(base,currentfont) + if basechar then + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + if ma then + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", + cref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy) + end + return head,start,true end - return head,start,true end + elseif trace_bugs then + logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1) end elseif trace_bugs then - logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1) + logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2) end elseif trace_bugs then - logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2) + logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) end elseif trace_bugs then - logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) end - elseif trace_bugs then - logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) end return head,start,false end @@ -18569,56 +22070,171 @@ function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup, if nofsteps>1 then reportmoresteps(dataset,sequence) end - local startchar=getchar(start) - local exitanchors=steps[1].coverage[startchar] - if exitanchors then - local done=false - if marks[startchar] then - if trace_cursive then - logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) + if nofsteps==0 then + reportzerosteps(dataset,sequence) + else + local startchar=getchar(start) + local exitanchors=steps[1].coverage[startchar] + if exitanchors then + if marks[startchar] then + if trace_cursive then + logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) + end + else + local nxt=getnext(start) + while nxt do + local nextchar=ischar(nxt,currentfont) + if not nextchar then + break + elseif marks[nextchar] then + nxt=getnext(nxt) + else + local exit=exitanchors[3] + if exit then + local entry=exitanchors[1][nextchar] + if entry then + entry=entry[2] + if entry then + local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar]) + if trace_cursive then + logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,anchor,bound,mref(rlmode)) + end + return head,start,true + end + end + elseif trace_bugs then + onetimemessage(currentfont,startchar,"no entry anchors",report_fonts) + end + break + end + end + end + elseif trace_cursive and trace_details then + logprocess("%s, cursive %s is already done",pref(dataset,sequence),gref(getchar(start)),alreadydone) + end + end + return head,start,false +end +local function show_skip(dataset,sequence,char,ck,class) + logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(dataset,sequence),gref(char),class,ck[1],ck[8] or ck[2]) +end +local new_kern=nuts.pool.kern +local function checked(head) + local current=head + while current do + if getid(current)==glue_code then + local kern=new_kern(getwidth(current)) + if head==current then + local next=getnext(current) + if next then + setlink(kern,next) + end + flush_node(current) + head=kern + current=next + else + local prev,next=getboth(current) + setlink(prev,kern,next) + flush_node(current) + current=next end else - local nxt=getnext(start) - while not done and nxt do - local nextchar=ischar(nxt,currentfont) - if not nextchar then - break - elseif marks[nextchar] then - nxt=getnext(nxt) + current=getnext(current) + end + end + return head +end +local function setdiscchecked(d,pre,post,replace) + if pre then pre=checked(pre) end + if post then post=checked(post) end + if replace then replace=checked(replace) end + setdisc(d,pre,post,replace) +end +local noflags={ false,false,false,false } +local function chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped) + local size=ck[5]-ck[4]+1 + local flags=sequence.flags or noflags + local done=false + local skipmark=flags[1] + local chainlookups=ck[6] + if chainlookups then + local nofchainlookups=#chainlookups + if size==1 then + local chainlookup=chainlookups[1] + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local chainkind=chainstep.type + local chainproc=chainprocs[chainkind] + if chainproc then + local ok + head,start,ok=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,1) + if ok then + done=true + end else - local exit=exitanchors[3] - if exit then - local entry=exitanchors[1][nextchar] - if entry then - entry=entry[2] - if entry then - local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar]) - if trace_cursive then - logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,anchor,bound,mref(rlmode)) - end - done=true + logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind) + end + end + else + local i=1 + while start do + if skipped then + while start do + local char=getchar(start) + local class=classes[char] + if class then + if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then + start=getnext(start) + else break end + else + break + end + end + end + local chainlookup=chainlookups[i] + if chainlookup then + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local chainkind=chainstep.type + local chainproc=chainprocs[chainkind] + if chainproc then + local ok,n + head,start,ok,n=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,i) + if ok then + done=true + if n and n>1 and i+n>nofchainlookups then + break + end + end + else + logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind) end - elseif trace_bugs then - onetimemessage(currentfont,startchar,"no entry anchors",report_fonts) end + end + i=i+1 + if i>size or not start then break + elseif start then + start=getnext(start) end end end - return head,start,done else - if trace_cursive and trace_details then - logprocess("%s, cursive %s is already done",pref(dataset,sequence),gref(getchar(start)),alreadydone) + local replacements=ck[7] + if replacements then + head,start,done=reversesub(head,start,last,dataset,sequence,replacements,rlmode) + else + done=true + if trace_contexts then + logprocess("%s: skipping match",cref(dataset,sequence)) + end end - return head,start,false end + return head,start,done end -local function show_skip(dataset,sequence,char,ck,class) - logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(dataset,sequence),gref(char),class,ck[1],ck[8] or ck[2]) -end -local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,ck,chainproc) +local function chaindisk(head,start,dataset,sequence,rlmode,ck,skipped) if not start then return head,start,false end @@ -18631,13 +22247,13 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c local sweepnode=sweepnode local sweeptype=sweeptype local sweepoverflow=false - local checkdisc=getprev(head) local keepdisc=not sweepnode local lookaheaddisc=nil local backtrackdisc=nil local current=start local last=start local prev=getprev(start) + local hasglue=false local i=f while i<=l do local id=getid(current) @@ -18645,21 +22261,30 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c i=i+1 last=current current=getnext(current) + elseif id==glue_code then + i=i+1 + last=current + current=getnext(current) + hasglue=true elseif id==disc_code then if keepdisc then keepdisc=false - if notmatchpre[current]~=notmatchreplace[current] then - lookaheaddisc=current - end + lookaheaddisc=current local replace=getfield(current,"replace") - while replace and i<=l do - if getid(replace)==glyph_code then - i=i+1 + if not replace then + sweepoverflow=true + sweepnode=current + current=getnext(current) + else + while replace and i<=l do + if getid(replace)==glyph_code then + i=i+1 + end + replace=getnext(replace) end - replace=getnext(replace) + current=getnext(replace) end last=current - current=getnext(c) else head,current=flattendisk(head,current) end @@ -18694,8 +22319,8 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c tail=find_node_tail(head) end setnext(sweepnode,current) - setprev(head,nil) - setnext(tail,nil) + setprev(head) + setnext(tail) appenddisc(sweepnode,head) end end @@ -18707,13 +22332,17 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c if id==glyph_code then i=i+1 current=getnext(current) + elseif id==glue_code then + i=i+1 + current=getnext(current) + hasglue=true elseif id==disc_code then if keepdisc then keepdisc=false if notmatchpre[current]~=notmatchreplace[current] then lookaheaddisc=current end - local replace=getfield(c,"replace") + local replace=getfield(current,"replace") while replace and i<s do if getid(replace)==glyph_code then i=i+1 @@ -18748,6 +22377,9 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c local id=getid(current) if id==glyph_code then i=i-1 + elseif id==glue_code then + i=i-1 + hasglue=true elseif id==disc_code then if keepdisc then keepdisc=false @@ -18771,7 +22403,7 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c end end end - local ok=false + local done=false if lookaheaddisc then local cf=start local cl=getprev(lookaheaddisc) @@ -18788,42 +22420,53 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c break end end - setprev(lookaheaddisc,cprev) - if cprev then - setnext(cprev,lookaheaddisc) - end - setprev(cf,nil) - setnext(cl,nil) + setlink(cprev,lookaheaddisc) + setprev(cf) + setnext(cl) if startishead then head=lookaheaddisc end local pre,post,replace=getdisc(lookaheaddisc) local new=copy_node_list(cf) local cnew=new + if pre then + setlink(find_node_tail(cf),pre) + end + if replace then + local tail=find_node_tail(new) + setlink(tail,replace) + end for i=1,insertedmarks do cnew=getnext(cnew) end + cl=start local clast=cnew for i=f,l do + cl=getnext(cl) clast=getnext(clast) end if not notmatchpre[lookaheaddisc] then - cf,start,ok=chainproc(cf,start,last,dataset,sequence,chainlookup,rlmode,k) + local ok=false + cf,start,ok=chainrun(cf,start,cl,dataset,sequence,rlmode,ck,skipped) + if ok then + done=true + end end if not notmatchreplace[lookaheaddisc] then - new,cnew,ok=chainproc(new,cnew,clast,dataset,sequence,chainlookup,rlmode,k) - end - if pre then - setlink(cl,pre) + local ok=false + new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,ck,skipped) + if ok then + done=true + end end - if replace then - local tail=find_node_tail(new) - setlink(tail,replace) + if hasglue then + setdiscchecked(lookaheaddisc,cf,post,new) + else + setdisc(lookaheaddisc,cf,post,new) end - setdisc(lookaheaddisc,cf,post,new) start=getprev(lookaheaddisc) sweephead[cf]=getnext(clast) - sweephead[new]=getnext(last) + sweephead[new]=getnext(cl) elseif backtrackdisc then local cf=getnext(backtrackdisc) local cl=start @@ -18843,8 +22486,8 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c setprev(cnext,backtrackdisc) end setnext(backtrackdisc,cnext) - setprev(cf,nil) - setnext(cl,nil) + setprev(cf) + setnext(cl) local pre,post,replace,pretail,posttail,replacetail=getdisc(backtrackdisc,true) local new=copy_node_list(cf) local cnew=find_node_tail(new) @@ -18856,10 +22499,18 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c clast=getnext(clast) end if not notmatchpost[backtrackdisc] then - cf,start,ok=chainproc(cf,start,last,dataset,sequence,chainlookup,rlmode,k) + local ok=false + cf,start,ok=chainrun(cf,start,last,dataset,sequence,rlmode,ck,skipped) + if ok then + done=true + end end if not notmatchreplace[backtrackdisc] then - new,cnew,ok=chainproc(new,cnew,clast,dataset,sequence,chainlookup,rlmode,k) + local ok=false + new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,ck,skipped) + if ok then + done=true + end end if post then setlink(posttail,cf) @@ -18871,22 +22522,39 @@ local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,c else replace=new end - setdisc(backtrackdisc,pre,post,replace) + if hasglue then + setdiscchecked(backtrackdisc,pre,post,replace) + else + setdisc(backtrackdisc,pre,post,replace) + end start=getprev(backtrackdisc) sweephead[post]=getnext(clast) sweephead[replace]=getnext(last) else - head,start,ok=chainproc(head,start,last,dataset,sequence,chainlookup,rlmode,k) + local ok=false + head,start,ok=chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped) + if ok then + done=true + end end - return head,start,ok + return head,start,done +end +local function chaintrac(head,start,dataset,sequence,rlmode,ck,skipped) + local rule=ck[1] + local lookuptype=ck[8] or ck[2] + local nofseq=#ck[3] + local first=ck[4] + local last=ck[5] + local char=getchar(start) + logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %a", + cref(dataset,sequence),rule,gref(char),first-1,last-first+1,nofseq-last,lookuptype) end -local noflags={ false,false,false,false } local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) local sweepnode=sweepnode local sweeptype=sweeptype local currentfont=currentfont local diskseen=false - local checkdisc=getprev(head) + local checkdisc=sweeptype and getprev(head) local flags=sequence.flags or noflags local done=false local skipmark=flags[1] @@ -18894,6 +22562,8 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) local skipbase=flags[3] local markclass=sequence.markclass local skipped=false + local startprev, + startnext=getboth(start) for k=1,#contexts do local match=true local current=start @@ -18901,155 +22571,165 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) local ck=contexts[k] local seq=ck[3] local s=#seq + local size=1 if s==1 then local char=ischar(current,currentfont) if char then - match=seq[1][char] + if not seq[1][char] then + match=false + end end else local f=ck[4] local l=ck[5] - if f==1 and f==l then - else - if f==l then - else - local discfound=nil - local n=f+1 - last=getnext(last) - while n<=l do - if not last and (sweeptype=="post" or sweeptype=="replace") then - last=getnext(sweepnode) - sweeptype=nil - end - if last then - local char,id=ischar(last,currentfont) - if char then - local ccd=descriptions[char] - if ccd then - local class=ccd.class or "base" - if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then - skipped=true - if trace_skips then - show_skip(dataset,sequence,char,ck,class) - end + size=l-f+1 + if size>1 then + local discfound + local n=f+1 + last=startnext + while n<=l do + if not last and (sweeptype=="post" or sweeptype=="replace") then + last=getnext(sweepnode) + sweeptype=nil + end + if last then + local char,id=ischar(last,currentfont) + if char then + local class=classes[char] + if class then + if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then + skipped=true + if trace_skips then + show_skip(dataset,sequence,char,ck,class) + end + last=getnext(last) + elseif seq[n][char] then + if n<l then last=getnext(last) - elseif seq[n][char] then - if n<l then - last=getnext(last) - end - n=n+1 - else - if discfound then - notmatchreplace[discfound]=true - match=not notmatchpre[discfound] - else - match=false - end - break end + n=n+1 else if discfound then notmatchreplace[discfound]=true - match=not notmatchpre[discfound] + if notmatchpre[discfound] then + match=false + end else match=false end break end - elseif char==false then + else if discfound then notmatchreplace[discfound]=true - match=not notmatchpre[discfound] + if notmatchpre[discfound] then + match=false + end else match=false end break - elseif id==disc_code then - diskseen=true - discfound=last - notmatchpre[last]=nil - notmatchpost[last]=true - notmatchreplace[last]=nil - local pre,post,replace=getdisc(last) - if pre then - local n=n - while pre do - if seq[n][getchar(pre)] then - n=n+1 - pre=getnext(pre) - if n>l then - break - end - else - notmatchpre[last]=true + end + elseif char==false then + if discfound then + notmatchreplace[discfound]=true + if notmatchpre[discfound] then + match=false + end + else + match=false + end + break + elseif id==disc_code then + diskseen=true + discfound=last + notmatchpre[last]=nil + notmatchpost[last]=true + notmatchreplace[last]=nil + local pre,post,replace=getdisc(last) + if pre then + local n=n + while pre do + if seq[n][getchar(pre)] then + n=n+1 + pre=getnext(pre) + if n>l then break end - end - if n<=l then + else notmatchpre[last]=true + break end - else + end + if n<=l then notmatchpre[last]=true end - if replace then - while replace do - if seq[n][getchar(replace)] then - n=n+1 - replace=getnext(replace) - if n>l then - break - end - else - notmatchreplace[last]=true - match=not notmatchpre[last] + else + notmatchpre[last]=true + end + if replace then + while replace do + if seq[n][getchar(replace)] then + n=n+1 + replace=getnext(replace) + if n>l then break end + else + notmatchreplace[last]=true + if notmatchpre[last] then + match=false + end + break end - match=not notmatchpre[last] end - last=getnext(last) - else - match=false - break + if notmatchpre[last] then + match=false + end end + last=getnext(last) else match=false break end + else + match=false + break end end end if match and f>1 then - local prev=getprev(start) - if prev then + if startprev then + local prev=startprev if prev==checkdisc and (sweeptype=="pre" or sweeptype=="replace") then prev=getprev(sweepnode) end if prev then - local discfound=nil + local discfound local n=f-1 while n>=1 do if prev then local char,id=ischar(prev,currentfont) if char then - local ccd=descriptions[char] - if ccd then - local class=ccd.class + local class=classes[char] + if class then if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then skipped=true if trace_skips then show_skip(dataset,sequence,char,ck,class) end - prev=getprev(prev) + prev=getprev(prev) elseif seq[n][char] then - if n>1 then - prev=getprev(prev) + if n>1 then + prev=getprev(prev) end n=n-1 else if discfound then notmatchreplace[discfound]=true - match=not notmatchpost[discfound] + if notmatchpost[discfound] then + match=false + end else match=false end @@ -19058,7 +22738,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) else if discfound then notmatchreplace[discfound]=true - match=not notmatchpost[discfound] + if notmatchpost[discfound] then + match=false + end else match=false end @@ -19067,7 +22749,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) elseif char==false then if discfound then notmatchreplace[discfound]=true - match=not notmatchpost[discfound] + if notmatchpost[discfound] then + match=false + end else match=false end @@ -19118,7 +22802,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end else notmatchreplace[prev]=true - match=not notmatchpost[prev] + if notmatchpost[prev] then + match=false + end break end end @@ -19128,16 +22814,13 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end end prev=getprev(prev) - elseif seq[n][32] then + elseif id==glue_code and seq[n][32] and isspace(prev,threshold,id) then n=n-1 prev=getprev(prev) else match=false break end - elseif seq[n][32] then - n=n-1 - prev=getprev(prev) else match=false break @@ -19152,21 +22835,18 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end if match and s>l then local current=last and getnext(last) - if not current then - if sweeptype=="post" or sweeptype=="replace" then - current=getnext(sweepnode) - end + if not current and (sweeptype=="post" or sweeptype=="replace") then + current=getnext(sweepnode) end if current then - local discfound=nil + local discfound local n=l+1 while n<=s do if current then local char,id=ischar(current,currentfont) if char then - local ccd=descriptions[char] - if ccd then - local class=ccd.class + local class=classes[char] + if class then if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then skipped=true if trace_skips then @@ -19181,7 +22861,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) else if discfound then notmatchreplace[discfound]=true - match=not notmatchpre[discfound] + if notmatchpre[discfound] then + match=false + end else match=false end @@ -19190,7 +22872,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) else if discfound then notmatchreplace[discfound]=true - match=not notmatchpre[discfound] + if notmatchpre[discfound] then + match=false + end else match=false end @@ -19199,7 +22883,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) elseif char==false then if discfound then notmatchreplace[discfound]=true - match=not notmatchpre[discfound] + if notmatchpre[discfound] then + match=false + end else match=false end @@ -19241,7 +22927,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end else notmatchreplace[current]=true - match=notmatchpre[current] + if not notmatchpre[current] then + match=false + end break end end @@ -19251,15 +22939,13 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) else end current=getnext(current) - elseif seq[n][32] then + elseif id==glue_code and seq[n][32] and isspace(current,threshold,id) then n=n+1 + current=getnext(current) else match=false break end - elseif seq[n][32] then - n=n+1 - current=getnext(current) else match=false break @@ -19271,99 +22957,13 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode) end end if match then - local diskchain=diskseen or sweepnode if trace_contexts then - local rule=ck[1] - local lookuptype=ck[8] or ck[2] - local first=ck[4] - local last=ck[5] - local char=getchar(start) - logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %a", - cref(dataset,sequence),rule,gref(char),first-1,last-first+1,s-last,lookuptype) - end - local chainlookups=ck[6] - if chainlookups then - local nofchainlookups=#chainlookups - if nofchainlookups==1 then - local chainlookup=chainlookups[1] - local chainkind=chainlookup.type - local chainproc=chainprocs[chainkind] - if chainproc then - local ok - if diskchain then - head,start,ok=chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,1,ck,chainproc) - else - head,start,ok=chainproc(head,start,last,dataset,sequence,chainlookup,rlmode,1) - end - if ok then - done=true - end - else - logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind) - end - else - local i=1 - while start and true do - if skipped then - while start do - local char=getchar(start) - local ccd=descriptions[char] - if ccd then - local class=ccd.class or "base" - if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then - start=getnext(start) - else - break - end - else - break - end - end - end - local chainlookup=chainlookups[1] - if not chainlookup then - i=i+1 - else - local chainkind=chainlookup.type - local chainproc=chainprocs[chainkind] - if chainproc then - local ok,n - if diskchain then - head,start,ok=chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,i,ck,chainproc) - else - head,start,ok,n=chainproc(head,start,last,dataset,sequence,chainlookup,rlmode,i) - end - if ok then - done=true - if n and n>1 then - if i+n>nofchainlookups then - break - else - end - end - end - else - logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind) - end - i=i+1 - end - if i>nofchainlookups or not start then - break - elseif start then - start=getnext(start) - end - end - end + chaintrac(head,start,dataset,sequence,rlmode,ck,skipped) + end + if diskseen or sweepnode then + head,start,done=chaindisk(head,start,dataset,sequence,rlmode,ck,skipped) else - local replacements=ck[7] - if replacements then - head,start,done=reversesub(head,start,last,dataset,sequence,replacements,rlmode) - else - done=quit_on_no_replacement - if trace_contexts then - logprocess("%s: skipping match",cref(dataset,sequence)) - end - end + head,start,done=chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped) end if done then break @@ -19420,73 +23020,79 @@ local sequencelists=setmetatableindex(function(t,font) t[font]=sequences return sequences end) -local autofeatures=fonts.analyzers.features -local featuretypes=otf.tables.featuretypes -local defaultscript=otf.features.checkeddefaultscript -local defaultlanguage=otf.features.checkeddefaultlanguage -local function initialize(sequence,script,language,enabled,autoscript,autolanguage) - local features=sequence.features - if features then - local order=sequence.order - if order then - local featuretype=featuretypes[sequence.type or "unknown"] - for i=1,#order do - local kind=order[i] - local valid=enabled[kind] - if valid then - local scripts=features[kind] - local languages=scripts and ( - scripts[script] or - scripts[wildcard] or - (autoscript and defaultscript(featuretype,autoscript,scripts)) - ) - local enabled=languages and ( - languages[language] or - languages[wildcard] or - (autolanguage and defaultlanguage(featuretype,autolanguage,languages)) - ) - if enabled then - return { valid,autofeatures[kind] or false,sequence,kind } +do + local autofeatures=fonts.analyzers.features + local featuretypes=otf.tables.featuretypes + local defaultscript=otf.features.checkeddefaultscript + local defaultlanguage=otf.features.checkeddefaultlanguage + local wildcard="*" + local default="dflt" + local function initialize(sequence,script,language,enabled,autoscript,autolanguage) + local features=sequence.features + if features then + local order=sequence.order + if order then + local featuretype=featuretypes[sequence.type or "unknown"] + for i=1,#order do + local kind=order[i] + local valid=enabled[kind] + if valid then + local scripts=features[kind] + local languages=scripts and ( + scripts[script] or + scripts[wildcard] or + (autoscript and defaultscript(featuretype,autoscript,scripts)) + ) + local enabled=languages and ( + languages[language] or + languages[wildcard] or + (autolanguage and defaultlanguage(featuretype,autolanguage,languages)) + ) + if enabled then + return { valid,autofeatures[kind] or false,sequence,kind } + end end end + else end - else end + return false end - return false -end -function otf.dataset(tfmdata,font) - local shared=tfmdata.shared - local properties=tfmdata.properties - local language=properties.language or "dflt" - local script=properties.script or "dflt" - local enabled=shared.features - local autoscript=enabled and enabled.autoscript - local autolanguage=enabled and enabled.autolanguage - local res=resolved[font] - if not res then - res={} - resolved[font]=res - end - local rs=res[script] - if not rs then - rs={} - res[script]=rs - end - local rl=rs[language] - if not rl then - rl={ - } - rs[language]=rl - local sequences=tfmdata.resources.sequences - for s=1,#sequences do - local v=enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage) - if v then - rl[#rl+1]=v + function otf.dataset(tfmdata,font) + local shared=tfmdata.shared + local properties=tfmdata.properties + local language=properties.language or "dflt" + local script=properties.script or "dflt" + local enabled=shared.features + local autoscript=enabled and enabled.autoscript + local autolanguage=enabled and enabled.autolanguage + local res=resolved[font] + if not res then + res={} + resolved[font]=res + end + local rs=res[script] + if not rs then + rs={} + res[script]=rs + end + local rl=rs[language] + if not rl then + rl={ + } + rs[language]=rl + local sequences=tfmdata.resources.sequences + if sequences then + for s=1,#sequences do + local v=enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage) + if v then + rl[#rl+1]=v + end + end end end + return rl end - return rl end local function report_disc(what,n) report_run("%s: %s > %s",what,n,languages.serializediscretionary(n)) @@ -19508,10 +23114,10 @@ local function kernrun(disc,k_run,font,attr,...) break end end - if prev and (pre or replace) and not ischar(prev,font) then + if prev and not ischar(prev,font) then prev=false end - if next and (post or replace) and not ischar(next,font) then + if next and not ischar(next,font) then next=false end if pre then @@ -19537,7 +23143,7 @@ local function kernrun(disc,k_run,font,attr,...) if k_run(posttail,"postinjections",next,font,attr,...) then done=true end - setnext(posttail,nil) + setnext(posttail) setprev(next,disc) end end @@ -19559,7 +23165,7 @@ local function kernrun(disc,k_run,font,attr,...) if k_run(replacetail,"replaceinjections",next,font,attr,...) then done=true end - setnext(replacetail,nil) + setnext(replacetail) setprev(next,disc) end elseif prev and next then @@ -19567,12 +23173,11 @@ local function kernrun(disc,k_run,font,attr,...) if k_run(prevmarks,"emptyinjections",next,font,attr,...) then done=true end - setlink(prev,disc) - setlink(disc,next) + setlink(prev,disc,next) end return nextstart,done end -local function comprun(disc,c_run,...) +local function comprun(disc,c_run,...) if trace_compruns then report_disc("comp",disc) end @@ -19622,17 +23227,58 @@ local function testrun(disc,t_run,c_run,...) end local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) local done=false - if replace and prev then - setlink(replacetail,next) - local ok,overflow=t_run(replace,next,...) - if ok and overflow then - setfield(disc,"replace",nil) - setlink(prev,replace) - setboth(disc) - flush_node_list(disc) - return replace,true + if (post or replace) and prev then + if post then + setlink(posttail,next) + else + post=next + end + if replace then + setlink(replacetail,next) else + replace=next + end + local d_post=t_run(post,next,...) + local d_replace=t_run(replace,next,...) + if (d_post and d_post>0) or (d_replace and d_replace>0) then + local d=d_replace or d_post + if d_post and d<d_post then + d=d_post + end + local head,tail=getnext(disc),disc + for i=1,d do + tail=getnext(tail) + if getid(tail)==disc_code then + head,tail=flattendisk(head,tail) + end + end + local next=getnext(tail) + setnext(tail) + setprev(head) + local new=copy_node_list(head) + if posttail then + setlink(posttail,head) + else + post=head + end + if replacetail then + setlink(replacetail,new) + else + replace=new + end + setlink(disc,next) + else + if posttail then + setnext(posttail) + else + post=nil + end setnext(replacetail) + if replacetail then + setnext(replacetail) + else + replace=nil + end setprev(next,disc) end end @@ -19686,7 +23332,10 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm while start do local char=ischar(start,font) if char then - local a=attr and getattr(start,0) + local a + if attr then + a=getattr(start,0) + end if not a or (a==attr) then local lookupmatch=lookupcache[char] if lookupmatch then @@ -19713,43 +23362,82 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm return head,done end local function t_run_single(start,stop,font,attr,lookupcache) + local lastd=nil while start~=stop do local char=ischar(start,font) if char then - local a=attr and getattr(start,0) + local a + if attr then + a=getattr(start,0) + end + local startnext=getnext(start) if not a or (a==attr) then local lookupmatch=lookupcache[char] if lookupmatch then - local s=getnext(start) + local s=startnext + local ss=nil + local sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getfield(s,"replace") + if not s then + s=ss + ss=nil + end + end local l=nil local d=0 while s do - if s==stop then - d=1 - elseif d>0 then - d=d+1 - end local lg=lookupmatch[getchar(s)] if lg then + if sstop then + d=1 + elseif d>0 then + d=d+1 + end l=lg s=getnext(s) + sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getfield(s,"replace") + if not s then + s=ss + ss=nil + end + end else break end end if l and l.ligature then - return true,d>1 + lastd=d end end + else end - start=getnext(start) + if lastd then + return lastd + end + start=startnext else break end end end local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,handler) - local a=attr and getattr(sub,0) + local a + if attr then + a=getattr(sub,0) + end if not a or (a==attr) then for n in traverse_nodes(sub) do if n==last then @@ -19780,7 +23468,10 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm while start do local char=ischar(start,font) if char then - local a=attr and getattr(start,0) + local a + if attr then + a=getattr(start,0) + end if not a or (a==attr) then for i=1,nofsteps do local step=steps[i] @@ -19818,10 +23509,15 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm return head,done end local function t_run_multiple(start,stop,font,attr,steps,nofsteps) + local lastd=nil while start~=stop do local char=ischar(start,font) if char then - local a=attr and getattr(start,0) + local a + if attr then + a=getattr(start,0) + end + local startnext=getnext(start) if not a or (a==attr) then for i=1,nofsteps do local step=steps[i] @@ -19829,40 +23525,74 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) if lookupcache then local lookupmatch=lookupcache[char] if lookupmatch then - local s=getnext(start) + local s=startnext + local ss=nil + local sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getfield(s,"replace") + if not s then + s=ss + ss=nil + end + end local l=nil local d=0 while s do - if s==stop then - d=1 - elseif d>0 then - d=d+1 - end local lg=lookupmatch[getchar(s)] if lg then + if sstop then + d=1 + elseif d>0 then + d=d+1 + end l=lg s=getnext(s) + sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getfield(s,"replace") + if not s then + s=ss + ss=nil + end + end else break end end if l and l.ligature then - return true,d>1 + lastd=d end end else report_missing_coverage(dataset,sequence) end end + else end - start=getnext(start) + if lastd then + return lastd + end + start=startnext else break end end end local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler) - local a=attr and getattr(sub,0) + local a + if attr then + a=getattr(sub,0) + end if not a or (a==attr) then for n in traverse_nodes(sub) do if n==last then @@ -19890,7 +23620,7 @@ local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,datase end end local function txtdirstate(start,stack,top,rlparmode) - local dir=getfield(start,"dir") + local dir=getdir(start) local new=1 if dir=="+TRT" then top=top+1 @@ -19913,7 +23643,7 @@ local function txtdirstate(start,stack,top,rlparmode) return getnext(start),top,new end local function pardirstate(start) - local dir=getfield(start,"dir") + local dir=getdir(start) local new=0 if dir=="TLT" then new=1 @@ -19925,7 +23655,10 @@ local function pardirstate(start) end return getnext(start),new,new end -local function featuresprocessor(head,font,attr) +otf.helpers=otf.helpers or {} +otf.helpers.txtdirstate=txtdirstate +otf.helpers.pardirstate=pardirstate +local function featuresprocessor(head,font,attr,direction) local sequences=sequencelists[font] if not sequencelists then return head,false @@ -19934,24 +23667,24 @@ local function featuresprocessor(head,font,attr) if nesting==1 then currentfont=font tfmdata=fontdata[font] - descriptions=tfmdata.descriptions - characters=tfmdata.characters - marks=tfmdata.resources.marks - factor=tfmdata.parameters.factor - threshold=tfmdata.parameters.spacing.width or 65536*10 + descriptions=tfmdata.descriptions + characters=tfmdata.characters + local resources=tfmdata.resources + marks=resources.marks + classes=resources.classes + threshold, + factor=getthreshold(font) + checkmarks=tfmdata.properties.checkmarks elseif currentfont~=font then report_warning("nested call with a different font, level %s, quitting",nesting) nesting=nesting-1 return head,false end - if attr==0 then - attr=false - end head=tonut(head) if trace_steps then checkstep(head) end - local rlmode=0 + local initialrl=direction=="TRT" and -1 or 0 local done=false local datasets=otf.dataset(tfmdata,font,attr) local dirstack={} @@ -19960,31 +23693,31 @@ local function featuresprocessor(head,font,attr) local dataset=datasets[s] local attribute=dataset[2] local sequence=dataset[3] - local rlparmode=0 + local rlparmode=initialrl local topstack=0 - local success=false local typ=sequence.type local gpossing=typ=="gpos_single" or typ=="gpos_pair" local handler=handlers[typ] local steps=sequence.steps local nofsteps=sequence.nofsteps if not steps then - local h,d,ok=handler(head,start,dataset,sequence,nil,nil,nil,0,font,attr) + local h,d,ok=handler(head,head,dataset,sequence,nil,nil,nil,0,font,attr) if ok then - success=true + done=true if h then head=h end - if d then - start=d - end end elseif typ=="gsub_reversecontextchain" then local start=find_node_tail(head) + local rlmode=0 while start do local char=ischar(start,font) if char then - local a=attr and getattr(start,0) + local a + if attr then + a=getattr(start,0) + end if not a or (a==attr) then for i=1,nofsteps do local step=steps[i] @@ -19995,7 +23728,7 @@ local function featuresprocessor(head,font,attr) local ok head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i) if ok then - success=true + done=true break end end @@ -20014,8 +23747,8 @@ local function featuresprocessor(head,font,attr) end end else - local start=head - rlmode=0 + local start=head + local rlmode=initialrl if nofsteps==1 then local step=steps[1] local lookupcache=step.coverage @@ -20025,11 +23758,13 @@ local function featuresprocessor(head,font,attr) while start do local char,id=ischar(start,font) if char then - local a=attr and getattr(start,0) - if a then - a=(a==attr) and (not attribute or getprop(start,a_state)==attribute) - else - a=not attribute or getprop(start,a_state)==attribute + local a + if attr then + if getattr(start,0)==attr and (not attribute or getprop(start,a_state)==attribute) then + a=true + end + elseif not attribute or getprop(start,a_state)==attribute then + a=true end if a then local lookupmatch=lookupcache[char] @@ -20037,7 +23772,7 @@ local function featuresprocessor(head,font,attr) local ok head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,step,1) if ok then - success=true + done=true end end if start then @@ -20048,6 +23783,8 @@ local function featuresprocessor(head,font,attr) end elseif char==false then start=getnext(start) + elseif id==glue_code then + start=getnext(start) elseif id==disc_code then local ok if gpossing then @@ -20058,7 +23795,7 @@ local function featuresprocessor(head,font,attr) start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,handler) end if ok then - success=true + done=true end elseif id==math_code then start=getnext(end_of_math(start)) @@ -20075,11 +23812,13 @@ local function featuresprocessor(head,font,attr) while start do local char,id=ischar(start,font) if char then - local a=attr and getattr(start,0) - if a then - a=(a==attr) and (not attribute or getprop(start,a_state)==attribute) - else - a=not attribute or getprop(start,a_state)==attribute + local a + if attr then + if getattr(start,0)==attr and (not attribute or getprop(start,a_state)==attribute) then + a=true + end + elseif not attribute or getprop(start,a_state)==attribute then + a=true end if a then for i=1,nofsteps do @@ -20091,7 +23830,7 @@ local function featuresprocessor(head,font,attr) local ok head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i) if ok then - success=true + done=true break elseif not start then break @@ -20109,6 +23848,8 @@ local function featuresprocessor(head,font,attr) end elseif char==false then start=getnext(start) + elseif id==glue_code then + start=getnext(start) elseif id==disc_code then local ok if gpossing then @@ -20119,7 +23860,7 @@ local function featuresprocessor(head,font,attr) start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler) end if ok then - success=true + done=true end elseif id==math_code then start=getnext(end_of_math(start)) @@ -20133,9 +23874,6 @@ local function featuresprocessor(head,font,attr) end end end - if success then - done=true - end if trace_steps then registerstep(head) end @@ -20144,6 +23882,30 @@ local function featuresprocessor(head,font,attr) head=tonode(head) return head,done end +local plugins={} +otf.plugins=plugins +function otf.registerplugin(name,f) + if type(name)=="string" and type(f)=="function" then + plugins[name]={ name,f } + end +end +local function plugininitializer(tfmdata,value) + if type(value)=="string" then + tfmdata.shared.plugin=plugins[value] + end +end +local function pluginprocessor(head,font) + local s=fontdata[font].shared + local p=s and s.plugin + if p then + if trace_plugins then + report_process("applying plugin %a",p[1]) + end + return p[2](head,font) + else + return head,false + end +end local function featuresinitializer(tfmdata,value) end registerotffeature { @@ -20153,18 +23915,36 @@ registerotffeature { initializers={ position=1, node=featuresinitializer, + plug=plugininitializer, }, processors={ node=featuresprocessor, + plug=pluginprocessor, } } otf.nodemodeinitializer=featuresinitializer otf.featuresprocessor=featuresprocessor otf.handlers=handlers local setspacekerns=nodes.injections.setspacekerns if not setspacekerns then os.exit() end -function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) - setspacekerns(font,sequence) - return head,start,true +if fontfeatures then + function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) + local features=fontfeatures[font] + local enabled=features and features.spacekern and features.kern + if enabled then + setspacekerns(font,sequence) + end + return head,start,enabled + end +else + function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr) + local shared=fontdata[font].shared + local features=shared and shared.features + local enabled=features and features.spacekern and features.kern + if enabled then + setspacekerns(font,sequence) + end + return head,start,enabled + end end local function hasspacekerns(data) local sequences=data.resources.sequences @@ -20198,8 +23978,8 @@ otf.readers.registerextender { local function spaceinitializer(tfmdata,value) local resources=tfmdata.resources local spacekerns=resources and resources.spacekerns - if spacekerns==nil then - local properties=tfmdata.properties + local properties=tfmdata.properties + if value and spacekerns==nil then if properties and properties.hasspacekerns then local sequences=resources.sequences local left={} @@ -20212,28 +23992,55 @@ local function spaceinitializer(tfmdata,value) if steps then local kern=sequence.features.kern if kern then - feat=feat or kern + if feat then + for script,languages in next,kern do + local f=feat[script] + if f then + for l in next,languages do + f[l]=true + end + else + feat[script]=languages + end + end + else + feat=kern + end for i=1,#steps do local step=steps[i] local coverage=step.coverage - if coverage then + local rules=step.rules + local format=step.format + if rules then + elseif coverage then + local single=format==gpos_single local kerns=coverage[32] if kerns then for k,v in next,kerns do - if type(v)=="table" then - right[k]=v[3] - else + if type(v)~="table" then right[k]=v + elseif single then + right[k]=v[3] + else + local one=v[1] + if one then + right[k]=one[3] + end end end end for k,v in next,coverage do local kern=v[32] if kern then - if type(kern)=="table" then - left[k]=kern[3] - else + if type(kern)~="table" then left[k]=kern + elseif single then + left[k]=v[3] + else + local one=v[1] + if one then + left[k]=one[3] + end end end end @@ -20281,6 +24088,18 @@ registerotffeature { node=spaceinitializer, }, } +local function markinitializer(tfmdata,value) + local properties=tfmdata.properties + properties.checkmarks=value +end +registerotffeature { + name="checkmarks", + description="check mark widths", + default=true, + initializers={ + node=markinitializer, + }, +} end -- closure @@ -20300,11 +24119,9 @@ fonts=fonts or {} fonts.analyzers=fonts.analyzers or {} fonts.analyzers.methods=fonts.analyzers.methods or { node={ otf={} } } local otf=fonts.handlers.otf -local nodecodes=nodes.nodecodes -local glyph_code=nodecodes.glyph local handlers=otf.handlers local methods=fonts.analyzers.methods -local otffeatures=fonts.constructors.newfeatures("otf") +local otffeatures=fonts.constructors.features.otf local registerotffeature=otffeatures.register local nuts=nodes.nuts local tonode=nuts.tonode @@ -20325,9 +24142,9 @@ local setprop=nuts.setprop local ischar=nuts.is_char local insert_node_after=nuts.insert_after local copy_node=nuts.copy -local free_node=nuts.free local remove_node=nuts.remove local flush_list=nuts.flush_list +local flush_node=nuts.flush_node local copyinjection=nodes.injections.copy local unsetvalue=attributes.unsetvalue local fontdata=fonts.hashes.identifiers @@ -20686,9 +24503,11 @@ local function initializedevanagi(tfmdata) local steps=sequence.steps local nofsteps=sequence.nofsteps local features=sequence.features - if features["rphf"] then + local has_rphf=features.rphf + local has_blwf=features.blwf + if has_rphf and has_rphf.deva then devanagari.reph=true - elseif features["blwf"] then + elseif has_blwf and has_blwf.deva then devanagari.vattu=true for i=1,nofsteps do local step=steps[i] @@ -20702,57 +24521,60 @@ local function initializedevanagi(tfmdata) end end end - if valid[kind] then - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - local reph=false - if step.osdstep then - for k,v in next,ra do - local r=coverage[k] - if r then - local h=false - for k,v in next,halant do - local h=r[k] - if h then - reph=h.ligature or false - break + for kind,spec in next,features do + if spec.dev2 and valid[kind] then + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + local reph=false + if kind=="rphf" then + if true then + for k,v in next,ra do + local r=coverage[k] + if r then + local h=false + for k,v in next,halant do + local h=r[k] + if h then + reph=h.ligature or false + break + end + end + if reph then + break + end end end - if reph then - break - end + else end end - else + seqsubset[#seqsubset+1]={ kind,coverage,reph } end - seqsubset[#seqsubset+1]={ kind,coverage,reph } end end - end - if kind=="pref" then - local sequence=dataset[3] - local steps=sequence.steps - local nofsteps=sequence.nofsteps - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - for k,v in next,halant do - local h=coverage[k] - if h then - local found=false - for k,v in next,h do - found=v and v.ligature + if kind=="pref" then + local steps=sequence.steps + local nofsteps=sequence.nofsteps + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + for k,v in next,halant do + local h=coverage[k] + if h then + local found=false + for k,v in next,h do + found=v and v.ligature + if found then + pre_base_reordering_consonants[k]=found + break + end + end if found then - pre_base_reordering_consonants[k]=found break end end - if found then - break - end end end end @@ -20837,7 +24659,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) if current==stop then stop=getprev(stop) head=remove_node(head,current) - free_node(current) + flush_node(current) return head,stop,nbspaces else nbspaces=nbspaces+1 @@ -20875,7 +24697,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) setchar(current,getchar(tempcurrent)) local freenode=getnext(current) setlink(current,tmp) - free_node(freenode) + flush_node(freenode) flush_list(tempcurrent) if changestop then stop=current @@ -21112,7 +24934,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) if getchar(base)==c_nbsp then nbspaces=nbspaces-1 head=remove_node(head,base) - free_node(base) + flush_node(base) end return head,stop,nbspaces end @@ -21139,6 +24961,8 @@ function handlers.devanagari_reorder_matras(head,start) start=startnext break end + else + break end current=next end @@ -21151,12 +24975,12 @@ function handlers.devanagari_reorder_reph(head,start) local startfont=getfont(start) local startattr=getprop(start,a_syllabe) while current do - local char=ischar(current,font) + local char=ischar(current,startfont) if char and getprop(current,a_syllabe)==startattr then if halant[char] and not getprop(current,a_state) then local next=getnext(current) if next then - local nextchar=ischar(next,font) + local nextchar=ischar(next,startfont) if nextchar and zw_char[nextchar] and getprop(next,a_syllabe)==startattr then current=next next=getnext(current) @@ -21178,13 +25002,12 @@ function handlers.devanagari_reorder_reph(head,start) if not startnext then current=getnext(start) while current do - local char=ischar(current,font) + local char=ischar(current,startfont) if char and getprop(current,a_syllabe)==startattr then if getprop(current,a_state)==s_pstf then startnext=getnext(start) head=remove_node(head,start) - local prev=getprev(current) - setlink(prev,start) + setlink(getprev(current),start) setlink(start,current) start=startnext startattr=getprop(start,a_syllabe) @@ -21200,7 +25023,7 @@ function handlers.devanagari_reorder_reph(head,start) current=getnext(start) local c=nil while current do - local char=ischar(current,font) + local char=ischar(current,startfont) if char and getprop(current,a_syllabe)==startattr then if not c and mark_above_below_post[char] and reorder_class[char]~="after subscript" then c=current @@ -21213,8 +25036,7 @@ function handlers.devanagari_reorder_reph(head,start) if c then startnext=getnext(start) head=remove_node(head,start) - local prev=getprev(c) - setlink(prev,start) + setlink(getprev(c),start) setlink(start,c) start=startnext startattr=getprop(start,a_syllabe) @@ -21224,7 +25046,7 @@ function handlers.devanagari_reorder_reph(head,start) current=start local next=getnext(current) while next do - local nextchar=ischar(next,font) + local nextchar=ischar(next,startfont) if nextchar and getprop(next,a_syllabe)==startattr then current=next next=getnext(current) @@ -21235,9 +25057,8 @@ function handlers.devanagari_reorder_reph(head,start) if start~=current then startnext=getnext(start) head=remove_node(head,start) - local next=getnext(current) - setlink(start,next) - setlink(current,"next",start) + setlink(start,getnext(current)) + setlink(current,start) start=startnext end end @@ -21250,12 +25071,12 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start) local startfont=getfont(start) local startattr=getprop(start,a_syllabe) while current do - local char=ischar(current,font) + local char=ischar(current,startfont) if char and getprop(current,a_syllabe)==startattr then local next=getnext(current) if halant[char] and not getprop(current,a_state) then if next then - local nextchar=ischar(next,font) + local nextchar=ischar(next,startfont) if nextchar and getprop(next,a_syllabe)==startattr then if nextchar==c_zwnj or nextchar==c_zwj then current=next @@ -21279,13 +25100,12 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start) current=getnext(start) startattr=getprop(start,a_syllabe) while current do - local char=ischar(current,font) + local char=ischar(current,startfont) if char and getprop(current,a_syllabe)==startattr then if not consonant[char] and getprop(current,a_state) then startnext=getnext(start) removenode(start,start) - local prev=getprev(current) - setlink(start,prev) + setlink(getprev(current),start) setlink(start,current) start=startnext break @@ -21345,21 +25165,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) local kind=subset[1] local lookupcache=subset[2] if kind=="rphf" then - for k,v in next,ra do - local r=lookupcache[k] - if r then - for k,v in next,halant do - local h=r[k] - if h then - reph=h.ligature or false - break - end - end - if reph then - break - end - end - end + reph=subset[3] local current=start local last=getnext(stop) while current~=last do @@ -21392,7 +25198,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) if current~=stop then local c=locl[current] or getchar(current) local found=lookupcache[c] - if found then + if found then local next=getnext(current) local n=locl[next] or getchar(next) if found[n] then @@ -21480,7 +25286,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) if current==stop then stop=getprev(stop) head=remove_node(head,current) - free_node(current) + flush_node(current) return head,stop,nbspaces else nbspaces=nbspaces+1 @@ -21592,8 +25398,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) end start=current end - local prev=getprev(halfpos) - setlink(prev,current) + setlink(getprev(halfpos),current) setlink(current,halfpos) halfpos=current elseif above_mark[char] then @@ -21619,12 +25424,11 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) local prev=getprev(current) if prev~=target then local next=getnext(current) - setlink(next,prev) + setlink(prev,next) if current==stop then stop=prev end - local next=getnext(target) - setlink(current,next) + setlink(current,getnext(target)) setlink(target,current) end end @@ -21649,8 +25453,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) if stop==next then stop=current end - local prev=getprev(c) - setlink(next,prev) + setlink(getprev(c),next) local nextnext=getnext(next) setnext(current,nextnext) local nextnextnext=getnext(nextnext) @@ -21663,9 +25466,12 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) current=getnext(current) end if getchar(base)==c_nbsp then + if base==stop then + stop=getprev(stop) + end nbspaces=nbspaces-1 head=remove_node(head,base) - free_node(base) + flush_node(base) end return head,stop,nbspaces end @@ -21704,7 +25510,7 @@ local function analyze_next_chars_one(c,font,variant) elseif (vv==c_zwnj or vv==c_zwj) and halant[vvv] then local nnnn=getnext(nnn) if nnnn then - local vvvv=ischar(nnnn) + local vvvv=ischar(nnnn,font) if vvvv and consonant[vvvv] then c=nnnn end @@ -21727,7 +25533,7 @@ local function analyze_next_chars_one(c,font,variant) local nn=getnext(n) if nn then local vv=ischar(nn,font) - if vv and zw_char[vv] then + if vv and zw_char[v] then n=nn v=vv nn=getnext(nn) @@ -22257,6 +26063,1340 @@ end -- closure do -- begin closure to overcome local limits and interference +if not modules then modules={} end modules ['font-ocl']={ + version=1.001, + comment="companion to font-otf.lua (context)", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local tostring,next,format=tostring,next,string.format +local round,max=math.round,math.round +local sortedkeys,sortedhash=table.sortedkeys,table.sortedhash +local setmetatableindex=table.setmetatableindex +local formatters=string.formatters +local tounicode=fonts.mappings.tounicode +local otf=fonts.handlers.otf +local f_color=formatters["pdf:direct:%f %f %f rg"] +local f_gray=formatters["pdf:direct:%f g"] +if context then + local startactualtext=nil + local stopactualtext=nil + function otf.getactualtext(s) + if not startactualtext then + startactualtext=backends.codeinjections.startunicodetoactualtextdirect + stopactualtext=backends.codeinjections.stopunicodetoactualtextdirect + end + return startactualtext(s),stopactualtext() + end +else + local tounicode=fonts.mappings.tounicode16 + function otf.getactualtext(s) + return + "/Span << /ActualText <feff"..n.."> >> BDC", + "EMC" + end +end +local sharedpalettes={} +local hash=setmetatableindex(function(t,k) + local v={ "special",k } + t[k]=v + return v +end) +if context then + local colors=attributes.list[attributes.private('color')] or {} + local transparencies=attributes.list[attributes.private('transparency')] or {} + function otf.registerpalette(name,values) + sharedpalettes[name]=values + for i=1,#values do + local v=values[i] + local c=nil + local t=nil + if type(v)=="table" then + c=colors.register(name,"rgb", + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + ) + else + c=colors[v] + t=transparencies[v] + end + if c and t then + values[i]=hash["pdf:direct:"..lpdf.color(1,c).." "..lpdf.transparency(t)] + elseif c then + values[i]=hash["pdf:direct:"..lpdf.color(1,c)] + elseif t then + values[i]=hash["pdf:direct:"..lpdf.color(1,t)] + end + end + end +else + function otf.registerpalette(name,values) + sharedpalettes[name]=values + for i=1,#values do + local v=values[i] + values[i]=hash[f_color( + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + )] + end + end +end +local function convert(t,k) + local v={} + for i=1,#k do + local p=k[i] + local r,g,b=p[1],p[2],p[3] + if r==g and g==b then + v[i]=hash[f_gray(r/255)] + else + v[i]=hash[f_color(r/255,g/255,b/255)] + end + end + t[k]=v + return v +end +local function initializecolr(tfmdata,kind,value) + if value then + local resources=tfmdata.resources + local palettes=resources.colorpalettes + if palettes then + local converted=resources.converted + if not converted then + converted=setmetatableindex(convert) + resources.converted=converted + end + local colorvalues=sharedpalettes[value] or converted[palettes[tonumber(value) or 1] or palettes[1]] or {} + local classes=#colorvalues + if classes==0 then + return + end + local characters=tfmdata.characters + local descriptions=tfmdata.descriptions + local properties=tfmdata.properties + properties.virtualized=true + tfmdata.fonts={ + { id=0 } + } + local widths=setmetatableindex(function(t,k) + local v={ "right",-k } + t[k]=v + return v + end) + local getactualtext=otf.getactualtext + local default=colorvalues[#colorvalues] + local b,e=getactualtext(tounicode(0xFFFD)) + local start={ "special","pdf:page:q" } + local stop={ "special","pdf:raw:Q" } + local actualb={ "special","pdf:page:"..b } + local actuale={ "special","pdf:page:"..e } + local cache=setmetatableindex(function(t,k) + local v={ "char",k } + t[k]=v + return v + end) + for unicode,character in next,characters do + local description=descriptions[unicode] + if description then + local colorlist=description.colors + if colorlist then + local u=description.unicode or characters[unicode].unicode + local w=character.width or 0 + local s=#colorlist + local goback=w~=0 and widths[w] or nil + local t={ + start, + not u and actualb or { "special","pdf:raw:"..getactualtext(tounicode(u)) } + } + local n=2 + local l=nil + for i=1,s do + local entry=colorlist[i] + local v=colorvalues[entry.class] or default + if v and l~=v then + n=n+1 t[n]=v + l=v + end + n=n+1 t[n]=cache[entry.slot] + if s>1 and i<s and goback then + n=n+1 t[n]=goback + end + end + n=n+1 t[n]=actuale + n=n+1 t[n]=stop + character.commands=t + end + end + end + end + end +end +fonts.handlers.otf.features.register { + name="colr", + description="color glyphs", + manipulators={ + base=initializecolr, + node=initializecolr, + } +} +do + local nofstreams=0 + local f_name=formatters[ [[pdf-glyph-%05i]] ] + local f_used=context and formatters[ [[original:///%s]] ] or formatters[ [[%s]] ] + local hashed={} + local cache={} + function otf.storepdfdata(pdf) + local done=hashed[pdf] + if not done then + nofstreams=nofstreams+1 + local o,n=epdf.openMemStream(pdf,#pdf,f_name(nofstreams)) + cache[n]=o + done=f_used(n) + hashed[pdf]=done + end + return nil,done,nil + end +end +local function pdftovirtual(tfmdata,pdfshapes,kind) + if not tfmdata or not pdfshapes or not kind then + return + end + local characters=tfmdata.characters + local properties=tfmdata.properties + local parameters=tfmdata.parameters + local hfactor=parameters.hfactor + properties.virtualized=true + tfmdata.fonts={ + { id=0 } + } + local getactualtext=otf.getactualtext + local storepdfdata=otf.storepdfdata + for unicode,character in sortedhash(characters) do + local index=character.index + if index then + local pdf=pdfshapes[index] + local typ=type(pdf) + local data=nil + local dx=nil + local dy=nil + if typ=="table" then + data=pdf.data + dx=pdf.dx or 0 + dy=pdf.dy or 0 + elseif typ=="string" then + data=pdf + dx=0 + dy=0 + end + if data then + local setcode,name,nilcode=storepdfdata(data) + if name then + local bt,et=getactualtext(unicode) + local wd=character.width or 0 + local ht=character.height or 0 + local dp=character.depth or 0 + character.commands={ + { "special","pdf:direct:"..bt }, + { "down",dp+dy*hfactor }, + { "right",dx*hfactor }, + { "image",{ filename=name,width=wd,height=ht,depth=dp } }, + { "special","pdf:direct:"..et }, + } + character[kind]=true + end + end + end + end +end +local otfsvg=otf.svg or {} +otf.svg=otfsvg +otf.svgenabled=true +do + local report_svg=logs.reporter("fonts","svg conversion") + local loaddata=io.loaddata + local savedata=io.savedata + local remove=os.remove + if context and xml.convert then + local xmlconvert=xml.convert + local xmlfirst=xml.first + function otfsvg.filterglyph(entry,index) + local svg=xmlconvert(entry.data) + local root=svg and xmlfirst(svg,"/svg[@id='glyph"..index.."']") + local data=root and tostring(root) + return data + end + else + function otfsvg.filterglyph(entry,index) + return entry.data + end + end + local runner=sandbox and sandbox.registerrunner { + name="otfsvg", + program="inkscape", + method="pipeto", + template="--shell > temp-otf-svg-shape.log", + reporter=report_svg, + } + if not runner then + runner=function() + return io.open("inkscape --shell > temp-otf-svg-shape.log","w") + end + end + function otfsvg.topdf(svgshapes) + local pdfshapes={} + local inkscape=runner() + if inkscape then + local nofshapes=#svgshapes + local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"] + local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"] + local f_convert=formatters["%s --export-pdf=%s\n"] + local filterglyph=otfsvg.filterglyph + local nofdone=0 + report_svg("processing %i svg containers",nofshapes) + statistics.starttiming() + for i=1,nofshapes do + local entry=svgshapes[i] + for index=entry.first,entry.last do + local data=filterglyph(entry,index) + if data and data~="" then + local svgfile=f_svgfile(index) + local pdffile=f_pdffile(index) + savedata(svgfile,data) + inkscape:write(f_convert(svgfile,pdffile)) + pdfshapes[index]=true + nofdone=nofdone+1 + if nofdone%100==0 then + report_svg("%i shapes processed",nofdone) + end + end + end + end + inkscape:write("quit\n") + inkscape:close() + report_svg("processing %i pdf results",nofshapes) + for index in next,pdfshapes do + local svgfile=f_svgfile(index) + local pdffile=f_pdffile(index) + pdfshapes[index]=loaddata(pdffile) + remove(svgfile) + remove(pdffile) + end + statistics.stoptiming() + if statistics.elapsedseconds then + report_svg("svg conversion time %s",statistics.elapsedseconds() or "-") + end + end + return pdfshapes + end +end +local function initializesvg(tfmdata,kind,value) + if value and otf.svgenabled then + local svg=tfmdata.properties.svg + local hash=svg and svg.hash + local timestamp=svg and svg.timestamp + if not hash then + return + end + local pdffile=containers.read(otf.pdfcache,hash) + local pdfshapes=pdffile and pdffile.pdfshapes + if not pdfshapes or pdffile.timestamp~=timestamp then + local svgfile=containers.read(otf.svgcache,hash) + local svgshapes=svgfile and svgfile.svgshapes + pdfshapes=svgshapes and otfsvg.topdf(svgshapes) or {} + containers.write(otf.pdfcache,hash,{ + pdfshapes=pdfshapes, + timestamp=timestamp, + }) + end + pdftovirtual(tfmdata,pdfshapes,"svg") + end +end +fonts.handlers.otf.features.register { + name="svg", + description="svg glyphs", + manipulators={ + base=initializesvg, + node=initializesvg, + } +} +local otfsbix=otf.sbix or {} +otf.sbix=otfsbix +otf.sbixenabled=true +do + local report_sbix=logs.reporter("fonts","sbix conversion") + local loaddata=io.loaddata + local savedata=io.savedata + local remove=os.remove + local runner=sandbox and sandbox.registerrunner { + name="otfsbix", + program="gm", + template="convert -quality 100 temp-otf-sbix-shape.sbix temp-otf-sbix-shape.pdf > temp-otf-svg-shape.log", + } + if not runner then + runner=function() + return os.execute("gm convert -quality 100 temp-otf-sbix-shape.sbix temp-otf-sbix-shape.pdf > temp-otf-svg-shape.log") + end + end + function otfsbix.topdf(sbixshapes) + local pdfshapes={} + local sbixfile="temp-otf-sbix-shape.sbix" + local pdffile="temp-otf-sbix-shape.pdf" + local nofdone=0 + local indices=sortedkeys(sbixshapes) + local nofindices=#indices + report_sbix("processing %i sbix containers",nofindices) + statistics.starttiming() + for i=1,nofindices do + local index=indices[i] + local entry=sbixshapes[index] + local data=entry.data + local x=entry.x + local y=entry.y + savedata(sbixfile,data) + runner() + pdfshapes[index]={ + x=x~=0 and x or nil, + y=y~=0 and y or nil, + data=loaddata(pdffile), + } + nofdone=nofdone+1 + if nofdone%100==0 then + report_sbix("%i shapes processed",nofdone) + end + end + report_sbix("processing %i pdf results",nofindices) + remove(sbixfile) + remove(pdffile) + statistics.stoptiming() + if statistics.elapsedseconds then + report_sbix("sbix conversion time %s",statistics.elapsedseconds() or "-") + end + return pdfshapes + end +end +local function initializesbix(tfmdata,kind,value) + if value and otf.sbixenabled then + local sbix=tfmdata.properties.sbix + local hash=sbix and sbix.hash + local timestamp=sbix and sbix.timestamp + if not hash then + return + end + local pdffile=containers.read(otf.pdfcache,hash) + local pdfshapes=pdffile and pdffile.pdfshapes + if not pdfshapes or pdffile.timestamp~=timestamp then + local sbixfile=containers.read(otf.sbixcache,hash) + local sbixshapes=sbixfile and sbixfile.sbixshapes + pdfshapes=sbixshapes and otfsbix.topdf(sbixshapes) or {} + containers.write(otf.pdfcache,hash,{ + pdfshapes=pdfshapes, + timestamp=timestamp, + }) + end + pdftovirtual(tfmdata,pdfshapes,"sbix") + end +end +fonts.handlers.otf.features.register { + name="sbix", + description="sbix glyphs", + manipulators={ + base=initializesbix, + node=initializesbix, + } +} + +end -- closure + +do -- begin closure to overcome local limits and interference + +if not modules then modules={} end modules ['font-otc']={ + version=1.001, + comment="companion to font-otf.lua (context)", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local format,insert,sortedkeys,tohash=string.format,table.insert,table.sortedkeys,table.tohash +local type,next=type,next +local lpegmatch=lpeg.match +local utfbyte,utflen,utfsplit=utf.byte,utf.len,utf.split +local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) +local report_otf=logs.reporter("fonts","otf loading") +local fonts=fonts +local otf=fonts.handlers.otf +local registerotffeature=otf.features.register +local setmetatableindex=table.setmetatableindex +local normalized={ + substitution="substitution", + single="substitution", + ligature="ligature", + alternate="alternate", + multiple="multiple", + kern="kern", + pair="pair", + chainsubstitution="chainsubstitution", + chainposition="chainposition", +} +local types={ + substitution="gsub_single", + ligature="gsub_ligature", + alternate="gsub_alternate", + multiple="gsub_multiple", + kern="gpos_pair", + pair="gpos_pair", + chainsubstitution="gsub_contextchain", + chainposition="gpos_contextchain", +} +local names={ + gsub_single="gsub", + gsub_multiple="gsub", + gsub_alternate="gsub", + gsub_ligature="gsub", + gsub_context="gsub", + gsub_contextchain="gsub", + gsub_reversecontextchain="gsub", + gpos_single="gpos", + gpos_pair="gpos", + gpos_cursive="gpos", + gpos_mark2base="gpos", + gpos_mark2ligature="gpos", + gpos_mark2mark="gpos", + gpos_context="gpos", + gpos_contextchain="gpos", +} +setmetatableindex(types,function(t,k) t[k]=k return k end) +local everywhere={ ["*"]={ ["*"]=true } } +local noflags={ false,false,false,false } +local function getrange(sequences,category) + local count=#sequences + local first=nil + local last=nil + for i=1,count do + local t=sequences[i].type + if t and names[t]==category then + if not first then + first=i + end + last=i + end + end + return first or 1,last or count +end +local function validspecification(specification,name) + local dataset=specification.dataset + if dataset then + elseif specification[1] then + dataset=specification + specification={ dataset=dataset } + else + dataset={ { data=specification.data } } + specification.data=nil + specification.dataset=dataset + end + local first=dataset[1] + if first then + first=first.data + end + if not first then + report_otf("invalid feature specification, no dataset") + return + end + if type(name)~="string" then + name=specification.name or first.name + end + if type(name)~="string" then + report_otf("invalid feature specification, no name") + return + end + local n=#dataset + if n>0 then + for i=1,n do + setmetatableindex(dataset[i],specification) + end + return specification,name + end +end +local function addfeature(data,feature,specifications) + if not specifications then + report_otf("missing specification") + return + end + local descriptions=data.descriptions + local resources=data.resources + local features=resources.features + local sequences=resources.sequences + if not features or not sequences then + report_otf("missing specification") + return + end + local alreadydone=resources.alreadydone + if not alreadydone then + alreadydone={} + resources.alreadydone=alreadydone + end + if alreadydone[specifications] then + return + else + alreadydone[specifications]=true + end + local fontfeatures=resources.features or everywhere + local unicodes=resources.unicodes + local splitter=lpeg.splitter(" ",unicodes) + local done=0 + local skip=0 + local aglunicodes=false + local specifications=validspecification(specifications,feature) + if not specifications then + return + end + local function tounicode(code) + if not code then + return + end + if type(code)=="number" then + return code + end + local u=unicodes[code] + if u then + return u + end + if utflen(code)==1 then + u=utfbyte(code) + if u then + return u + end + end + if not aglunicodes then + aglunicodes=fonts.encodings.agl.unicodes + end + return aglunicodes[code] + end + local coverup=otf.coverup + local coveractions=coverup.actions + local stepkey=coverup.stepkey + local register=coverup.register + local function prepare_substitution(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + else + if type(replacement)=="table" then + replacement=replacement[1] + end + replacement=tounicode(replacement) + if replacement and descriptions[replacement] then + cover(coverage,unicode,replacement) + done=done+1 + else + skip=skip+1 + end + end + end + return coverage + end + local function prepare_alternate(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + elseif type(replacement)=="table" then + local r={} + for i=1,#replacement do + local u=tounicode(replacement[i]) + r[i]=(nocheck or descriptions[u]) and u or unicode + end + cover(coverage,unicode,r) + done=done+1 + else + local u=tounicode(replacement) + if u then + cover(coverage,unicode,{ u }) + done=done+1 + else + skip=skip+1 + end + end + end + return coverage + end + local function prepare_multiple(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + elseif type(replacement)=="table" then + local r,n={},0 + for i=1,#replacement do + local u=tounicode(replacement[i]) + if nocheck or descriptions[u] then + n=n+1 + r[n]=u + end + end + if n>0 then + cover(coverage,unicode,r) + done=done+1 + else + skip=skip+1 + end + else + local u=tounicode(replacement) + if u then + cover(coverage,unicode,{ u }) + done=done+1 + else + skip=skip+1 + end + end + end + return coverage + end + local function prepare_ligature(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,ligature in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + else + if type(ligature)=="string" then + ligature={ lpegmatch(splitter,ligature) } + end + local present=true + for i=1,#ligature do + local l=ligature[i] + local u=tounicode(l) + if nocheck or descriptions[u] then + ligature[i]=u + else + present=false + break + end + end + if present then + cover(coverage,unicode,ligature) + done=done+1 + else + skip=skip+1 + end + end + end + return coverage + end + local function resetspacekerns() + data.properties.hasspacekerns=true + data.resources .spacekerns=nil + end + local function prepare_kern(list,featuretype) + local coverage={} + local cover=coveractions[featuretype] + local isspace=false + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if description and type(replacement)=="table" then + local r={} + for k,v in next,replacement do + local u=tounicode(k) + if u then + r[u]=v + if u==32 then + isspace=true + end + end + end + if next(r) then + cover(coverage,unicode,r) + done=done+1 + if unicode==32 then + isspace=true + end + else + skip=skip+1 + end + else + skip=skip+1 + end + end + if isspace then + resetspacekerns() + end + return coverage + end + local function prepare_pair(list,featuretype) + local coverage={} + local cover=coveractions[featuretype] + if cover then + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if description and type(replacement)=="table" then + local r={} + for k,v in next,replacement do + local u=tounicode(k) + if u then + r[u]=v + if u==32 then + isspace=true + end + end + end + if next(r) then + cover(coverage,unicode,r) + done=done+1 + if unicode==32 then + isspace=true + end + else + skip=skip+1 + end + else + skip=skip+1 + end + end + if isspace then + resetspacekerns() + end + else + report_otf("unknown cover type %a",featuretype) + end + return coverage + end + local function prepare_chain(list,featuretype,sublookups) + local rules=list.rules + local coverage={} + if rules then + local rulehash={} + local rulesize=0 + local sequence={} + local nofsequences=0 + local lookuptype=types[featuretype] + for nofrules=1,#rules do + local rule=rules[nofrules] + local current=rule.current + local before=rule.before + local after=rule.after + local replacements=rule.replacements or false + local sequence={} + local nofsequences=0 + if before then + for n=1,#before do + nofsequences=nofsequences+1 + sequence[nofsequences]=before[n] + end + end + local start=nofsequences+1 + for n=1,#current do + nofsequences=nofsequences+1 + sequence[nofsequences]=current[n] + end + local stop=nofsequences + if after then + for n=1,#after do + nofsequences=nofsequences+1 + sequence[nofsequences]=after[n] + end + end + local lookups=rule.lookups or false + local subtype=nil + if lookups and sublookups then + for k,v in next,lookups do + local t=type(v) + if t=="table" then + for i=1,#v do + local vi=v[i] + if type(vi)~="table" then + v[i]={ vi } + end + end + elseif t=="number" then + local lookup=sublookups[v] + if lookup then + lookups[k]={ lookup } + if not subtype then + subtype=lookup.type + end + else + lookups[k]=false + end + else + lookups[k]=false + end + end + end + if nofsequences>0 then + local hashed={} + for i=1,nofsequences do + local t={} + local s=sequence[i] + for i=1,#s do + local u=tounicode(s[i]) + if u then + t[u]=true + end + end + hashed[i]=t + end + sequence=hashed + rulesize=rulesize+1 + rulehash[rulesize]={ + nofrules, + lookuptype, + sequence, + start, + stop, + lookups, + replacements, + subtype, + } + for unic in next,sequence[start] do + local cu=coverage[unic] + if not cu then + coverage[unic]=rulehash + end + end + end + end + end + return coverage + end + local dataset=specifications.dataset + local function report(name,category,position,first,last,sequences) + report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]", + name,category,position,first,last,1,#sequences) + end + local function inject(specification,sequences,sequence,first,last,category,name) + local position=specification.position or false + if not position then + position=specification.prepend + if position==true then + if trace_loading then + report(name,category,first,first,last,sequences) + end + insert(sequences,first,sequence) + return + end + end + if not position then + position=specification.append + if position==true then + if trace_loading then + report(name,category,last+1,first,last,sequences) + end + insert(sequences,last+1,sequence) + return + end + end + local kind=type(position) + if kind=="string" then + local index=false + for i=first,last do + local s=sequences[i] + local f=s.features + if f then + for k in next,f do + if k==position then + index=i + break + end + end + if index then + break + end + end + end + if index then + position=index + else + position=last+1 + end + elseif kind=="number" then + if position<0 then + position=last-position+1 + end + if position>last then + position=last+1 + elseif position<first then + position=first + end + else + position=last+1 + end + if trace_loading then + report(name,category,position,first,last,sequences) + end + insert(sequences,position,sequence) + end + for s=1,#dataset do + local specification=dataset[s] + local valid=specification.valid + local feature=specification.name or feature + if not feature or feature=="" then + report_otf("no valid name given for extra feature") + elseif not valid or valid(data,specification,feature) then + local initialize=specification.initialize + if initialize then + specification.initialize=initialize(specification,data) and initialize or nil + end + local askedfeatures=specification.features or everywhere + local askedsteps=specification.steps or specification.subtables or { specification.data } or {} + local featuretype=normalized[specification.type or "substitution"] or "substitution" + local featureflags=specification.flags or noflags + local nocheck=specification.nocheck + local futuresteps=specification.futuresteps + local featureorder=specification.order or { feature } + local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0 + local nofsteps=0 + local steps={} + local sublookups=specification.lookups + local category=nil + if sublookups then + local s={} + for i=1,#sublookups do + local specification=sublookups[i] + local askedsteps=specification.steps or specification.subtables or { specification.data } or {} + local featuretype=normalized[specification.type or "substitution"] or "substitution" + local featureflags=specification.flags or noflags + local nofsteps=0 + local steps={} + for i=1,#askedsteps do + local list=askedsteps[i] + local coverage=nil + local format=nil + if featuretype=="substitution" then + coverage=prepare_substitution(list,featuretype,nocheck) + elseif featuretype=="ligature" then + coverage=prepare_ligature(list,featuretype,nocheck) + elseif featuretype=="alternate" then + coverage=prepare_alternate(list,featuretype,nocheck) + elseif featuretype=="multiple" then + coverage=prepare_multiple(list,featuretype,nocheck) + elseif featuretype=="kern" then + format="kern" + coverage=prepare_kern(list,featuretype) + elseif featuretype=="pair" then + format="pair" + coverage=prepare_pair(list,featuretype) + end + if coverage and next(coverage) then + nofsteps=nofsteps+1 + steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources) + end + end + s[i]={ + [stepkey]=steps, + nofsteps=nofsteps, + flags=featureflags, + type=types[featuretype], + } + end + sublookups=s + end + for i=1,#askedsteps do + local list=askedsteps[i] + local coverage=nil + local format=nil + if featuretype=="substitution" then + category="gsub" + coverage=prepare_substitution(list,featuretype,nocheck) + elseif featuretype=="ligature" then + category="gsub" + coverage=prepare_ligature(list,featuretype,nocheck) + elseif featuretype=="alternate" then + category="gsub" + coverage=prepare_alternate(list,featuretype,nocheck) + elseif featuretype=="multiple" then + category="gsub" + coverage=prepare_multiple(list,featuretype,nocheck) + elseif featuretype=="kern" then + category="gpos" + format="kern" + coverage=prepare_kern(list,featuretype) + elseif featuretype=="pair" then + category="gpos" + format="pair" + coverage=prepare_pair(list,featuretype) + elseif featuretype=="chainsubstitution" then + category="gsub" + coverage=prepare_chain(list,featuretype,sublookups) + elseif featuretype=="chainposition" then + category="gpos" + coverage=prepare_chain(list,featuretype,sublookups) + else + report_otf("not registering feature %a, unknown category",feature) + return + end + if coverage and next(coverage) then + nofsteps=nofsteps+1 + steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources) + end + end + if nofsteps>0 then + for k,v in next,askedfeatures do + if v[1] then + askedfeatures[k]=tohash(v) + end + end + if featureflags[1] then featureflags[1]="mark" end + if featureflags[2] then featureflags[2]="ligature" end + if featureflags[3] then featureflags[3]="base" end + local steptype=types[featuretype] + local sequence={ + chain=featurechain, + features={ [feature]=askedfeatures }, + flags=featureflags, + name=feature, + order=featureorder, + [stepkey]=steps, + nofsteps=nofsteps, + type=steptype, + } + local first,last=getrange(sequences,category) + inject(specification,sequences,sequence,first,last,category,feature) + local features=fontfeatures[category] + if not features then + features={} + fontfeatures[category]=features + end + local k=features[feature] + if not k then + k={} + features[feature]=k + end + for script,languages in next,askedfeatures do + local kk=k[script] + if not kk then + kk={} + k[script]=kk + end + for language,value in next,languages do + kk[language]=value + end + end + end + end + end + if trace_loading then + report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip) + end +end +otf.enhancers.addfeature=addfeature +local extrafeatures={} +local knownfeatures={} +function otf.addfeature(name,specification) + if type(name)=="table" then + specification=name + end + if type(specification)~="table" then + report_otf("invalid feature specification, no valid table") + return + end + specification,name=validspecification(specification,name) + if name and specification then + local slot=knownfeatures[name] + if not slot then + slot=#extrafeatures+1 + knownfeatures[name]=slot + elseif specification.overload==false then + slot=#extrafeatures+1 + knownfeatures[name]=slot + else + end + specification.name=name + extrafeatures[slot]=specification + end +end +local function enhance(data,filename,raw) + for slot=1,#extrafeatures do + local specification=extrafeatures[slot] + addfeature(data,specification.name,specification) + end +end +otf.enhancers.enhance=enhance +otf.enhancers.register("check extra features",enhance) +local tlig={ + [0x2013]={ 0x002D,0x002D }, + [0x2014]={ 0x002D,0x002D,0x002D }, +} +local tlig_specification={ + type="ligature", + features=everywhere, + data=tlig, + order={ "tlig" }, + flags=noflags, + prepend=true, +} +otf.addfeature("tlig",tlig_specification) +registerotffeature { + name='tlig', + description='tex ligatures', +} +local trep={ + [0x0027]=0x2019, +} +local trep_specification={ + type="substitution", + features=everywhere, + data=trep, + order={ "trep" }, + flags=noflags, + prepend=true, +} +otf.addfeature("trep",trep_specification) +registerotffeature { + name='trep', + description='tex replacements', +} +local anum_arabic={ + [0x0030]=0x0660, + [0x0031]=0x0661, + [0x0032]=0x0662, + [0x0033]=0x0663, + [0x0034]=0x0664, + [0x0035]=0x0665, + [0x0036]=0x0666, + [0x0037]=0x0667, + [0x0038]=0x0668, + [0x0039]=0x0669, +} +local anum_persian={ + [0x0030]=0x06F0, + [0x0031]=0x06F1, + [0x0032]=0x06F2, + [0x0033]=0x06F3, + [0x0034]=0x06F4, + [0x0035]=0x06F5, + [0x0036]=0x06F6, + [0x0037]=0x06F7, + [0x0038]=0x06F8, + [0x0039]=0x06F9, +} +local function valid(data) + local features=data.resources.features + if features then + for k,v in next,features do + for k,v in next,v do + if v.arab then + return true + end + end + end + end +end +local anum_specification={ + { + type="substitution", + features={ arab={ urd=true,dflt=true } }, + order={ "anum" }, + data=anum_arabic, + flags=noflags, + valid=valid, + }, + { + type="substitution", + features={ arab={ urd=true } }, + order={ "anum" }, + data=anum_persian, + flags=noflags, + valid=valid, + }, +} +otf.addfeature("anum",anum_specification) +registerotffeature { + name='anum', + description='arabic digits', +} +local lookups={} +local protect={} +local revert={} +local zwj={ 0x200C } +otf.addfeature { + name="blockligatures", + type="chainsubstitution", + nocheck=true, + prepend=true, + future=true, + lookups={ + { + type="multiple", + data=lookups, + }, + }, + data={ + rules=protect, + } +} +otf.addfeature { + name="blockligatures", + type="chainsubstitution", + nocheck=true, + append=true, + overload=false, + lookups={ + { + type="ligature", + data=lookups, + }, + }, + data={ + rules=revert, + } +} +registerotffeature { + name='blockligatures', + description='block certain ligatures', +} +local settings_to_array=utilities.parsers and utilities.parsers.settings_to_array + or function(s) return string.split(s,",") end +local function blockligatures(str) + local t=settings_to_array(str) + for i=1,#t do + local ti=utfsplit(t[i]) + if #ti>1 then + local one=ti[1] + local two=ti[2] + lookups[one]={ one,0x200C } + local one={ one } + local two={ two } + local new=#protect+1 + protect[new]={ + current={ one,two }, + lookups={ 1 }, + } + revert[new]={ + current={ one,zwj }, + after={ two }, + lookups={ 1 }, + } + end + end +end +otf.helpers.blockligatures=blockligatures +if context then + interfaces.implement { + name="blockligatures", + arguments="string", + actions=blockligatures, + } +end + +end -- closure + +do -- begin closure to overcome local limits and interference + if not modules then modules={} end modules ['font-onr']={ version=1.001, comment="companion to font-ini.mkiv", @@ -22265,51 +27405,25 @@ if not modules then modules={} end modules ['font-onr']={ license="see context related readme files" } local fonts,logs,trackers,resolvers=fonts,logs,trackers,resolvers -local next,type,tonumber,rawget=next,type,tonumber,rawget +local next,type,tonumber,rawget,rawset=next,type,tonumber,rawget,rawset local match,lower,gsub,strip,find=string.match,string.lower,string.gsub,string.strip,string.find local char,byte,sub=string.char,string.byte,string.sub local abs=math.abs local bxor,rshift=bit32.bxor,bit32.rshift -local P,S,R,Cmt,C,Ct,Cs,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg +local P,S,R,Cmt,C,Ct,Cs,Carg,Cf,Cg=lpeg.P,lpeg.S,lpeg.R,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cf,lpeg.Cg local lpegmatch,patterns=lpeg.match,lpeg.patterns local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end) local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end) local report_afm=logs.reporter("fonts","afm loading") -local report_afm=logs.reporter("fonts","pfb loading") -fonts=fonts or {} -local handlers=fonts.handlers or {} -fonts.handlers=handlers +local report_pfb=logs.reporter("fonts","pfb loading") +local handlers=fonts.handlers local afm=handlers.afm or {} handlers.afm=afm local readers=afm.readers or {} afm.readers=readers afm.version=1.512 -local get_indexes +local get_indexes,get_shapes do - local n,m - local progress=function(str,position,name,size) - local forward=position+tonumber(size)+3+2 - n=n+1 - if n>=m then - return #str,name - elseif forward<#str then - return forward,name - else - return #str,name - end - end - local initialize=function(str,position,size) - n=0 - m=tonumber(size) - return position+1 - end - local charstrings=P("/CharStrings") - local name=P("/")*C((R("az")+R("AZ")+R("09")+S("-_."))^1) - local size=C(R("09")^1) - local spaces=P(" ")^1 - local p_filternames=Ct ( - (1-charstrings)^0*charstrings*spaces*Cmt(size,initialize)*(Cmt(name*P(" ")^1*C(R("09")^1),progress)+P(1))^1 - ) local decrypt do local r,c1,c2,n=0,0,0,0 @@ -22319,13 +27433,75 @@ do r=((cipher+r)*c1+c2)%65536 return char(plain) end - decrypt=function(binary) - r,c1,c2,n=55665,52845,22719,4 + decrypt=function(binary,initial,seed) + r,c1,c2,n=initial,52845,22719,seed binary=gsub(binary,".",step) return sub(binary,n+1) end end - local function loadpfbvector(filename) + local charstrings=P("/CharStrings") + local subroutines=P("/Subrs") + local encoding=P("/Encoding") + local dup=P("dup") + local put=P("put") + local array=P("array") + local name=P("/")*C((R("az")+R("AZ")+R("09")+S("-_."))^1) + local digits=R("09")^1 + local cardinal=digits/tonumber + local spaces=P(" ")^1 + local spacing=patterns.whitespace^0 + local routines,vector,chars,n,m + local initialize=function(str,position,size) + n=0 + m=size + return position+1 + end + local setroutine=function(str,position,index,size) + local forward=position+tonumber(size) + local stream=decrypt(sub(str,position+1,forward),4330,4) + routines[index]={ byte(stream,1,#stream) } + return forward + end + local setvector=function(str,position,name,size) + local forward=position+tonumber(size) + if n>=m then + return #str + elseif forward<#str then + vector[n]=name + n=n+1 + return forward + else + return #str + end + end + local setshapes=function(str,position,name,size) + local forward=position+tonumber(size) + local stream=sub(str,position+1,forward) + if n>m then + return #str + elseif forward<#str then + vector[n]=name + n=n+1 + chars [n]=decrypt(stream,4330,4) + return forward + else + return #str + end + end + local p_rd=spacing*(P("RD")+P("-|")) + local p_np=spacing*(P("NP")+P("|")) + local p_nd=spacing*(P("ND")+P("|")) + local p_filterroutines= + (1-subroutines)^0*subroutines*spaces*Cmt(cardinal,initialize)*(Cmt(cardinal*spaces*cardinal*p_rd,setroutine)*p_np+P(1))^1 + local p_filtershapes= + (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*p_rd,setshapes)*p_nd+P(1))^1 + local p_filternames=Ct ( + (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal,setvector)+P(1))^1 + ) + local p_filterencoding=(1-encoding)^0*encoding*spaces*digits*spaces*array*(1-dup)^0*Cf( + Ct("")*Cg(spacing*dup*spaces*cardinal*spaces*name*spaces*put)^1 +,rawset) + local function loadpfbvector(filename,shapestoo) local data=io.loaddata(resolvers.findfile(filename)) if not data then report_pfb("no data in %a",filename) @@ -22340,17 +27516,34 @@ do report_pfb("no binary data in %a",filename) return end - binary=decrypt(binary,4) - local vector=lpegmatch(p_filternames,binary) - if vector[1]==".notdef" then - vector[0]=table.remove(vector,1) - end - if not vector then - report_pfb("no vector in %a",filename) - return + binary=decrypt(binary,55665,4) + local names={} + local encoding=lpegmatch(p_filterencoding,ascii) + local glyphs={} + routines,vector,chars={},{},{} + if shapestoo then + lpegmatch(p_filterroutines,binary) + lpegmatch(p_filtershapes,binary) + local data={ + dictionaries={ + { + charstrings=chars, + charset=vector, + subroutines=routines, + } + }, + } + fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,true) + else + lpegmatch(p_filternames,binary) end - return vector + names=vector + routines,vector,chars=nil,nil,nil + return names,encoding,glyphs end + local pfb=handlers.pfb or {} + handlers.pfb=pfb + pfb.loadvector=loadpfbvector get_indexes=function(data,pfbname) local vector=loadpfbvector(pfbname) if vector then @@ -22370,6 +27563,10 @@ do end end end + get_shapes=function(pfbname) + local vector,encoding,glyphs=loadpfbvector(pfbname,true) + return glyphs + end end local spacer=patterns.spacer local whitespace=patterns.whitespace @@ -22506,16 +27703,31 @@ function readers.loadfont(afmname,pfbname) local data=read(resolvers.findfile(afmname),fullparser) if data then if not pfbname or pfbname=="" then - pfbname=file.replacesuffix(file.nameonly(afmname),"pfb") - pfbname=resolvers.findfile(pfbname) + pfbname=resolvers.findfile(file.replacesuffix(file.nameonly(afmname),"pfb")) end if pfbname and pfbname~="" then data.resources.filename=resolvers.unresolve(pfbname) get_indexes(data,pfbname) - elseif trace_loading then + return data + else report_afm("no pfb file for %a",afmname) end - return data + end +end +function readers.loadshapes(filename) + local fullname=resolvers.findfile(filename) or "" + if fullname=="" then + return { + filename="not found: "..filename, + glyphs={} + } + else + return { + filename=fullname, + format="opentype", + glyphs=get_shapes(fullname) or {}, + units=1000, + } end end function readers.getinfo(filename) @@ -22555,43 +27767,22 @@ local findbinfile=resolvers.findbinfile local definers=fonts.definers local readers=fonts.readers local constructors=fonts.constructors -local afm=constructors.newhandler("afm") -local pfb=constructors.newhandler("pfb") +local afm=constructors.handlers.afm +local pfb=constructors.handlers.pfb local otf=fonts.handlers.otf local otfreaders=otf.readers local otfenhancers=otf.enhancers -local afmfeatures=constructors.newfeatures("afm") +local afmfeatures=constructors.features.afm local registerafmfeature=afmfeatures.register +local afmenhancers=constructors.enhancers.afm +local registerafmenhancer=afmenhancers.register afm.version=1.512 -afm.cache=containers.define("fonts","afm",afm.version,true) +afm.cache=containers.define("fonts","one",afm.version,true) afm.autoprefixed=true afm.helpdata={} afm.syncspace=true local overloads=fonts.mappings.overloads local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes -local enhancers={ -} -local steps={ - "unify names", - "add ligatures", - "add extra kerns", - "normalize features", - "fix names", -} -local function applyenhancers(data,filename) - for i=1,#steps do - local step=steps[i] - local enhancer=enhancers[step] - if enhancer then - if trace_loading then - report_afm("applying enhancer %a",step) - end - enhancer(data,filename) - else - report_afm("invalid enhancer %a",step) - end - end -end function afm.load(filename) filename=resolvers.findfile(filename,'afm') or "" if filename~="" and not fonts.names.ignoredfile(filename) then @@ -22614,7 +27805,7 @@ function afm.load(filename) report_afm("reading %a",filename) data=afm.readers.loadfont(filename,pfbname) if data then - applyenhancers(data,filename) + afmenhancers.apply(data,filename) fonts.mappings.addtounicode(data,filename) otfreaders.pack(data) data.size=size @@ -22639,7 +27830,7 @@ function afm.load(filename) end end local uparser=fonts.mappings.makenameparser() -enhancers["unify names"]=function(data,filename) +local function enhance_unify_names(data,filename) local unicodevector=fonts.encodings.agl.unicodes local unicodes={} local names={} @@ -22691,7 +27882,7 @@ enhancers["unify names"]=function(data,filename) end local everywhere={ ["*"]={ ["*"]=true } } local noflags={ false,false,false,false } -enhancers["normalize features"]=function(data) +local function enhance_normalize_features(data) local ligatures=setmetatableindex("table") local kerns=setmetatableindex("table") local extrakerns=setmetatableindex("table") @@ -22789,7 +27980,7 @@ enhancers["normalize features"]=function(data) data.resources.features=features data.resources.sequences=sequences end -enhancers["fix names"]=function(data) +local function enhance_fix_names(data) for k,v in next,data.descriptions do local n=v.name local r=overloads[n] @@ -22828,10 +28019,10 @@ local addthem=function(rawdata,ligatures) end end end -enhancers["add ligatures"]=function(rawdata) +local function enhance_add_ligatures(rawdata) addthem(rawdata,afm.helpdata.ligatures) end -enhancers["add extra kerns"]=function(rawdata) +local function enhance_add_extra_kerns(rawdata) local descriptions=rawdata.descriptions local resources=rawdata.resources local unicodes=resources.unicodes @@ -23150,17 +28341,12 @@ local function read_from_afm(specification) end return tfmdata end -local function setmode(tfmdata,value) - if value then - tfmdata.properties.mode=lower(value) - end -end registerafmfeature { name="mode", description="mode", initializers={ - base=setmode, - node=setmode, + base=otf.modeinitializer, + node=otf.modeinitializer, } } registerafmfeature { @@ -23175,7 +28361,6 @@ registerafmfeature { node=otf.featuresprocessor, } } -local check_tfm=readers.check_tfm fonts.formats.afm="type1" fonts.formats.pfb="type1" local function check_afm(specification,fullname) @@ -23210,7 +28395,8 @@ function readers.afm(specification,method) tfmdata=check_afm(specification,specification.name.."."..forced) end if not tfmdata then - method=method or definers.method or "afm or tfm" + local check_tfm=readers.check_tfm + method=(check_tfm and (method or definers.method or "afm or tfm")) or "afm" if method=="tfm" then tfmdata=check_tfm(specification,specification.name) elseif method=="afm" then @@ -23244,6 +28430,12 @@ function readers.pfb(specification,method) swap("specification") return readers.afm(specification,method) end +registerafmenhancer("unify names",enhance_unify_names) +registerafmenhancer("add ligatures",enhance_add_ligatures) +registerafmenhancer("add extra kerns",enhance_add_extra_kerns) +registerafmenhancer("normalize features",enhance_normalize_features) +registerafmenhancer("check extra features",otfenhancers.enhance) +registerafmenhancer("fix names",enhance_fix_names) end -- closure @@ -23418,6 +28610,514 @@ end -- closure do -- begin closure to overcome local limits and interference +if not modules then modules={} end modules ['font-tfm']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type=next,type +local match,format=string.match,string.format +local concat,sortedhash=table.concat,table.sortedhash +local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) +local trace_features=false trackers.register("tfm.features",function(v) trace_features=v end) +local report_defining=logs.reporter("fonts","defining") +local report_tfm=logs.reporter("fonts","tfm loading") +local findbinfile=resolvers.findbinfile +local setmetatableindex=table.setmetatableindex +local fonts=fonts +local handlers=fonts.handlers +local readers=fonts.readers +local constructors=fonts.constructors +local encodings=fonts.encodings +local tfm=constructors.handlers.tfm +tfm.version=1.000 +tfm.maxnestingdepth=5 +tfm.maxnestingsize=65536*1024 +local otf=fonts.handlers.otf +local otfenhancers=otf.enhancers +local tfmfeatures=constructors.features.tfm +local registertfmfeature=tfmfeatures.register +local tfmenhancers=constructors.enhancers.tfm +local registertfmenhancer=tfmenhancers.register +constructors.resolvevirtualtoo=false +fonts.formats.tfm="type1" +fonts.formats.ofm="type1" +function tfm.setfeatures(tfmdata,features) + local okay=constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm) + if okay then + return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm) + else + return {} + end +end +local depth={} +local function read_from_tfm(specification) + local filename=specification.filename + local size=specification.size + depth[filename]=(depth[filename] or 0)+1 + if trace_defining then + report_defining("loading tfm file %a at size %s",filename,size) + end + local tfmdata=font.read_tfm(filename,size) + if tfmdata then + local features=specification.features and specification.features.normal or {} + local features=constructors.checkedfeatures("tfm",features) + specification.features.normal=features + local newtfmdata=(depth[filename]==1) and tfm.reencode(tfmdata,specification) + if newtfmdata then + tfmdata=newtfmdata + end + local resources=tfmdata.resources or {} + local properties=tfmdata.properties or {} + local parameters=tfmdata.parameters or {} + local shared=tfmdata.shared or {} + shared.features=features + shared.resources=resources + properties.name=tfmdata.name + properties.fontname=tfmdata.fontname + properties.psname=tfmdata.psname + properties.fullname=tfmdata.fullname + properties.filename=specification.filename + properties.format=fonts.formats.tfm + tfmdata.properties=properties + tfmdata.resources=resources + tfmdata.parameters=parameters + tfmdata.shared=shared + shared.rawdata={ resources=resources } + shared.features=features + if newtfmdata then + if not resources.marks then + resources.marks={} + end + if not resources.sequences then + resources.sequences={} + end + if not resources.features then + resources.features={ + gsub={}, + gpos={}, + } + end + if not tfmdata.changed then + tfmdata.changed={} + end + if not tfmdata.descriptions then + tfmdata.descriptions=tfmdata.characters + end + otf.readers.addunicodetable(tfmdata) + tfmenhancers.apply(tfmdata,filename) + constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm) + otf.readers.unifymissing(tfmdata) + fonts.mappings.addtounicode(tfmdata,filename) + tfmdata.tounicode=1 + local tounicode=fonts.mappings.tounicode + for unicode,v in next,tfmdata.characters do + local u=v.unicode + if u then + v.tounicode=tounicode(u) + end + end + if tfmdata.usedbitmap then + tfm.addtounicode(tfmdata) + end + end + shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil + parameters.factor=1 + parameters.size=size + parameters.slant=parameters.slant or parameters[1] or 0 + parameters.space=parameters.space or parameters[2] or 0 + parameters.space_stretch=parameters.space_stretch or parameters[3] or 0 + parameters.space_shrink=parameters.space_shrink or parameters[4] or 0 + parameters.x_height=parameters.x_height or parameters[5] or 0 + parameters.quad=parameters.quad or parameters[6] or 0 + parameters.extra_space=parameters.extra_space or parameters[7] or 0 + constructors.enhanceparameters(parameters) + if newtfmdata then + elseif constructors.resolvevirtualtoo then + fonts.loggers.register(tfmdata,file.suffix(filename),specification) + local vfname=findbinfile(specification.name,'ovf') + if vfname and vfname~="" then + local vfdata=font.read_vf(vfname,size) + if vfdata then + local chars=tfmdata.characters + for k,v in next,vfdata.characters do + chars[k].commands=v.commands + end + properties.virtualized=true + tfmdata.fonts=vfdata.fonts + tfmdata.type="virtual" + local fontlist=vfdata.fonts + local name=file.nameonly(filename) + for i=1,#fontlist do + local n=fontlist[i].name + local s=fontlist[i].size + local d=depth[filename] + s=constructors.scaled(s,vfdata.designsize) + if d>tfm.maxnestingdepth then + report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth) + fontlist[i]={ id=0 } + elseif (d>1) and (s>tfm.maxnestingsize) then + report_defining("virtual font %a exceeds size %s",n,s) + fontlist[i]={ id=0 } + else + local t,id=fonts.constructors.readanddefine(n,s) + fontlist[i]={ id=id } + end + end + end + end + end + properties.haskerns=true + properties.hasligatures=true + resources.unicodes={} + resources.lookuptags={} + depth[filename]=depth[filename]-1 + return tfmdata + else + depth[filename]=depth[filename]-1 + end +end +local function check_tfm(specification,fullname) + local foundname=findbinfile(fullname,'tfm') or "" + if foundname=="" then + foundname=findbinfile(fullname,'ofm') or "" + end + if foundname=="" then + foundname=fonts.names.getfilename(fullname,"tfm") or "" + end + if foundname~="" then + specification.filename=foundname + specification.format="ofm" + return read_from_tfm(specification) + elseif trace_defining then + report_defining("loading tfm with name %a fails",specification.name) + end +end +readers.check_tfm=check_tfm +function readers.tfm(specification) + local fullname=specification.filename or "" + if fullname=="" then + local forced=specification.forced or "" + if forced~="" then + fullname=specification.name.."."..forced + else + fullname=specification.name + end + end + return check_tfm(specification,fullname) +end +readers.ofm=readers.tfm +do + local outfiles={} + local tfmcache=table.setmetatableindex(function(t,tfmdata) + local id=font.define(tfmdata) + t[tfmdata]=id + return id + end) + local encdone=table.setmetatableindex("table") + function tfm.reencode(tfmdata,specification) + local features=specification.features + if not features then + return + end + local features=features.normal + if not features then + return + end + local tfmfile=file.basename(tfmdata.name) + local encfile=features.reencode + local pfbfile=features.pfbfile + local bitmap=features.bitmap + if not encfile then + return + end + local pfbfile=outfiles[tfmfile] + if pfbfile==nil then + if bitmap then + pfbfile=false + elseif type(pfbfile)~="string" then + pfbfile=tfmfile + end + if type(pfbfile)=="string" then + pfbfile=file.addsuffix(pfbfile,"pfb") + report_tfm("using type1 shapes from %a for %a",pfbfile,tfmfile) + else + report_tfm("using bitmap shapes for %a",tfmfile) + pfbfile=false + end + outfiles[tfmfile]=pfbfile + end + local encoding=false + local vector=false + if type(pfbfile)=="string" then + local pfb=fonts.constructors.handlers.pfb + if pfb and pfb.loadvector then + local v,e=pfb.loadvector(pfbfile) + if v then + vector=v + end + if e then + encoding=e + end + end + end + if type(encfile)=="string" and encfile~="auto" then + encoding=fonts.encodings.load(file.addsuffix(encfile,"enc")) + if encoding then + encoding=encoding.vector + end + end + if not encoding then + report_tfm("bad encoding for %a, quitting",tfmfile) + return + end + local unicoding=fonts.encodings.agl and fonts.encodings.agl.unicodes + local virtualid=tfmcache[tfmdata] + local tfmdata=table.copy(tfmdata) + local characters={} + local originals=tfmdata.characters + local indices={} + local parentfont={ "font",1 } + local private=fonts.constructors.privateoffset + local reported=encdone[tfmfile][encfile] + local backmap=vector and table.swapped(vector) + local done={} + for index,name in sortedhash(encoding) do + local unicode=unicoding[name] + local original=originals[index] + if original then + if unicode then + original.unicode=unicode + else + unicode=private + private=private+1 + if not reported then + report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode) + end + end + characters[unicode]=original + indices[index]=unicode + original.name=name + if backmap then + original.index=backmap[name] + else + original.commands={ parentfont,{ "char",index } } + original.oindex=index + end + done[name]=true + elseif not done[name] then + report_tfm("bad index %a in font %a with name %a",index,tfmfile,name) + end + end + encdone[tfmfile][encfile]=true + for k,v in next,characters do + local kerns=v.kerns + if kerns then + local t={} + for k,v in next,kerns do + local i=indices[k] + if i then + t[i]=v + end + end + v.kerns=next(t) and t or nil + end + local ligatures=v.ligatures + if ligatures then + local t={} + for k,v in next,ligatures do + local i=indices[k] + if i then + t[i]=v + v.char=indices[v.char] + end + end + v.ligatures=next(t) and t or nil + end + end + tfmdata.fonts={ { id=virtualid } } + tfmdata.characters=characters + tfmdata.fullname=tfmdata.fullname or tfmdata.name + tfmdata.psname=file.nameonly(pfbfile or tfmdata.name) + tfmdata.filename=pfbfile + tfmdata.encodingbytes=2 + tfmdata.format="type1" + tfmdata.tounicode=1 + tfmdata.embedding="subset" + tfmdata.usedbitmap=bitmap and virtualid + return tfmdata + end +end +do + local template=[[ +/CIDInit /ProcSet findresource begin + 12 dict begin + begincmap + /CIDSystemInfo << /Registry (TeX) /Ordering (bitmap-%s) /Supplement 0 >> def + /CMapName /TeX-bitmap-%s def + /CMapType 2 def + 1 begincodespacerange + <00> <FF> + endcodespacerange + %s beginbfchar +%s + endbfchar + endcmap +CMapName currentdict /CMap defineresource pop end +end +end +]] + local flushstreamobject=lpdf and lpdf.flushstreamobject + local setfontattributes=pdf.setfontattributes + if not flushstreamobject then + flushstreamobject=function(data) + return pdf.obj { + immediate=true, + type="stream", + string=data, + } + end + end + if not setfontattributes then + setfontattributes=function(id,data) + print(format("your luatex is too old so no tounicode bitmap font%i",id)) + end + end + function tfm.addtounicode(tfmdata) + local id=tfmdata.usedbitmap + local map={} + local char={} + for k,v in next,tfmdata.characters do + local index=v.oindex + local tounicode=v.tounicode + if index and tounicode then + map[index]=tounicode + end + end + for k,v in sortedhash(map) do + char[#char+1]=format("<%02X> <%s>",k,v) + end + char=concat(char,"\n") + local stream=format(template,id,id,#char,char) + local reference=flushstreamobject(stream,nil,true) + setfontattributes(id,format("/ToUnicode %i 0 R",reference)) + end +end +do + local everywhere={ ["*"]={ ["*"]=true } } + local noflags={ false,false,false,false } + local function enhance_normalize_features(data) + local ligatures=setmetatableindex("table") + local kerns=setmetatableindex("table") + local characters=data.characters + for u,c in next,characters do + local l=c.ligatures + local k=c.kerns + if l then + ligatures[u]=l + for u,v in next,l do + l[u]={ ligature=v.char } + end + c.ligatures=nil + end + if k then + kerns[u]=k + for u,v in next,k do + k[u]=v + end + c.kerns=nil + end + end + for u,l in next,ligatures do + for k,v in next,l do + local vl=v.ligature + local dl=ligatures[vl] + if dl then + for kk,vv in next,dl do + v[kk]=vv + end + end + end + end + local features={ + gpos={}, + gsub={}, + } + local sequences={ + } + if next(ligatures) then + features.gsub.liga=everywhere + data.properties.hasligatures=true + sequences[#sequences+1]={ + features={ + liga=everywhere, + }, + flags=noflags, + name="s_s_0", + nofsteps=1, + order={ "liga" }, + type="gsub_ligature", + steps={ + { + coverage=ligatures, + }, + }, + } + end + if next(kerns) then + features.gpos.kern=everywhere + data.properties.haskerns=true + sequences[#sequences+1]={ + features={ + kern=everywhere, + }, + flags=noflags, + name="p_s_0", + nofsteps=1, + order={ "kern" }, + type="gpos_pair", + steps={ + { + format="kern", + coverage=kerns, + }, + }, + } + end + data.resources.features=features + data.resources.sequences=sequences + data.shared.resources=data.shared.resources or resources + end + registertfmenhancer("normalize features",enhance_normalize_features) + registertfmenhancer("check extra features",otfenhancers.enhance) +end +registertfmfeature { + name="mode", + description="mode", + initializers={ + base=otf.modeinitializer, + node=otf.modeinitializer, + } +} +registertfmfeature { + name="features", + description="features", + default=true, + initializers={ + base=otf.basemodeinitializer, + node=otf.nodemodeinitializer, + }, + processors={ + node=otf.featuresprocessor, + } +} + +end -- closure + +do -- begin closure to overcome local limits and interference + if not modules then modules={} end modules ['font-lua']={ version=1.001, comment="companion to font-ini.mkiv", @@ -23467,10 +29167,12 @@ if not modules then modules={} end modules ['font-def']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local format,gmatch,match,find,lower,gsub=string.format,string.gmatch,string.match,string.find,string.lower,string.gsub +local lower,gsub=string.lower,string.gsub local tostring,next=tostring,next local lpegmatch=lpeg.match -local suffixonly,removesuffix=file.suffix,file.removesuffix +local suffixonly,removesuffix,basename=file.suffix,file.removesuffix,file.basename +local formatters=string.formatters +local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys local allocate=utilities.storage.allocate local trace_defining=false trackers .register("fonts.defining",function(v) trace_defining=v end) local directive_embedall=false directives.register("fonts.embedall",function(v) directive_embedall=v end) @@ -23572,11 +29274,28 @@ end function resolvers.name(specification) local resolve=fonts.names.resolve if resolve then - local resolved,sub,subindex=resolve(specification.name,specification.sub,specification) + local resolved,sub,subindex,instance=resolve(specification.name,specification.sub,specification) if resolved then specification.resolved=resolved specification.sub=sub specification.subindex=subindex + if instance then + specification.instance=instance + local features=specification.features + if not features then + features={} + specification.features=features + end + local normal=features.normal + if not normal then + normal={} + features.normal=normal + end + normal.instance=instance + if not callbacks.supported.glyph_stream_provider then + normal.variableshapes=true + end + end local suffix=lower(suffixonly(resolved)) if fonts.formats[suffix] then specification.forced=suffix @@ -23631,7 +29350,7 @@ function definers.applypostprocessors(tfmdata) local extrahash=postprocessors[i](tfmdata) if type(extrahash)=="string" and extrahash~="" then extrahash=gsub(lower(extrahash),"[^a-z]","-") - properties.fullname=format("%s-%s",properties.fullname,extrahash) + properties.fullname=formatters["%s-%s"](properties.fullname,extrahash) end end end @@ -23654,6 +29373,60 @@ local function checkembedding(tfmdata) end tfmdata.embedding=embedding end +local function checkfeatures(tfmdata) + local resources=tfmdata.resources + local shared=tfmdata.shared + if resources and shared then + local features=resources.features + local usedfeatures=shared.features + if features and usedfeatures then + local usedlanguage=usedfeatures.language or "dflt" + local usedscript=usedfeatures.script or "dflt" + local function check(what) + if what then + local foundlanguages={} + for feature,scripts in next,what do + if usedscript=="auto" or scripts["*"] then + elseif not scripts[usedscript] then + else + for script,languages in next,scripts do + if languages["*"] then + elseif not languages[usedlanguage] then + report_defining("font %!font:name!, feature %a, script %a, no language %a", + tfmdata,feature,script,usedlanguage) + end + end + end + for script,languages in next,scripts do + for language in next,languages do + foundlanguages[language]=true + end + end + end + if false then + foundlanguages["*"]=nil + foundlanguages=sortedkeys(foundlanguages) + for feature,scripts in sortedhash(what) do + for script,languages in next,scripts do + if not languages["*"] then + for i=1,#foundlanguages do + local language=foundlanguages[i] + if not languages[language] then + report_defining("font %!font:name!, feature %a, script %a, no language %a", + tfmdata,feature,script,language) + end + end + end + end + end + end + end + end + check(features.gsub) + check(features.gpos) + end + end +end function definers.loadfont(specification) local hash=constructors.hashinstance(specification) local tfmdata=loadedfonts[hash] @@ -23687,6 +29460,7 @@ function definers.loadfont(specification) checkembedding(tfmdata) loadedfonts[hash]=tfmdata designsizes[specification.hash]=tfmdata.parameters.designsize + checkfeatures(tfmdata) end end if not tfmdata then @@ -23779,7 +29553,7 @@ function definers.read(specification,size,id) local parameters=tfmdata.parameters or {} report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a", properties.format or "unknown",id,properties.name,parameters.size,properties.encodingbytes, - properties.encodingname,properties.fullname,file.basename(properties.filename)) + properties.encodingname,properties.fullname,basename(properties.filename)) end statistics.stoptiming(fonts) return tfmdata @@ -23887,7 +29661,7 @@ if context then os.exit() end local fonts=fonts -local otffeatures=fonts.constructors.newfeatures("otf") +local otffeatures=fonts.constructors.features.otf local function initializeitlc(tfmdata,value) if value then local parameters=tfmdata.parameters @@ -24089,11 +29863,2131 @@ otffeatures.register { node=reencode, } } +local function ignore(tfmdata,key,value) + if value then + tfmdata.mathparameters=nil + end +end +otffeatures.register { + name="ignoremathconstants", + description="ignore math constants table", + initializers={ + base=ignore, + node=ignore, + } +} +local setmetatableindex=table.setmetatableindex +local function additalictowidth(tfmdata,key,value) + local characters=tfmdata.characters + local resources=tfmdata.resources + local additions={} + local private=resources.private + for unicode,old_c in next,characters do + local oldwidth=old_c.width + local olditalic=old_c.italic + if olditalic and olditalic~=0 then + private=private+1 + local new_c={ + width=oldwidth+olditalic, + height=old_c.height, + depth=old_c.depth, + commands={ + { "slot",1,private }, + { "right",olditalic }, + }, + } + setmetatableindex(new_c,old_c) + characters[unicode]=new_c + additions[private]=old_c + end + end + for k,v in next,additions do + characters[k]=v + end + resources.private=private +end +otffeatures.register { + name="italicwidths", + description="add italic to width", + manipulators={ + base=additalictowidth, + } +} end -- closure do -- begin closure to overcome local limits and interference + +fonts.handlers.otf.addfeature { + ["dataset"]={ + { + ["data"]={ + ["À"]={ "A","̀" }, + ["Á"]={ "A","́" }, + ["Â"]={ "A","̂" }, + ["Ã"]={ "A","̃" }, + ["Ä"]={ "A","̈" }, + ["Å"]={ "A","̊" }, + ["Ç"]={ "C","̧" }, + ["È"]={ "E","̀" }, + ["É"]={ "E","́" }, + ["Ê"]={ "E","̂" }, + ["Ë"]={ "E","̈" }, + ["Ì"]={ "I","̀" }, + ["Í"]={ "I","́" }, + ["Î"]={ "I","̂" }, + ["Ï"]={ "I","̈" }, + ["Ñ"]={ "N","̃" }, + ["Ò"]={ "O","̀" }, + ["Ó"]={ "O","́" }, + ["Ô"]={ "O","̂" }, + ["Õ"]={ "O","̃" }, + ["Ö"]={ "O","̈" }, + ["Ù"]={ "U","̀" }, + ["Ú"]={ "U","́" }, + ["Û"]={ "U","̂" }, + ["Ü"]={ "U","̈" }, + ["Ý"]={ "Y","́" }, + ["à"]={ "a","̀" }, + ["á"]={ "a","́" }, + ["â"]={ "a","̂" }, + ["ã"]={ "a","̃" }, + ["ä"]={ "a","̈" }, + ["å"]={ "a","̊" }, + ["ç"]={ "c","̧" }, + ["è"]={ "e","̀" }, + ["é"]={ "e","́" }, + ["ê"]={ "e","̂" }, + ["ë"]={ "e","̈" }, + ["ì"]={ "i","̀" }, + ["í"]={ "i","́" }, + ["î"]={ "i","̂" }, + ["ï"]={ "i","̈" }, + ["ñ"]={ "n","̃" }, + ["ò"]={ "o","̀" }, + ["ó"]={ "o","́" }, + ["ô"]={ "o","̂" }, + ["õ"]={ "o","̃" }, + ["ö"]={ "o","̈" }, + ["ù"]={ "u","̀" }, + ["ú"]={ "u","́" }, + ["û"]={ "u","̂" }, + ["ü"]={ "u","̈" }, + ["ý"]={ "y","́" }, + ["ÿ"]={ "y","̈" }, + ["Ā"]={ "A","̄" }, + ["ā"]={ "a","̄" }, + ["Ă"]={ "A","̆" }, + ["ă"]={ "a","̆" }, + ["Ą"]={ "A","̨" }, + ["ą"]={ "a","̨" }, + ["Ć"]={ "C","́" }, + ["ć"]={ "c","́" }, + ["Ĉ"]={ "C","̂" }, + ["ĉ"]={ "c","̂" }, + ["Ċ"]={ "C","̇" }, + ["ċ"]={ "c","̇" }, + ["Č"]={ "C","̌" }, + ["č"]={ "c","̌" }, + ["Ď"]={ "D","̌" }, + ["ď"]={ "d","̌" }, + ["Ē"]={ "E","̄" }, + ["ē"]={ "e","̄" }, + ["Ĕ"]={ "E","̆" }, + ["ĕ"]={ "e","̆" }, + ["Ė"]={ "E","̇" }, + ["ė"]={ "e","̇" }, + ["Ę"]={ "E","̨" }, + ["ę"]={ "e","̨" }, + ["Ě"]={ "E","̌" }, + ["ě"]={ "e","̌" }, + ["Ĝ"]={ "G","̂" }, + ["ĝ"]={ "g","̂" }, + ["Ğ"]={ "G","̆" }, + ["ğ"]={ "g","̆" }, + ["Ġ"]={ "G","̇" }, + ["ġ"]={ "g","̇" }, + ["Ģ"]={ "G","̧" }, + ["ģ"]={ "g","̧" }, + ["Ĥ"]={ "H","̂" }, + ["ĥ"]={ "h","̂" }, + ["Ĩ"]={ "I","̃" }, + ["ĩ"]={ "i","̃" }, + ["Ī"]={ "I","̄" }, + ["ī"]={ "i","̄" }, + ["Ĭ"]={ "I","̆" }, + ["ĭ"]={ "i","̆" }, + ["Į"]={ "I","̨" }, + ["į"]={ "i","̨" }, + ["İ"]={ "I","̇" }, + ["Ĵ"]={ "J","̂" }, + ["ĵ"]={ "j","̂" }, + ["Ķ"]={ "K","̧" }, + ["ķ"]={ "k","̧" }, + ["Ĺ"]={ "L","́" }, + ["ĺ"]={ "l","́" }, + ["Ļ"]={ "L","̧" }, + ["ļ"]={ "l","̧" }, + ["Ľ"]={ "L","̌" }, + ["ľ"]={ "l","̌" }, + ["Ń"]={ "N","́" }, + ["ń"]={ "n","́" }, + ["Ņ"]={ "N","̧" }, + ["ņ"]={ "n","̧" }, + ["Ň"]={ "N","̌" }, + ["ň"]={ "n","̌" }, + ["Ō"]={ "O","̄" }, + ["ō"]={ "o","̄" }, + ["Ŏ"]={ "O","̆" }, + ["ŏ"]={ "o","̆" }, + ["Ő"]={ "O","̋" }, + ["ő"]={ "o","̋" }, + ["Ŕ"]={ "R","́" }, + ["ŕ"]={ "r","́" }, + ["Ŗ"]={ "R","̧" }, + ["ŗ"]={ "r","̧" }, + ["Ř"]={ "R","̌" }, + ["ř"]={ "r","̌" }, + ["Ś"]={ "S","́" }, + ["ś"]={ "s","́" }, + ["Ŝ"]={ "S","̂" }, + ["ŝ"]={ "s","̂" }, + ["Ş"]={ "S","̧" }, + ["ş"]={ "s","̧" }, + ["Š"]={ "S","̌" }, + ["š"]={ "s","̌" }, + ["Ţ"]={ "T","̧" }, + ["ţ"]={ "t","̧" }, + ["Ť"]={ "T","̌" }, + ["ť"]={ "t","̌" }, + ["Ũ"]={ "U","̃" }, + ["ũ"]={ "u","̃" }, + ["Ū"]={ "U","̄" }, + ["ū"]={ "u","̄" }, + ["Ŭ"]={ "U","̆" }, + ["ŭ"]={ "u","̆" }, + ["Ů"]={ "U","̊" }, + ["ů"]={ "u","̊" }, + ["Ű"]={ "U","̋" }, + ["ű"]={ "u","̋" }, + ["Ų"]={ "U","̨" }, + ["ų"]={ "u","̨" }, + ["Ŵ"]={ "W","̂" }, + ["ŵ"]={ "w","̂" }, + ["Ŷ"]={ "Y","̂" }, + ["ŷ"]={ "y","̂" }, + ["Ÿ"]={ "Y","̈" }, + ["Ź"]={ "Z","́" }, + ["ź"]={ "z","́" }, + ["Ż"]={ "Z","̇" }, + ["ż"]={ "z","̇" }, + ["Ž"]={ "Z","̌" }, + ["ž"]={ "z","̌" }, + ["Ơ"]={ "O","̛" }, + ["ơ"]={ "o","̛" }, + ["Ư"]={ "U","̛" }, + ["ư"]={ "u","̛" }, + ["Ǎ"]={ "A","̌" }, + ["ǎ"]={ "a","̌" }, + ["Ǐ"]={ "I","̌" }, + ["ǐ"]={ "i","̌" }, + ["Ǒ"]={ "O","̌" }, + ["ǒ"]={ "o","̌" }, + ["Ǔ"]={ "U","̌" }, + ["ǔ"]={ "u","̌" }, + ["Ǖ"]={ "Ü","̄" }, + ["ǖ"]={ "ü","̄" }, + ["Ǘ"]={ "Ü","́" }, + ["ǘ"]={ "ü","́" }, + ["Ǚ"]={ "Ü","̌" }, + ["ǚ"]={ "ü","̌" }, + ["Ǜ"]={ "Ü","̀" }, + ["ǜ"]={ "ü","̀" }, + ["Ǟ"]={ "Ä","̄" }, + ["ǟ"]={ "ä","̄" }, + ["Ǡ"]={ "Ȧ","̄" }, + ["ǡ"]={ "ȧ","̄" }, + ["Ǣ"]={ "Æ","̄" }, + ["ǣ"]={ "æ","̄" }, + ["Ǧ"]={ "G","̌" }, + ["ǧ"]={ "g","̌" }, + ["Ǩ"]={ "K","̌" }, + ["ǩ"]={ "k","̌" }, + ["Ǫ"]={ "O","̨" }, + ["ǫ"]={ "o","̨" }, + ["Ǭ"]={ "Ǫ","̄" }, + ["ǭ"]={ "ǫ","̄" }, + ["Ǯ"]={ "Ʒ","̌" }, + ["ǯ"]={ "ʒ","̌" }, + ["ǰ"]={ "j","̌" }, + ["Ǵ"]={ "G","́" }, + ["ǵ"]={ "g","́" }, + ["Ǹ"]={ "N","̀" }, + ["ǹ"]={ "n","̀" }, + ["Ǻ"]={ "Å","́" }, + ["ǻ"]={ "å","́" }, + ["Ǽ"]={ "Æ","́" }, + ["ǽ"]={ "æ","́" }, + ["Ǿ"]={ "Ø","́" }, + ["ǿ"]={ "ø","́" }, + ["Ȁ"]={ "A","̏" }, + ["ȁ"]={ "a","̏" }, + ["Ȃ"]={ "A","̑" }, + ["ȃ"]={ "a","̑" }, + ["Ȅ"]={ "E","̏" }, + ["ȅ"]={ "e","̏" }, + ["Ȇ"]={ "E","̑" }, + ["ȇ"]={ "e","̑" }, + ["Ȉ"]={ "I","̏" }, + ["ȉ"]={ "i","̏" }, + ["Ȋ"]={ "I","̑" }, + ["ȋ"]={ "i","̑" }, + ["Ȍ"]={ "O","̏" }, + ["ȍ"]={ "o","̏" }, + ["Ȏ"]={ "O","̑" }, + ["ȏ"]={ "o","̑" }, + ["Ȑ"]={ "R","̏" }, + ["ȑ"]={ "r","̏" }, + ["Ȓ"]={ "R","̑" }, + ["ȓ"]={ "r","̑" }, + ["Ȕ"]={ "U","̏" }, + ["ȕ"]={ "u","̏" }, + ["Ȗ"]={ "U","̑" }, + ["ȗ"]={ "u","̑" }, + ["Ș"]={ "S","̦" }, + ["ș"]={ "s","̦" }, + ["Ț"]={ "T","̦" }, + ["ț"]={ "t","̦" }, + ["Ȟ"]={ "H","̌" }, + ["ȟ"]={ "h","̌" }, + ["Ȧ"]={ "A","̇" }, + ["ȧ"]={ "a","̇" }, + ["Ȩ"]={ "E","̧" }, + ["ȩ"]={ "e","̧" }, + ["Ȫ"]={ "Ö","̄" }, + ["ȫ"]={ "ö","̄" }, + ["Ȭ"]={ "Õ","̄" }, + ["ȭ"]={ "õ","̄" }, + ["Ȯ"]={ "O","̇" }, + ["ȯ"]={ "o","̇" }, + ["Ȱ"]={ "Ȯ","̄" }, + ["ȱ"]={ "ȯ","̄" }, + ["Ȳ"]={ "Y","̄" }, + ["ȳ"]={ "y","̄" }, + ["̈́"]={ "̈","́" }, + ["΅"]={ "¨","́" }, + ["Ά"]={ "Α","́" }, + ["Έ"]={ "Ε","́" }, + ["Ή"]={ "Η","́" }, + ["Ί"]={ "Ι","́" }, + ["Ό"]={ "Ο","́" }, + ["Ύ"]={ "Υ","́" }, + ["Ώ"]={ "Ω","́" }, + ["ΐ"]={ "ϊ","́" }, + ["Ϊ"]={ "Ι","̈" }, + ["Ϋ"]={ "Υ","̈" }, + ["ά"]={ "α","́" }, + ["έ"]={ "ε","́" }, + ["ή"]={ "η","́" }, + ["ί"]={ "ι","́" }, + ["ΰ"]={ "ϋ","́" }, + ["ϊ"]={ "ι","̈" }, + ["ϋ"]={ "υ","̈" }, + ["ό"]={ "ο","́" }, + ["ύ"]={ "υ","́" }, + ["ώ"]={ "ω","́" }, + ["ϓ"]={ "ϒ","́" }, + ["ϔ"]={ "ϒ","̈" }, + ["Ѐ"]={ "Е","̀" }, + ["Ё"]={ "Е","̈" }, + ["Ѓ"]={ "Г","́" }, + ["Ї"]={ "І","̈" }, + ["Ќ"]={ "К","́" }, + ["Ѝ"]={ "И","̀" }, + ["Ў"]={ "У","̆" }, + ["Й"]={ "И","̆" }, + ["й"]={ "и","̆" }, + ["ѐ"]={ "е","̀" }, + ["ё"]={ "е","̈" }, + ["ѓ"]={ "г","́" }, + ["ї"]={ "і","̈" }, + ["ќ"]={ "к","́" }, + ["ѝ"]={ "и","̀" }, + ["ў"]={ "у","̆" }, + ["Ѷ"]={ "Ѵ","̏" }, + ["ѷ"]={ "ѵ","̏" }, + ["Ӂ"]={ "Ж","̆" }, + ["ӂ"]={ "ж","̆" }, + ["Ӑ"]={ "А","̆" }, + ["ӑ"]={ "а","̆" }, + ["Ӓ"]={ "А","̈" }, + ["ӓ"]={ "а","̈" }, + ["Ӗ"]={ "Е","̆" }, + ["ӗ"]={ "е","̆" }, + ["Ӛ"]={ "Ә","̈" }, + ["ӛ"]={ "ә","̈" }, + ["Ӝ"]={ "Ж","̈" }, + ["ӝ"]={ "ж","̈" }, + ["Ӟ"]={ "З","̈" }, + ["ӟ"]={ "з","̈" }, + ["Ӣ"]={ "И","̄" }, + ["ӣ"]={ "и","̄" }, + ["Ӥ"]={ "И","̈" }, + ["ӥ"]={ "и","̈" }, + ["Ӧ"]={ "О","̈" }, + ["ӧ"]={ "о","̈" }, + ["Ӫ"]={ "Ө","̈" }, + ["ӫ"]={ "ө","̈" }, + ["Ӭ"]={ "Э","̈" }, + ["ӭ"]={ "э","̈" }, + ["Ӯ"]={ "У","̄" }, + ["ӯ"]={ "у","̄" }, + ["Ӱ"]={ "У","̈" }, + ["ӱ"]={ "у","̈" }, + ["Ӳ"]={ "У","̋" }, + ["ӳ"]={ "у","̋" }, + ["Ӵ"]={ "Ч","̈" }, + ["ӵ"]={ "ч","̈" }, + ["Ӹ"]={ "Ы","̈" }, + ["ӹ"]={ "ы","̈" }, + ["آ"]={ "ا","ٓ" }, + ["أ"]={ "ا","ٔ" }, + ["ؤ"]={ "و","ٔ" }, + ["إ"]={ "ا","ٕ" }, + ["ئ"]={ "ي","ٔ" }, + ["ۀ"]={ "ە","ٔ" }, + ["ۂ"]={ "ہ","ٔ" }, + ["ۓ"]={ "ے","ٔ" }, + ["ऩ"]={ "न","़" }, + ["ऱ"]={ "र","़" }, + ["ऴ"]={ "ळ","़" }, + ["क़"]={ "क","़" }, + ["ख़"]={ "ख","़" }, + ["ग़"]={ "ग","़" }, + ["ज़"]={ "ज","़" }, + ["ड़"]={ "ड","़" }, + ["ढ़"]={ "ढ","़" }, + ["फ़"]={ "फ","़" }, + ["य़"]={ "य","़" }, + ["ো"]={ "ে","া" }, + ["ৌ"]={ "ে","ৗ" }, + ["ড়"]={ "ড","়" }, + ["ঢ়"]={ "ঢ","়" }, + ["য়"]={ "য","়" }, + ["ਲ਼"]={ "ਲ","਼" }, + ["ਸ਼"]={ "ਸ","਼" }, + ["ਖ਼"]={ "ਖ","਼" }, + ["ਗ਼"]={ "ਗ","਼" }, + ["ਜ਼"]={ "ਜ","਼" }, + ["ਫ਼"]={ "ਫ","਼" }, + ["ୈ"]={ "େ","ୖ" }, + ["ୋ"]={ "େ","ା" }, + ["ୌ"]={ "େ","ୗ" }, + ["ଡ଼"]={ "ଡ","଼" }, + ["ଢ଼"]={ "ଢ","଼" }, + ["ஔ"]={ "ஒ","ௗ" }, + ["ொ"]={ "ெ","ா" }, + ["ோ"]={ "ே","ா" }, + ["ௌ"]={ "ெ","ௗ" }, + ["ై"]={ "ె","ౖ" }, + ["ೀ"]={ "ಿ","ೕ" }, + ["ೇ"]={ "ೆ","ೕ" }, + ["ೈ"]={ "ೆ","ೖ" }, + ["ೊ"]={ "ೆ","ೂ" }, + ["ೋ"]={ "ೊ","ೕ" }, + ["ൊ"]={ "െ","ാ" }, + ["ോ"]={ "േ","ാ" }, + ["ൌ"]={ "െ","ൗ" }, + ["ේ"]={ "ෙ","්" }, + ["ො"]={ "ෙ","ා" }, + ["ෝ"]={ "ො","්" }, + ["ෞ"]={ "ෙ","ෟ" }, + ["གྷ"]={ "ག","ྷ" }, + ["ཌྷ"]={ "ཌ","ྷ" }, + ["དྷ"]={ "ད","ྷ" }, + ["བྷ"]={ "བ","ྷ" }, + ["ཛྷ"]={ "ཛ","ྷ" }, + ["ཀྵ"]={ "ཀ","ྵ" }, + ["ཱི"]={ "ཱ","ི" }, + ["ཱུ"]={ "ཱ","ུ" }, + ["ྲྀ"]={ "ྲ","ྀ" }, + ["ླྀ"]={ "ླ","ྀ" }, + ["ཱྀ"]={ "ཱ","ྀ" }, + ["ྒྷ"]={ "ྒ","ྷ" }, + ["ྜྷ"]={ "ྜ","ྷ" }, + ["ྡྷ"]={ "ྡ","ྷ" }, + ["ྦྷ"]={ "ྦ","ྷ" }, + ["ྫྷ"]={ "ྫ","ྷ" }, + ["ྐྵ"]={ "ྐ","ྵ" }, + ["ဦ"]={ "ဥ","ီ" }, + ["ᬆ"]={ "ᬅ","ᬵ" }, + ["ᬈ"]={ "ᬇ","ᬵ" }, + ["ᬊ"]={ "ᬉ","ᬵ" }, + ["ᬌ"]={ "ᬋ","ᬵ" }, + ["ᬎ"]={ "ᬍ","ᬵ" }, + ["ᬒ"]={ "ᬑ","ᬵ" }, + ["ᬻ"]={ "ᬺ","ᬵ" }, + ["ᬽ"]={ "ᬼ","ᬵ" }, + ["ᭀ"]={ "ᬾ","ᬵ" }, + ["ᭁ"]={ "ᬿ","ᬵ" }, + ["ᭃ"]={ "ᭂ","ᬵ" }, + ["Ḁ"]={ "A","̥" }, + ["ḁ"]={ "a","̥" }, + ["Ḃ"]={ "B","̇" }, + ["ḃ"]={ "b","̇" }, + ["Ḅ"]={ "B","̣" }, + ["ḅ"]={ "b","̣" }, + ["Ḇ"]={ "B","̱" }, + ["ḇ"]={ "b","̱" }, + ["Ḉ"]={ "Ç","́" }, + ["ḉ"]={ "ç","́" }, + ["Ḋ"]={ "D","̇" }, + ["ḋ"]={ "d","̇" }, + ["Ḍ"]={ "D","̣" }, + ["ḍ"]={ "d","̣" }, + ["Ḏ"]={ "D","̱" }, + ["ḏ"]={ "d","̱" }, + ["Ḑ"]={ "D","̧" }, + ["ḑ"]={ "d","̧" }, + ["Ḓ"]={ "D","̭" }, + ["ḓ"]={ "d","̭" }, + ["Ḕ"]={ "Ē","̀" }, + ["ḕ"]={ "ē","̀" }, + ["Ḗ"]={ "Ē","́" }, + ["ḗ"]={ "ē","́" }, + ["Ḙ"]={ "E","̭" }, + ["ḙ"]={ "e","̭" }, + ["Ḛ"]={ "E","̰" }, + ["ḛ"]={ "e","̰" }, + ["Ḝ"]={ "Ȩ","̆" }, + ["ḝ"]={ "ȩ","̆" }, + ["Ḟ"]={ "F","̇" }, + ["ḟ"]={ "f","̇" }, + ["Ḡ"]={ "G","̄" }, + ["ḡ"]={ "g","̄" }, + ["Ḣ"]={ "H","̇" }, + ["ḣ"]={ "h","̇" }, + ["Ḥ"]={ "H","̣" }, + ["ḥ"]={ "h","̣" }, + ["Ḧ"]={ "H","̈" }, + ["ḧ"]={ "h","̈" }, + ["Ḩ"]={ "H","̧" }, + ["ḩ"]={ "h","̧" }, + ["Ḫ"]={ "H","̮" }, + ["ḫ"]={ "h","̮" }, + ["Ḭ"]={ "I","̰" }, + ["ḭ"]={ "i","̰" }, + ["Ḯ"]={ "Ï","́" }, + ["ḯ"]={ "ï","́" }, + ["Ḱ"]={ "K","́" }, + ["ḱ"]={ "k","́" }, + ["Ḳ"]={ "K","̣" }, + ["ḳ"]={ "k","̣" }, + ["Ḵ"]={ "K","̱" }, + ["ḵ"]={ "k","̱" }, + ["Ḷ"]={ "L","̣" }, + ["ḷ"]={ "l","̣" }, + ["Ḹ"]={ "Ḷ","̄" }, + ["ḹ"]={ "ḷ","̄" }, + ["Ḻ"]={ "L","̱" }, + ["ḻ"]={ "l","̱" }, + ["Ḽ"]={ "L","̭" }, + ["ḽ"]={ "l","̭" }, + ["Ḿ"]={ "M","́" }, + ["ḿ"]={ "m","́" }, + ["Ṁ"]={ "M","̇" }, + ["ṁ"]={ "m","̇" }, + ["Ṃ"]={ "M","̣" }, + ["ṃ"]={ "m","̣" }, + ["Ṅ"]={ "N","̇" }, + ["ṅ"]={ "n","̇" }, + ["Ṇ"]={ "N","̣" }, + ["ṇ"]={ "n","̣" }, + ["Ṉ"]={ "N","̱" }, + ["ṉ"]={ "n","̱" }, + ["Ṋ"]={ "N","̭" }, + ["ṋ"]={ "n","̭" }, + ["Ṍ"]={ "Õ","́" }, + ["ṍ"]={ "õ","́" }, + ["Ṏ"]={ "Õ","̈" }, + ["ṏ"]={ "õ","̈" }, + ["Ṑ"]={ "Ō","̀" }, + ["ṑ"]={ "ō","̀" }, + ["Ṓ"]={ "Ō","́" }, + ["ṓ"]={ "ō","́" }, + ["Ṕ"]={ "P","́" }, + ["ṕ"]={ "p","́" }, + ["Ṗ"]={ "P","̇" }, + ["ṗ"]={ "p","̇" }, + ["Ṙ"]={ "R","̇" }, + ["ṙ"]={ "r","̇" }, + ["Ṛ"]={ "R","̣" }, + ["ṛ"]={ "r","̣" }, + ["Ṝ"]={ "Ṛ","̄" }, + ["ṝ"]={ "ṛ","̄" }, + ["Ṟ"]={ "R","̱" }, + ["ṟ"]={ "r","̱" }, + ["Ṡ"]={ "S","̇" }, + ["ṡ"]={ "s","̇" }, + ["Ṣ"]={ "S","̣" }, + ["ṣ"]={ "s","̣" }, + ["Ṥ"]={ "Ś","̇" }, + ["ṥ"]={ "ś","̇" }, + ["Ṧ"]={ "Š","̇" }, + ["ṧ"]={ "š","̇" }, + ["Ṩ"]={ "Ṣ","̇" }, + ["ṩ"]={ "ṣ","̇" }, + ["Ṫ"]={ "T","̇" }, + ["ṫ"]={ "t","̇" }, + ["Ṭ"]={ "T","̣" }, + ["ṭ"]={ "t","̣" }, + ["Ṯ"]={ "T","̱" }, + ["ṯ"]={ "t","̱" }, + ["Ṱ"]={ "T","̭" }, + ["ṱ"]={ "t","̭" }, + ["Ṳ"]={ "U","̤" }, + ["ṳ"]={ "u","̤" }, + ["Ṵ"]={ "U","̰" }, + ["ṵ"]={ "u","̰" }, + ["Ṷ"]={ "U","̭" }, + ["ṷ"]={ "u","̭" }, + ["Ṹ"]={ "Ũ","́" }, + ["ṹ"]={ "ũ","́" }, + ["Ṻ"]={ "Ū","̈" }, + ["ṻ"]={ "ū","̈" }, + ["Ṽ"]={ "V","̃" }, + ["ṽ"]={ "v","̃" }, + ["Ṿ"]={ "V","̣" }, + ["ṿ"]={ "v","̣" }, + ["Ẁ"]={ "W","̀" }, + ["ẁ"]={ "w","̀" }, + ["Ẃ"]={ "W","́" }, + ["ẃ"]={ "w","́" }, + ["Ẅ"]={ "W","̈" }, + ["ẅ"]={ "w","̈" }, + ["Ẇ"]={ "W","̇" }, + ["ẇ"]={ "w","̇" }, + ["Ẉ"]={ "W","̣" }, + ["ẉ"]={ "w","̣" }, + ["Ẋ"]={ "X","̇" }, + ["ẋ"]={ "x","̇" }, + ["Ẍ"]={ "X","̈" }, + ["ẍ"]={ "x","̈" }, + ["Ẏ"]={ "Y","̇" }, + ["ẏ"]={ "y","̇" }, + ["Ẑ"]={ "Z","̂" }, + ["ẑ"]={ "z","̂" }, + ["Ẓ"]={ "Z","̣" }, + ["ẓ"]={ "z","̣" }, + ["Ẕ"]={ "Z","̱" }, + ["ẕ"]={ "z","̱" }, + ["ẖ"]={ "h","̱" }, + ["ẗ"]={ "t","̈" }, + ["ẘ"]={ "w","̊" }, + ["ẙ"]={ "y","̊" }, + ["ẛ"]={ "ſ","̇" }, + ["Ạ"]={ "A","̣" }, + ["ạ"]={ "a","̣" }, + ["Ả"]={ "A","̉" }, + ["ả"]={ "a","̉" }, + ["Ấ"]={ "Â","́" }, + ["ấ"]={ "â","́" }, + ["Ầ"]={ "Â","̀" }, + ["ầ"]={ "â","̀" }, + ["Ẩ"]={ "Â","̉" }, + ["ẩ"]={ "â","̉" }, + ["Ẫ"]={ "Â","̃" }, + ["ẫ"]={ "â","̃" }, + ["Ậ"]={ "Ạ","̂" }, + ["ậ"]={ "ạ","̂" }, + ["Ắ"]={ "Ă","́" }, + ["ắ"]={ "ă","́" }, + ["Ằ"]={ "Ă","̀" }, + ["ằ"]={ "ă","̀" }, + ["Ẳ"]={ "Ă","̉" }, + ["ẳ"]={ "ă","̉" }, + ["Ẵ"]={ "Ă","̃" }, + ["ẵ"]={ "ă","̃" }, + ["Ặ"]={ "Ạ","̆" }, + ["ặ"]={ "ạ","̆" }, + ["Ẹ"]={ "E","̣" }, + ["ẹ"]={ "e","̣" }, + ["Ẻ"]={ "E","̉" }, + ["ẻ"]={ "e","̉" }, + ["Ẽ"]={ "E","̃" }, + ["ẽ"]={ "e","̃" }, + ["Ế"]={ "Ê","́" }, + ["ế"]={ "ê","́" }, + ["Ề"]={ "Ê","̀" }, + ["ề"]={ "ê","̀" }, + ["Ể"]={ "Ê","̉" }, + ["ể"]={ "ê","̉" }, + ["Ễ"]={ "Ê","̃" }, + ["ễ"]={ "ê","̃" }, + ["Ệ"]={ "Ẹ","̂" }, + ["ệ"]={ "ẹ","̂" }, + ["Ỉ"]={ "I","̉" }, + ["ỉ"]={ "i","̉" }, + ["Ị"]={ "I","̣" }, + ["ị"]={ "i","̣" }, + ["Ọ"]={ "O","̣" }, + ["ọ"]={ "o","̣" }, + ["Ỏ"]={ "O","̉" }, + ["ỏ"]={ "o","̉" }, + ["Ố"]={ "Ô","́" }, + ["ố"]={ "ô","́" }, + ["Ồ"]={ "Ô","̀" }, + ["ồ"]={ "ô","̀" }, + ["Ổ"]={ "Ô","̉" }, + ["ổ"]={ "ô","̉" }, + ["Ỗ"]={ "Ô","̃" }, + ["ỗ"]={ "ô","̃" }, + ["Ộ"]={ "Ọ","̂" }, + ["ộ"]={ "ọ","̂" }, + ["Ớ"]={ "Ơ","́" }, + ["ớ"]={ "ơ","́" }, + ["Ờ"]={ "Ơ","̀" }, + ["ờ"]={ "ơ","̀" }, + ["Ở"]={ "Ơ","̉" }, + ["ở"]={ "ơ","̉" }, + ["Ỡ"]={ "Ơ","̃" }, + ["ỡ"]={ "ơ","̃" }, + ["Ợ"]={ "Ơ","̣" }, + ["ợ"]={ "ơ","̣" }, + ["Ụ"]={ "U","̣" }, + ["ụ"]={ "u","̣" }, + ["Ủ"]={ "U","̉" }, + ["ủ"]={ "u","̉" }, + ["Ứ"]={ "Ư","́" }, + ["ứ"]={ "ư","́" }, + ["Ừ"]={ "Ư","̀" }, + ["ừ"]={ "ư","̀" }, + ["Ử"]={ "Ư","̉" }, + ["ử"]={ "ư","̉" }, + ["Ữ"]={ "Ư","̃" }, + ["ữ"]={ "ư","̃" }, + ["Ự"]={ "Ư","̣" }, + ["ự"]={ "ư","̣" }, + ["Ỳ"]={ "Y","̀" }, + ["ỳ"]={ "y","̀" }, + ["Ỵ"]={ "Y","̣" }, + ["ỵ"]={ "y","̣" }, + ["Ỷ"]={ "Y","̉" }, + ["ỷ"]={ "y","̉" }, + ["Ỹ"]={ "Y","̃" }, + ["ỹ"]={ "y","̃" }, + ["ἀ"]={ "α","̓" }, + ["ἁ"]={ "α","̔" }, + ["ἂ"]={ "ἀ","̀" }, + ["ἃ"]={ "ἁ","̀" }, + ["ἄ"]={ "ἀ","́" }, + ["ἅ"]={ "ἁ","́" }, + ["ἆ"]={ "ἀ","͂" }, + ["ἇ"]={ "ἁ","͂" }, + ["Ἀ"]={ "Α","̓" }, + ["Ἁ"]={ "Α","̔" }, + ["Ἂ"]={ "Ἀ","̀" }, + ["Ἃ"]={ "Ἁ","̀" }, + ["Ἄ"]={ "Ἀ","́" }, + ["Ἅ"]={ "Ἁ","́" }, + ["Ἆ"]={ "Ἀ","͂" }, + ["Ἇ"]={ "Ἁ","͂" }, + ["ἐ"]={ "ε","̓" }, + ["ἑ"]={ "ε","̔" }, + ["ἒ"]={ "ἐ","̀" }, + ["ἓ"]={ "ἑ","̀" }, + ["ἔ"]={ "ἐ","́" }, + ["ἕ"]={ "ἑ","́" }, + ["Ἐ"]={ "Ε","̓" }, + ["Ἑ"]={ "Ε","̔" }, + ["Ἒ"]={ "Ἐ","̀" }, + ["Ἓ"]={ "Ἑ","̀" }, + ["Ἔ"]={ "Ἐ","́" }, + ["Ἕ"]={ "Ἑ","́" }, + ["ἠ"]={ "η","̓" }, + ["ἡ"]={ "η","̔" }, + ["ἢ"]={ "ἠ","̀" }, + ["ἣ"]={ "ἡ","̀" }, + ["ἤ"]={ "ἠ","́" }, + ["ἥ"]={ "ἡ","́" }, + ["ἦ"]={ "ἠ","͂" }, + ["ἧ"]={ "ἡ","͂" }, + ["Ἠ"]={ "Η","̓" }, + ["Ἡ"]={ "Η","̔" }, + ["Ἢ"]={ "Ἠ","̀" }, + ["Ἣ"]={ "Ἡ","̀" }, + ["Ἤ"]={ "Ἠ","́" }, + ["Ἥ"]={ "Ἡ","́" }, + ["Ἦ"]={ "Ἠ","͂" }, + ["Ἧ"]={ "Ἡ","͂" }, + ["ἰ"]={ "ι","̓" }, + ["ἱ"]={ "ι","̔" }, + ["ἲ"]={ "ἰ","̀" }, + ["ἳ"]={ "ἱ","̀" }, + ["ἴ"]={ "ἰ","́" }, + ["ἵ"]={ "ἱ","́" }, + ["ἶ"]={ "ἰ","͂" }, + ["ἷ"]={ "ἱ","͂" }, + ["Ἰ"]={ "Ι","̓" }, + ["Ἱ"]={ "Ι","̔" }, + ["Ἲ"]={ "Ἰ","̀" }, + ["Ἳ"]={ "Ἱ","̀" }, + ["Ἴ"]={ "Ἰ","́" }, + ["Ἵ"]={ "Ἱ","́" }, + ["Ἶ"]={ "Ἰ","͂" }, + ["Ἷ"]={ "Ἱ","͂" }, + ["ὀ"]={ "ο","̓" }, + ["ὁ"]={ "ο","̔" }, + ["ὂ"]={ "ὀ","̀" }, + ["ὃ"]={ "ὁ","̀" }, + ["ὄ"]={ "ὀ","́" }, + ["ὅ"]={ "ὁ","́" }, + ["Ὀ"]={ "Ο","̓" }, + ["Ὁ"]={ "Ο","̔" }, + ["Ὂ"]={ "Ὀ","̀" }, + ["Ὃ"]={ "Ὁ","̀" }, + ["Ὄ"]={ "Ὀ","́" }, + ["Ὅ"]={ "Ὁ","́" }, + ["ὐ"]={ "υ","̓" }, + ["ὑ"]={ "υ","̔" }, + ["ὒ"]={ "ὐ","̀" }, + ["ὓ"]={ "ὑ","̀" }, + ["ὔ"]={ "ὐ","́" }, + ["ὕ"]={ "ὑ","́" }, + ["ὖ"]={ "ὐ","͂" }, + ["ὗ"]={ "ὑ","͂" }, + ["Ὑ"]={ "Υ","̔" }, + ["Ὓ"]={ "Ὑ","̀" }, + ["Ὕ"]={ "Ὑ","́" }, + ["Ὗ"]={ "Ὑ","͂" }, + ["ὠ"]={ "ω","̓" }, + ["ὡ"]={ "ω","̔" }, + ["ὢ"]={ "ὠ","̀" }, + ["ὣ"]={ "ὡ","̀" }, + ["ὤ"]={ "ὠ","́" }, + ["ὥ"]={ "ὡ","́" }, + ["ὦ"]={ "ὠ","͂" }, + ["ὧ"]={ "ὡ","͂" }, + ["Ὠ"]={ "Ω","̓" }, + ["Ὡ"]={ "Ω","̔" }, + ["Ὢ"]={ "Ὠ","̀" }, + ["Ὣ"]={ "Ὡ","̀" }, + ["Ὤ"]={ "Ὠ","́" }, + ["Ὥ"]={ "Ὡ","́" }, + ["Ὦ"]={ "Ὠ","͂" }, + ["Ὧ"]={ "Ὡ","͂" }, + ["ὰ"]={ "α","̀" }, + ["ὲ"]={ "ε","̀" }, + ["ὴ"]={ "η","̀" }, + ["ὶ"]={ "ι","̀" }, + ["ὸ"]={ "ο","̀" }, + ["ὺ"]={ "υ","̀" }, + ["ὼ"]={ "ω","̀" }, + ["ᾀ"]={ "ἀ","ͅ" }, + ["ᾁ"]={ "ἁ","ͅ" }, + ["ᾂ"]={ "ἂ","ͅ" }, + ["ᾃ"]={ "ἃ","ͅ" }, + ["ᾄ"]={ "ἄ","ͅ" }, + ["ᾅ"]={ "ἅ","ͅ" }, + ["ᾆ"]={ "ἆ","ͅ" }, + ["ᾇ"]={ "ἇ","ͅ" }, + ["ᾈ"]={ "Ἀ","ͅ" }, + ["ᾉ"]={ "Ἁ","ͅ" }, + ["ᾊ"]={ "Ἂ","ͅ" }, + ["ᾋ"]={ "Ἃ","ͅ" }, + ["ᾌ"]={ "Ἄ","ͅ" }, + ["ᾍ"]={ "Ἅ","ͅ" }, + ["ᾎ"]={ "Ἆ","ͅ" }, + ["ᾏ"]={ "Ἇ","ͅ" }, + ["ᾐ"]={ "ἠ","ͅ" }, + ["ᾑ"]={ "ἡ","ͅ" }, + ["ᾒ"]={ "ἢ","ͅ" }, + ["ᾓ"]={ "ἣ","ͅ" }, + ["ᾔ"]={ "ἤ","ͅ" }, + ["ᾕ"]={ "ἥ","ͅ" }, + ["ᾖ"]={ "ἦ","ͅ" }, + ["ᾗ"]={ "ἧ","ͅ" }, + ["ᾘ"]={ "Ἠ","ͅ" }, + ["ᾙ"]={ "Ἡ","ͅ" }, + ["ᾚ"]={ "Ἢ","ͅ" }, + ["ᾛ"]={ "Ἣ","ͅ" }, + ["ᾜ"]={ "Ἤ","ͅ" }, + ["ᾝ"]={ "Ἥ","ͅ" }, + ["ᾞ"]={ "Ἦ","ͅ" }, + ["ᾟ"]={ "Ἧ","ͅ" }, + ["ᾠ"]={ "ὠ","ͅ" }, + ["ᾡ"]={ "ὡ","ͅ" }, + ["ᾢ"]={ "ὢ","ͅ" }, + ["ᾣ"]={ "ὣ","ͅ" }, + ["ᾤ"]={ "ὤ","ͅ" }, + ["ᾥ"]={ "ὥ","ͅ" }, + ["ᾦ"]={ "ὦ","ͅ" }, + ["ᾧ"]={ "ὧ","ͅ" }, + ["ᾨ"]={ "Ὠ","ͅ" }, + ["ᾩ"]={ "Ὡ","ͅ" }, + ["ᾪ"]={ "Ὢ","ͅ" }, + ["ᾫ"]={ "Ὣ","ͅ" }, + ["ᾬ"]={ "Ὤ","ͅ" }, + ["ᾭ"]={ "Ὥ","ͅ" }, + ["ᾮ"]={ "Ὦ","ͅ" }, + ["ᾯ"]={ "Ὧ","ͅ" }, + ["ᾰ"]={ "α","̆" }, + ["ᾱ"]={ "α","̄" }, + ["ᾲ"]={ "ὰ","ͅ" }, + ["ᾳ"]={ "α","ͅ" }, + ["ᾴ"]={ "ά","ͅ" }, + ["ᾶ"]={ "α","͂" }, + ["ᾷ"]={ "ᾶ","ͅ" }, + ["Ᾰ"]={ "Α","̆" }, + ["Ᾱ"]={ "Α","̄" }, + ["Ὰ"]={ "Α","̀" }, + ["ᾼ"]={ "Α","ͅ" }, + ["῁"]={ "¨","͂" }, + ["ῂ"]={ "ὴ","ͅ" }, + ["ῃ"]={ "η","ͅ" }, + ["ῄ"]={ "ή","ͅ" }, + ["ῆ"]={ "η","͂" }, + ["ῇ"]={ "ῆ","ͅ" }, + ["Ὲ"]={ "Ε","̀" }, + ["Ὴ"]={ "Η","̀" }, + ["ῌ"]={ "Η","ͅ" }, + ["῍"]={ "᾿","̀" }, + ["῎"]={ "᾿","́" }, + ["῏"]={ "᾿","͂" }, + ["ῐ"]={ "ι","̆" }, + ["ῑ"]={ "ι","̄" }, + ["ῒ"]={ "ϊ","̀" }, + ["ῖ"]={ "ι","͂" }, + ["ῗ"]={ "ϊ","͂" }, + ["Ῐ"]={ "Ι","̆" }, + ["Ῑ"]={ "Ι","̄" }, + ["Ὶ"]={ "Ι","̀" }, + ["῝"]={ "῾","̀" }, + ["῞"]={ "῾","́" }, + ["῟"]={ "῾","͂" }, + ["ῠ"]={ "υ","̆" }, + ["ῡ"]={ "υ","̄" }, + ["ῢ"]={ "ϋ","̀" }, + ["ῤ"]={ "ρ","̓" }, + ["ῥ"]={ "ρ","̔" }, + ["ῦ"]={ "υ","͂" }, + ["ῧ"]={ "ϋ","͂" }, + ["Ῠ"]={ "Υ","̆" }, + ["Ῡ"]={ "Υ","̄" }, + ["Ὺ"]={ "Υ","̀" }, + ["Ῥ"]={ "Ρ","̔" }, + ["῭"]={ "¨","̀" }, + ["ῲ"]={ "ὼ","ͅ" }, + ["ῳ"]={ "ω","ͅ" }, + ["ῴ"]={ "ώ","ͅ" }, + ["ῶ"]={ "ω","͂" }, + ["ῷ"]={ "ῶ","ͅ" }, + ["Ὸ"]={ "Ο","̀" }, + ["Ὼ"]={ "Ω","̀" }, + ["ῼ"]={ "Ω","ͅ" }, + ["↚"]={ "←","̸" }, + ["↛"]={ "→","̸" }, + ["↮"]={ "↔","̸" }, + ["⇍"]={ "⇐","̸" }, + ["⇎"]={ "⇔","̸" }, + ["⇏"]={ "⇒","̸" }, + ["∄"]={ "∃","̸" }, + ["∉"]={ "∈","̸" }, + ["∌"]={ "∋","̸" }, + ["∤"]={ "∣","̸" }, + ["∦"]={ "∥","̸" }, + ["≁"]={ "∼","̸" }, + ["≄"]={ "≃","̸" }, + ["≇"]={ "≅","̸" }, + ["≉"]={ "≈","̸" }, + ["≠"]={ "=","̸" }, + ["≢"]={ "≡","̸" }, + ["≭"]={ "≍","̸" }, + ["≮"]={ "<","̸" }, + ["≯"]={ ">","̸" }, + ["≰"]={ "≤","̸" }, + ["≱"]={ "≥","̸" }, + ["≴"]={ "≲","̸" }, + ["≵"]={ "≳","̸" }, + ["≸"]={ "≶","̸" }, + ["≹"]={ "≷","̸" }, + ["⊀"]={ "≺","̸" }, + ["⊁"]={ "≻","̸" }, + ["⊄"]={ "⊂","̸" }, + ["⊅"]={ "⊃","̸" }, + ["⊈"]={ "⊆","̸" }, + ["⊉"]={ "⊇","̸" }, + ["⊬"]={ "⊢","̸" }, + ["⊭"]={ "⊨","̸" }, + ["⊮"]={ "⊩","̸" }, + ["⊯"]={ "⊫","̸" }, + ["⋠"]={ "≼","̸" }, + ["⋡"]={ "≽","̸" }, + ["⋢"]={ "⊑","̸" }, + ["⋣"]={ "⊒","̸" }, + ["⋪"]={ "⊲","̸" }, + ["⋫"]={ "⊳","̸" }, + ["⋬"]={ "⊴","̸" }, + ["⋭"]={ "⊵","̸" }, + ["⫝̸"]={ "⫝","̸" }, + ["が"]={ "か","゙" }, + ["ぎ"]={ "き","゙" }, + ["ぐ"]={ "く","゙" }, + ["げ"]={ "け","゙" }, + ["ご"]={ "こ","゙" }, + ["ざ"]={ "さ","゙" }, + ["じ"]={ "し","゙" }, + ["ず"]={ "す","゙" }, + ["ぜ"]={ "せ","゙" }, + ["ぞ"]={ "そ","゙" }, + ["だ"]={ "た","゙" }, + ["ぢ"]={ "ち","゙" }, + ["づ"]={ "つ","゙" }, + ["で"]={ "て","゙" }, + ["ど"]={ "と","゙" }, + ["ば"]={ "は","゙" }, + ["ぱ"]={ "は","゚" }, + ["び"]={ "ひ","゙" }, + ["ぴ"]={ "ひ","゚" }, + ["ぶ"]={ "ふ","゙" }, + ["ぷ"]={ "ふ","゚" }, + ["べ"]={ "へ","゙" }, + ["ぺ"]={ "へ","゚" }, + ["ぼ"]={ "ほ","゙" }, + ["ぽ"]={ "ほ","゚" }, + ["ゔ"]={ "う","゙" }, + ["ゞ"]={ "ゝ","゙" }, + ["ガ"]={ "カ","゙" }, + ["ギ"]={ "キ","゙" }, + ["グ"]={ "ク","゙" }, + ["ゲ"]={ "ケ","゙" }, + ["ゴ"]={ "コ","゙" }, + ["ザ"]={ "サ","゙" }, + ["ジ"]={ "シ","゙" }, + ["ズ"]={ "ス","゙" }, + ["ゼ"]={ "セ","゙" }, + ["ゾ"]={ "ソ","゙" }, + ["ダ"]={ "タ","゙" }, + ["ヂ"]={ "チ","゙" }, + ["ヅ"]={ "ツ","゙" }, + ["デ"]={ "テ","゙" }, + ["ド"]={ "ト","゙" }, + ["バ"]={ "ハ","゙" }, + ["パ"]={ "ハ","゚" }, + ["ビ"]={ "ヒ","゙" }, + ["ピ"]={ "ヒ","゚" }, + ["ブ"]={ "フ","゙" }, + ["プ"]={ "フ","゚" }, + ["ベ"]={ "ヘ","゙" }, + ["ペ"]={ "ヘ","゚" }, + ["ボ"]={ "ホ","゙" }, + ["ポ"]={ "ホ","゚" }, + ["ヴ"]={ "ウ","゙" }, + ["ヷ"]={ "ワ","゙" }, + ["ヸ"]={ "ヰ","゙" }, + ["ヹ"]={ "ヱ","゙" }, + ["ヺ"]={ "ヲ","゙" }, + ["ヾ"]={ "ヽ","゙" }, + ["יִ"]={ "י","ִ" }, + ["ײַ"]={ "ײ","ַ" }, + ["שׁ"]={ "ש","ׁ" }, + ["שׂ"]={ "ש","ׂ" }, + ["שּׁ"]={ "שּ","ׁ" }, + ["שּׂ"]={ "שּ","ׂ" }, + ["אַ"]={ "א","ַ" }, + ["אָ"]={ "א","ָ" }, + ["אּ"]={ "א","ּ" }, + ["בּ"]={ "ב","ּ" }, + ["גּ"]={ "ג","ּ" }, + ["דּ"]={ "ד","ּ" }, + ["הּ"]={ "ה","ּ" }, + ["וּ"]={ "ו","ּ" }, + ["זּ"]={ "ז","ּ" }, + ["טּ"]={ "ט","ּ" }, + ["יּ"]={ "י","ּ" }, + ["ךּ"]={ "ך","ּ" }, + ["כּ"]={ "כ","ּ" }, + ["לּ"]={ "ל","ּ" }, + ["מּ"]={ "מ","ּ" }, + ["נּ"]={ "נ","ּ" }, + ["סּ"]={ "ס","ּ" }, + ["ףּ"]={ "ף","ּ" }, + ["פּ"]={ "פ","ּ" }, + ["צּ"]={ "צ","ּ" }, + ["קּ"]={ "ק","ּ" }, + ["רּ"]={ "ר","ּ" }, + ["שּ"]={ "ש","ּ" }, + ["תּ"]={ "ת","ּ" }, + ["וֹ"]={ "ו","ֹ" }, + ["בֿ"]={ "ב","ֿ" }, + ["כֿ"]={ "כ","ֿ" }, + ["פֿ"]={ "פ","ֿ" }, + ["𑂚"]={ "𑂙","𑂺" }, + ["𑂜"]={ "𑂛","𑂺" }, + ["𑂫"]={ "𑂥","𑂺" }, + ["𑄮"]={ "𑄱","𑄧" }, + ["𑄯"]={ "𑄲","𑄧" }, + ["𑍋"]={ "𑍇","𑌾" }, + ["𑍌"]={ "𑍇","𑍗" }, + ["𑒻"]={ "𑒹","𑒺" }, + ["𑒼"]={ "𑒹","𑒰" }, + ["𑒾"]={ "𑒹","𑒽" }, + ["𑖺"]={ "𑖸","𑖯" }, + ["𑖻"]={ "𑖹","𑖯" }, + ["𝅗𝅥"]={ "𝅗","𝅥" }, + ["𝅘𝅥"]={ "𝅘","𝅥" }, + ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" }, + ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" }, + ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" }, + ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" }, + ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" }, + ["𝆹𝅥"]={ "𝆹","𝅥" }, + ["𝆺𝅥"]={ "𝆺","𝅥" }, + ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" }, + ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" }, + ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" }, + ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" }, + }, + }, + { + ["data"]={ + ["À"]={ "A","̀" }, + ["Á"]={ "A","́" }, + ["Â"]={ "A","̂" }, + ["Ã"]={ "A","̃" }, + ["Ä"]={ "A","̈" }, + ["Å"]={ "A","̊" }, + ["Ç"]={ "C","̧" }, + ["È"]={ "E","̀" }, + ["É"]={ "E","́" }, + ["Ê"]={ "E","̂" }, + ["Ë"]={ "E","̈" }, + ["Ì"]={ "I","̀" }, + ["Í"]={ "I","́" }, + ["Î"]={ "I","̂" }, + ["Ï"]={ "I","̈" }, + ["Ñ"]={ "N","̃" }, + ["Ò"]={ "O","̀" }, + ["Ó"]={ "O","́" }, + ["Ô"]={ "O","̂" }, + ["Õ"]={ "O","̃" }, + ["Ö"]={ "O","̈" }, + ["Ù"]={ "U","̀" }, + ["Ú"]={ "U","́" }, + ["Û"]={ "U","̂" }, + ["Ü"]={ "U","̈" }, + ["Ý"]={ "Y","́" }, + ["à"]={ "a","̀" }, + ["á"]={ "a","́" }, + ["â"]={ "a","̂" }, + ["ã"]={ "a","̃" }, + ["ä"]={ "a","̈" }, + ["å"]={ "a","̊" }, + ["ç"]={ "c","̧" }, + ["è"]={ "e","̀" }, + ["é"]={ "e","́" }, + ["ê"]={ "e","̂" }, + ["ë"]={ "e","̈" }, + ["ì"]={ "i","̀" }, + ["í"]={ "i","́" }, + ["î"]={ "i","̂" }, + ["ï"]={ "i","̈" }, + ["ñ"]={ "n","̃" }, + ["ò"]={ "o","̀" }, + ["ó"]={ "o","́" }, + ["ô"]={ "o","̂" }, + ["õ"]={ "o","̃" }, + ["ö"]={ "o","̈" }, + ["ù"]={ "u","̀" }, + ["ú"]={ "u","́" }, + ["û"]={ "u","̂" }, + ["ü"]={ "u","̈" }, + ["ý"]={ "y","́" }, + ["ÿ"]={ "y","̈" }, + ["Ā"]={ "A","̄" }, + ["ā"]={ "a","̄" }, + ["Ă"]={ "A","̆" }, + ["ă"]={ "a","̆" }, + ["Ą"]={ "A","̨" }, + ["ą"]={ "a","̨" }, + ["Ć"]={ "C","́" }, + ["ć"]={ "c","́" }, + ["Ĉ"]={ "C","̂" }, + ["ĉ"]={ "c","̂" }, + ["Ċ"]={ "C","̇" }, + ["ċ"]={ "c","̇" }, + ["Č"]={ "C","̌" }, + ["č"]={ "c","̌" }, + ["Ď"]={ "D","̌" }, + ["ď"]={ "d","̌" }, + ["Ē"]={ "E","̄" }, + ["ē"]={ "e","̄" }, + ["Ĕ"]={ "E","̆" }, + ["ĕ"]={ "e","̆" }, + ["Ė"]={ "E","̇" }, + ["ė"]={ "e","̇" }, + ["Ę"]={ "E","̨" }, + ["ę"]={ "e","̨" }, + ["Ě"]={ "E","̌" }, + ["ě"]={ "e","̌" }, + ["Ĝ"]={ "G","̂" }, + ["ĝ"]={ "g","̂" }, + ["Ğ"]={ "G","̆" }, + ["ğ"]={ "g","̆" }, + ["Ġ"]={ "G","̇" }, + ["ġ"]={ "g","̇" }, + ["Ģ"]={ "G","̧" }, + ["ģ"]={ "g","̧" }, + ["Ĥ"]={ "H","̂" }, + ["ĥ"]={ "h","̂" }, + ["Ĩ"]={ "I","̃" }, + ["ĩ"]={ "i","̃" }, + ["Ī"]={ "I","̄" }, + ["ī"]={ "i","̄" }, + ["Ĭ"]={ "I","̆" }, + ["ĭ"]={ "i","̆" }, + ["Į"]={ "I","̨" }, + ["į"]={ "i","̨" }, + ["İ"]={ "I","̇" }, + ["Ĵ"]={ "J","̂" }, + ["ĵ"]={ "j","̂" }, + ["Ķ"]={ "K","̧" }, + ["ķ"]={ "k","̧" }, + ["Ĺ"]={ "L","́" }, + ["ĺ"]={ "l","́" }, + ["Ļ"]={ "L","̧" }, + ["ļ"]={ "l","̧" }, + ["Ľ"]={ "L","̌" }, + ["ľ"]={ "l","̌" }, + ["Ń"]={ "N","́" }, + ["ń"]={ "n","́" }, + ["Ņ"]={ "N","̧" }, + ["ņ"]={ "n","̧" }, + ["Ň"]={ "N","̌" }, + ["ň"]={ "n","̌" }, + ["Ō"]={ "O","̄" }, + ["ō"]={ "o","̄" }, + ["Ŏ"]={ "O","̆" }, + ["ŏ"]={ "o","̆" }, + ["Ő"]={ "O","̋" }, + ["ő"]={ "o","̋" }, + ["Ŕ"]={ "R","́" }, + ["ŕ"]={ "r","́" }, + ["Ŗ"]={ "R","̧" }, + ["ŗ"]={ "r","̧" }, + ["Ř"]={ "R","̌" }, + ["ř"]={ "r","̌" }, + ["Ś"]={ "S","́" }, + ["ś"]={ "s","́" }, + ["Ŝ"]={ "S","̂" }, + ["ŝ"]={ "s","̂" }, + ["Ş"]={ "S","̧" }, + ["ş"]={ "s","̧" }, + ["Š"]={ "S","̌" }, + ["š"]={ "s","̌" }, + ["Ţ"]={ "T","̧" }, + ["ţ"]={ "t","̧" }, + ["Ť"]={ "T","̌" }, + ["ť"]={ "t","̌" }, + ["Ũ"]={ "U","̃" }, + ["ũ"]={ "u","̃" }, + ["Ū"]={ "U","̄" }, + ["ū"]={ "u","̄" }, + ["Ŭ"]={ "U","̆" }, + ["ŭ"]={ "u","̆" }, + ["Ů"]={ "U","̊" }, + ["ů"]={ "u","̊" }, + ["Ű"]={ "U","̋" }, + ["ű"]={ "u","̋" }, + ["Ų"]={ "U","̨" }, + ["ų"]={ "u","̨" }, + ["Ŵ"]={ "W","̂" }, + ["ŵ"]={ "w","̂" }, + ["Ŷ"]={ "Y","̂" }, + ["ŷ"]={ "y","̂" }, + ["Ÿ"]={ "Y","̈" }, + ["Ź"]={ "Z","́" }, + ["ź"]={ "z","́" }, + ["Ż"]={ "Z","̇" }, + ["ż"]={ "z","̇" }, + ["Ž"]={ "Z","̌" }, + ["ž"]={ "z","̌" }, + ["Ơ"]={ "O","̛" }, + ["ơ"]={ "o","̛" }, + ["Ư"]={ "U","̛" }, + ["ư"]={ "u","̛" }, + ["Ǎ"]={ "A","̌" }, + ["ǎ"]={ "a","̌" }, + ["Ǐ"]={ "I","̌" }, + ["ǐ"]={ "i","̌" }, + ["Ǒ"]={ "O","̌" }, + ["ǒ"]={ "o","̌" }, + ["Ǔ"]={ "U","̌" }, + ["ǔ"]={ "u","̌" }, + ["Ǖ"]={ "Ü","̄" }, + ["ǖ"]={ "ü","̄" }, + ["Ǘ"]={ "Ü","́" }, + ["ǘ"]={ "ü","́" }, + ["Ǚ"]={ "Ü","̌" }, + ["ǚ"]={ "ü","̌" }, + ["Ǜ"]={ "Ü","̀" }, + ["ǜ"]={ "ü","̀" }, + ["Ǟ"]={ "Ä","̄" }, + ["ǟ"]={ "ä","̄" }, + ["Ǡ"]={ "Ȧ","̄" }, + ["ǡ"]={ "ȧ","̄" }, + ["Ǣ"]={ "Æ","̄" }, + ["ǣ"]={ "æ","̄" }, + ["Ǧ"]={ "G","̌" }, + ["ǧ"]={ "g","̌" }, + ["Ǩ"]={ "K","̌" }, + ["ǩ"]={ "k","̌" }, + ["Ǫ"]={ "O","̨" }, + ["ǫ"]={ "o","̨" }, + ["Ǭ"]={ "Ǫ","̄" }, + ["ǭ"]={ "ǫ","̄" }, + ["Ǯ"]={ "Ʒ","̌" }, + ["ǯ"]={ "ʒ","̌" }, + ["ǰ"]={ "j","̌" }, + ["Ǵ"]={ "G","́" }, + ["ǵ"]={ "g","́" }, + ["Ǹ"]={ "N","̀" }, + ["ǹ"]={ "n","̀" }, + ["Ǻ"]={ "Å","́" }, + ["ǻ"]={ "å","́" }, + ["Ǽ"]={ "Æ","́" }, + ["ǽ"]={ "æ","́" }, + ["Ǿ"]={ "Ø","́" }, + ["ǿ"]={ "ø","́" }, + ["Ȁ"]={ "A","̏" }, + ["ȁ"]={ "a","̏" }, + ["Ȃ"]={ "A","̑" }, + ["ȃ"]={ "a","̑" }, + ["Ȅ"]={ "E","̏" }, + ["ȅ"]={ "e","̏" }, + ["Ȇ"]={ "E","̑" }, + ["ȇ"]={ "e","̑" }, + ["Ȉ"]={ "I","̏" }, + ["ȉ"]={ "i","̏" }, + ["Ȋ"]={ "I","̑" }, + ["ȋ"]={ "i","̑" }, + ["Ȍ"]={ "O","̏" }, + ["ȍ"]={ "o","̏" }, + ["Ȏ"]={ "O","̑" }, + ["ȏ"]={ "o","̑" }, + ["Ȑ"]={ "R","̏" }, + ["ȑ"]={ "r","̏" }, + ["Ȓ"]={ "R","̑" }, + ["ȓ"]={ "r","̑" }, + ["Ȕ"]={ "U","̏" }, + ["ȕ"]={ "u","̏" }, + ["Ȗ"]={ "U","̑" }, + ["ȗ"]={ "u","̑" }, + ["Ș"]={ "S","̦" }, + ["ș"]={ "s","̦" }, + ["Ț"]={ "T","̦" }, + ["ț"]={ "t","̦" }, + ["Ȟ"]={ "H","̌" }, + ["ȟ"]={ "h","̌" }, + ["Ȧ"]={ "A","̇" }, + ["ȧ"]={ "a","̇" }, + ["Ȩ"]={ "E","̧" }, + ["ȩ"]={ "e","̧" }, + ["Ȫ"]={ "Ö","̄" }, + ["ȫ"]={ "ö","̄" }, + ["Ȭ"]={ "Õ","̄" }, + ["ȭ"]={ "õ","̄" }, + ["Ȯ"]={ "O","̇" }, + ["ȯ"]={ "o","̇" }, + ["Ȱ"]={ "Ȯ","̄" }, + ["ȱ"]={ "ȯ","̄" }, + ["Ȳ"]={ "Y","̄" }, + ["ȳ"]={ "y","̄" }, + ["̈́"]={ "̈","́" }, + ["΅"]={ "¨","́" }, + ["Ά"]={ "Α","́" }, + ["Έ"]={ "Ε","́" }, + ["Ή"]={ "Η","́" }, + ["Ί"]={ "Ι","́" }, + ["Ό"]={ "Ο","́" }, + ["Ύ"]={ "Υ","́" }, + ["Ώ"]={ "Ω","́" }, + ["ΐ"]={ "ϊ","́" }, + ["Ϊ"]={ "Ι","̈" }, + ["Ϋ"]={ "Υ","̈" }, + ["ά"]={ "α","́" }, + ["έ"]={ "ε","́" }, + ["ή"]={ "η","́" }, + ["ί"]={ "ι","́" }, + ["ΰ"]={ "ϋ","́" }, + ["ϊ"]={ "ι","̈" }, + ["ϋ"]={ "υ","̈" }, + ["ό"]={ "ο","́" }, + ["ύ"]={ "υ","́" }, + ["ώ"]={ "ω","́" }, + ["ϓ"]={ "ϒ","́" }, + ["ϔ"]={ "ϒ","̈" }, + ["Ѐ"]={ "Е","̀" }, + ["Ё"]={ "Е","̈" }, + ["Ѓ"]={ "Г","́" }, + ["Ї"]={ "І","̈" }, + ["Ќ"]={ "К","́" }, + ["Ѝ"]={ "И","̀" }, + ["Ў"]={ "У","̆" }, + ["Й"]={ "И","̆" }, + ["й"]={ "и","̆" }, + ["ѐ"]={ "е","̀" }, + ["ё"]={ "е","̈" }, + ["ѓ"]={ "г","́" }, + ["ї"]={ "і","̈" }, + ["ќ"]={ "к","́" }, + ["ѝ"]={ "и","̀" }, + ["ў"]={ "у","̆" }, + ["Ѷ"]={ "Ѵ","̏" }, + ["ѷ"]={ "ѵ","̏" }, + ["Ӂ"]={ "Ж","̆" }, + ["ӂ"]={ "ж","̆" }, + ["Ӑ"]={ "А","̆" }, + ["ӑ"]={ "а","̆" }, + ["Ӓ"]={ "А","̈" }, + ["ӓ"]={ "а","̈" }, + ["Ӗ"]={ "Е","̆" }, + ["ӗ"]={ "е","̆" }, + ["Ӛ"]={ "Ә","̈" }, + ["ӛ"]={ "ә","̈" }, + ["Ӝ"]={ "Ж","̈" }, + ["ӝ"]={ "ж","̈" }, + ["Ӟ"]={ "З","̈" }, + ["ӟ"]={ "з","̈" }, + ["Ӣ"]={ "И","̄" }, + ["ӣ"]={ "и","̄" }, + ["Ӥ"]={ "И","̈" }, + ["ӥ"]={ "и","̈" }, + ["Ӧ"]={ "О","̈" }, + ["ӧ"]={ "о","̈" }, + ["Ӫ"]={ "Ө","̈" }, + ["ӫ"]={ "ө","̈" }, + ["Ӭ"]={ "Э","̈" }, + ["ӭ"]={ "э","̈" }, + ["Ӯ"]={ "У","̄" }, + ["ӯ"]={ "у","̄" }, + ["Ӱ"]={ "У","̈" }, + ["ӱ"]={ "у","̈" }, + ["Ӳ"]={ "У","̋" }, + ["ӳ"]={ "у","̋" }, + ["Ӵ"]={ "Ч","̈" }, + ["ӵ"]={ "ч","̈" }, + ["Ӹ"]={ "Ы","̈" }, + ["ӹ"]={ "ы","̈" }, + ["آ"]={ "ا","ٓ" }, + ["أ"]={ "ا","ٔ" }, + ["ؤ"]={ "و","ٔ" }, + ["إ"]={ "ا","ٕ" }, + ["ئ"]={ "ي","ٔ" }, + ["ۀ"]={ "ە","ٔ" }, + ["ۂ"]={ "ہ","ٔ" }, + ["ۓ"]={ "ے","ٔ" }, + ["ऩ"]={ "न","़" }, + ["ऱ"]={ "र","़" }, + ["ऴ"]={ "ळ","़" }, + ["क़"]={ "क","़" }, + ["ख़"]={ "ख","़" }, + ["ग़"]={ "ग","़" }, + ["ज़"]={ "ज","़" }, + ["ड़"]={ "ड","़" }, + ["ढ़"]={ "ढ","़" }, + ["फ़"]={ "फ","़" }, + ["य़"]={ "य","़" }, + ["ো"]={ "ে","া" }, + ["ৌ"]={ "ে","ৗ" }, + ["ড়"]={ "ড","়" }, + ["ঢ়"]={ "ঢ","়" }, + ["য়"]={ "য","়" }, + ["ਲ਼"]={ "ਲ","਼" }, + ["ਸ਼"]={ "ਸ","਼" }, + ["ਖ਼"]={ "ਖ","਼" }, + ["ਗ਼"]={ "ਗ","਼" }, + ["ਜ਼"]={ "ਜ","਼" }, + ["ਫ਼"]={ "ਫ","਼" }, + ["ୈ"]={ "େ","ୖ" }, + ["ୋ"]={ "େ","ା" }, + ["ୌ"]={ "େ","ୗ" }, + ["ଡ଼"]={ "ଡ","଼" }, + ["ଢ଼"]={ "ଢ","଼" }, + ["ஔ"]={ "ஒ","ௗ" }, + ["ொ"]={ "ெ","ா" }, + ["ோ"]={ "ே","ா" }, + ["ௌ"]={ "ெ","ௗ" }, + ["ై"]={ "ె","ౖ" }, + ["ೀ"]={ "ಿ","ೕ" }, + ["ೇ"]={ "ೆ","ೕ" }, + ["ೈ"]={ "ೆ","ೖ" }, + ["ೊ"]={ "ೆ","ೂ" }, + ["ೋ"]={ "ೊ","ೕ" }, + ["ൊ"]={ "െ","ാ" }, + ["ോ"]={ "േ","ാ" }, + ["ൌ"]={ "െ","ൗ" }, + ["ේ"]={ "ෙ","්" }, + ["ො"]={ "ෙ","ා" }, + ["ෝ"]={ "ො","්" }, + ["ෞ"]={ "ෙ","ෟ" }, + ["གྷ"]={ "ག","ྷ" }, + ["ཌྷ"]={ "ཌ","ྷ" }, + ["དྷ"]={ "ད","ྷ" }, + ["བྷ"]={ "བ","ྷ" }, + ["ཛྷ"]={ "ཛ","ྷ" }, + ["ཀྵ"]={ "ཀ","ྵ" }, + ["ཱི"]={ "ཱ","ི" }, + ["ཱུ"]={ "ཱ","ུ" }, + ["ྲྀ"]={ "ྲ","ྀ" }, + ["ླྀ"]={ "ླ","ྀ" }, + ["ཱྀ"]={ "ཱ","ྀ" }, + ["ྒྷ"]={ "ྒ","ྷ" }, + ["ྜྷ"]={ "ྜ","ྷ" }, + ["ྡྷ"]={ "ྡ","ྷ" }, + ["ྦྷ"]={ "ྦ","ྷ" }, + ["ྫྷ"]={ "ྫ","ྷ" }, + ["ྐྵ"]={ "ྐ","ྵ" }, + ["ဦ"]={ "ဥ","ီ" }, + ["ᬆ"]={ "ᬅ","ᬵ" }, + ["ᬈ"]={ "ᬇ","ᬵ" }, + ["ᬊ"]={ "ᬉ","ᬵ" }, + ["ᬌ"]={ "ᬋ","ᬵ" }, + ["ᬎ"]={ "ᬍ","ᬵ" }, + ["ᬒ"]={ "ᬑ","ᬵ" }, + ["ᬻ"]={ "ᬺ","ᬵ" }, + ["ᬽ"]={ "ᬼ","ᬵ" }, + ["ᭀ"]={ "ᬾ","ᬵ" }, + ["ᭁ"]={ "ᬿ","ᬵ" }, + ["ᭃ"]={ "ᭂ","ᬵ" }, + ["Ḁ"]={ "A","̥" }, + ["ḁ"]={ "a","̥" }, + ["Ḃ"]={ "B","̇" }, + ["ḃ"]={ "b","̇" }, + ["Ḅ"]={ "B","̣" }, + ["ḅ"]={ "b","̣" }, + ["Ḇ"]={ "B","̱" }, + ["ḇ"]={ "b","̱" }, + ["Ḉ"]={ "Ç","́" }, + ["ḉ"]={ "ç","́" }, + ["Ḋ"]={ "D","̇" }, + ["ḋ"]={ "d","̇" }, + ["Ḍ"]={ "D","̣" }, + ["ḍ"]={ "d","̣" }, + ["Ḏ"]={ "D","̱" }, + ["ḏ"]={ "d","̱" }, + ["Ḑ"]={ "D","̧" }, + ["ḑ"]={ "d","̧" }, + ["Ḓ"]={ "D","̭" }, + ["ḓ"]={ "d","̭" }, + ["Ḕ"]={ "Ē","̀" }, + ["ḕ"]={ "ē","̀" }, + ["Ḗ"]={ "Ē","́" }, + ["ḗ"]={ "ē","́" }, + ["Ḙ"]={ "E","̭" }, + ["ḙ"]={ "e","̭" }, + ["Ḛ"]={ "E","̰" }, + ["ḛ"]={ "e","̰" }, + ["Ḝ"]={ "Ȩ","̆" }, + ["ḝ"]={ "ȩ","̆" }, + ["Ḟ"]={ "F","̇" }, + ["ḟ"]={ "f","̇" }, + ["Ḡ"]={ "G","̄" }, + ["ḡ"]={ "g","̄" }, + ["Ḣ"]={ "H","̇" }, + ["ḣ"]={ "h","̇" }, + ["Ḥ"]={ "H","̣" }, + ["ḥ"]={ "h","̣" }, + ["Ḧ"]={ "H","̈" }, + ["ḧ"]={ "h","̈" }, + ["Ḩ"]={ "H","̧" }, + ["ḩ"]={ "h","̧" }, + ["Ḫ"]={ "H","̮" }, + ["ḫ"]={ "h","̮" }, + ["Ḭ"]={ "I","̰" }, + ["ḭ"]={ "i","̰" }, + ["Ḯ"]={ "Ï","́" }, + ["ḯ"]={ "ï","́" }, + ["Ḱ"]={ "K","́" }, + ["ḱ"]={ "k","́" }, + ["Ḳ"]={ "K","̣" }, + ["ḳ"]={ "k","̣" }, + ["Ḵ"]={ "K","̱" }, + ["ḵ"]={ "k","̱" }, + ["Ḷ"]={ "L","̣" }, + ["ḷ"]={ "l","̣" }, + ["Ḹ"]={ "Ḷ","̄" }, + ["ḹ"]={ "ḷ","̄" }, + ["Ḻ"]={ "L","̱" }, + ["ḻ"]={ "l","̱" }, + ["Ḽ"]={ "L","̭" }, + ["ḽ"]={ "l","̭" }, + ["Ḿ"]={ "M","́" }, + ["ḿ"]={ "m","́" }, + ["Ṁ"]={ "M","̇" }, + ["ṁ"]={ "m","̇" }, + ["Ṃ"]={ "M","̣" }, + ["ṃ"]={ "m","̣" }, + ["Ṅ"]={ "N","̇" }, + ["ṅ"]={ "n","̇" }, + ["Ṇ"]={ "N","̣" }, + ["ṇ"]={ "n","̣" }, + ["Ṉ"]={ "N","̱" }, + ["ṉ"]={ "n","̱" }, + ["Ṋ"]={ "N","̭" }, + ["ṋ"]={ "n","̭" }, + ["Ṍ"]={ "Õ","́" }, + ["ṍ"]={ "õ","́" }, + ["Ṏ"]={ "Õ","̈" }, + ["ṏ"]={ "õ","̈" }, + ["Ṑ"]={ "Ō","̀" }, + ["ṑ"]={ "ō","̀" }, + ["Ṓ"]={ "Ō","́" }, + ["ṓ"]={ "ō","́" }, + ["Ṕ"]={ "P","́" }, + ["ṕ"]={ "p","́" }, + ["Ṗ"]={ "P","̇" }, + ["ṗ"]={ "p","̇" }, + ["Ṙ"]={ "R","̇" }, + ["ṙ"]={ "r","̇" }, + ["Ṛ"]={ "R","̣" }, + ["ṛ"]={ "r","̣" }, + ["Ṝ"]={ "Ṛ","̄" }, + ["ṝ"]={ "ṛ","̄" }, + ["Ṟ"]={ "R","̱" }, + ["ṟ"]={ "r","̱" }, + ["Ṡ"]={ "S","̇" }, + ["ṡ"]={ "s","̇" }, + ["Ṣ"]={ "S","̣" }, + ["ṣ"]={ "s","̣" }, + ["Ṥ"]={ "Ś","̇" }, + ["ṥ"]={ "ś","̇" }, + ["Ṧ"]={ "Š","̇" }, + ["ṧ"]={ "š","̇" }, + ["Ṩ"]={ "Ṣ","̇" }, + ["ṩ"]={ "ṣ","̇" }, + ["Ṫ"]={ "T","̇" }, + ["ṫ"]={ "t","̇" }, + ["Ṭ"]={ "T","̣" }, + ["ṭ"]={ "t","̣" }, + ["Ṯ"]={ "T","̱" }, + ["ṯ"]={ "t","̱" }, + ["Ṱ"]={ "T","̭" }, + ["ṱ"]={ "t","̭" }, + ["Ṳ"]={ "U","̤" }, + ["ṳ"]={ "u","̤" }, + ["Ṵ"]={ "U","̰" }, + ["ṵ"]={ "u","̰" }, + ["Ṷ"]={ "U","̭" }, + ["ṷ"]={ "u","̭" }, + ["Ṹ"]={ "Ũ","́" }, + ["ṹ"]={ "ũ","́" }, + ["Ṻ"]={ "Ū","̈" }, + ["ṻ"]={ "ū","̈" }, + ["Ṽ"]={ "V","̃" }, + ["ṽ"]={ "v","̃" }, + ["Ṿ"]={ "V","̣" }, + ["ṿ"]={ "v","̣" }, + ["Ẁ"]={ "W","̀" }, + ["ẁ"]={ "w","̀" }, + ["Ẃ"]={ "W","́" }, + ["ẃ"]={ "w","́" }, + ["Ẅ"]={ "W","̈" }, + ["ẅ"]={ "w","̈" }, + ["Ẇ"]={ "W","̇" }, + ["ẇ"]={ "w","̇" }, + ["Ẉ"]={ "W","̣" }, + ["ẉ"]={ "w","̣" }, + ["Ẋ"]={ "X","̇" }, + ["ẋ"]={ "x","̇" }, + ["Ẍ"]={ "X","̈" }, + ["ẍ"]={ "x","̈" }, + ["Ẏ"]={ "Y","̇" }, + ["ẏ"]={ "y","̇" }, + ["Ẑ"]={ "Z","̂" }, + ["ẑ"]={ "z","̂" }, + ["Ẓ"]={ "Z","̣" }, + ["ẓ"]={ "z","̣" }, + ["Ẕ"]={ "Z","̱" }, + ["ẕ"]={ "z","̱" }, + ["ẖ"]={ "h","̱" }, + ["ẗ"]={ "t","̈" }, + ["ẘ"]={ "w","̊" }, + ["ẙ"]={ "y","̊" }, + ["ẛ"]={ "ſ","̇" }, + ["Ạ"]={ "A","̣" }, + ["ạ"]={ "a","̣" }, + ["Ả"]={ "A","̉" }, + ["ả"]={ "a","̉" }, + ["Ấ"]={ "Â","́" }, + ["ấ"]={ "â","́" }, + ["Ầ"]={ "Â","̀" }, + ["ầ"]={ "â","̀" }, + ["Ẩ"]={ "Â","̉" }, + ["ẩ"]={ "â","̉" }, + ["Ẫ"]={ "Â","̃" }, + ["ẫ"]={ "â","̃" }, + ["Ậ"]={ "Ạ","̂" }, + ["ậ"]={ "ạ","̂" }, + ["Ắ"]={ "Ă","́" }, + ["ắ"]={ "ă","́" }, + ["Ằ"]={ "Ă","̀" }, + ["ằ"]={ "ă","̀" }, + ["Ẳ"]={ "Ă","̉" }, + ["ẳ"]={ "ă","̉" }, + ["Ẵ"]={ "Ă","̃" }, + ["ẵ"]={ "ă","̃" }, + ["Ặ"]={ "Ạ","̆" }, + ["ặ"]={ "ạ","̆" }, + ["Ẹ"]={ "E","̣" }, + ["ẹ"]={ "e","̣" }, + ["Ẻ"]={ "E","̉" }, + ["ẻ"]={ "e","̉" }, + ["Ẽ"]={ "E","̃" }, + ["ẽ"]={ "e","̃" }, + ["Ế"]={ "Ê","́" }, + ["ế"]={ "ê","́" }, + ["Ề"]={ "Ê","̀" }, + ["ề"]={ "ê","̀" }, + ["Ể"]={ "Ê","̉" }, + ["ể"]={ "ê","̉" }, + ["Ễ"]={ "Ê","̃" }, + ["ễ"]={ "ê","̃" }, + ["Ệ"]={ "Ẹ","̂" }, + ["ệ"]={ "ẹ","̂" }, + ["Ỉ"]={ "I","̉" }, + ["ỉ"]={ "i","̉" }, + ["Ị"]={ "I","̣" }, + ["ị"]={ "i","̣" }, + ["Ọ"]={ "O","̣" }, + ["ọ"]={ "o","̣" }, + ["Ỏ"]={ "O","̉" }, + ["ỏ"]={ "o","̉" }, + ["Ố"]={ "Ô","́" }, + ["ố"]={ "ô","́" }, + ["Ồ"]={ "Ô","̀" }, + ["ồ"]={ "ô","̀" }, + ["Ổ"]={ "Ô","̉" }, + ["ổ"]={ "ô","̉" }, + ["Ỗ"]={ "Ô","̃" }, + ["ỗ"]={ "ô","̃" }, + ["Ộ"]={ "Ọ","̂" }, + ["ộ"]={ "ọ","̂" }, + ["Ớ"]={ "Ơ","́" }, + ["ớ"]={ "ơ","́" }, + ["Ờ"]={ "Ơ","̀" }, + ["ờ"]={ "ơ","̀" }, + ["Ở"]={ "Ơ","̉" }, + ["ở"]={ "ơ","̉" }, + ["Ỡ"]={ "Ơ","̃" }, + ["ỡ"]={ "ơ","̃" }, + ["Ợ"]={ "Ơ","̣" }, + ["ợ"]={ "ơ","̣" }, + ["Ụ"]={ "U","̣" }, + ["ụ"]={ "u","̣" }, + ["Ủ"]={ "U","̉" }, + ["ủ"]={ "u","̉" }, + ["Ứ"]={ "Ư","́" }, + ["ứ"]={ "ư","́" }, + ["Ừ"]={ "Ư","̀" }, + ["ừ"]={ "ư","̀" }, + ["Ử"]={ "Ư","̉" }, + ["ử"]={ "ư","̉" }, + ["Ữ"]={ "Ư","̃" }, + ["ữ"]={ "ư","̃" }, + ["Ự"]={ "Ư","̣" }, + ["ự"]={ "ư","̣" }, + ["Ỳ"]={ "Y","̀" }, + ["ỳ"]={ "y","̀" }, + ["Ỵ"]={ "Y","̣" }, + ["ỵ"]={ "y","̣" }, + ["Ỷ"]={ "Y","̉" }, + ["ỷ"]={ "y","̉" }, + ["Ỹ"]={ "Y","̃" }, + ["ỹ"]={ "y","̃" }, + ["ἀ"]={ "α","̓" }, + ["ἁ"]={ "α","̔" }, + ["ἂ"]={ "ἀ","̀" }, + ["ἃ"]={ "ἁ","̀" }, + ["ἄ"]={ "ἀ","́" }, + ["ἅ"]={ "ἁ","́" }, + ["ἆ"]={ "ἀ","͂" }, + ["ἇ"]={ "ἁ","͂" }, + ["Ἀ"]={ "Α","̓" }, + ["Ἁ"]={ "Α","̔" }, + ["Ἂ"]={ "Ἀ","̀" }, + ["Ἃ"]={ "Ἁ","̀" }, + ["Ἄ"]={ "Ἀ","́" }, + ["Ἅ"]={ "Ἁ","́" }, + ["Ἆ"]={ "Ἀ","͂" }, + ["Ἇ"]={ "Ἁ","͂" }, + ["ἐ"]={ "ε","̓" }, + ["ἑ"]={ "ε","̔" }, + ["ἒ"]={ "ἐ","̀" }, + ["ἓ"]={ "ἑ","̀" }, + ["ἔ"]={ "ἐ","́" }, + ["ἕ"]={ "ἑ","́" }, + ["Ἐ"]={ "Ε","̓" }, + ["Ἑ"]={ "Ε","̔" }, + ["Ἒ"]={ "Ἐ","̀" }, + ["Ἓ"]={ "Ἑ","̀" }, + ["Ἔ"]={ "Ἐ","́" }, + ["Ἕ"]={ "Ἑ","́" }, + ["ἠ"]={ "η","̓" }, + ["ἡ"]={ "η","̔" }, + ["ἢ"]={ "ἠ","̀" }, + ["ἣ"]={ "ἡ","̀" }, + ["ἤ"]={ "ἠ","́" }, + ["ἥ"]={ "ἡ","́" }, + ["ἦ"]={ "ἠ","͂" }, + ["ἧ"]={ "ἡ","͂" }, + ["Ἠ"]={ "Η","̓" }, + ["Ἡ"]={ "Η","̔" }, + ["Ἢ"]={ "Ἠ","̀" }, + ["Ἣ"]={ "Ἡ","̀" }, + ["Ἤ"]={ "Ἠ","́" }, + ["Ἥ"]={ "Ἡ","́" }, + ["Ἦ"]={ "Ἠ","͂" }, + ["Ἧ"]={ "Ἡ","͂" }, + ["ἰ"]={ "ι","̓" }, + ["ἱ"]={ "ι","̔" }, + ["ἲ"]={ "ἰ","̀" }, + ["ἳ"]={ "ἱ","̀" }, + ["ἴ"]={ "ἰ","́" }, + ["ἵ"]={ "ἱ","́" }, + ["ἶ"]={ "ἰ","͂" }, + ["ἷ"]={ "ἱ","͂" }, + ["Ἰ"]={ "Ι","̓" }, + ["Ἱ"]={ "Ι","̔" }, + ["Ἲ"]={ "Ἰ","̀" }, + ["Ἳ"]={ "Ἱ","̀" }, + ["Ἴ"]={ "Ἰ","́" }, + ["Ἵ"]={ "Ἱ","́" }, + ["Ἶ"]={ "Ἰ","͂" }, + ["Ἷ"]={ "Ἱ","͂" }, + ["ὀ"]={ "ο","̓" }, + ["ὁ"]={ "ο","̔" }, + ["ὂ"]={ "ὀ","̀" }, + ["ὃ"]={ "ὁ","̀" }, + ["ὄ"]={ "ὀ","́" }, + ["ὅ"]={ "ὁ","́" }, + ["Ὀ"]={ "Ο","̓" }, + ["Ὁ"]={ "Ο","̔" }, + ["Ὂ"]={ "Ὀ","̀" }, + ["Ὃ"]={ "Ὁ","̀" }, + ["Ὄ"]={ "Ὀ","́" }, + ["Ὅ"]={ "Ὁ","́" }, + ["ὐ"]={ "υ","̓" }, + ["ὑ"]={ "υ","̔" }, + ["ὒ"]={ "ὐ","̀" }, + ["ὓ"]={ "ὑ","̀" }, + ["ὔ"]={ "ὐ","́" }, + ["ὕ"]={ "ὑ","́" }, + ["ὖ"]={ "ὐ","͂" }, + ["ὗ"]={ "ὑ","͂" }, + ["Ὑ"]={ "Υ","̔" }, + ["Ὓ"]={ "Ὑ","̀" }, + ["Ὕ"]={ "Ὑ","́" }, + ["Ὗ"]={ "Ὑ","͂" }, + ["ὠ"]={ "ω","̓" }, + ["ὡ"]={ "ω","̔" }, + ["ὢ"]={ "ὠ","̀" }, + ["ὣ"]={ "ὡ","̀" }, + ["ὤ"]={ "ὠ","́" }, + ["ὥ"]={ "ὡ","́" }, + ["ὦ"]={ "ὠ","͂" }, + ["ὧ"]={ "ὡ","͂" }, + ["Ὠ"]={ "Ω","̓" }, + ["Ὡ"]={ "Ω","̔" }, + ["Ὢ"]={ "Ὠ","̀" }, + ["Ὣ"]={ "Ὡ","̀" }, + ["Ὤ"]={ "Ὠ","́" }, + ["Ὥ"]={ "Ὡ","́" }, + ["Ὦ"]={ "Ὠ","͂" }, + ["Ὧ"]={ "Ὡ","͂" }, + ["ὰ"]={ "α","̀" }, + ["ὲ"]={ "ε","̀" }, + ["ὴ"]={ "η","̀" }, + ["ὶ"]={ "ι","̀" }, + ["ὸ"]={ "ο","̀" }, + ["ὺ"]={ "υ","̀" }, + ["ὼ"]={ "ω","̀" }, + ["ᾀ"]={ "ἀ","ͅ" }, + ["ᾁ"]={ "ἁ","ͅ" }, + ["ᾂ"]={ "ἂ","ͅ" }, + ["ᾃ"]={ "ἃ","ͅ" }, + ["ᾄ"]={ "ἄ","ͅ" }, + ["ᾅ"]={ "ἅ","ͅ" }, + ["ᾆ"]={ "ἆ","ͅ" }, + ["ᾇ"]={ "ἇ","ͅ" }, + ["ᾈ"]={ "Ἀ","ͅ" }, + ["ᾉ"]={ "Ἁ","ͅ" }, + ["ᾊ"]={ "Ἂ","ͅ" }, + ["ᾋ"]={ "Ἃ","ͅ" }, + ["ᾌ"]={ "Ἄ","ͅ" }, + ["ᾍ"]={ "Ἅ","ͅ" }, + ["ᾎ"]={ "Ἆ","ͅ" }, + ["ᾏ"]={ "Ἇ","ͅ" }, + ["ᾐ"]={ "ἠ","ͅ" }, + ["ᾑ"]={ "ἡ","ͅ" }, + ["ᾒ"]={ "ἢ","ͅ" }, + ["ᾓ"]={ "ἣ","ͅ" }, + ["ᾔ"]={ "ἤ","ͅ" }, + ["ᾕ"]={ "ἥ","ͅ" }, + ["ᾖ"]={ "ἦ","ͅ" }, + ["ᾗ"]={ "ἧ","ͅ" }, + ["ᾘ"]={ "Ἠ","ͅ" }, + ["ᾙ"]={ "Ἡ","ͅ" }, + ["ᾚ"]={ "Ἢ","ͅ" }, + ["ᾛ"]={ "Ἣ","ͅ" }, + ["ᾜ"]={ "Ἤ","ͅ" }, + ["ᾝ"]={ "Ἥ","ͅ" }, + ["ᾞ"]={ "Ἦ","ͅ" }, + ["ᾟ"]={ "Ἧ","ͅ" }, + ["ᾠ"]={ "ὠ","ͅ" }, + ["ᾡ"]={ "ὡ","ͅ" }, + ["ᾢ"]={ "ὢ","ͅ" }, + ["ᾣ"]={ "ὣ","ͅ" }, + ["ᾤ"]={ "ὤ","ͅ" }, + ["ᾥ"]={ "ὥ","ͅ" }, + ["ᾦ"]={ "ὦ","ͅ" }, + ["ᾧ"]={ "ὧ","ͅ" }, + ["ᾨ"]={ "Ὠ","ͅ" }, + ["ᾩ"]={ "Ὡ","ͅ" }, + ["ᾪ"]={ "Ὢ","ͅ" }, + ["ᾫ"]={ "Ὣ","ͅ" }, + ["ᾬ"]={ "Ὤ","ͅ" }, + ["ᾭ"]={ "Ὥ","ͅ" }, + ["ᾮ"]={ "Ὦ","ͅ" }, + ["ᾯ"]={ "Ὧ","ͅ" }, + ["ᾰ"]={ "α","̆" }, + ["ᾱ"]={ "α","̄" }, + ["ᾲ"]={ "ὰ","ͅ" }, + ["ᾳ"]={ "α","ͅ" }, + ["ᾴ"]={ "ά","ͅ" }, + ["ᾶ"]={ "α","͂" }, + ["ᾷ"]={ "ᾶ","ͅ" }, + ["Ᾰ"]={ "Α","̆" }, + ["Ᾱ"]={ "Α","̄" }, + ["Ὰ"]={ "Α","̀" }, + ["ᾼ"]={ "Α","ͅ" }, + ["῁"]={ "¨","͂" }, + ["ῂ"]={ "ὴ","ͅ" }, + ["ῃ"]={ "η","ͅ" }, + ["ῄ"]={ "ή","ͅ" }, + ["ῆ"]={ "η","͂" }, + ["ῇ"]={ "ῆ","ͅ" }, + ["Ὲ"]={ "Ε","̀" }, + ["Ὴ"]={ "Η","̀" }, + ["ῌ"]={ "Η","ͅ" }, + ["῍"]={ "᾿","̀" }, + ["῎"]={ "᾿","́" }, + ["῏"]={ "᾿","͂" }, + ["ῐ"]={ "ι","̆" }, + ["ῑ"]={ "ι","̄" }, + ["ῒ"]={ "ϊ","̀" }, + ["ῖ"]={ "ι","͂" }, + ["ῗ"]={ "ϊ","͂" }, + ["Ῐ"]={ "Ι","̆" }, + ["Ῑ"]={ "Ι","̄" }, + ["Ὶ"]={ "Ι","̀" }, + ["῝"]={ "῾","̀" }, + ["῞"]={ "῾","́" }, + ["῟"]={ "῾","͂" }, + ["ῠ"]={ "υ","̆" }, + ["ῡ"]={ "υ","̄" }, + ["ῢ"]={ "ϋ","̀" }, + ["ῤ"]={ "ρ","̓" }, + ["ῥ"]={ "ρ","̔" }, + ["ῦ"]={ "υ","͂" }, + ["ῧ"]={ "ϋ","͂" }, + ["Ῠ"]={ "Υ","̆" }, + ["Ῡ"]={ "Υ","̄" }, + ["Ὺ"]={ "Υ","̀" }, + ["Ῥ"]={ "Ρ","̔" }, + ["῭"]={ "¨","̀" }, + ["ῲ"]={ "ὼ","ͅ" }, + ["ῳ"]={ "ω","ͅ" }, + ["ῴ"]={ "ώ","ͅ" }, + ["ῶ"]={ "ω","͂" }, + ["ῷ"]={ "ῶ","ͅ" }, + ["Ὸ"]={ "Ο","̀" }, + ["Ὼ"]={ "Ω","̀" }, + ["ῼ"]={ "Ω","ͅ" }, + ["↚"]={ "←","̸" }, + ["↛"]={ "→","̸" }, + ["↮"]={ "↔","̸" }, + ["⇍"]={ "⇐","̸" }, + ["⇎"]={ "⇔","̸" }, + ["⇏"]={ "⇒","̸" }, + ["∄"]={ "∃","̸" }, + ["∉"]={ "∈","̸" }, + ["∌"]={ "∋","̸" }, + ["∤"]={ "∣","̸" }, + ["∦"]={ "∥","̸" }, + ["≁"]={ "∼","̸" }, + ["≄"]={ "≃","̸" }, + ["≇"]={ "≅","̸" }, + ["≉"]={ "≈","̸" }, + ["≠"]={ "=","̸" }, + ["≢"]={ "≡","̸" }, + ["≭"]={ "≍","̸" }, + ["≮"]={ "<","̸" }, + ["≯"]={ ">","̸" }, + ["≰"]={ "≤","̸" }, + ["≱"]={ "≥","̸" }, + ["≴"]={ "≲","̸" }, + ["≵"]={ "≳","̸" }, + ["≸"]={ "≶","̸" }, + ["≹"]={ "≷","̸" }, + ["⊀"]={ "≺","̸" }, + ["⊁"]={ "≻","̸" }, + ["⊄"]={ "⊂","̸" }, + ["⊅"]={ "⊃","̸" }, + ["⊈"]={ "⊆","̸" }, + ["⊉"]={ "⊇","̸" }, + ["⊬"]={ "⊢","̸" }, + ["⊭"]={ "⊨","̸" }, + ["⊮"]={ "⊩","̸" }, + ["⊯"]={ "⊫","̸" }, + ["⋠"]={ "≼","̸" }, + ["⋡"]={ "≽","̸" }, + ["⋢"]={ "⊑","̸" }, + ["⋣"]={ "⊒","̸" }, + ["⋪"]={ "⊲","̸" }, + ["⋫"]={ "⊳","̸" }, + ["⋬"]={ "⊴","̸" }, + ["⋭"]={ "⊵","̸" }, + ["⫝̸"]={ "⫝","̸" }, + ["が"]={ "か","゙" }, + ["ぎ"]={ "き","゙" }, + ["ぐ"]={ "く","゙" }, + ["げ"]={ "け","゙" }, + ["ご"]={ "こ","゙" }, + ["ざ"]={ "さ","゙" }, + ["じ"]={ "し","゙" }, + ["ず"]={ "す","゙" }, + ["ぜ"]={ "せ","゙" }, + ["ぞ"]={ "そ","゙" }, + ["だ"]={ "た","゙" }, + ["ぢ"]={ "ち","゙" }, + ["づ"]={ "つ","゙" }, + ["で"]={ "て","゙" }, + ["ど"]={ "と","゙" }, + ["ば"]={ "は","゙" }, + ["ぱ"]={ "は","゚" }, + ["び"]={ "ひ","゙" }, + ["ぴ"]={ "ひ","゚" }, + ["ぶ"]={ "ふ","゙" }, + ["ぷ"]={ "ふ","゚" }, + ["べ"]={ "へ","゙" }, + ["ぺ"]={ "へ","゚" }, + ["ぼ"]={ "ほ","゙" }, + ["ぽ"]={ "ほ","゚" }, + ["ゔ"]={ "う","゙" }, + ["ゞ"]={ "ゝ","゙" }, + ["ガ"]={ "カ","゙" }, + ["ギ"]={ "キ","゙" }, + ["グ"]={ "ク","゙" }, + ["ゲ"]={ "ケ","゙" }, + ["ゴ"]={ "コ","゙" }, + ["ザ"]={ "サ","゙" }, + ["ジ"]={ "シ","゙" }, + ["ズ"]={ "ス","゙" }, + ["ゼ"]={ "セ","゙" }, + ["ゾ"]={ "ソ","゙" }, + ["ダ"]={ "タ","゙" }, + ["ヂ"]={ "チ","゙" }, + ["ヅ"]={ "ツ","゙" }, + ["デ"]={ "テ","゙" }, + ["ド"]={ "ト","゙" }, + ["バ"]={ "ハ","゙" }, + ["パ"]={ "ハ","゚" }, + ["ビ"]={ "ヒ","゙" }, + ["ピ"]={ "ヒ","゚" }, + ["ブ"]={ "フ","゙" }, + ["プ"]={ "フ","゚" }, + ["ベ"]={ "ヘ","゙" }, + ["ペ"]={ "ヘ","゚" }, + ["ボ"]={ "ホ","゙" }, + ["ポ"]={ "ホ","゚" }, + ["ヴ"]={ "ウ","゙" }, + ["ヷ"]={ "ワ","゙" }, + ["ヸ"]={ "ヰ","゙" }, + ["ヹ"]={ "ヱ","゙" }, + ["ヺ"]={ "ヲ","゙" }, + ["ヾ"]={ "ヽ","゙" }, + ["יִ"]={ "י","ִ" }, + ["ײַ"]={ "ײ","ַ" }, + ["שׁ"]={ "ש","ׁ" }, + ["שׂ"]={ "ש","ׂ" }, + ["שּׁ"]={ "שּ","ׁ" }, + ["שּׂ"]={ "שּ","ׂ" }, + ["אַ"]={ "א","ַ" }, + ["אָ"]={ "א","ָ" }, + ["אּ"]={ "א","ּ" }, + ["בּ"]={ "ב","ּ" }, + ["גּ"]={ "ג","ּ" }, + ["דּ"]={ "ד","ּ" }, + ["הּ"]={ "ה","ּ" }, + ["וּ"]={ "ו","ּ" }, + ["זּ"]={ "ז","ּ" }, + ["טּ"]={ "ט","ּ" }, + ["יּ"]={ "י","ּ" }, + ["ךּ"]={ "ך","ּ" }, + ["כּ"]={ "כ","ּ" }, + ["לּ"]={ "ל","ּ" }, + ["מּ"]={ "מ","ּ" }, + ["נּ"]={ "נ","ּ" }, + ["סּ"]={ "ס","ּ" }, + ["ףּ"]={ "ף","ּ" }, + ["פּ"]={ "פ","ּ" }, + ["צּ"]={ "צ","ּ" }, + ["קּ"]={ "ק","ּ" }, + ["רּ"]={ "ר","ּ" }, + ["שּ"]={ "ש","ּ" }, + ["תּ"]={ "ת","ּ" }, + ["וֹ"]={ "ו","ֹ" }, + ["בֿ"]={ "ב","ֿ" }, + ["כֿ"]={ "כ","ֿ" }, + ["פֿ"]={ "פ","ֿ" }, + ["𑂚"]={ "𑂙","𑂺" }, + ["𑂜"]={ "𑂛","𑂺" }, + ["𑂫"]={ "𑂥","𑂺" }, + ["𑄮"]={ "𑄱","𑄧" }, + ["𑄯"]={ "𑄲","𑄧" }, + ["𑍋"]={ "𑍇","𑌾" }, + ["𑍌"]={ "𑍇","𑍗" }, + ["𑒻"]={ "𑒹","𑒺" }, + ["𑒼"]={ "𑒹","𑒰" }, + ["𑒾"]={ "𑒹","𑒽" }, + ["𑖺"]={ "𑖸","𑖯" }, + ["𑖻"]={ "𑖹","𑖯" }, + ["𝅗𝅥"]={ "𝅗","𝅥" }, + ["𝅘𝅥"]={ "𝅘","𝅥" }, + ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" }, + ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" }, + ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" }, + ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" }, + ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" }, + ["𝆹𝅥"]={ "𝆹","𝅥" }, + ["𝆺𝅥"]={ "𝆺","𝅥" }, + ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" }, + ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" }, + ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" }, + ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" }, + }, + }, + }, + ["name"]="collapse", + ["prepend"]=true, + ["type"]="ligature", +} +end -- closure + +do -- begin closure to overcome local limits and interference + if not modules then modules={} end modules ['font-gbn']={ version=1.001, comment="companion to luatex-*.tex", @@ -24109,8 +32003,7 @@ local fonts=fonts local nodes=nodes local nuts=nodes.nuts local traverse_id=nuts.traverse_id -local remove_node=nuts.remove -local free_node=nuts.free +local flush_node=nuts.flush_node local glyph_code=nodes.nodecodes.glyph local disc_code=nodes.nodecodes.disc local tonode=nuts.tonode @@ -24234,7 +32127,7 @@ function nodes.handlers.nodepass(head) end end end - free_node(r) + flush_node(r) end end for d in traverse_id(disc_code,nuthead) do diff --git a/tex/generic/context/luatex/luatex-fonts.lua b/tex/generic/context/luatex/luatex-fonts.lua index c493844c8..20690992c 100644 --- a/tex/generic/context/luatex/luatex-fonts.lua +++ b/tex/generic/context/luatex/luatex-fonts.lua @@ -186,6 +186,7 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then loadmodule("l-file.lua") loadmodule("l-boolean.lua") loadmodule("l-math.lua") + loadmodule("l-unicode.lua") -- A few slightly higher level support modules: @@ -229,7 +230,6 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then loadmodule('luatex-fonts-syn.lua') - loadmodule('font-tfm.lua') loadmodule('font-oti.lua') -- These are the old loader and processing modules. These use the built-in font loader and @@ -257,6 +257,9 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then loadmodule('font-ota.lua') loadmodule('font-ots.lua') loadmodule('font-osd.lua') + loadmodule('font-ocl.lua') -- svg needs 0.97 (for fix in memstreams) + + loadmodule('font-otc.lua') -- type one code @@ -264,12 +267,17 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then loadmodule('font-one.lua') -- was font-afm.lua loadmodule('font-afk.lua') + -- traditional code + + loadmodule('font-tfm.lua') + -- common code loadmodule('font-lua.lua') loadmodule('font-def.lua') loadmodule('font-xtx.lua') -- xetex compatible specifiers (plain/latex only) loadmodule('luatex-fonts-ext.lua') -- some extensions + -- loadmodule('luatex-fonts-lig.lua') -- and another one -- We need to plug into a callback and the following module implements the handlers. Actual -- plugging in happens later. diff --git a/tex/generic/context/luatex/luatex-math.tex b/tex/generic/context/luatex/luatex-math.tex index 604b4a1f8..acf1d2308 100644 --- a/tex/generic/context/luatex/luatex-math.tex +++ b/tex/generic/context/luatex/luatex-math.tex @@ -13,9 +13,14 @@ %D approach (and thereby far from the \CONTEXT\ way). This file is mainly meant for %D Boguslaw Jackowski. +%D In the perspective of the TUG Lucida Opentype project Bruno Voisin checked the code +%D and definitions below and suggested some improvements. + % we provide a remap feature -\directlua{dofile(kpse.find_file('luatex-math.lua'))} +\ifdefined\directlua + \directlua{dofile(kpse.find_file('luatex-math.lua'))} +\fi % a bunch of fonts: @@ -40,14 +45,22 @@ \font\tenbf = file:lmroman10-bold.otf:+liga;+kern;+tlig;+trep at 10pt \font\tenbi = file:lmroman10-bolditalic.otf:+liga;+kern;+tlig;+trep at 10pt % - \font\mathfonttextupright = file:latinmodern-math.otf:ssty=0;fixmath=yes at 10pt - \font\mathfontscriptupright = file:latinmodern-math.otf:ssty=1;fixmath=yes at 7pt - \font\mathfontscriptscriptupright = file:latinmodern-math.otf:ssty=2;fixmath=yes at 5pt + \font\tenos = file:lmroman10-regular.otf:+onum;+liga;+kern;+tlig;+trep at 10pt + \font\sevenos = file:lmroman7-regular.otf:+onum;+liga;+kern;+tlig;+trep at 7pt + \font\fiveos = file:lmroman5-regular.otf:+onum;+liga;+kern;+tlig;+trep at 5pt + % + \font\mathfonttextupright = file:latinmodern-math.otf:script=math;ssty=0;mathsize=yes at 10pt + \font\mathfontscriptupright = file:latinmodern-math.otf:script=math;ssty=1;mathsize=yes at 7pt + \font\mathfontscriptscriptupright = file:latinmodern-math.otf:script=math;ssty=2;mathsize=yes at 5pt % \textfont 0 = \mathfonttextupright \scriptfont 0 = \mathfontscriptupright \scriptscriptfont 0 = \mathfontscriptscriptupright % + \textfont 1 = \tenos + \scriptfont 1 = \sevenos + \scriptscriptfont 1 = \fiveos + % \tenrm} \def\lucidabright @@ -55,32 +68,41 @@ \font\sevenrm = file:lucidabrightot.otf:+liga;+kern;+tlig;+trep at 7pt \font\fiverm = file:lucidabrightot.otf:+liga;+kern;+tlig;+trep at 5pt % - \font\tentt = file:lucidabrightot.otf at 10pt - \font\tenit = file:lucidabrightot.otf:+liga;+kern;+tlig;+trep at 10pt - \font\tenit = file:lucidabrightot-italic.otf:+liga;+kern;+tlig;+trep at 10pt - \font\tenbf = file:lucidabrightot-demi.otf:+liga;+kern;+tlig;+trep at 10pt - \font\tenbi = file:lucidabrightot-demiitalic.otf:+liga;+kern;+tlig;+trep at 10pt + \font\tentt = file:lucidasanstypewriterot.otf at 10pt + \font\tensl = file:lucidabrightot.otf:slant=0.167;+liga;+kern;+tlig;+trep at 10pt + \font\tenit = file:lucidabrightot-italic.otf:+liga;+kern;+tlig;+trep at 10pt + \font\tenbf = file:lucidabrightot-demi.otf:+liga;+kern;+tlig;+trep at 10pt + \font\tenbi = file:lucidabrightot-demiitalic.otf:+liga;+kern;+tlig;+trep at 10pt % - \font\mathfonttextupright = file:lucidabrightmathot.otf:ssty=0;fixmath=yes at 10pt - \font\mathfontscriptupright = file:lucidabrightmathot.otf:ssty=1;fixmath=yes at 7pt - \font\mathfontscriptscriptupright = file:lucidabrightmathot.otf:ssty=2;fixmath=yes at 5pt + \font\tenos = file:lucidabrightot.otf:+onum;+liga;+kern;+tlig;+trep at 10pt + \font\sevenos = file:lucidabrightot.otf:+onum;+liga;+kern;+tlig;+trep at 7pt + \font\fiveos = file:lucidabrightot.otf:+onum;+liga;+kern;+tlig;+trep at 5pt + % + \font\mathfonttextupright = file:lucidabrightmathot.otf:script=math;ssty=0;mathsize=yes at 10pt + \font\mathfontscriptupright = file:lucidabrightmathot.otf:script=math;ssty=1;mathsize=yes at 7pt + \font\mathfontscriptscriptupright = file:lucidabrightmathot.otf:script=math;ssty=2;mathsize=yes at 5pt % \textfont 0 = \mathfonttextupright \scriptfont 0 = \mathfontscriptupright \scriptscriptfont 0 = \mathfontscriptscriptupright % + \textfont 1 = \tenos + \scriptfont 1 = \sevenos + \scriptscriptfont 1 = \fiveos + % \tenrm} -\directlua { - if arguments["mtx:lucidabright"] then - tex.print("\string\\lucidabright") - else - tex.print("\string\\latinmodern") - end -} +\ifdefined\directlua + \directlua { + if arguments["mtx:lucidabright"] then + tex.print("\string\\lucidabright") + else + tex.print("\string\\latinmodern") + end + } +\fi \newtoks\everymathrm -\newtoks\everymathmit \newtoks\everymathcal \newtoks\everymathit \newtoks\everymathsl @@ -88,6 +110,8 @@ \newtoks\everymathbi \newtoks\everymathtt +% the following commands switch text as well as math + \def\rm{\fam0\relax\the\everymathrm\relax\tenrm\relax} \def\it{\fam0\relax\the\everymathit\relax\tenit\relax} \def\sl{\fam0\relax\the\everymathsl\relax\tensl\relax} @@ -95,13 +119,10 @@ \def\bi{\fam0\relax\the\everymathbi\relax\tenbi\relax} \def\tt{\fam0\relax\the\everymathtt\relax\tentt\relax} -\let\mit \relax % use names or \Uchar or define a vector -\let\cal \relax % idem, i'm not in the mood for this now -\let\oldstyle\relax % no longer misuse of math mode - % tex is fast enough for this kind of assignments: \everymathrm {% + % codes \Umathcode"0041="0"0"0041% \Umathcode"0042="0"0"0042% \Umathcode"0043="0"0"0043% @@ -212,18 +233,69 @@ \Umathcode"03F5="0"0"03F5% \Umathcode"2202="0"0"2202% \Umathcode"2207="0"0"2207% + % commands + \Umathchardef\Alpha "0"0"000391% + \Umathchardef\Beta "0"0"000392% + \Umathchardef\Gamma "0"0"000393% + \Umathchardef\Delta "0"0"000394% + \Umathchardef\Epsilon "0"0"000395% + \Umathchardef\Zeta "0"0"000396% + \Umathchardef\Eta "0"0"000397% + \Umathchardef\Theta "0"0"000398% + \Umathchardef\Iota "0"0"000399% + \Umathchardef\Kappa "0"0"00039A% + \Umathchardef\Lambda "0"0"00039B% + \Umathchardef\Mu "0"0"00039C% + \Umathchardef\Nu "0"0"00039D% + \Umathchardef\Xi "0"0"00039E% + \Umathchardef\Omicron "0"0"00039F% + \Umathchardef\Pi "0"0"0003A0% + \Umathchardef\Rho "0"0"0003A1% + \Umathchardef\Sigma "0"0"0003A3% + \Umathchardef\Tau "0"0"0003A4% + \Umathchardef\Upsilon "0"0"0003A5% + \Umathchardef\Phi "0"0"0003A6% + \Umathchardef\Chi "0"0"0003A7% + \Umathchardef\Psi "0"0"0003A8% + \Umathchardef\Omega "0"0"0003A9% + \Umathchardef\alpha "0"0"0003B1% + \Umathchardef\beta "0"0"0003B2% + \Umathchardef\gamma "0"0"0003B3% + \Umathchardef\delta "0"0"0003B4% + \Umathchardef\varepsilon"0"0"0003B5% + \Umathchardef\zeta "0"0"0003B6% + \Umathchardef\eta "0"0"0003B7% + \Umathchardef\theta "0"0"0003B8% + \Umathchardef\iota "0"0"0003B9% + \Umathchardef\kappa "0"0"0003BA% + \Umathchardef\lambda "0"0"0003BB% + \Umathchardef\mu "0"0"0003BC% + \Umathchardef\nu "0"0"0003BD% + \Umathchardef\xi "0"0"0003BE% + \Umathchardef\omicron "0"0"0003BF% + \Umathchardef\pi "0"0"0003C0% + \Umathchardef\rho "0"0"0003C1% + \Umathchardef\varsigma "0"0"0003C2% + \Umathchardef\sigma "0"0"0003C3% + \Umathchardef\tau "0"0"0003C4% + \Umathchardef\upsilon "0"0"0003C5% + \Umathchardef\varphi "0"0"0003C6% + \Umathchardef\chi "0"0"0003C7% + \Umathchardef\psi "0"0"0003C8% + \Umathchardef\omega "0"0"0003C9% + \Umathchardef\vartheta "0"0"0003D1% + \Umathchardef\phi "0"0"0003D5% + \Umathchardef\varpi "0"0"0003D6% + \Umathchardef\varkappa "0"0"0003F0% + \Umathchardef\varrho "0"0"0003F1% + \Umathchardef\epsilon "0"0"0003F5% + \Umathchardef\varTheta "0"0"0003F4% + \Umathchardef\digamma "0"0"0003DC% \relax } -\everymathmit {% - % not done -} - -\everymathcal {% - % not done -} - \everymathit {% + % codes \Umathcode"0041="0"0"1D434% \Umathcode"0042="0"0"1D435% \Umathcode"0043="0"0"1D436% @@ -334,6 +406,64 @@ \Umathcode"03F5="0"0"1D716% \Umathcode"2202="0"0"1D715% \Umathcode"2207="0"0"1D6FB% + % commands + \Umathchardef\Alpha "0"0"01D6E2% + \Umathchardef\Beta "0"0"01D6E3% + \Umathchardef\Gamma "0"0"01D6E4% + \Umathchardef\Delta "0"0"01D6E5% + \Umathchardef\Epsilon "0"0"01D6E6% + \Umathchardef\Zeta "0"0"01D6E7% + \Umathchardef\Eta "0"0"01D6E8% + \Umathchardef\Theta "0"0"01D6E9% + \Umathchardef\Iota "0"0"01D6EA% + \Umathchardef\Kappa "0"0"01D6EB% + \Umathchardef\Lambda "0"0"01D6EC% + \Umathchardef\Mu "0"0"01D6ED% + \Umathchardef\Nu "0"0"01D6EE% + \Umathchardef\Xi "0"0"01D6EF% + \Umathchardef\Omicron "0"0"01D6F0% + \Umathchardef\Pi "0"0"01D6F1% + \Umathchardef\Rho "0"0"01D6F2% + \Umathchardef\Sigma "0"0"01D6F4% + \Umathchardef\Tau "0"0"01D6F5% + \Umathchardef\Upsilon "0"0"01D6F6% + \Umathchardef\Phi "0"0"01D6F7% + \Umathchardef\Chi "0"0"01D6F8% + \Umathchardef\Psi "0"0"01D6F9% + \Umathchardef\Omega "0"0"01D6FA% + \Umathchardef\alpha "0"0"01D6FC% + \Umathchardef\beta "0"0"01D6FD% + \Umathchardef\gamma "0"0"01D6FE% + \Umathchardef\delta "0"0"01D6FF% + \Umathchardef\varepsilon"0"0"01D700% + \Umathchardef\zeta "0"0"01D701% + \Umathchardef\eta "0"0"01D702% + \Umathchardef\theta "0"0"01D703% + \Umathchardef\iota "0"0"01D704% + \Umathchardef\kappa "0"0"01D705% + \Umathchardef\lambda "0"0"01D706% + \Umathchardef\mu "0"0"01D707% + \Umathchardef\nu "0"0"01D708% + \Umathchardef\xi "0"0"01D709% + \Umathchardef\omicron "0"0"01D70A% + \Umathchardef\pi "0"0"01D70B% + \Umathchardef\rho "0"0"01D70C% + \Umathchardef\varsigma "0"0"01D70D% + \Umathchardef\sigma "0"0"01D70E% + \Umathchardef\tau "0"0"01D70F% + \Umathchardef\upsilon "0"0"01D710% + \Umathchardef\varphi "0"0"01D711% + \Umathchardef\chi "0"0"01D712% + \Umathchardef\psi "0"0"01D713% + \Umathchardef\omega "0"0"01D714% + \Umathchardef\epsilon "0"0"01D716% + \Umathchardef\vartheta "0"0"01D717% + \Umathchardef\varkappa "0"0"01D718% + \Umathchardef\phi "0"0"01D719% + \Umathchardef\varrho "0"0"01D71A% + \Umathchardef\varpi "0"0"01D71B% + \Umathchardef\varTheta "0"0"01D6F3% + \Umathchardef\digamma "0"0"0003DC% \relax } @@ -342,6 +472,7 @@ } \everymathbf {% + % codes \Umathcode"0030="0"0"1D7CE% \Umathcode"0031="0"0"1D7CF% \Umathcode"0032="0"0"1D7D0% @@ -462,10 +593,69 @@ \Umathcode"03F5="0"0"1D6DC% \Umathcode"2202="0"0"1D6DB% \Umathcode"2207="0"0"1D6C1% + % commands + \Umathchardef\Alpha "0"0"01D6A8% + \Umathchardef\Beta "0"0"01D6A9% + \Umathchardef\Gamma "0"0"01D6AA% + \Umathchardef\Delta "0"0"01D6AB% + \Umathchardef\Epsilon "0"0"01D6AC% + \Umathchardef\Zeta "0"0"01D6AD% + \Umathchardef\Eta "0"0"01D6AE% + \Umathchardef\Theta "0"0"01D6AF% + \Umathchardef\Iota "0"0"01D6B0% + \Umathchardef\Kappa "0"0"01D6B1% + \Umathchardef\Lambda "0"0"01D6B2% + \Umathchardef\Mu "0"0"01D6B3% + \Umathchardef\Nu "0"0"01D6B4% + \Umathchardef\Xi "0"0"01D6B5% + \Umathchardef\Omicron "0"0"01D6B6% + \Umathchardef\Pi "0"0"01D6B7% + \Umathchardef\Rho "0"0"01D6B8% + \Umathchardef\Sigma "0"0"01D6BA% + \Umathchardef\Tau "0"0"01D6BB% + \Umathchardef\Upsilon "0"0"01D6BC% + \Umathchardef\Phi "0"0"01D6BD% + \Umathchardef\Chi "0"0"01D6BE% + \Umathchardef\Psi "0"0"01D6BF% + \Umathchardef\Omega "0"0"01D6C0% + \Umathchardef\alpha "0"0"01D6C2% + \Umathchardef\beta "0"0"01D6C3% + \Umathchardef\gamma "0"0"01D6C4% + \Umathchardef\delta "0"0"01D6C5% + \Umathchardef\varepsilon"0"0"01D6C6% + \Umathchardef\zeta "0"0"01D6C7% + \Umathchardef\eta "0"0"01D6C8% + \Umathchardef\theta "0"0"01D6C9% + \Umathchardef\iota "0"0"01D6CA% + \Umathchardef\kappa "0"0"01D6CB% + \Umathchardef\lambda "0"0"01D6CC% + \Umathchardef\mu "0"0"01D6CD% + \Umathchardef\nu "0"0"01D6CE% + \Umathchardef\xi "0"0"01D6CF% + \Umathchardef\omicron "0"0"01D6D0% + \Umathchardef\pi "0"0"01D6D1% + \Umathchardef\rho "0"0"01D6D2% + \Umathchardef\varsigma "0"0"01D6D3% + \Umathchardef\sigma "0"0"01D6D4% + \Umathchardef\tau "0"0"01D6D5% + \Umathchardef\upsilon "0"0"01D6D6% + \Umathchardef\varphi "0"0"01D6D7% + \Umathchardef\chi "0"0"01D6D8% + \Umathchardef\psi "0"0"01D6D9% + \Umathchardef\omega "0"0"01D6DA% + \Umathchardef\epsilon "0"0"01D6DC% + \Umathchardef\vartheta "0"0"01D6DD% + \Umathchardef\varkappa "0"0"01D6DE% + \Umathchardef\phi "0"0"01D6DF% + \Umathchardef\varrho "0"0"01D6E0% + \Umathchardef\varpi "0"0"01D6E1% + \Umathchardef\varTheta "0"0"01D6B9% + \Umathchardef\digamma "0"0"01D7CA% \relax } \everymathbi {% + % codes \Umathcode"0030="0"0"1D7CE% \Umathcode"0031="0"0"1D7CF% \Umathcode"0032="0"0"1D7D0% @@ -586,6 +776,64 @@ \Umathcode"03F5="0"0"1D750% \Umathcode"2202="0"0"1D74F% \Umathcode"2207="0"0"1D735% + % commands + \Umathchardef\Alpha "0"0"01D71C% + \Umathchardef\Beta "0"0"01D71D% + \Umathchardef\Gamma "0"0"01D71E% + \Umathchardef\Delta "0"0"01D71F% + \Umathchardef\Epsilon "0"0"01D720% + \Umathchardef\Zeta "0"0"01D721% + \Umathchardef\Eta "0"0"01D722% + \Umathchardef\Theta "0"0"01D723% + \Umathchardef\Iota "0"0"01D724% + \Umathchardef\Kappa "0"0"01D725% + \Umathchardef\Lambda "0"0"01D726% + \Umathchardef\Mu "0"0"01D727% + \Umathchardef\Nu "0"0"01D728% + \Umathchardef\Xi "0"0"01D729% + \Umathchardef\Omicron "0"0"01D72A% + \Umathchardef\Pi "0"0"01D72B% + \Umathchardef\Rho "0"0"01D72C% + \Umathchardef\Sigma "0"0"01D72E% + \Umathchardef\Tau "0"0"01D72F% + \Umathchardef\Upsilon "0"0"01D730% + \Umathchardef\Phi "0"0"01D731% + \Umathchardef\Chi "0"0"01D732% + \Umathchardef\Psi "0"0"01D733% + \Umathchardef\Omega "0"0"01D734% + \Umathchardef\alpha "0"0"01D736% + \Umathchardef\beta "0"0"01D737% + \Umathchardef\gamma "0"0"01D738% + \Umathchardef\delta "0"0"01D739% + \Umathchardef\varepsilon"0"0"01D73A% + \Umathchardef\zeta "0"0"01D73B% + \Umathchardef\eta "0"0"01D73C% + \Umathchardef\theta "0"0"01D73D% + \Umathchardef\iota "0"0"01D73E% + \Umathchardef\kappa "0"0"01D73F% + \Umathchardef\lambda "0"0"01D740% + \Umathchardef\mu "0"0"01D741% + \Umathchardef\nu "0"0"01D742% + \Umathchardef\xi "0"0"01D743% + \Umathchardef\omicron "0"0"01D744% + \Umathchardef\pi "0"0"01D745% + \Umathchardef\rho "0"0"01D746% + \Umathchardef\varsigma "0"0"01D747% + \Umathchardef\sigma "0"0"01D748% + \Umathchardef\tau "0"0"01D749% + \Umathchardef\upsilon "0"0"01D74A% + \Umathchardef\varphi "0"0"01D74B% + \Umathchardef\chi "0"0"01D74C% + \Umathchardef\psi "0"0"01D74D% + \Umathchardef\omega "0"0"01D74E% + \Umathchardef\epsilon "0"0"01D750% + \Umathchardef\vartheta "0"0"01D751% + \Umathchardef\varkappa "0"0"01D752% + \Umathchardef\phi "0"0"01D753% + \Umathchardef\varrho "0"0"01D754% + \Umathchardef\varpi "0"0"01D755% + \Umathchardef\varTheta "0"0"01D72D% + \Umathchardef\digamma "0"0"01D7CA% \relax } @@ -593,6 +841,75 @@ % not done } +% Nothing special here: + +\let\mit\it + +% We use a special family for this, not that oldstyle in math makes +% much sense, it's more that in good old tex oldstyle was taken from +% math fonts. So, just something compatible: + +\def\oldstyle{\fam1\relax\tenos\relax} + +% Again a text and math one and it had better be used grouped. + +\def\cal{\fam0\relax\the\everymathcal\relax\tenit\relax} + +\everymathcal {% + \Umathcode"0041="0"0"1D49C% A + \Umathcode"0042="0"0"0212C% B + \Umathcode"0043="0"0"1D49E% C + \Umathcode"0044="0"0"1D49F% D + \Umathcode"0045="0"0"02130% E + \Umathcode"0046="0"0"02131% F + \Umathcode"0047="0"0"1D4A2% G + \Umathcode"0048="0"0"0210B% H + \Umathcode"0049="0"0"02110% I + \Umathcode"004A="0"0"1D4A5% J + \Umathcode"004B="0"0"1D4A6% K + \Umathcode"004C="0"0"02112% L + \Umathcode"004D="0"0"02133% M + \Umathcode"004E="0"0"1D4A9% N + \Umathcode"004F="0"0"1D4AA% O + \Umathcode"0050="0"0"1D4AB% P + \Umathcode"0051="0"0"1D4AC% Q + \Umathcode"0052="0"0"0211B% R + \Umathcode"0053="0"0"1D4AE% S + \Umathcode"0054="0"0"1D4AF% T + \Umathcode"0055="0"0"1D4B0% U + \Umathcode"0056="0"0"1D4B1% V + \Umathcode"0057="0"0"1D4B2% W + \Umathcode"0058="0"0"1D4B3% X + \Umathcode"0059="0"0"1D4B4% Y + \Umathcode"005A="0"0"1D4B5% Z + \Umathcode"0061="0"0"1D4B6% a + \Umathcode"0062="0"0"1D4B7% b + \Umathcode"0063="0"0"1D4B8% c + \Umathcode"0064="0"0"1D4B9% d + \Umathcode"0065="0"0"0212F% e + \Umathcode"0066="0"0"1D4BB% f + \Umathcode"0067="0"0"0210A% g + \Umathcode"0068="0"0"1D4BD% h + \Umathcode"0069="0"0"1D4BE% i + \Umathcode"006A="0"0"1D4BF% j + \Umathcode"006B="0"0"1D4C0% k + \Umathcode"006C="0"0"1D4C1% l + \Umathcode"006D="0"0"1D4C2% m + \Umathcode"006E="0"0"1D4C3% n + \Umathcode"006F="0"0"02134% o + \Umathcode"0070="0"0"1D4C5% p + \Umathcode"0071="0"0"1D4C6% q + \Umathcode"0072="0"0"1D4C7% r + \Umathcode"0073="0"0"1D4C8% s + \Umathcode"0074="0"0"1D4C9% t + \Umathcode"0075="0"0"1D4CA% u + \Umathcode"0076="0"0"1D4CB% v + \Umathcode"0077="0"0"1D4CC% w + \Umathcode"0078="0"0"1D4CD% x + \Umathcode"0079="0"0"1D4CE% y + \Umathcode"007A="0"0"1D4CF% z +} + \Udelcode "00021 = "0 "00021 \Udelcode "00028 = "0 "00028 \Udelcode "00028 = "0 "00028 @@ -1827,6 +2144,44 @@ \def\Zeta {\Umathchar "0"0"000396 } \def\zeta {\Umathchar "0"0"0003B6 } +%D The following are suggested by Bruno. As I don't use plain and as the above are +%D taken from text unicode greek I suppose his list is better: + +\def\alpha {\Umathchar "0"0"01D6FC } +\def\beta {\Umathchar "0"0"01D6FD } +\def\chi {\Umathchar "0"0"01D712 } +\def\delta {\Umathchar "0"0"01D6FF } +\def\digamma {\Umathchar "0"0"0003DC } +\def\epsilon {\Umathchar "0"0"01D716 } +\def\eta {\Umathchar "0"0"01D702 } +\def\gamma {\Umathchar "0"0"01D6FE } +\def\iota {\Umathchar "0"0"01D704 } +\def\kappa {\Umathchar "0"0"01D705 } +\def\lambda {\Umathchar "0"0"01D706 } +\def\mu {\Umathchar "0"0"01D707 } +\def\nu {\Umathchar "0"0"01D708 } +\def\omega {\Umathchar "0"0"01D714 } +\def\omicron {\Umathchar "0"0"01D70A } +\def\phi {\Umathchar "0"0"01D719 } +\def\pi {\Umathchar "0"0"01D70B } +\def\psi {\Umathchar "0"0"01D713 } +\def\rho {\Umathchar "0"0"01D70C } +\def\sigma {\Umathchar "0"0"01D70E } +\def\tau {\Umathchar "0"0"01D70F } +\def\theta {\Umathchar "0"0"01D703 } +\def\upsilon {\Umathchar "0"0"01D710 } +\def\varepsilon {\Umathchar "0"0"01D700 } +\def\varkappa {\Umathchar "0"0"01D718 } +\def\varphi {\Umathchar "0"0"01D711 } +\def\varpi {\Umathchar "0"0"01D71B } +\def\varrho {\Umathchar "0"0"01D71A } +\def\varsigma {\Umathchar "0"0"01D70D } +\def\vartheta {\Umathchar "0"0"01D717 } +\def\xi {\Umathchar "0"0"01D709 } +\def\zeta {\Umathchar "0"0"01D701 } + +\def\varTheta {\Umathchar "0"0"0003F4 } + % a few definitions: \def\sqrt {\Uroot "0 "221A{}} @@ -1849,26 +2204,52 @@ \let\OE Œ \let\O Ø \let\i ı +\let\j ȷ \let\aa å \let\l ł \let\L Ł \let\AA Å \let\copyright © +\let\S § +\let\P ¶ +\let\dag † +\let\ddag ‡ +\let\pounds £ % just use utf -\def\`#1{\string\`\string{#1\string}} -\def\'#1{\string\'\string{#1\string}} -\def\v#1{\string\v\string{#1\string}} -\def\u#1{\string\u\string{#1\string}} -\def\=#1{\string\=\string{#1\string}} -\def\^#1{\string\^\string{#1\string}} -\def\.#1{\string\.\string{#1\string}} -\def\H#1{\string\H\string{#1\string}} -\def\~#1{\string\~\string{#1\string}} -\def\"#1{\string\"\string{#1\string}} -\def\d#1{\string\d\string{#1\string}} -\def\b#1{\string\b\string{#1\string}} -\def\c#1{\string\c\string{#1\string}} +\def\`#1{#1^^^^0300} +\def\'#1{#1^^^^0301} +\def\^#1{#1^^^^0302} +\def\~#1{#1^^^^0303} +\def\=#1{#1^^^^0304} +\def\u#1{#1^^^^0306} +\def\.#1{#1^^^^0307} +\def\"#1{#1^^^^0308} +\def\r#1{#1^^^^030a} % not in plain +\def\H#1{#1^^^^030b} +\def\v#1{#1^^^^030c} +\def\d#1{#1^^^^0323} +\def\c#1{#1^^^^0327} +\def\k#1{#1^^^^0328} % not in plain +\def\b#1{#1^^^^0331} + +% for Bruno, when he tests this file with xetex: + +\ifdefined\directlua \else + + \catcode`@=11 + + \def\sqrt{\Uradical "0 "221A } + + \def\root#1\of + {\setbox\rootbox\hbox\bgroup + $\m@th\scriptscriptstyle{#1}$% + \egroup}% + \mathpalette\r@@t} + + \catcode`@=12 + +\fi \endinput diff --git a/tex/generic/context/luatex/luatex-mplib.lua b/tex/generic/context/luatex/luatex-mplib.lua index fd6eb975c..976bb59f9 100644 --- a/tex/generic/context/luatex/luatex-mplib.lua +++ b/tex/generic/context/luatex/luatex-mplib.lua @@ -352,7 +352,7 @@ else return not (sx==1 and rx==0 and ry==0 and sy==1 and tx==0 and ty==0), t.width end - local function concat(px, py) -- no tx, ty here + local function concatinated(px, py) -- no tx, ty here return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider end @@ -401,29 +401,29 @@ else for i=1,#path do pth = path[i] if not ith then - pdf_literalcode("%f %f m",concat(pth.x_coord,pth.y_coord)) + pdf_literalcode("%f %f m",concatinated(pth.x_coord,pth.y_coord)) elseif curved(ith,pth) then - local a, b = concat(ith.right_x,ith.right_y) - local c, d = concat(pth.left_x,pth.left_y) - pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(pth.x_coord, pth.y_coord)) + local a, b = concatinated(ith.right_x,ith.right_y) + local c, d = concatinated(pth.left_x,pth.left_y) + pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concatinated(pth.x_coord, pth.y_coord)) else - pdf_literalcode("%f %f l",concat(pth.x_coord, pth.y_coord)) + pdf_literalcode("%f %f l",concatinated(pth.x_coord, pth.y_coord)) end ith = pth end if not open then local one = path[1] if curved(pth,one) then - local a, b = concat(pth.right_x,pth.right_y) - local c, d = concat(one.left_x,one.left_y) - pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(one.x_coord, one.y_coord)) + local a, b = concatinated(pth.right_x,pth.right_y) + local c, d = concatinated(one.left_x,one.left_y) + pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concatinated(one.x_coord, one.y_coord)) else - pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord)) + pdf_literalcode("%f %f l",concatinated(one.x_coord,one.y_coord)) end elseif #path == 1 then -- special case .. draw point local one = path[1] - pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord)) + pdf_literalcode("%f %f l",concatinated(one.x_coord,one.y_coord)) end return t end diff --git a/tex/generic/context/luatex/luatex-pdf.tex b/tex/generic/context/luatex/luatex-pdf.tex index 81eb872ab..57004c6f8 100644 --- a/tex/generic/context/luatex/luatex-pdf.tex +++ b/tex/generic/context/luatex/luatex-pdf.tex @@ -168,7 +168,7 @@ \global\pdfobjcompresslevel 1 \global\pdfdecimaldigits 4 \global\pdfgamma 1000 - \global\pdfimageresolution 71 + \global\pdfimageresolution 72 \global\pdfimageapplygamma 0 \global\pdfimagegamma 2200 \global\pdfimagehicolor 1 diff --git a/tex/generic/context/luatex/luatex-plain.tex b/tex/generic/context/luatex/luatex-plain.tex index 99347ed2c..0a806c76f 100644 --- a/tex/generic/context/luatex/luatex-plain.tex +++ b/tex/generic/context/luatex/luatex-plain.tex @@ -17,7 +17,9 @@ \input luatex-pdf \relax \fi -\pdfoutput 1 +\outputmode 1 + +% \outputmode 0 \magnification\magstep5 % We set the page dimensions because otherwise the backend does weird things % when we have for instance this on a line of its own: @@ -31,8 +33,8 @@ % has to deal with the lack of a page concept on tex by some guessing. Normally % a macro package will set the dimensions to something reasonable anyway. -\pagewidth 8.5in -\pageheight 11.0in +\pagewidth 8.5truein +\pageheight 11.0truein % We load some code at runtime: diff --git a/tex/generic/context/luatex/luatex-swiglib-test.lua b/tex/generic/context/luatex/luatex-swiglib-test.lua index db6a72909..00d7c5a4e 100644 --- a/tex/generic/context/luatex/luatex-swiglib-test.lua +++ b/tex/generic/context/luatex/luatex-swiglib-test.lua @@ -1,25 +1,743 @@ -local gm = swiglib("gmwand.core") -gm.InitializeMagick(".") -local magick_wand = gm.NewMagickWand() -local drawing_wand = gm.NewDrawingWand() +-- local gm = require("swiglib.gmwand.core") -- local gm = swiglib("gmwand.core") +-- +-- gm.InitializeMagick(".") +-- +-- local magick_wand = gm.NewMagickWand() +-- local drawing_wand = gm.NewDrawingWand() +-- +-- gm.MagickSetSize(magick_wand,800,600) +-- gm.MagickReadImage(magick_wand,"xc:red") +-- +-- gm.DrawPushGraphicContext(drawing_wand) +-- +-- gm.DrawSetFillColor(drawing_wand,gm.NewPixelWand()) +-- +-- -- gm.DrawSetFont(drawing_wand, kpse.findfile("DejaVuSerifBold.ttf")) +-- -- gm.DrawSetFontSize(drawing_wand, 96) +-- -- gm.DrawAnnotation(drawing_wand,300,200, "LuaTeX") +-- +-- gm.DrawPopGraphicContext(drawing_wand) +-- gm.MagickDrawImage(magick_wand,drawing_wand) +-- +-- gm.MagickWriteImages(magick_wand,"./luatex-swiglib-test.jpg",1) +-- +-- gm.DestroyDrawingWand(drawing_wand) +-- gm.DestroyMagickWand(magick_wand) -gm.MagickSetSize(magick_wand,800,600) -gm.MagickReadImage(magick_wand,"xc:red") +local swighelpers = require("swiglib.helpers.core") +local sqlite = require("swiglib.sqlite.core") -gm.DrawPushGraphicContext(drawing_wand) +-- s.sqlite3_create_function_v2_lua_callback(function() end) -gm.DrawSetFillColor(drawing_wand,gm.NewPixelWand()) --- gm.DrawSetFont(drawing_wand, kpse.findfile("DejaVuSerifBold.ttf")) --- gm.DrawSetFontSize(drawing_wand, 96) --- gm.DrawAnnotation(drawing_wand,300,200, "LuaTeX") +local t = [[ + CREATE TABLE IF NOT EXISTS loggers ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `time` int(11) NOT NULL, + `type` int(11) NOT NULL, + `action` varchar(15) NOT NULL, + `data` longtext, + PRIMARY KEY (`id`), + UNIQUE KEY `id_unique_key` (`id`) + ) + DEFAULT CHARSET = utf8 ; +]] -gm.DrawPopGraphicContext(drawing_wand) -gm.MagickDrawImage(magick_wand,drawing_wand) +local t = [[ +CREATE TABLE IF NOT EXISTS loggers ( + `id` INTEGER PRIMARY KEY AUTOINCREMENT, + `time` int(11) NOT NULL, + `type` int(11) NOT NULL, + `action` varchar(15) NOT NULL, + `data` longtext + ); +]] -gm.MagickWriteImages(magick_wand,"./luatex-swiglib-test.jpg",1) +local function execute(name,query) + local db = sqlite.new_sqlite3_p_array(1) + local okay = sqlite.sqlite3_open(name,db) + local dbh = sqlite.sqlite3_p_array_getitem(db,0) + if okay ~= sqlite.SQLITE_OK then + return false, sqlite.sqlite3_errmsg(dbh) + end + local result = { } + local callback = function(data,nofcolumns,values,fields) + local r = { } + for i=0,nofcolumns-1 do + local field = sqlite.char_p_array_getitem(fields,i) + local value = sqlite.char_p_array_getitem(values,i) + r[field] = value + end + result[#result+1] = r + return sqlite.SQLITE_OK + end + local data = nil + local message = nil + local okay = sqlite.sqlite3_exec_lua_callback(dbh,query,callback,data,message) + if okay ~= sqlite.SQLITE_OK then + return false, sqlite.sqlite3_errmsg(dbh) + end + sqlite.sqlite3_close(dbh) + sqlite.delete_sqlite3_p_array(db) + return result +end -gm.DestroyDrawingWand(drawing_wand) -gm.DestroyMagickWand(magick_wand) +execute("foo.db",t) +-- execute("test.db",t) + +local template =[[ + INSERT INTO loggers ( + `time`, + `type`, + `action`, + `data` + ) VALUES ( + %s, + %s, + '%s', + '%s' + ) ; +]] + +-- for i=1,100 do +-- local t = string.format(template,os.time(),1,"oeps " .. i,"more") +-- execute("foo.db",t) +-- end + + +local r = execute("foo.db","select * from loggers;") +inspect(r) + + +-- inspect(table.sortedkeys(sqlite)) +-- inspect(table.sortedkeys(swighelpers)) + + + +t={ + "FULLY_WITHIN", + "NOT_WITHIN", + "PARTLY_WITHIN", + "SQLITE3_TEXT", + "SQLITE_ABORT", + "SQLITE_ABORT_ROLLBACK", + "SQLITE_ACCESS_EXISTS", + "SQLITE_ACCESS_READ", + "SQLITE_ACCESS_READWRITE", + "SQLITE_ALTER_TABLE", + "SQLITE_ANALYZE", + "SQLITE_ANY", + "SQLITE_ATTACH", + "SQLITE_AUTH", + "SQLITE_AUTH_USER", + "SQLITE_BLOB", + "SQLITE_BUSY", + "SQLITE_BUSY_RECOVERY", + "SQLITE_BUSY_SNAPSHOT", + "SQLITE_CANTOPEN", + "SQLITE_CANTOPEN_CONVPATH", + "SQLITE_CANTOPEN_FULLPATH", + "SQLITE_CANTOPEN_ISDIR", + "SQLITE_CANTOPEN_NOTEMPDIR", + "SQLITE_CHECKPOINT_FULL", + "SQLITE_CHECKPOINT_PASSIVE", + "SQLITE_CHECKPOINT_RESTART", + "SQLITE_CONFIG_COVERING_INDEX_SCAN", + "SQLITE_CONFIG_GETMALLOC", + "SQLITE_CONFIG_GETMUTEX", + "SQLITE_CONFIG_GETPCACHE", + "SQLITE_CONFIG_GETPCACHE2", + "SQLITE_CONFIG_HEAP", + "SQLITE_CONFIG_LOG", + "SQLITE_CONFIG_LOOKASIDE", + "SQLITE_CONFIG_MALLOC", + "SQLITE_CONFIG_MEMSTATUS", + "SQLITE_CONFIG_MMAP_SIZE", + "SQLITE_CONFIG_MULTITHREAD", + "SQLITE_CONFIG_MUTEX", + "SQLITE_CONFIG_PAGECACHE", + "SQLITE_CONFIG_PCACHE", + "SQLITE_CONFIG_PCACHE2", + "SQLITE_CONFIG_SCRATCH", + "SQLITE_CONFIG_SERIALIZED", + "SQLITE_CONFIG_SINGLETHREAD", + "SQLITE_CONFIG_SQLLOG", + "SQLITE_CONFIG_URI", + "SQLITE_CONFIG_WIN32_HEAPSIZE", + "SQLITE_CONSTRAINT", + "SQLITE_CONSTRAINT_CHECK", + "SQLITE_CONSTRAINT_COMMITHOOK", + "SQLITE_CONSTRAINT_FOREIGNKEY", + "SQLITE_CONSTRAINT_FUNCTION", + "SQLITE_CONSTRAINT_NOTNULL", + "SQLITE_CONSTRAINT_PRIMARYKEY", + "SQLITE_CONSTRAINT_ROWID", + "SQLITE_CONSTRAINT_TRIGGER", + "SQLITE_CONSTRAINT_UNIQUE", + "SQLITE_CONSTRAINT_VTAB", + "SQLITE_COPY", + "SQLITE_CORRUPT", + "SQLITE_CORRUPT_VTAB", + "SQLITE_CREATE_INDEX", + "SQLITE_CREATE_TABLE", + "SQLITE_CREATE_TEMP_INDEX", + "SQLITE_CREATE_TEMP_TABLE", + "SQLITE_CREATE_TEMP_TRIGGER", + "SQLITE_CREATE_TEMP_VIEW", + "SQLITE_CREATE_TRIGGER", + "SQLITE_CREATE_VIEW", + "SQLITE_CREATE_VTABLE", + "SQLITE_DBCONFIG_ENABLE_FKEY", + "SQLITE_DBCONFIG_ENABLE_TRIGGER", + "SQLITE_DBCONFIG_LOOKASIDE", + "SQLITE_DBSTATUS_CACHE_HIT", + "SQLITE_DBSTATUS_CACHE_MISS", + "SQLITE_DBSTATUS_CACHE_USED", + "SQLITE_DBSTATUS_CACHE_WRITE", + "SQLITE_DBSTATUS_DEFERRED_FKS", + "SQLITE_DBSTATUS_LOOKASIDE_HIT", + "SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL", + "SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE", + "SQLITE_DBSTATUS_LOOKASIDE_USED", + "SQLITE_DBSTATUS_MAX", + "SQLITE_DBSTATUS_SCHEMA_USED", + "SQLITE_DBSTATUS_STMT_USED", + "SQLITE_DELETE", + "SQLITE_DENY", + "SQLITE_DETACH", + "SQLITE_DETERMINISTIC", + "SQLITE_DONE", + "SQLITE_DROP_INDEX", + "SQLITE_DROP_TABLE", + "SQLITE_DROP_TEMP_INDEX", + "SQLITE_DROP_TEMP_TABLE", + "SQLITE_DROP_TEMP_TRIGGER", + "SQLITE_DROP_TEMP_VIEW", + "SQLITE_DROP_TRIGGER", + "SQLITE_DROP_VIEW", + "SQLITE_DROP_VTABLE", + "SQLITE_EMPTY", + "SQLITE_ERROR", + "SQLITE_FAIL", + "SQLITE_FCNTL_BUSYHANDLER", + "SQLITE_FCNTL_CHUNK_SIZE", + "SQLITE_FCNTL_COMMIT_PHASETWO", + "SQLITE_FCNTL_FILE_POINTER", + "SQLITE_FCNTL_HAS_MOVED", + "SQLITE_FCNTL_LOCKSTATE", + "SQLITE_FCNTL_MMAP_SIZE", + "SQLITE_FCNTL_OVERWRITE", + "SQLITE_FCNTL_PERSIST_WAL", + "SQLITE_FCNTL_POWERSAFE_OVERWRITE", + "SQLITE_FCNTL_PRAGMA", + "SQLITE_FCNTL_SIZE_HINT", + "SQLITE_FCNTL_SYNC", + "SQLITE_FCNTL_SYNC_OMITTED", + "SQLITE_FCNTL_TEMPFILENAME", + "SQLITE_FCNTL_TRACE", + "SQLITE_FCNTL_VFSNAME", + "SQLITE_FCNTL_WIN32_AV_RETRY", + "SQLITE_FCNTL_WIN32_SET_HANDLE", + "SQLITE_FLOAT", + "SQLITE_FORMAT", + "SQLITE_FULL", + "SQLITE_FUNCTION", + "SQLITE_GET_LOCKPROXYFILE", + "SQLITE_IGNORE", + "SQLITE_INDEX_CONSTRAINT_EQ", + "SQLITE_INDEX_CONSTRAINT_GE", + "SQLITE_INDEX_CONSTRAINT_GT", + "SQLITE_INDEX_CONSTRAINT_LE", + "SQLITE_INDEX_CONSTRAINT_LT", + "SQLITE_INDEX_CONSTRAINT_MATCH", + "SQLITE_INSERT", + "SQLITE_INTEGER", + "SQLITE_INTERNAL", + "SQLITE_INTERRUPT", + "SQLITE_IOCAP_ATOMIC", + "SQLITE_IOCAP_ATOMIC16K", + "SQLITE_IOCAP_ATOMIC1K", + "SQLITE_IOCAP_ATOMIC2K", + "SQLITE_IOCAP_ATOMIC32K", + "SQLITE_IOCAP_ATOMIC4K", + "SQLITE_IOCAP_ATOMIC512", + "SQLITE_IOCAP_ATOMIC64K", + "SQLITE_IOCAP_ATOMIC8K", + "SQLITE_IOCAP_IMMUTABLE", + "SQLITE_IOCAP_POWERSAFE_OVERWRITE", + "SQLITE_IOCAP_SAFE_APPEND", + "SQLITE_IOCAP_SEQUENTIAL", + "SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN", + "SQLITE_IOERR", + "SQLITE_IOERR_ACCESS", + "SQLITE_IOERR_BLOCKED", + "SQLITE_IOERR_CHECKRESERVEDLOCK", + "SQLITE_IOERR_CLOSE", + "SQLITE_IOERR_CONVPATH", + "SQLITE_IOERR_DELETE", + "SQLITE_IOERR_DELETE_NOENT", + "SQLITE_IOERR_DIR_CLOSE", + "SQLITE_IOERR_DIR_FSYNC", + "SQLITE_IOERR_FSTAT", + "SQLITE_IOERR_FSYNC", + "SQLITE_IOERR_GETTEMPPATH", + "SQLITE_IOERR_LOCK", + "SQLITE_IOERR_MMAP", + "SQLITE_IOERR_NOMEM", + "SQLITE_IOERR_RDLOCK", + "SQLITE_IOERR_READ", + "SQLITE_IOERR_SEEK", + "SQLITE_IOERR_SHMLOCK", + "SQLITE_IOERR_SHMMAP", + "SQLITE_IOERR_SHMOPEN", + "SQLITE_IOERR_SHMSIZE", + "SQLITE_IOERR_SHORT_READ", + "SQLITE_IOERR_TRUNCATE", + "SQLITE_IOERR_UNLOCK", + "SQLITE_IOERR_WRITE", + "SQLITE_LAST_ERRNO", + "SQLITE_LIMIT_ATTACHED", + "SQLITE_LIMIT_COLUMN", + "SQLITE_LIMIT_COMPOUND_SELECT", + "SQLITE_LIMIT_EXPR_DEPTH", + "SQLITE_LIMIT_FUNCTION_ARG", + "SQLITE_LIMIT_LENGTH", + "SQLITE_LIMIT_LIKE_PATTERN_LENGTH", + "SQLITE_LIMIT_SQL_LENGTH", + "SQLITE_LIMIT_TRIGGER_DEPTH", + "SQLITE_LIMIT_VARIABLE_NUMBER", + "SQLITE_LIMIT_VDBE_OP", + "SQLITE_LIMIT_WORKER_THREADS", + "SQLITE_LOCKED", + "SQLITE_LOCKED_SHAREDCACHE", + "SQLITE_LOCK_EXCLUSIVE", + "SQLITE_LOCK_NONE", + "SQLITE_LOCK_PENDING", + "SQLITE_LOCK_RESERVED", + "SQLITE_LOCK_SHARED", + "SQLITE_MISMATCH", + "SQLITE_MISUSE", + "SQLITE_MUTEX_FAST", + "SQLITE_MUTEX_RECURSIVE", + "SQLITE_MUTEX_STATIC_APP1", + "SQLITE_MUTEX_STATIC_APP2", + "SQLITE_MUTEX_STATIC_APP3", + "SQLITE_MUTEX_STATIC_LRU", + "SQLITE_MUTEX_STATIC_LRU2", + "SQLITE_MUTEX_STATIC_MASTER", + "SQLITE_MUTEX_STATIC_MEM", + "SQLITE_MUTEX_STATIC_MEM2", + "SQLITE_MUTEX_STATIC_OPEN", + "SQLITE_MUTEX_STATIC_PMEM", + "SQLITE_MUTEX_STATIC_PRNG", + "SQLITE_NOLFS", + "SQLITE_NOMEM", + "SQLITE_NOTADB", + "SQLITE_NOTFOUND", + "SQLITE_NOTICE", + "SQLITE_NOTICE_RECOVER_ROLLBACK", + "SQLITE_NOTICE_RECOVER_WAL", + "SQLITE_NULL", + "SQLITE_OK", + "SQLITE_OPEN_AUTOPROXY", + "SQLITE_OPEN_CREATE", + "SQLITE_OPEN_DELETEONCLOSE", + "SQLITE_OPEN_EXCLUSIVE", + "SQLITE_OPEN_FULLMUTEX", + "SQLITE_OPEN_MAIN_DB", + "SQLITE_OPEN_MAIN_JOURNAL", + "SQLITE_OPEN_MASTER_JOURNAL", + "SQLITE_OPEN_MEMORY", + "SQLITE_OPEN_NOMUTEX", + "SQLITE_OPEN_PRIVATECACHE", + "SQLITE_OPEN_READONLY", + "SQLITE_OPEN_READWRITE", + "SQLITE_OPEN_SHAREDCACHE", + "SQLITE_OPEN_SUBJOURNAL", + "SQLITE_OPEN_TEMP_DB", + "SQLITE_OPEN_TEMP_JOURNAL", + "SQLITE_OPEN_TRANSIENT_DB", + "SQLITE_OPEN_URI", + "SQLITE_OPEN_WAL", + "SQLITE_PERM", + "SQLITE_PRAGMA", + "SQLITE_PROTOCOL", + "SQLITE_RANGE", + "SQLITE_READ", + "SQLITE_READONLY", + "SQLITE_READONLY_CANTLOCK", + "SQLITE_READONLY_DBMOVED", + "SQLITE_READONLY_RECOVERY", + "SQLITE_READONLY_ROLLBACK", + "SQLITE_RECURSIVE", + "SQLITE_REINDEX", + "SQLITE_REPLACE", + "SQLITE_ROLLBACK", + "SQLITE_ROW", + "SQLITE_SAVEPOINT", + "SQLITE_SCHEMA", + "SQLITE_SELECT", + "SQLITE_SET_LOCKPROXYFILE", + "SQLITE_SHM_EXCLUSIVE", + "SQLITE_SHM_LOCK", + "SQLITE_SHM_NLOCK", + "SQLITE_SHM_SHARED", + "SQLITE_SHM_UNLOCK", + "SQLITE_SOURCE_ID", + "SQLITE_STATUS_MALLOC_COUNT", + "SQLITE_STATUS_MALLOC_SIZE", + "SQLITE_STATUS_MEMORY_USED", + "SQLITE_STATUS_PAGECACHE_OVERFLOW", + "SQLITE_STATUS_PAGECACHE_SIZE", + "SQLITE_STATUS_PAGECACHE_USED", + "SQLITE_STATUS_PARSER_STACK", + "SQLITE_STATUS_SCRATCH_OVERFLOW", + "SQLITE_STATUS_SCRATCH_SIZE", + "SQLITE_STATUS_SCRATCH_USED", + "SQLITE_STMTSTATUS_AUTOINDEX", + "SQLITE_STMTSTATUS_FULLSCAN_STEP", + "SQLITE_STMTSTATUS_SORT", + "SQLITE_STMTSTATUS_VM_STEP", + "SQLITE_SYNC_DATAONLY", + "SQLITE_SYNC_FULL", + "SQLITE_SYNC_NORMAL", + "SQLITE_TESTCTRL_ALWAYS", + "SQLITE_TESTCTRL_ASSERT", + "SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS", + "SQLITE_TESTCTRL_BITVEC_TEST", + "SQLITE_TESTCTRL_BYTEORDER", + "SQLITE_TESTCTRL_EXPLAIN_STMT", + "SQLITE_TESTCTRL_FAULT_INSTALL", + "SQLITE_TESTCTRL_FIRST", + "SQLITE_TESTCTRL_ISINIT", + "SQLITE_TESTCTRL_ISKEYWORD", + "SQLITE_TESTCTRL_LAST", + "SQLITE_TESTCTRL_LOCALTIME_FAULT", + "SQLITE_TESTCTRL_NEVER_CORRUPT", + "SQLITE_TESTCTRL_OPTIMIZATIONS", + "SQLITE_TESTCTRL_PENDING_BYTE", + "SQLITE_TESTCTRL_PRNG_RESET", + "SQLITE_TESTCTRL_PRNG_RESTORE", + "SQLITE_TESTCTRL_PRNG_SAVE", + "SQLITE_TESTCTRL_RESERVE", + "SQLITE_TESTCTRL_SCRATCHMALLOC", + "SQLITE_TESTCTRL_SORTER_MMAP", + "SQLITE_TESTCTRL_VDBE_COVERAGE", + "SQLITE_TEXT", + "SQLITE_TOOBIG", + "SQLITE_TRANSACTION", + "SQLITE_UPDATE", + "SQLITE_UTF16", + "SQLITE_UTF16BE", + "SQLITE_UTF16LE", + "SQLITE_UTF16_ALIGNED", + "SQLITE_UTF8", + "SQLITE_VERSION", + "SQLITE_VERSION_NUMBER", + "SQLITE_VTAB_CONSTRAINT_SUPPORT", + "SQLITE_WARNING", + "SQLITE_WARNING_AUTOINDEX", + "call_callback_sqlite3_create_collation_v2_1", + "call_callback_sqlite3_create_collation_v2_2", + "call_callback_sqlite3_create_function16_1", + "call_callback_sqlite3_create_function16_2", + "call_callback_sqlite3_create_function16_3", + "call_callback_sqlite3_create_function_1", + "call_callback_sqlite3_create_function_2", + "call_callback_sqlite3_create_function_3", + "call_callback_sqlite3_create_function_v2_1", + "call_callback_sqlite3_create_function_v2_2", + "call_callback_sqlite3_create_function_v2_3", + "call_callback_sqlite3_create_function_v2_4", + "call_callback_sqlite3_rtree_query_callback_1", + "call_callback_sqlite3_rtree_query_callback_2", + "char_p_array_getitem", + "char_p_array_setitem", + "delete_char_p_array", + "delete_sqlite3_p_array", + "delete_sqlite3_rtree_dbl_array", + "delete_sqlite3_stmt_p_array", + "delete_sqlite3_value_p_array", + "delete_sqlite3_vtab_cursor_p_array", + "delete_sqlite3_vtab_p_array", + "delete_void_p_array", + "new_char_p_array", + "new_sqlite3_p_array", + "new_sqlite3_rtree_dbl_array", + "new_sqlite3_stmt_p_array", + "new_sqlite3_value_p_array", + "new_sqlite3_vtab_cursor_p_array", + "new_sqlite3_vtab_p_array", + "new_void_p_array", + "sqlite3_aggregate_context", + "sqlite3_aggregate_count", + "sqlite3_auto_extension", + "sqlite3_auto_extension_lua_callback", + "sqlite3_backup_finish", + "sqlite3_backup_init", + "sqlite3_backup_pagecount", + "sqlite3_backup_remaining", + "sqlite3_backup_step", + "sqlite3_bind_blob", + "sqlite3_bind_blob64", + "sqlite3_bind_blob64_lua_callback", + "sqlite3_bind_blob_lua_callback", + "sqlite3_bind_double", + "sqlite3_bind_int", + "sqlite3_bind_int64", + "sqlite3_bind_null", + "sqlite3_bind_parameter_count", + "sqlite3_bind_parameter_index", + "sqlite3_bind_parameter_name", + "sqlite3_bind_text", + "sqlite3_bind_text16", + "sqlite3_bind_text16_lua_callback", + "sqlite3_bind_text64", + "sqlite3_bind_text64_lua_callback", + "sqlite3_bind_text_lua_callback", + "sqlite3_bind_value", + "sqlite3_bind_zeroblob", + "sqlite3_blob_bytes", + "sqlite3_blob_close", + "sqlite3_blob_open", + "sqlite3_blob_read", + "sqlite3_blob_reopen", + "sqlite3_blob_write", + "sqlite3_busy_handler", + "sqlite3_busy_handler_lua_callback", + "sqlite3_busy_timeout", + "sqlite3_cancel_auto_extension", + "sqlite3_cancel_auto_extension_lua_callback", + "sqlite3_changes", + "sqlite3_clear_bindings", + "sqlite3_close", + "sqlite3_close_v2", + "sqlite3_collation_needed", + "sqlite3_collation_needed16", + "sqlite3_collation_needed16_lua_callback", + "sqlite3_collation_needed_lua_callback", + "sqlite3_column_blob", + "sqlite3_column_bytes", + "sqlite3_column_bytes16", + "sqlite3_column_count", + "sqlite3_column_decltype", + "sqlite3_column_decltype16", + "sqlite3_column_double", + "sqlite3_column_int", + "sqlite3_column_int64", + "sqlite3_column_name", + "sqlite3_column_name16", + "sqlite3_column_text", + "sqlite3_column_text16", + "sqlite3_column_type", + "sqlite3_column_value", + "sqlite3_commit_hook", + "sqlite3_commit_hook_lua_callback", + "sqlite3_compileoption_get", + "sqlite3_compileoption_used", + "sqlite3_complete", + "sqlite3_complete16", + "sqlite3_config", + "sqlite3_context_db_handle", + "sqlite3_create_collation", + "sqlite3_create_collation16", + "sqlite3_create_collation16_lua_callback", + "sqlite3_create_collation_lua_callback", + "sqlite3_create_collation_v2", + "sqlite3_create_collation_v2_lua_callback", + "sqlite3_create_function", + "sqlite3_create_function16", + "sqlite3_create_function16_lua_callback", + "sqlite3_create_function_lua_callback", + "sqlite3_create_function_v2", + "sqlite3_create_function_v2_lua_callback", + "sqlite3_create_module", + "sqlite3_create_module_v2", + "sqlite3_create_module_v2_lua_callback", + "sqlite3_data_count", + "sqlite3_db_config", + "sqlite3_db_filename", + "sqlite3_db_handle", + "sqlite3_db_mutex", + "sqlite3_db_readonly", + "sqlite3_db_release_memory", + "sqlite3_db_status", + "sqlite3_declare_vtab", + "sqlite3_enable_load_extension", + "sqlite3_enable_shared_cache", + "sqlite3_errcode", + "sqlite3_errmsg", + "sqlite3_errmsg16", + "sqlite3_errstr", + "sqlite3_exec", + "sqlite3_exec_lua_callback", + "sqlite3_expired", + "sqlite3_extended_errcode", + "sqlite3_extended_result_codes", + "sqlite3_file", + "sqlite3_file_control", + "sqlite3_finalize", + "sqlite3_free", + "sqlite3_free_table", + "sqlite3_get_autocommit", + "sqlite3_get_auxdata", + "sqlite3_get_table", + "sqlite3_global_recover", + "sqlite3_index_info", + "sqlite3_index_info_aConstraint", + "sqlite3_index_info_aConstraintUsage", + "sqlite3_index_info_aOrderBy", + "sqlite3_initialize", + "sqlite3_interrupt", + "sqlite3_io_methods", + "sqlite3_last_insert_rowid", + "sqlite3_libversion", + "sqlite3_libversion_number", + "sqlite3_limit", + "sqlite3_load_extension", + "sqlite3_log", + "sqlite3_malloc", + "sqlite3_malloc64", + "sqlite3_mem_methods", + "sqlite3_memory_alarm", + "sqlite3_memory_highwater", + "sqlite3_memory_used", + "sqlite3_module", + "sqlite3_mprintf", + "sqlite3_msize", + "sqlite3_mutex_alloc", + "sqlite3_mutex_enter", + "sqlite3_mutex_free", + "sqlite3_mutex_leave", + "sqlite3_mutex_methods", + "sqlite3_mutex_try", + "sqlite3_next_stmt", + "sqlite3_open", + "sqlite3_open16", + "sqlite3_open_v2", + "sqlite3_os_end", + "sqlite3_os_init", + "sqlite3_overload_function", + "sqlite3_p_array_getitem", + "sqlite3_p_array_setitem", + "sqlite3_pcache_methods", + "sqlite3_pcache_methods2", + "sqlite3_pcache_page", + "sqlite3_prepare", + "sqlite3_prepare16", + "sqlite3_prepare16_v2", + "sqlite3_prepare_v2", + "sqlite3_profile", + "sqlite3_progress_handler", + "sqlite3_progress_handler_lua_callback", + "sqlite3_randomness", + "sqlite3_realloc", + "sqlite3_realloc64", + "sqlite3_release_memory", + "sqlite3_reset", + "sqlite3_reset_auto_extension", + "sqlite3_result_blob", + "sqlite3_result_blob64", + "sqlite3_result_blob64_lua_callback", + "sqlite3_result_blob_lua_callback", + "sqlite3_result_double", + "sqlite3_result_error", + "sqlite3_result_error16", + "sqlite3_result_error_code", + "sqlite3_result_error_nomem", + "sqlite3_result_error_toobig", + "sqlite3_result_int", + "sqlite3_result_int64", + "sqlite3_result_null", + "sqlite3_result_text", + "sqlite3_result_text16", + "sqlite3_result_text16_lua_callback", + "sqlite3_result_text16be", + "sqlite3_result_text16be_lua_callback", + "sqlite3_result_text16le", + "sqlite3_result_text16le_lua_callback", + "sqlite3_result_text64", + "sqlite3_result_text64_lua_callback", + "sqlite3_result_text_lua_callback", + "sqlite3_result_value", + "sqlite3_result_zeroblob", + "sqlite3_rollback_hook", + "sqlite3_rollback_hook_lua_callback", + "sqlite3_rtree_dbl_array_getitem", + "sqlite3_rtree_dbl_array_setitem", + "sqlite3_rtree_geometry", + "sqlite3_rtree_geometry_callback", + "sqlite3_rtree_geometry_callback_lua_callback", + "sqlite3_rtree_query_callback", + "sqlite3_rtree_query_callback_lua_callback", + "sqlite3_rtree_query_info", + "sqlite3_set_authorizer", + "sqlite3_set_authorizer_lua_callback", + "sqlite3_set_auxdata", + "sqlite3_set_auxdata_lua_callback", + "sqlite3_shutdown", + "sqlite3_sleep", + "sqlite3_snprintf", + "sqlite3_soft_heap_limit", + "sqlite3_soft_heap_limit64", + "sqlite3_sourceid", + "sqlite3_sql", + "sqlite3_status", + "sqlite3_step", + "sqlite3_stmt_busy", + "sqlite3_stmt_p_array_getitem", + "sqlite3_stmt_p_array_setitem", + "sqlite3_stmt_readonly", + "sqlite3_stmt_status", + "sqlite3_strglob", + "sqlite3_stricmp", + "sqlite3_strnicmp", + "sqlite3_test_control", + "sqlite3_thread_cleanup", + "sqlite3_threadsafe", + "sqlite3_total_changes", + "sqlite3_trace", + "sqlite3_trace_lua_callback", + "sqlite3_transfer_bindings", + "sqlite3_update_hook", + "sqlite3_update_hook_lua_callback", + "sqlite3_uri_boolean", + "sqlite3_uri_int64", + "sqlite3_uri_parameter", + "sqlite3_user_data", + "sqlite3_value_blob", + "sqlite3_value_bytes", + "sqlite3_value_bytes16", + "sqlite3_value_double", + "sqlite3_value_int", + "sqlite3_value_int64", + "sqlite3_value_numeric_type", + "sqlite3_value_p_array_getitem", + "sqlite3_value_p_array_setitem", + "sqlite3_value_text", + "sqlite3_value_text16", + "sqlite3_value_text16be", + "sqlite3_value_text16le", + "sqlite3_value_type", + "sqlite3_vfs", + "sqlite3_vfs_find", + "sqlite3_vfs_register", + "sqlite3_vfs_unregister", + "sqlite3_vtab", + "sqlite3_vtab_config", + "sqlite3_vtab_cursor", + "sqlite3_vtab_cursor_p_array_getitem", + "sqlite3_vtab_cursor_p_array_setitem", + "sqlite3_vtab_on_conflict", + "sqlite3_vtab_p_array_getitem", + "sqlite3_vtab_p_array_setitem", + "sqlite3_wal_autocheckpoint", + "sqlite3_wal_checkpoint", + "sqlite3_wal_checkpoint_v2", + "sqlite3_wal_hook", + "sqlite3_wal_hook_lua_callback", + "void_p_array_getitem", + "void_p_array_setitem", +} diff --git a/tex/generic/context/luatex/luatex-swiglib.lua b/tex/generic/context/luatex/luatex-swiglib.lua index 7ffcdc375..3108dd43f 100644 --- a/tex/generic/context/luatex/luatex-swiglib.lua +++ b/tex/generic/context/luatex/luatex-swiglib.lua @@ -8,7 +8,8 @@ if not modules then modules = { } end modules ['luatex-swiglib'] = { local savedrequire = require -local libsuffix = os.type == "windows" and ".dll" or ".so" +local libsuffix = os.type == "windows" and ".dll" or ".so" +local pathsplit = "([^" .. io.pathseparator .. "]+)" function requireswiglib(required,version) local library = package.loaded[required] @@ -17,7 +18,7 @@ function requireswiglib(required,version) else local name = string.gsub(required,"%.","/") .. libsuffix local list = kpse.show_path("clua") - for root in string.gmatch(list,"([^;]+)") do + for root in string.gmatch(list,pathsplit) do local full = false if type(version) == "string" and version ~= "" then full = root .. "/" .. version .. "/" .. name diff --git a/tex/generic/context/luatex/luatex-test.tex b/tex/generic/context/luatex/luatex-test.tex index 0bb752b3f..2aa4f22d9 100644 --- a/tex/generic/context/luatex/luatex-test.tex +++ b/tex/generic/context/luatex/luatex-test.tex @@ -158,4 +158,16 @@ $\sin{x}$ % \textdir TRT\amiri بِسْمِ اللَّـهِ الرَّحْمَـٰنِ الرَّحِيمِ % \egroup +% assumes csr10.tfm csr10.pfb csr.enc to be present + +% \font\foo=file:luatex-plain-tfm.lua:tfm=csr10;enc=csr;pfb=csr10 at 12pt +% +% \foo áäčďěíĺľňóôŕřšťúýž ff ffi + +% \font\foo=file:csr10.tfm:reencode=csr +% \font\foo=file:csr10.tfm:reencode=csr;bitmap=yes % use map file +% \font\foo=file:csr10.tfm:reencode=auto +% +% \foo áäčďěíĺľňóôŕřšťúýž ff ffi \input tufte\par + \end |